TL; DR;
*IDENTIFIED*:*PASSWORD*にマッチしたクエリ、つまりパスワードを含むクエリはヒストリーに記録されない- 環境変数
MYSQL_HISTIGNOREで記録しないクエリを追加指定できる
ヒストリーに記録されない時がある
mysql コマンド には履歴機能があります。
Linuxのシェルのように、過去に実行したSQLを上の矢印キーで遡ったり、Ctrl-R でキーワード検索することが出来ます。
時々、ヒストリーに記録されないSQLがあることが気になっていました。 今回はその条件を調べてみました。
ソースから辿ってみる
client/mysql.cc を読んでいきます。
add_filtered_history() という関数でヒストリーファイルに追記しています。
ignore_matcher がヒストリーに残さないものを判定していそうです。
2929 /* Add the given line to mysql history and syslog. */
2930 static void add_filtered_history(const char *string) {
2931 // line shouldn't be on history ignore list
2932 if (ignore_matcher.is_matching(string, charset_info)) return;
2933
2934 #ifdef HAVE_READLINE
2935 if (!quick && not_in_history(string)) add_history(string);
2936 #endif
2937
2938 if (opt_syslog) add_syslog(string);
2939 }
ignore_matcher は 以下の箇所で定義されており、HI_DEFAULTS がデフォルト値です。
そして、 MYSQL_HISTIGNORE という環境変数でヒストリーに記録しないパターンを追加できることもわかりました。
1349 if (!status.batch) {
1350 // history ignore patterns are initialized to default values
1351 ignore_matcher.add_patterns(HI_DEFAULTS);
1352
1353 /*
1354 Additional patterns may be supplied using either --histignore option or
1355 MYSQL_HISTIGNORE environment variable. If supplied, they'll get appended
1356 to the default patterns. In case both are specified, pattern(s) supplied
1357 using --histignore option will be used.
1358 */
1359 if (opt_histignore)
1360 ignore_matcher.add_patterns(opt_histignore);
1361 else if (getenv("MYSQL_HISTIGNORE"))
1362 ignore_matcher.add_patterns(getenv("MYSQL_HISTIGNORE"));
HI_DEFAULTS は以下のように定義されていました。
パスワードが入っているSQLをヒストリーに記録してしまうと、ヒストリーファイルからパスワードが読み取られてしまうリスクがあるため、記録しないということでしょう。
132 /** default set of patterns used for history exclusion filter */
133 const static std::string HI_DEFAULTS("*IDENTIFIED*:*PASSWORD*");
MYSQL_HISTIGNORE を試してみる
環境変数 MYSQL_HISTIGNORE で無視する条件を追加してみます。
HIMITSU を含んだSQLをヒストリーに記録しないようにします。
$ export MYSQL_HISTIGNORE='*HIMITSU*' $ mysql mysql> SELECT 'HOGEHOGE'; +----------+ | HOGEHOGE | +----------+ | HOGEHOGE | +----------+ 1 row in set (0.00 sec) mysql> SELECT 'HIMITSU NO HOGEHOGE'; +---------------------+ | HIMITSU NO HOGEHOGE | +---------------------+ | HIMITSU NO HOGEHOGE | +---------------------+ 1 row in set (0.00 sec)
ちゃんと、HIMITSU NO HOGEHOGE が無視されて、HOGEHOGEだけがヒストリーファイルに記録されてました。
$ cat ~/.mysql_history _HiStOrY_V2_ SELECT\040'HOGEHOGE'; exit
マニュアルにも書いてある
ソースから辿りましたが、マニュアルにもちゃんと記載がありました。
mysql ignores for logging purposes statements that match any pattern in the “ignore” list. By default, the pattern list is "IDENTIFIED:PASSWORD", to ignore statements that refer to passwords. Pattern matching is not case-sensitive. Within patterns, two characters are special: https://dev.mysql.com/doc/refman/8.0/en/mysql-logging.html