はじめに
以前、MySQL Shell から実行したSQLをログに出力する制御方法ついて記事を記載しました。
最新の MySQL Shell 8.0.30 のバージョンでは、上記記事でご紹介しました制御方法から情報をアップデートする必要がありそうですので、記事にしたいと思います。
変更内容
MySQL Shell 8.0.29 までは、冒頭に記載しました過去の記事の通り、dba.logSql
オプションを指定して制御を行う必要がありました。
しかし、MySQL Shell 8.0.30 では リリースノートに以下の記載があり、dba.logSql
オプションでの制御は非推奨となり、新たに追加された logSql
オプションで制御する事になるようです。
The new option, logSql/–log-sql enables you to log all SQL statements executed by MySQL Shell commands or utilities to the MySQL Shell log file.
Note
This option deprecates dba.logSql.
検証
それでは、確認していきたいと思います。
まずは、MySQL Shell 8.0.30 で、オプションを確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
MySQL JS > \option -l autocomplete.nameCache true batchContinueOnError false connectTimeout 10 credentialStore.excludeFilters [] credentialStore.helper default credentialStore.savePasswords prompt dba.connectTimeout 5 dba.gtidWaitTimeout 60 dba.logSql 0 dba.restartWaitTimeout 60 defaultCompress false defaultMode none devapi.dbObjectHandles true history.autoSave false history.maxSize 1000 history.sql.ignorePattern *IDENTIFIED*:*PASSWORD* history.sql.syslog false interactive true logFile /root/.mysqlsh/mysqlsh.log logLevel 5 logSql error logSql.ignorePattern SELECT*:SHOW*:*IDENTIFIED*:*PASSWORD* mysqlPluginDir "" oci.configFile /root/.oci/config oci.profile DEFAULT outputFormat table pager "" passwordsFromStdin false resultFormat table sandboxDir /root/mysql-sandboxes showColumnTypeInfo false showWarnings true ssh.bufferSize 10240 ssh.configFile "" useWizards true verbose 0 |
以下の2つのオプションが新たに追加されています。
オプション | 設定値 |
---|---|
logSql | error |
logSql.ignorePattern | SELECT*:SHOW*:*IDENTIFIED*:*PASSWORD* |
詳細については、以下のリファレンスに記載されています。
- 13.4 Configuring MySQL Shell Options
- 12.4 MySQL Shell SQL Logging / SQL Logging Options
(執筆時点では、日本語リファレンスには最新情報が反映されていなかった為、英語リファレンスへのリンクとしています)
logSql
の設定については、以下のようになります。
設定値 | 詳細 |
---|---|
off | SQLをログに記録しない。 |
error | エラーとなったSQLのみを記録する。 ※デフォルト値 |
on | logSql.ignorePattern にマッチングしないSQLのみを記録する。 |
unfiltered | logSql.ignorePattern の設定に関係なく全てのSQLを記録する。 |
on
を設定した場合に、logSql.ignorePattern
のパターン設定が適用されるということのようです。
デフォルトでは、 SELECT*:SHOW*:*IDENTIFIED*:*PASSWORD*
にマッチングしないSQLがログに出力されます。
各設定値に沿って、以下の 6 パターンのSQLを実行して、ログの出力状況を確認してみたいと思います。
① SELECT ステートメント
1 2 3 4 5 6 |
MySQL mysql:33060+ ssl SQL > SELECT Code, Name, Population FROM world.country WHERE Code = 'JPN'; +------+-------+------------+ | Code | Name | Population | +------+-------+------------+ | JPN | Japan | 126714000 | +------+-------+------------+ |
② UPDATE ステートメント
1 2 3 4 |
MySQL mysql:33060+ ssl SQL > UPDATE world.country SET Population = 126715000 WHERE Code = 'JPN'; Query OK, 1 row affected (0.0038 sec) Rows matched: 1 Changed: 1 Warnings: 0 |
③ SHOW ステートメント
1 2 3 4 5 6 |
MySQL mysql:33060+ ssl SQL > SHOW GLOBAL VARIABLES LIKE 'version'; +---------------+--------+ | Variable_name | Value | +---------------+--------+ | version | 8.0.30 | +---------------+--------+ |
④ CREATE USER ステートメント(IDENTIFIED含む)
1 2 |
MySQL mysql:33060+ ssl SQL > CREATE USER user01@localhost IDENTIFIED BY 'MySQL8.0'; Query OK, 0 rows affected (0.0097 sec) |
⑤ SET PASSWORD ステートメント
1 2 |
MySQL mysql:33060+ ssl SQL > SET PASSWORD FOR user01@localhost = 'mYsql8.0'; Query OK, 0 rows affected (0.0087 sec) |
⑥ SELECT ステートメント(エラー)
1 2 |
MySQL mysql:33060+ ssl SQL > SELECT Code, Name, Population FROM world.country2 WHERE Code = 'JPN'; ERROR: 1146: Table 'world.country2' doesn't exist |
logSql = off
logSql = off
に設定します。
1 2 3 |
MySQL mysql:33060+ ssl JS > shell.options["logSql"]='off'; off MySQL mysql:33060+ ssl JS > |
設定変更後、6 つのSQLを実行しましたが、想定通り、全てのSQLがログに出力されませんでした。
(ログはデフォルトでは、 ~/.mysqlsh/mysqlsh.log
に出力されます。)
logSql = error
次はデフォルト設定となる、logSql = error
に設定し、各SQLを実行します。
1 2 3 |
MySQL mysql:33060+ ssl JS > shell.options["logSql"]='error'; error MySQL mysql:33060+ ssl JS > |
「⑥ SELECT ステートメント(エラー)」のみがログに出力され、想定通りの結果となりました。
1 |
2022-09-25 01:31:14: Info: sql: tid=25: MySQL Error 1146: Table 'world.country2' doesn't exist, SQL: SELECT Code, Name, Population FROM world.country2 WHERE Code = 'JPN' |
ただ、この設定では、logSql.ignorePattern
は適用されない為、例えばパスワード設定するようなSQLでも、そのままログに出力される為、注意が必要です。
1 |
2022-09-25 01:32:26: Info: sql: tid=8: MySQL Error 1396: Operation CREATE USER failed for 'user02'@'localhost', SQL: create user user02@localhost identified by 'MySQL8.0' |
logSql = on
次は、logSql = on
に設定し、各SQLを実行します。
1 2 3 |
MySQL mysql:33060+ ssl JS > shell.options["logSql"]='on'; on MySQL mysql:33060+ ssl JS > |
「② UPDATE ステートメント」が想定通り出力されました。
1 2 |
2022-09-25 01:42:27: Info: sql: tid=25: SQL: UPDATE world.country SET Population = 126715000 WHERE Code = 'JPN' 2022-09-25 01:42:56: Info: sql: tid=25: MySQL Error 1146: Table 'world.country2' doesn't exist, SQL: <filtered> |
また、実行エラーとなる「⑥ SELECT ステートメント(エラー)」もエラーメッセージのみが出力されていますが、実行したSELECTステートメントは SQL: <filtered>
となっています。
試しに、logSql.ignorePattern
から SELECT*
を除外して、もう一度実行してみます。
1 2 3 |
MySQL mysql:33060+ ssl JS > shell.options["logSql.ignorePattern"]='SHOW*:*IDENTIFIED*:*PASSWORD*'; SHOW*:*IDENTIFIED*:*PASSWORD* MySQL mysql:33060+ ssl JS > |
実行エラーとなった SELECT ステートメントについても、ログが出力されるようになりました。
1 2 3 |
2022-09-25 01:51:07: Info: main: tid=25: SQL: select schema() 2022-09-25 01:51:14: Info: sql: tid=25: SQL: SELECT Code, Name, Population FROM world.country2 WHERE Code = 'JPN' 2022-09-25 01:51:14: Info: sql: tid=25: MySQL Error 1146: Table 'world.country2' doesn't exist |
logSql = unfiltered
logSql = unfiltered
に設定し、各SQLを実行します。
1 2 3 |
MySQL mysql:33060+ ssl JS > shell.options["logSql"]='unfiltered'; on MySQL mysql:33060+ ssl JS > |
全ての実行したSQLがログに含まれていることが確認できます。
1 2 3 4 5 6 7 8 |
2022-09-25 01:58:43: Info: main: tid=25: SQL: select schema() 2022-09-25 01:59:10: Info: sql: tid=25: SQL: SELECT Code, Name, Population FROM world.country WHERE Code = 'JPN' 2022-09-25 01:59:17: Info: sql: tid=25: SQL: UPDATE world.country SET Population = 126715000 WHERE Code = 'JPN' 2022-09-25 01:59:24: Info: sql: tid=25: SQL: SHOW GLOBAL VARIABLES LIKE 'version' 2022-09-25 01:59:30: Info: sql: tid=25: SQL: CREATE USER user01@localhost IDENTIFIED BY 'MySQL8.0' 2022-09-25 01:59:35: Info: sql: tid=25: SQL: SET PASSWORD FOR user01@localhost = 'mYsql8.0' 2022-09-25 01:59:43: Info: sql: tid=25: SQL: SELECT Code, Name, Population FROM world.country2 WHERE Code = 'JPN' 2022-09-25 01:59:43: Info: sql: tid=25: MySQL Error 1146: Table 'world.country2' doesn't exist |
まとめ
従来の dba.logSql
との大きな違いとしては、logSql.ignorePattern
の設定によって、ログに出力するSQLを細かく制御できるようになっています。
先週に引き続き、MySQL Shell の記事となりましたが、MySQL Shell が益々便利になっていく様子が伺えますので、今後のアップデートにも期待したいと思います。