お菓子と紅茶と、時々IT

趣味のお菓子(作る方)と紅茶の話、そして今進めているIT(プログラミングなど)に関する勉強の記録。

MySQLでバイナリログを利用

ローカルに、HomebrewでMySQLをインストールした。

ちなmac使用。

% brew install mysql

 

my.cnfにlog-binという一行を追加してやると、MySQLサーバーの起動時・停止時にバイナリログを出力してくれるようになる。

% pwd

/usr/local/etc

% cat my.cnf

# Default Homebrew MySQL server config

[mysqld]

# Only allow connections from localhost

bind-address = 127.0.0.1

mysqlx-bind-address = 127.0.0.1

log-bin

もちろん、設定変更後はMySQLサーバーの再起動を忘れないでね。

 

バイナリログファイルは /usr/local/var/mysql ディレクトリ配下に格納される。

バイナリログファイルのみならず、デフォルトのエラーログファイルとかMySQLサーバー起動時に必要なPIDファイルとかなんかも、ここにあった。

% pwd

/usr/local/var/mysql

% ls

#ib_16384_0.dblwr

ib_logfile0

performance_schema

#ib_16384_1.dblwr

ib_logfile1

private_key.pem

#innodb_temp

ibdata1

public_key.pem

auto.cnf ibtmp1

server-cert.pem

binlog.000001

username-bin.000001

server-key.pem

binlog.index

username-bin.000002

sys

ca-key.pem

username-bin.index

test

ca.pem

username.local.err

undo_001

client-cert.pem

username.local.pid

undo_002

client-key.pem

mysql

ib_buffer_pool

mysql.ibd

 

...ん?でも、このmy.cnfで設定したやつ起因のバイナリログファイルって、

binlog.000001

username-bin.000001

username-bin.000002

のうち、どっちなんだろうな。

どっちかが、デフォルトで出力されているバイナリファイルなんではないか。

 

試しに、my.cnfの設定を変更してみる(インストールした直後のデフォルトの状態へ戻す)。

% cat /usr/local/etc/my.cnf

# Default Homebrew MySQL server config

[mysqld]

# Only allow connections from localhost

bind-address = 127.0.0.1

mysqlx-bind-address = 127.0.0.1

 

MySQLサーバーを再起動させて、再度/usr/local/var/mysqlのバイナリログファイルらしきものを確認してみる

% sudo mysql.server restart

% cd /usr/local/var/mysql

% ls

余計なファイルがありすぎるので、バイナリログファイルっぽいものだけ抜粋すると...。

binlog.000001

binlog.000002

username-bin.000001

username-bin.000002

binlogの方が1ファイル増えておる。

 

再度、MySQLサーバーを再起動してみる。

% sudo mysql.server restart

Shutting down MySQL

. SUCCESS!

Starting MySQL

.. SUCCESS!

 

再度バイナリログファイルを確認してみる。

binlog.000001

binlog.000002

binlog.000003

username-bin.000001

username-bin.000002

 

やはり、binlogの方が1ファイル増えている。

てことは、今はもうデフォルトでbinlog.{連番} という形式でバイナリログファイルを出力してくれているということだな。

 

この状態で、mysqlにテーブルとレコードをセット。

mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 DATETIME);

Query OK, 0 rows affected (0.01 sec)

 

mysql> INSERT INTO t1 VALUES(1, NOW());

Query OK, 1 row affected (0.00 sec)

 

mysql> SELECT * FROM t1;

+----+---------------------+

| c1 | c2                  |

+----+---------------------+

|  1 | 2021-10-28 08:54:12 |

+----+---------------------+

1 row in set (0.00 sec)

 

mysql> quit

Bye

 

最新のバイナリログファイルをrecover.sqlという名前のsql文ファイルへ変換。

% sudo mysqlbinlog binlog.000003 > ~/recover.sql

 

確認してみると、SETほにゃららみたいな文言があったので、このバイナリファイルにテーブル&レコードをインサートしたSQL文実行履歴が確かに記録されていたとわかる。

% less ~/recover.sql

 

t1テーブルのレコードを削除してみる。

mysql> SHOW tables;

+----------------+

| Tables_in_test |

+----------------+

| t1             |

+----------------+

1 row in set (0.00 sec)

 

mysql> DELETE FROM t1;

Query OK, 1 row affected (0.00 sec)

 

mysql> SELECT * FROM t1;

Empty set (0.00 sec)

 

mysql> quit

Bye

 

さっき作ったrecover.sqlmysqlコマンドで実行。

% mysql -u root < ~/recover.sql

 

MySQLに再度接続して確認。

mysql> USE test;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> SELECT * FROM t1;

+----+---------------------+

| c1 | c2                  |

+----+---------------------+

|  1 | 2021-10-28 08:54:12 |

+----+---------------------+

1 row in set (0.00 sec)

 

mysql> quit;

Bye

 

おっ!無事レコードが復旧してますね!!

 

ちなみに、ずっとバックアップ取ってなくてかつその間に何度もサーバーが落ちていたら、その間に発生したバイナリログファイルを複数sql文へ書き換えては実行して、というのをやらないといけない。