[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.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值