Welcome 微信登录

首页 / 数据库 / MySQL / [MySQL Bug] 在RBR复制模式下使用Merge引擎导致备库Crash的bug

最近碰到一个很蛋疼的BUG,使用merge引擎,row模式下复制,极大的概率crash备库。我的测试环境是5.1的主库,5.5的备库test case:
  1. create table m1 (a int primary key, b int) engine=myisam;  
  2. create table m2 (a int primary key, b int) engine=myisam;  
  3. create table mm (a int primary key , b int) engine=mrg_myisam  INSERT_METHOD=LAST UNION=(m1,m2);  
  4. insert into mm values (1,2);  
crash的原因非常简单,实际上在很早之前这个bug就fix了(MySQL Bug#47103), 可能是官方疏忽,又或者是Merge存储引擎用的人少,没有将这个patch backport到5.5中。 以下是个简单的介绍。
我们知道每个Binlog的行事件都有一个table_map_event。在函数Table_map_log_event::do_apply_event中,会根据table map event的内容初始化table_list结构体,并构建table_list->m_tabledef。这里的table_list->m_tabledef.m_field_metadata是被分配内存的。然后将该table_list挂到rli->tables_to_lock上
而在函数Rows_log_event::do_apply_event中,当调用open_and_lock_tables实际打开表时,还会打开相依赖的子表,并将这些table_list挂到rli->tables_to_lock之后(链接指针为next_global),但要注意,这里打开的依赖字表时,其table_list->m_tabledef.m_field_metadata实0x0,并没有分配空间
随后,在打开表后,要检查table map里的定义和实际打开表的定义是否相容。
  1. 7663       RPL_TABLE_LIST *ptr= rli->tables_to_lock;  
  2. 7664       for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))  
  3. 7665       {  
  4. 7666         TABLE *conv_table;  
  5. 7667         if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),  
  6. 7668                                              ptr->table, &conv_table))  
而在table_def::compatible_with中: can_convert_field_to(field, type(col), field_metadata(col), rli, m_flags, &order)
其中type和field_metadata都会涉及到对m_field_metadata的引用,因此直接产生段错误,导致crash。官方的fix见http://lists.mysql.com/commits/86326PostgreSQL集群方案hot standby 安装和测试[MySQL Patch] Binlog文件预分配相关资讯      MySQL教程 
  • 30分钟带你快速入门MySQL教程  (02月03日)
  • MySQL教程:关于I/O内存方面的一些  (01月24日)
  • CentOS上开启MySQL远程访问权限  (01/29/2013 10:58:40)
  • MySQL教程:关于checkpoint机制  (01月24日)
  • MySQL::Sandbox  (04/14/2013 08:03:38)
  • 生产环境MySQL 5.5.x单机多实例配  (11/02/2012 21:02:36)
本文评论 查看全部评论 (0)
表情: 姓名: 字数