Chinaunix首页 | 论坛 | 博客
  • 博客访问: 339630
  • 博文数量: 105
  • 博客积分: 358
  • 博客等级: 一等列兵
  • 技术积分: 444
  • 用 户 组: 普通用户
  • 注册时间: 2011-06-25 23:00
个人简介

爱生活,爱养生 www.sijiyang.com 欢迎朋友来友联

文章分类

全部博文(105)

文章存档

2017年(2)

2016年(2)

2014年(24)

2013年(34)

2012年(39)

2011年(4)

分类: Mysql/postgreSQL

2013-08-07 00:19:25

目的

       mysqlbinlog在分析mysql的binlog日志时,有时需要针对某个表的操作进行分析。但是这个表属于“冷数据”,操作记录相对较少,而其他表操作往往很频繁,binlog日志量特别大。尤其是当binlog的模式设置为ROW时,情况就更加严重了,往往如大海捞针。为了提高获取binlog日志的有效性,对mysqlbinlog功能进行扩展,增加table参数,分析指定数据库的表操作记录。

实现

       以下实现基于MySQL 5.5.18源码,实现思路:参考--database参数的逻辑;修改原则:尽量少的变更MySQL源码,尽可能的优雅实现。

1、增加全局变量

       首先增加两个全局变量,用于存储table参数的状态和table的值,具体如下所示:

/* One table to filter out (Added by wangheng, email to wangheng.wh@alibaba-inc.com.).*/

static bool one_table=0;

static char* table_name = 0;

2、增加过滤函数

       过滤函数主要是根据one_table状态和table的值,比较当前事件涉及的表是否需要获取。具体如下所示:

/*

 * Check the given table should be filtered out, according to the --table=X option

 * @param

 *     log_tbname: Name of table.

 * @return

 *     0 : Skip.

 *     N: Filtered out.

 * @author:  wangheng

 * @email  : wangheng.wh@alibaba-inc.com

 */

static bool shall_skip_table(const char *log_tbname)

{

  return one_table &&

           (log_tbname != NULL) &&

           strcmp(log_tbname, table_name);

}

3、增加调用逻辑

       分析发现,有表信息的Log_event结构有:Table_map_log_event和Create_file_log_event两个结构,其中Table_map_log_event仅在ROW模式下有效,Create_file_log_event是在Load data时调用。为了尽快能少的减少修改引入的新问题,逻辑处理仅对这两个部分增加过滤函数的逻辑调用。具体如下:

   case CREATE_FILE_EVENT:

    {

      Create_file_log_event* ce= (Create_file_log_event*)ev;

      if (shall_skip_database(ce->db)

                     /* Filtered out the events of given table. (Added by wangheng, email to wangheng.wh@alibaba-inc.com) */

                     || shall_skip_table(ce->table_name))

……

    case TABLE_MAP_EVENT:

    {

      Table_map_log_event *map= ((Table_map_log_event *)ev);

      if (shall_skip_database(map->get_db_name())

                     /* Filtered out the events of given table.(Added by wangheng, email to wangheng.wh@alibaba-inc.com.). */

                     || shall_skip_table(map->get_table_name()))

4、增加输入参数选项

       在my_long_options参数选项中增加输入参数--table/-T,用于设置过滤的表名。具体如下:

/*Add the -T/--table option. (Added by wangheng, email to wangheng.wh@alibaba-inc.com.)*/

   {"table", 'T', "List entries for just this table in given database of -d/--database option. (row mode only).",

   &table_name, &table_name, 0, GET_STR_ALLOC, REQUIRED_ARG,

   0, 0, 0, 0, 0, 0},

5、释放参数变量

       因为table_name参数选项,在处理时分配了内存空间,在cleanup()函数中,释放table_name变量。具体如下:

/* Free the table name. (Added by wangheng, email to wangheng.wh@alibaba-inc.com.)*/

  my_free(table_name);

6、设置标记变量

       在table参数设置后,通过one_table变量标记当前有表需要过滤,从而在shall_skip_table()时过滤表操作记录。需要在get_one_option()函数中,设置one_table变量。具体如下:

/* Set the table filter flag. (Added by wangheng, email to wangheng.wh@alibaba-inc.com.)*/

case 't':

           one_table = 1;

           break;

       以上过程,尽可能少的对MySQL源码进行修改,扩展部分尽可能保证不影响正常的处理逻辑。

PATCH

       为了方便使用mysqlbinlog的扩展功能,基于MySQL 5.5.18官方源码修改,patch发布在github上分享。

patch发布在:

相关的说明文档:

结论:

       通过扩展mysqlbinlog功能,增加-T/--table参数,设置过滤数据表的操作记录,提高mysqlbinlog获取数据的有效性,减少分析数据的范围。然而,由于Query_log_event事件类型中没有提供tables信息,导致binlog在MIX和STATEMENT模式下,不能尽可能的过滤有效操作记录。

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