MySQL には binlog を出力する機能があります。binlog はこちらで紹介したレプリケーションなどで利用されます。binlog のフォーマットには STATEMENT,ROW,MIXED の三種類があります。MIXED は残り二つの混在モードのようなものですので STATEMENT,ROW の二つについて具体的に紹介します。検証用 MySQL のバージョンは 5.5 です。
MySQL Internals Manual::Chapter 19 The Binary Log
まずはサービスを停止します。これを忘れると後々設定が反映されずに困ります。
$ sudo service mysqld stop
my.cnf を編集して binlog を出力するように設定しておきましょう。ついでに NFS など外部ストレージを /data にマウントする場合を想定したその他の設定も行います。
$ sudo cp /etc/my.cnf /etc/my.cnf.backup
$ sudo vi /etc/my.cnf
設定例
[mysqld] # mysqld の設定
server-id=000001 # mysql サーバ ID
log-bin=mysql-bin # binlog ファイル名
datadir=/data/mysql # binlog などの出力先ディレクトリ
socket=/tmp/mysql.sock # UNIX ドメインソケット
user=mysql # mysqld ユーザ
binlog_format=2 # binlog フォーマット (0:MIXED, 1:STATEMENT, 2:ROW) ★
[mysqld_safe] # mysqld_save の設定
log-error=/var/log/mysqld.log # ログファイル
pid-file=/var/run/mysqld/mysqld.pid # PID ファイル
[mysql] # mysql クライアントの設定
socket=/tmp/mysql.sock # UNIX ドメインソケット
# これを指定しないと mysql -uroot -p -S /tmp/mysql.sock が毎回必要
ディレクトリを作成して既存のものを移動します。
$ sudo mkdir /data
$ sudo mv /var/lib/mysql /data/
サービスの起動
$ sudo service mysqld start
my.cnf で binlog_format を 2 に設定したので ROW になっています。既定値は 1 STATEMENT です。
mysql> SELECT @@binlog_format;
+-----------------+
| @@binlog_format |
+-----------------+
| ROW |
+-----------------+
1 row in set (0.00 sec)
以下のような SQL 文を発行してみます。
mysql> CREATE DATABASE mydb;
mysql> USE mydb;
mysql> CREATE TABLE my_table (
f1 integer,
f2 varchar(8)
);
mysql> INSERT INTO my_table VALUES (1,'abcd');
現在までの binlog を確認してみましょう。STATEMENT の SQL 文 (UPDATE,INSERT,DELETE) が base64 エンコードされた binlog になっています。
$ sudo mysqlbinlog /data/mysql/mysql-bin.000001 | less
...
CREATE DATABASE mydb
...
BINLOG '
qZQ3VRMBAAAAMgAAAKoBAAAAACEAAAAAAAEABG15ZGIACG15X3RhYmxlAAIDDwIIAAM=
qZQ3VRcBAAAAJwAAANEBAAAAACEAAAAAAAEAAv/8AQAAAARhYmNk
...
以下のコマンドで base64 デコードした状態で閲覧できます。
$ sudo mysqlbinlog /data/mysql/mysql-bin.000001 --base64-output=DECODE-ROWS -v | less
...
### INSERT INTO `mydb`.`my_table`
### SET
### @1=1
### @2='abcd'
...