[MySQL Bug] <=5.1.49 alter table rename 操作导致复制中断

转载请署名:印风

—————–
在我们传统的认识里,MySQL对于alter操作是隐式提交的,也就是说,执行一条Alter会直接写入binlog,而不等待commit。
这种看法在大多数情况下是正确的,但有一个例外,也就是alter table rename操作,在MySQL5.1.50之前,如果你设置了autocommit = 0 , 该DDL不会隐式提交,直到你显式的commit。
有意思的是,官方的修复初衷并不因为这个bug,而是其他的一个debug版本的断言失败(详见http://bugs.mysql.com/bug.php?id=54453
废话不多说,看test case:
session 1:
root@test 10:42:03>reset master;
Query OK, 0 rows affected (0.00 sec)
root@test 10:42:07>create table t1 (a int, b int);
Query OK, 0 rows affected (0.01 sec)
root@test 10:42:22>set autocommit = 0;
Query OK, 0 rows affected (0.00 sec)
root@test 10:42:27>alter table t1 rename to __tmp_t1;
Query OK, 0 rows affected (0.01 sec)
session 2:
root@test 10:42:54>insert into __tmp_t1 values (1,2);
Query OK, 1 row affected (0.00 sec)
session 1:
root@test 10:42:44>commit;
Query OK, 0 rows affected (0.00 sec)
root@test 10:43:20>show binlog events;
+——————+—–+————-+———–+————-+———————————————–+
| Log_name         | Pos | Event_type  | Server_id | End_log_pos | Info                                          |
+——————+—–+————-+———–+————-+———————————————–+
| mysql-bin.000001 |   4 | Format_desc |       112 |         106 | Server ver: 5.1.48-log, Binlog ver: 4         |
| mysql-bin.000001 | 106 | Query       |       112 |         199 | use `test`; create table t1 (a int, b int)    |
| mysql-bin.000001 | 199 | Query       |       112 |         267 | BEGIN                                         |
| mysql-bin.000001 | 267 | Query       |       112 |         363 | use `test`; insert into __tmp_t1 values (1,2) |
| mysql-bin.000001 | 363 | Xid         |       112 |         390 | COMMIT /* xid=15 */                           |
| mysql-bin.000001 | 390 | Query       |       112 |         458 | BEGIN                                         |
| mysql-bin.000001 | 458 | Query       |       112 |         554 | use `test`; alter table t1 rename to __tmp_t1 |
| mysql-bin.000001 | 554 | Xid         |       112 |         581 | COMMIT /* xid=10 */                           |
+——————+—–+————-+———–+————-+———————————————–+
8 rows in set (0.00 sec)
看看binlog里的顺序:
use `test`; create table t1 (a int, b int)
BEGIN
use `test`; insert into __tmp_t1 values (1,2)
COMMIT /* xid=15 */
BEGIN
use `test`; alter table t1 rename to __tmp_t1
COMMIT /* xid=10 */
很显然,binlog里产生了乱序,insert语句在rename之前就插入到了__tmp_t1表里,在备库上自然会产生找不到表的错误,导致复制中断。
patch很简单,就是在mysql_alter_table里增加一行,来做一次commit。
Index: /PS5518/branches/my5148-r1207-bugfix/sql/sql_table.cc
===================================================================
— /PS5518/branches/my5148-r1207-bugfix/sql/sql_table.cc (revision 1264)
+++ /PS5518/branches/my5148-r1207-bugfix/sql/sql_table.cc (revision 1265)
@@ -6848,6 +6848,8 @@
     if (!error && (new_name != table_name || new_db != db))
     {
       thd_proc_info(thd, “rename”);
+
+      ha_autocommit_or_rollback(thd,0);
       /*
         Then do a ‘simple’ rename of the table. First we need to close all
         instances of ‘source’ table.

原创文章,转载请注明: 转载自Simple Life

本文链接地址: [MySQL Bug] <=5.1.49 alter table rename 操作导致复制中断

Post Footer automatically generated by wp-posturl plugin for wordpress.


Comments

Leave a Reply

Your email address will not be published. Name and email are required


Current month ye@r day *