frei

旧「anney's room」からブログ「frei」だけ引っ越し&残しました

binlog。

仕事でエラーログを調査してたら

INSERT文が発行されたはずのタイミングで

mysql の binlog が保存されていない。

うーん、そういう仕様なんだっけ?

...と小首をかしげつつ、

上司さんに助言を求めてみたところ

rollback したトランザクションのログは記録されないのだそうで。

えー?そうなのかー。うーん、おかしいなぁ、

前の会社でバッチがエラった時に、

調査してた binlog には、コケたINSERT文が

ROLLBACK の文字列と共に記録されていたのに。

で、mysql のサイトの説明によると、

トランザクション非対応テーブルの操作まで含まれている

トランザクションで ROKLLBACK が実行された場合は

binlog にも記録されるのだ、とのこと。へー。

さらに別件でも不思議があって、

何故かここでは binlog に CREATE文が記録されてないという噂が。

うーん、なんでなんだろー。

よっし、ほんじゃ、家で実験するべー。

てな訳で、とりあえず、テーブルを用意。

mysql> show create table transaction_innodb;

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

| Table | Create Table |

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

| transaction_innodb | CREATE TABLE `transaction_innodb` (

`id` int(11) default NULL

) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

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

1 row in set (0.01 sec)

mysql> show create table transaction_myisam;

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

| Table | Create Table |

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

| transaction_myisam | CREATE TABLE `transaction_myisam` (

`id` int(11) default NULL

) ENGINE=MyISAM DEFAULT CHARSET=latin1 |

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

1 row in set (0.01 sec)

それから、トランザクションをかけて

両テーブルに INSERT文を発行、

それから ROLLBACK。

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into transaction_myisam values(1);

Query OK, 1 row affected (0.02 sec)

mysql> insert into transaction_innodb values(1);

Query OK, 1 row affected (0.00 sec)

mysql> rollback;

Query OK, 0 rows affected, 1 warning (0.02 sec)

えっと、それじゃ binlog を見てみますかー...

# at 995

#100403 12:39:14 server id 1 log_pos 995 Query thread_id=2 exec_time=0 error_code=0

SET TIMESTAMP=1270265954;

insert into transaction_myisam values(1);

# at 1070

#100403 12:39:27 server id 1 log_pos 1070 Query thread_id=2 exec_time=0 error_code=0

SET TIMESTAMP=1270265967;

BEGIN;

# at 1110

#100403 12:39:24 server id 1 log_pos 1070 Query thread_id=2 exec_time=0 error_code=0

SET TIMESTAMP=1270265964;

insert into transaction_innodb values(1);

# at 1185

#100403 12:39:27 server id 1 log_pos 1185 Query thread_id=2 exec_time=0 error_code=0

SET TIMESTAMP=1270265967;

ROLLBACK;

...おぉ。確かに記録されてるー。

勿論、片方だけトランザクションが効いてる訳だから

ROLLBACK 後に SELECT すると、片方のレコードだけ存在しています。

mysql> select * from transaction_myisam;

+------+

| id |

+------+

| 1 |

+------+

1 row in set (0.00 sec)

mysql> select * from transaction_innodb;

Empty set (0.01 sec)

念の為、InnoDB のテーブルにだけ

INSERT文を発行した上で、ROLLBACK するなら

binlog には記録されないのも確認。

よいしょ。

mysql> begin;

Query OK, 0 rows affected (0.00 sec)

mysql> insert into transaction_innodb values(2);

Query OK, 1 row affected (0.01 sec)

mysql> rollback;

Query OK, 0 rows affected (0.01 sec)

で、binlog を mysqlbinlog で見ると、

期待したとおり、今実行した内容は記録されていませんでした。よしよし。

一方、CREATE文の件は、binlog 見ると、ちゃんと記録されていて

もやもやしたままなのでした。あ、ALTER文も記録されてたよ。

うーん、なんでだろ。my.cnf の設定次第なのかなぁ?