ITPub博客

首页 > 数据库 > MySQL > table_map_event和table_id

table_map_event和table_id

原创 MySQL 作者:myownstars 时间:2015-02-08 14:58:18 0 删除 编辑
row-based replication引入此事件
TABLE_MAP_EVENT:
The TABLE_MAP_EVENT defines the structure if the tables that are about to be changed

row模式下,主库的DML对应一个table_map_event和一系列INSERT/UPDATE/WRITE_ROWS_EVENT;
table_map_event对应的class是Table_map_log_event(对应源码sql/log_event.cc),它保存了本次DML操作对应的:table_id,数据库名,表名,字段数,字段类型等,而这些信息都是从table_definition_cache通过get(table_id)获取的。


table_id的用途
innodb采用table_definition_cache缓存表的metadata,cache采用hash table结构,table_id用来做hash key;
通过set_table(table_id)的方法将某个表的信息hash到cache中,又可以通过get_table()方法来根据table_id获得对应的表信息; 

table_id和数据库表并非是固定的对应关系,table id在mysql实例生命周期内是递增的;
如果table cache中已经存在该表,则table id不变,而当table cache中不存在时,该值根据上一次操作的table id自增1。
此外,table_definition_cache中默认存放400个表定义,如果超出该范围,会将最久未用的表定义置换出table cache。 
table_map_event记录了table_id,而row_log_event也记录了table_id,两者通过table_id关联。
slave先解析table_map_event并存于内存,而后的row_log_event通过table_id找到对应的表信息。
这里的table_id的类型为ulong。


RPL_TABLE_LIST
RPL_TABLE_LIST是包含在Relay_log_info结构(对应源码sql/rpl_mi.h)中的,它记录了这次变更需要lock的多个表信息。
RPL_TABLE_LIST结构(对应源码sql/rpl_utility.h)的父类TABLE_LIST(对应源码:sql/table.h)中定义table_id为:
  uint          table_id; /* table id (from binlog) for opened table */   //这里就是最终需要bug fix的地方
这里定义为uint和其他地方定义为ulong不一样!


当slave执行table_map_event时,会把table_map_event信息解析到RRL_TABLE_LIST中,同时table_map_event->table_id(ulong)赋值给RPL_TABLE_LIST->table_id(ulint),当前者数值超出ulit时会发生截断;
而执行row_log_event时又需要通过get_table(table_id)从内存中获取表信息,当上面的赋值发生截断时便会产生错误。


解决方案
1、自己打patch,重编译并替换线上MySQL
2、增加table cache 大小。
3、重启主库让table_id归零。
 

 
参考资料
http://hatemysql.com/2012/11/23/ 


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15480802/viewspace-1430318/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2010-03-18

  • 博文量
    375
  • 访问量
    3095241