前提
- alibaba cloud上でRDS MySQL8のインスタンスがすでに作られている。
- RDSに以下の三種類がありまして、今回の検証は基礎版
Basic
で問題ありません。-
Basic
: 一つのinstanceしかありません。一時的な検証やテスト環境、開発環境など本番環境以外で利用されるのは一般的です。 -
High-availability
:- AWS RDSのmulti AZに似ている機能です
- primary instanceとsecondary instance(standby instance)の2つのinstanceで構成されている
- userから見ると、通常はprimary instanceしか利用されていない。
- secondary instanceはあくまでもstandby用であり、primary instanceが利用できない時は自動的にsecondary instanceにfail overすることになる。
-
Enterprise
:- 一つのprimary instance, 一つのsecondary instance, 一つのlogger instanceという合計3つのinstanceから構成されている
- 非常に高い可用性が求められている金融系などによく利用されている
-
binlogについて
- binlogはstorage engineとは関係なくて、上位のexcution engine(layer)の機能であり、つまりinnodbとMyISAMのどちらのストレージエンジンを使っても、binlogが生成されるということです。
- binlogはバイナリ形式でディスクに保存される論理ログ
- binlogは、データベースに対するすべてのDDLおよびDML操作(SELECTやSHOWなど、データそのものを変更しないコマンドを除く)を記録します。
- 誤って削除したデータを復元する場合、binlogを利用します。データベースのバックアップをベースに、バックアップ時点から指定時点の間のbinlogを適用することで、指定時点のデータを復元できます。
- また、マスタスレーブ構成で2つ以上のデータベースサーバが存在する場合、マスタサーバからスレーブサーバにbinlogの内容を転送します。スレーブサーバがbinlogを適用して、マスタサーバのデータと一致性を保ちます。
binglogとredo logの違いについては以下をご参考ください。
検証内容
- RDSのbinlogはデフォルトで有効であり、しかも無効にすることができない。
mysql> SHOW VARIABLES LIKE 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
mysql> SET GLOBAL log_bin=0;
ERROR 1238 (HY000): Variable 'log_bin' is a read only variable
- binlogのフォーマットに以下の三種類がありますが、RDSはRBRであり、しかも変更することもできない。
- SBR(statement base replication):
- insert,update,deleteなどのクエリ文がそのままバイナリログに記録される方式
- sysdate()などの実行時点で結果が変わってしまうような関数が起因し、復元前と完全に一致しない場合があるため、こちらを選択する理由はそもそもないだろう
- 以前はSTATEMENTがデフォルトでしたが、MySQL8.0からデフォルトはROWになっています。
- RBR(row base replication):
- 更新された行のデータそのものがバイナリログに記録される方式
- SQL 文 (UPDATE,INSERT,DELETE) が base64 エンコードされる
- MBR(mixed base replication):処理の内容に応じて同期にモードを切り替えられる
- 実行時点で結果が変わってしまうような関数の場合は、自動的に更新された行のデータそのものがバイナリログに記録される
- そうでないクエリはクエリ文そのままバイナリログに記録される方式
- SBR(statement base replication):
mysql> SHOW GLOBAL VARIABLES LIKE 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
mysql> SET GLOBAL binlog_format = 'MIXED';
ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER or SYSTEM_VARIABLES_ADMIN privilege(s) for this operation
- DDLおよびDML操作をしなくても、数秒ごとにbinlogにログが追加される
mysql> show binary logs;
+------------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000004 | 443190 | No |
| mysql-bin.000005 | 137446 | No |
+------------------+-----------+-----------+
mysql> show binary logs;
+------------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000004 | 443190 | No |
| mysql-bin.000005 | 137751 | No |
+------------------+-----------+-----------+
→数秒経ったら、上記のmysql-bin.000005
のFile_size
は変わってしまう。
- mysqlbinlogコマンドbinlogを取得してみる
$ mysqlbinlog -h rm-****.mysql.japan.rds.aliyuncs.com -u wangdan --read-from-remote-server --result-file=binlog mysql-bin.000005 -p
$ tail -n 20 binlog
BEGIN
/*!*/;
# at 148271
#220825 19:57:04 server id 100100013 end_log_pos 148339 CRC32 0xd008eee2 Table_map: `mysql`.`ha_health_check` mapped to number 122
# at 148339
#220825 19:57:04 server id 100100013 end_log_pos 148395 CRC32 0xd91f45ea Update_rows_v1: table id 122 flags: STMT_END_F
BINLOG '
gFUHYxOtZ/cFRAAAAHNDAgAAAHoAAAAAAAEABW15c3FsAA9oYV9oZWFsdGhfY2hlY2sAAgj+Av4D
AQEBAAIBIeLuCNA=
gFUHYxitZ/cFOAAAAKtDAgAAAHoAAAAAAAEAAv//ALvBpdSCAQAAAW0AjPyl1IIBAAABbepFH9k=
'/*!*/;
# at 148395
#220825 19:57:04 server id 100100013 end_log_pos 148426 CRC32 0xc459ca5f Xid = 155492
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
binlogからmysql
.ha_health_check
がupdateされていたようなので、中身を確認してみると数秒ごとにidが変わっていたことが分かりました。
おそらく、可用性担保するためには内部で数秒ごとにhealth checkがされていて、health checkの結果がシステムdatabaseのmysql
のha_health_check
というテーブルに書き込まれているようです。
mysql> select * from mysql.ha_health_check;
+---------------+------+
| id | type |
+---------------+------+
| 1661425174265 | k |
| 1661425174254 | m |
+---------------+------+
mysql> select * from mysql.ha_health_check;
+---------------+------+
| id | type |
+---------------+------+
| 1661425189252 | k |
| 1661425189223 | m |
+---------------+------+
- binlogにはSQL文(UPDATE,INSERT,DELETE) が base64 エンコードされていること