この記事では、MySQL8.0について調査している中で分かった些細な内容を、小ネタ集としてまとめてみました。
1. バイナリログを無効にしたいときは
17.1.6.4 Binary Logging Options and Variables
Binary logging is enabled by default, with the log_bin system variable set to ON.
上記のマニュアルの通り、MySQL8.0から、バイナリログがデフォルトで有効になりました。これにより特に意識しなくてもレプリケーションを使うことができますし、障害発生後のPITRなどでも役立ちます。
しかし、テスト環境やリソースに制限がある環境などでは、バイナリログを無効にしたいという要望もあるかと思います。これまでであれば、my.cnf に "log_bin" パラメータを書かなければよかったのですが、8.0からはそうもいきません。
また、"log_bin = OFF" や "log_bin = 0" といったパラメータを設定すると、『OFF.000001』のような名前のバイナリログが生成されてしまいます。
MySQL8.0でバイナリログを無効にする場合は、my.cnf に "disable-log-bin"(もしくは"skip-log-bin")というパラメータを記載します。または、mysqld の起動時に –disable-log-bin オプションを指定しても構いません。
2. コンポーネントとは?
これまでMySQLで特定の機能を追加したい場合は、以下のように「Plugin」(プラグイン)を使用するのが一般的でした。
1 |
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; |
MySQL8.0からは、上記に加え「Components」(コンポーネント)という機能が追加されました。両者は基本的に同じようなものですが、Componentsはプラットフォームの種類に左右されずにインストールできるというメリットがあるようです。
This means that a given INSTALL COMPONENT statement can be executed uniformly across platforms.
現在有効となっているコンポーネントの確認は、以下のクエリで行います。初期状態では「component_validate_password」のみが有効となっています。これはMySQL5.7で導入されたvalidate_passwordプラグインの後継です。
1 2 3 4 5 6 7 |
mysql> SELECT * FROM mysql.component; +--------------+--------------------+------------------------------------+ | component_id | component_group_id | component_urn | +--------------+--------------------+------------------------------------+ | 1 | 1 | file://component_validate_password | +--------------+--------------------+------------------------------------+ 1 row in set (0.01 sec) |
コンポーネントの場合、設定する変数名もプラグインとは異なります。component_validate_passwordの場合は以下のようになります。設定の変更は引き続き SET GLOBAL文で行うことができます。
※ その他、詳細については下記のマニュアルを参照してください。
6.5.3 The Password Validation Component
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
mysql> SHOW GLOBAL VARIABLES LIKE 'validate_password.%'; +--------------------------------------+--------+ | Variable_name | Value | +--------------------------------------+--------+ | validate_password.check_user_name | ON | | validate_password.dictionary_file | | | validate_password.length | 8 | | validate_password.mixed_case_count | 1 | | validate_password.number_count | 1 | | validate_password.policy | MEDIUM | | validate_password.special_char_count | 1 | +--------------------------------------+--------+ 7 rows in set (0.02 sec) mysql> SET GLOBAL validate_password.policy = LOW; Query OK, 0 rows affected (0.01 sec) |
また、コンポーネントのインストール / アンインストール方法は以下の通りです。
1 2 |
mysql> UNINSTALL COMPONENT 'file://component_validate_password'; Query OK, 0 rows affected (0.06 sec) |
3. Undoログの自動拡張がデフォルト有効に
素の状態の MySQL5.7 と MySQL8.0 のデータディレクトリを見比べてみると、MySQL8.0には「undo_001」なるファイルが作られていることに気が付きます。
1 2 3 4 |
$ sudo ls -l /var/lib/mysql ... -rw-r-----. 1 mysql mysql 12582912 7月 4 06:42 undo_001 -rw-r-----. 1 mysql mysql 12582912 7月 4 07:53 undo_002 |
これは、MySQL8.0から innodb_undo_tablespaces 変数のデフォルト値が「0」から「2」に変更になったことが原因です。このパラメータ変数は、Undoログの切り捨て機能で使用されます。
従来のMySQLでは長時間実行されるトランザクションなどがあると、Undoログが肥大化してしまい、元に戻すことは難しいケースが多くありました(MySQLの再起動が必要)。しかし、上記の機能を使えばUndoログのみ共通テーブルスペース(ibdata1)から切り離すことができ、なおかつMySQLが自動で肥大化した領域を削除するようになります。これにより、MySQL運用者の負担は軽減されるのではないでしょうか。
4. 予約語がテーブルで管理される
MySQL自体がシステム上使用する英単語などは、予約語とされテーブル名などに使用できません。従来は予約語に関しては内部的に管理されており、触れることができませんでしたが、MySQL8.0からは information_schema の KEYWORDS テーブルで管理されるようになりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
mysql> USE information_schema; mysql> SELECT * FROM KEYWORDS; +-------------------------------+----------+ | WORD | RESERVED | +-------------------------------+----------+ | ACCESSIBLE | 1 | | ACCOUNT | 0 | | ACTION | 0 | | ADD | 1 | | ADMIN | 1 | ... | YEAR | 0 | | YEAR_MONTH | 1 | | ZEROFILL | 1 | +-------------------------------+----------+ 675 rows in set (0.00 sec) |
このKEYWORDSテーブルを改変しようとしても、以下のようにrootユーザでも権限で弾かれます。
1 2 3 4 5 |
mysql> UPDATE KEYWORDS SET RESERVED = 0 WHERE WORD = "ADMIN"; ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'information_schema' mysql> CREATE DATABASE ADMIN; ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ADMIN' at line 1 |
ちなみに、以下のようにオブジェクト名を引用符で囲ってしまえば、例え予約語であっても使用できてしまいます。もちろん、推奨はしません。
1 2 |
mysql> CREATE DATABASE <code>ADMIN</code>; Query OK, 1 row affected (0.08 sec) |
5. MySQL5.7 / MySQL8.0 のデータディレクトリ比較
最後にMySQL5.7とMySQL8.0のデータディレクトリを比較してみましょう。両者ともOracle公式のyumリポジトリでインストールしており、my.cnfは変更していません。
※ バージョンは MySQL8.0.11 / MySQL 5.7.22 です
まずはデータディレクトリ内の使用データ量です。MySQL8.0の方が30MBほど大きいのが分かります。
1 2 3 4 5 |
mysql80$ sudo du -sh /var/lib/mysql 166M /var/lib/mysql mysql57$ sudo du -sh /var/lib/mysql 134M /var/lib/mysql |
次にデータディレクトリ内に含まれるファイル / ディレクトリを比較します。
ls -R でデータディレクトリ内に存在する全ファイルの一覧を出力し、diffコマンドで比較します。
(件数が多いので一部省略しています)
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 |
mysql80$ sudo ls -R /var/lib/mysql/ > ls_result_80.txt mysql57$ sudo ls -R /var/lib/mysql/ > ls_result_57.txt $ diff ls_result_80.txt ls_result_57.txt 3,4d2 < binlog.000001 < binlog.index 15d12 < mysql.ibd 24,25d20 < undo_001 < undo_002 27a23,37 > columns_priv.MYD > columns_priv.MYI > columns_priv.frm > db.MYD > db.MYI > db.frm > db.opt ... 33c81,97 < slow_log_196.sdi --- > slow_log.frm ... > user.MYD > user.MYI > user.frm 36,137c100,187 < accounts_133.sdi < cond_instances_72.sdi < data_lock_waits_148.sdi < data_locks_147.sdi ... |
気になる点をいくつかピックアップします。
- MySQL8.0は log_bin がデフォルト有効なので、バイナリログが作成されています。
- MySQL5.7には .frm / .MYD / .opt などのファイルがありますが、MySQL8.0は .ibd ファイルのみになっています。これは、MySQL8.0からシステムテーブル(mysqlスキーマ)がInnoDBになり、なおかつInnoDBのデータディクショナリの構成が変更になったためです。
- MySQL8.0 には .sdi というファイルが作成されています。このファイルは、「Serialized Dictionary Information」と呼ばれ、従来のメタファイルと同等の内容が含まれています。なおInnoDBテーブルでは作成されません。
まとめ
GA版のリリースノートの長さから分かる通り、MySQL8.0にはかなり大きな改良が加えられています。その全貌を明らかにするにはまだまだ時間も紙面も足りませんが、今後も少しずつ情報発信できればと思います。