プログラマ 福重 伸太朗 〜基本へ帰ろう〜 このページをアンテナに追加 RSSフィード

2011-10-26

MySQLのreplication時に起こる、double free or corruption について

環境

OS CentOS 6.0 (動作はMac OS X 10.6.8 上の VMWare Fuction)
MySQL MySQL-client-5.5.17-1.linux2.6.i386, MySQL-devel-5.5.17-1.linux2.6.i386, MySQL-server-5.5.17-1.linux2.6.i386, MySQL-shared-5.5.17-1.linux2.6.i386 (2011/10/26時点で最新)
CPU Intel(R) Core(TM) i7 CPU 870 @ 2.93GHz
メモリ 2GB (割り当てメモリ)

※Master, Slave共に同じです。


MySQL設定

Master

my.cnf

[mysqld]
skip-character-set-client-handshake
character-set-serve                 = utf8
character-set-filesystem            = utf8
datadir                             = /var/lib/mysql/
log-error                           = /home/mysql/mysqld.err
log-bin                             = /home/mysql/log-bin
master-info-file                    = /home/mysql/master.info
server-id                           = 1
binlog-do-db=hoge
binlog_format                       = STATEMENT
                                                                                                     
[mysql]
default-character-set               = utf8

[mysqldump]
default-character-set               = utf8
hex-blob
Slave

my.cnf

[mysqld]
skip-character-set-client-handshake
character-set-serve                 = utf8
character-set-filesystem            = utf8
datadir                             = /var/lib/mysql/
log-error                           = /home/mysql/mysqld.err
relay-log                           = /home/mysql/relay-bin
relay-log-info-file                 = /home/mysql/relay-log.info
server-id                           = 2
replicate-rewrite-db=hoge->foobarhogefoofoofoofoofoofoo
replicate-do-db=foobarhogefoofoofoofoofoofoo
replicate-wild-do-table=foobarhogefoofoofoofoofoofoo.baz
query_cache_size                    = 1M

[mysql]
default-character-set               = utf8

[mysqldump]
default-character-set               = utf8
hex-blob

エラー再現手順

1. Slave : stop replication

stop slave;
reset slave;

2. Master : create database and table

create database hoge;
use hoge;
CREATE TABLE `baz` (
 `id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(200),
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
reset master;

3. Slave : create database and table

create database foobarhogefoofoofoofoofoofoo;
use foobarhogefoofoofoofoofoofoo;
CREATE TABLE `baz` (
 `id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(200),
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
reset slave;

4. Slave : start slave

start slave;

5. Master : run query

use hoge;
/*!40000 ALTER TABLE `baz` DISABLE KEYS */;

6. Slave : mysql restart(mysql restart しなくてもエラーが出る場合がある)

$ sudo /etc/init.d/mysql restart

エラー内容

Slave側に以下のエラーがコンソールに出力されます。

 *** glibc detected *** /usr/sbin/mysqld: double free or corruption (!prev): 0xa4b09a50 ***
======= Backtrace: =========
/lib/libc.so.6(+0x6f1a1)[0x17f1a1]
/usr/sbin/mysqld(my_free+0x1d)[0x83bfaed]
/usr/sbin/mysqld(_ZN15Query_log_eventD0Ev+0x30)[0x8343206]
/usr/sbin/mysqld[0x813c3d0]
/usr/sbin/mysqld(handle_slave_sql+0xc4e)[0x813ea0f]
/lib/libpthread.so.0(+0x69e9)[0x4249e9]
/lib/libc.so.6(clone+0x5e)[0x1eddfe]
======= Memory map: ========
00110000-00295000 r-xp 00000000 fd:00 523149     /lib/libc-2.12.so
00295000-00297000 r--p 00185000 fd:00 523149     /lib/libc-2.12.so
00297000-00298000 rw-p 00187000 fd:00 523149     /lib/libc-2.12.so
00298000-0029b000 rw-p 00000000 00:00 0 
0029b000-002e0000 r-xp 00000000 fd:00 523129     /lib/libfreebl3.so
002e0000-002e1000 rw-p 00045000 fd:00 523129     /lib/libfreebl3.so
002e1000-002e5000 rw-p 00000000 00:00 0 
0041e000-00435000 r-xp 00000000 fd:00 523173     /lib/libpthread-2.12.so
00435000-00436000 r--p 00016000 fd:00 523173     /lib/libpthread-2.12.so
00436000-00437000 rw-p 00017000 fd:00 523173     /lib/libpthread-2.12.so
00437000-00439000 rw-p 00000000 00:00 0 
007fc000-00808000 r-xp 00000000 fd:00 523165     /lib/libnss_files-2.12.so
00808000-00809000 r--p 0000b000 fd:00 523165     /lib/libnss_files-2.12.so
00809000-0080a000 rw-p 0000c000 fd:00 523165     /lib/libnss_files-2.12.so
008c9000-008e6000 r-xp 00000000 fd:00 523126     /lib/libgcc_s-4.4.4-20100726.so.1
008e6000-008e7000 rw-p 0001d000 fd:00 523126     /lib/libgcc_s-4.4.4-20100726.so.1
00a0d000-00a0e000 r-xp 00000000 00:00 0          [vdso]
00b7e000-00b7f000 r-xp 00000000 fd:00 523528     /lib/libaio.so.1.0.1
00b7f000-00b80000 rw-p 00000000 fd:00 523528     /lib/libaio.so.1.0.1
00bbd000-00bdb000 r-xp 00000000 fd:00 523142     /lib/ld-2.12.so
00bdb000-00bdc000 r--p 0001d000 fd:00 523142     /lib/ld-2.12.so
00bdc000-00bdd000 rw-p 0001e000 fd:00 523142     /lib/ld-2.12.so
00c6d000-00c74000 r-xp 00000000 fd:00 523177     /lib/librt-2.12.so
00c74000-00c75000 r--p 00006000 fd:00 523177     /lib/librt-2.12.so
00c75000-00c76000 rw-p 00007000 fd:00 523177     /lib/librt-2.12.so
00c76000-00c9e000 r-xp 00000000 fd:00 523157     /lib/libm-2.12.so
00c9e000-00c9f000 r--p 00027000 fd:00 523157     /lib/libm-2.12.so
00c9f000-00ca0000 rw-p 00028000 fd:00 523157     /lib/libm-2.12.so
00d1b000-00d22000 r-xp 00000000 fd:00 523153     /lib/libcrypt-2.12.so
00d22000-00d23000 r--p 00007000 fd:00 523153     /lib/libcrypt-2.12.so
00d23000-00d24000 rw-p 00008000 fd:00 523153     /lib/libcrypt-2.12.so
00d24000-00d4b000 rw-p 00000000 00:00 0 
00d7e000-00d81000 r-xp 00000000 fd:00 523155     /lib/libdl-2.12.so
00d81000-00d82000 r--p 00002000 fd:00 523155     /lib/libdl-2.12.so
00d82000-00d83000 rw-p 00003000 fd:00 523155     /lib/libdl-2.12.so
08048000-08889000 r-xp 00000000 fd:00 795698     /usr/sbin/mysqld
08889000-08951000 rw-p 00840000 fd:00 795698     /usr/sbin/mysqld
08951000-08971000 rw-p 00000000 00:00 0 
09093000-09808000 rw-p 00000000 00:00 0          [heap]
a4a00000-a4a21000 rw-p 00000000 00:00 0 
a4a21000-a4b00000 ---p 00000000 00:00 0 
a4b00000-a4b21000 rw-p 00000000 00:00 0 
a4b21000-a4c00000 ---p 00000000 00:00 0 
a4c00000-a4c2e000 rw-p 00000000 00:00 0 
a4c2e000-a4d00000 ---p 00000000 00:00 0 
a4d45000-a4d46000 ---p 00000000 00:00 0 
a4d46000-a5746000 rw-p 00000000 00:00 0 
a5746000-a5747000 ---p 00000000 00:00 0 
a5747000-a6147000 rw-p 00000000 00:00 0 
a6147000-a6148000 ---p 00000000 00:00 0 
a6148000-a6b48000 rw-p 00000000 00:00 0 
a6b48000-a6b49000 ---p 00000000 00:00 0 
a6b49000-a77d7000 rw-p 00000000 00:00 0 
a7900000-a7921000 rw-p 00000000 00:00 0 
a7921000-a7a00000 ---p 00000000 00:00 0 
a7a85000-a7a86000 ---p 00000000 00:00 0 
a7a86000-a7ab6000 rw-p 00000000 00:00 0 
a7ab6000-a7ab7000 ---p 00000000 00:00 0 
a7ab7000-a7ae7000 rw-p 00000000 00:00 0 
a7ae7000-a7ae8000 ---p 00000000 00:00 0 
a7ae8000-a84e8000 rw-p 00000000 00:00 0 
a84e8000-a84e9000 ---p 00000000 00:00 0 
a84e9000-a8ee9000 rw-p 00000000 00:00 0 
a8ee9000-a8eea000 ---p 00000000 00:00 0 
a8eea000-a98ea000 rw-p 00000000 00:00 0 
a98ea000-a98eb000 ---p 00000000 00:00 0 
a98eb000-aa2eb000 rw-p 00000000 00:00 0 
aa2eb000-aa2ec000 ---p 00000000 00:00 0 
aa2ec000-aacec000 rw-p 00000000 00:00 0 
aacec000-aaced000 ---p 00000000 00:00 0 
aaced000-ab6ed000 rw-p 00000000 00:00 0 
ab6ed000-ab6ee000 ---p 00000000 00:00 0 
ab6ee000-ac0ee000 rw-p 00000000 00:00 0 
ac0ee000-ac0ef000 ---p 00000000 00:00 0 
ac0ef000-acaef000 rw-p 00000000 00:00 0 
acaef000-acaf0000 ---p 00000000 00:00 0 
acaf0000-b6c00000 rw-p 00000000 00:00 0 
b6c00000-b6c21000 rw-p 00000000 00:00 0 
b6c21000-b6d00000 ---p 00000000 00:00 0 
b6d0f000-b6d10000 ---p 00000000 00:00 0 
b6d10000-b6d40000 rw-p 00000000 00:00 0 
b6d40000-b6d41000 ---p 00000000 00:00 0 
b6d41000-b6d71000 rw-p 00000000 00:00 0 
b6d71000-b6d72000 ---p 00000000 00:00 0 
b6d72000-b7775000 rw-p 00000000 00:00 0 
b7782000-b7784000 rw-p 00000000 00:00 0 
bfd4a000-bfd5f000 rw-p 00000000 00:00 0          [stack]

エラーについて補足

  1. MySQLのBug Report( http://bugs.mysql.com/ ) のDBを検索したが、上記のエラーは見当たらなかった。
  2. MySQL5.5.15 でも同じ現象が起こることを確認している。
  3. 現時点(2011/10/26)では、私はMySQLのBug Reportには報告していない。 報告した => http://bugs.mysql.com/bug.php?id=62942
  4. 当該エラーが起こると、MySQLログインできなくなる場合がある
  5. 当該エラーが起こると、sudo /etc/init.d/mysql stop で MySQL を停止できなくなる。
  6. 当該エラーが起こると、MySQLが正しく起動できなくなる(プロセスを kill して sudo /etc/init.d/mysql start すると、同じエラーが起こる)

再現のポイント

  1. Slave側で query chache が有効になっている
  2. Slave側で replicate-rewrite-db オプションが使われている
  3. replication対象のDB名とテーブル名の文字数合計が35文字以上であること(MasterDB名(hoge) + SlaveDB名(foobarhogefoofoofoofoofoofoo) + replicaton対象のテーブル名(baz) = 35文字以上)
  4. Master側で発行するqueryが下記であること
/*!40000 ALTER TABLE `baz` DISABLE KEYS */;