Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1370075
  • 博文数量: 107
  • 博客积分: 1715
  • 博客等级: 上尉
  • 技术积分: 3168
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-18 18:42
个人简介

阿里巴巴DBA,原去哪儿网DBA。专注于MySQL源码研究、DBA运维、CGroup虚拟化及Linux Kernel源码研究等。 github:https://github.com/HengWang/ Email:king_wangheng@163.com 微博 :@王恒-Henry QQ :506437736

文章分类

全部博文(107)

文章存档

2014年(2)

2013年(38)

2012年(67)

分类: Mysql/postgreSQL

2012-08-28 19:19:41

目的

       MySQLbinlog日志中,基于行模式的方式,有table id的信息,而该table id并不是binlog中的操作表的固定id。为了进一步了解table id的改变,研究MySQL源码(MySQL-5.5.20),查看具体的处理逻辑,供开发和DBA参考。

源码分析

       table id的分配在函数assign_new_table_id()sql\sql_base.cc:3598)中分配,从处理的逻辑来看,每次分配都是对上一次的table id自增1。核心代码如下所示:


点击(此处)折叠或打开

  1. ulong tid= ++last_table_id; /* get next id */
  2.   /*
  3.     There is one reserved number that cannot be used. Remember to
  4.     change this when 6-byte global table id's are introduced.
  5.   */
  6.   if (unlikely(tid == ~0UL))
  7.     tid= ++last_table_id;
  8.   share->table_map_id= tid;

 

       而在TABLE_SHARE结构体(sql\table.h:541)的定义中,可以发现,table_map_id变量仅用于行模式的复制操作。具体定义如下所示:


点击(此处)折叠或打开

  1. ulong table_map_id; /* for row-based replication */

 

       根据以上线索,跟踪调用assign_new_table_id()函数的引用。只在get_table_share()函数(sql\sql_base.cc:560)中调用,该函数首先调用my_hash_search_using_hash_value()函数(mysys\hash.c:218)查找cache中是否有操作的表定义。如果找到表定义,则对其引用数自增1并返回该表定义;否则,创建一个TABLE_SHARE变量,并调用assign_new_table_id()函数分配一个新的table id,然后保存在cache中,调用open_table_def()函数(sql\table.cc:594)打开表定义并返回。其中,表定义在cache中是通过hash的方式组织,通过表的hash值获得。

       核心代码如下所示:


点击(此处)折叠或打开

  1. /* Read table definition from cache */
  2.   if ((share= (TABLE_SHARE*) my_hash_search_using_hash_value(&table_def_cache, hash_value, (uchar*) key, key_length)))
  3.     goto found;
  4.   if (!(share= alloc_table_share(table_list, key, key_length)))
  5.   {
  6.     DBUG_RETURN(0);
  7.   }
  8.   /*
  9.     We assign a new table id under the protection of LOCK_open.
  10.     We do this instead of creating a new mutex
  11.     and using it for the sole purpose of serializing accesses to a
  12.     static variable, we assign the table id here. We assign it to the
  13.     share before inserting it into the table_def_cache to be really
  14.     sure that it cannot be read from the cache without having a table
  15.     id assigned.
  16.     CAVEAT. This means that the table cannot be used for
  17.     binlogging/replication purposes, unless get_table_share() has been
  18.     called directly or indirectly.
  19.    */
  20.   assign_new_table_id(share);

 

       binlog的时候,在THD::binlog_write_table_map()函数(sql\log.cc:4760)中初始化Table_map_log_event对象the_event,初始化参数table id的值,即table_map_id的值,而该值是assign_new_table_id()函数获得的table id的值。核心代码如下:


点击(此处)折叠或打开

  1. Table_map_log_event
  2.     the_event(this, table, table->s->table_map_id, is_transactional);

 

       由以上内容可知,基于行模式的复制中,binlog中的table id是根据初始化的每个Table_map_log_event的时,传入的table_map_id的值。而get_table_share()函数可知,当cache中有该表定义时,该值的table id是不变的;而当cache中没有改表定义时,该值根据上一次操作的table id自增1获得的。

       为了更清晰的了解table idcache的关系,对table_def_cache进行分析,在get_table_share()函数中,如果在cache中找到表定义,在返回之前,会判断table_def_cache中是否太大,如果太大将清理cache中最久没用的表定义。

 

  

点击(此处)折叠或打开

  1. /* Free cache if too big */
  2.   while (table_def_cache.records > table_def_size &&
  3.          oldest_unused_share->next)
  4.     my_hash_delete(&table_def_cache, (uchar*) oldest_unused_share);

 

判断大小的标准是table_def_size变量,table_def_size的定义(sql\sys_vars.cc:2148)如下所示:

 


点击(此处)折叠或打开

  1. static Sys_var_ulong Sys_table_def_size(
  2.        "table_definition_cache",
  3.        "The number of cached table definitions",
  4.        GLOBAL_VAR(table_def_size), CMD_LINE(REQUIRED_ARG),
  5.        VALID_RANGE(TABLE_DEF_CACHE_MIN, 512*1024),
  6.        DEFAULT(TABLE_DEF_CACHE_DEFAULT), BLOCK_SIZE(1));

 

     从以上代码中可知,table_def_size是全变变量,有效值为:400~512*1024,默认值为:400TABLE_DEF_CACHE_MIN=400TABLE_DEF_CACHE_DEFAULT=400)。

       因此,由上面分析可知,当table_def_cache中的记录数大于400时,表定义将被置换出cache。被置换出的表如果有操作时,重新加载时,table id的值就会发生改变。

结论

       基于行模式复制的binlog中,table id的变化依赖于cache中是否存储了binlog操作表的表定义。如果cache中存在,则table id不变;而当cache中不存在时,该值根据上一次操作的table id自增1。因此,table id与实际操作的数据表没有直接对应关系,而与操作的数据表是否在cache中有关。此外,table_def_cache中默认存放400个表定义,如果超出该范围,会将最久未用的表定义置换出cache

阅读(7550) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~