注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

网易杭研后台技术中心的博客

 
 
 
 
 

日志

 
 

默认binlog_format在mysql-5.5.20/5.1.49自主binlog的实现差异  

来自sunny4715   2012-09-29 09:30:27|  分类: 默认分类 |举报 |字号 订阅

  下载LOFTER 我的照片书  |
跟踪debug版本下mysql_test用例ps,简单的如下测试SQL:
SET storage_engine=ntse;
drop table if exists t1,t2,t3,t4;
drop database if exists client_test_db;
create database client_test_db;
create table t1
(
a int primary key,
b char(10)
);
insert into t1 values (1,'one');//引发问题的SQL

mysql-5.5.20 NTSE调用堆栈如下:
mysql_insert ===>write_record ===>handler::ha_write_row===>ha_ntse::write_row===>ntse::Table::insert ===>ntse::NTSECallbackManager::callback===>NTSEDirectBinlog::logRowInsert ===>NTSEDirectBinlog::writeBinlog ===>NTSEDirectBinlog::DirectBinlogWriter::syncWrite===>NTSEDirectBinlog::DirectBinlogWriter::writeInTxn===> BinlogWriter::startTransaction===>THD::binlog_write_table_map===> DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());断言失败崩溃。


导致两个版本行为差异的原因是:
mysql-5.5.20版本:
inline injector::transaction::transaction(MYSQL_BIN_LOG *log, THD *thd)
  : m_state(START_STATE), m_thd(thd)
{
  LOG_INFO log_info;
  log->get_current_log(&log_info);
  m_start_pos.m_file_name= my_strdup(log_info.log_file_name, MYF(0));
  m_start_pos.m_file_pos= log_info.pos;

  trans_begin(m_thd);
}
mysql-5.1.49版本
/* inline since it's called below */
inline injector::transaction::transaction(MYSQL_BIN_LOG *log, THD *thd)
  : m_state(START_STATE), m_thd(thd)
{
  LOG_INFO log_info;
  log->get_current_log(&log_info);
  /* !!! binlog_pos does not follow RAII !!! */
  m_start_pos.m_file_name= my_strdup(log_info.log_file_name, MYF(0));
  m_start_pos.m_file_pos= log_info.pos;

  begin_trans(m_thd);

  thd->set_current_stmt_binlog_row_based();
}

可以看出差异在最后一句 thd->set_current_stmt_binlog_row_based() 而:
  inline void set_current_stmt_binlog_row_based()
  {
    current_stmt_binlog_row_based= TRUE;
  }
 
正是由于这句差异导致mysql-5.5.20版本(默认binlog_format=STATEMENT)在断言
int THD::binlog_write_table_map(TABLE *table, bool is_transactional)
{
.........
  DBUG_ASSERT(is_current_stmt_binlog_format_row() && mysql_bin_log.is_open());
.........
}时发生崩溃。
注:
 int is_current_stmt_binlog_format_row() const {
    DBUG_ASSERT(current_stmt_binlog_format == BINLOG_FORMAT_STMT ||
                current_stmt_binlog_format == BINLOG_FORMAT_ROW);
    return current_stmt_binlog_format == BINLOG_FORMAT_ROW;
  }


而mysql-5.5在insert操作时设置binlog_format的流程如下:
实际崩溃的m_thd是在NTSEDirectBinlog::DirectBinlogWriter::DirectBinlogWriter() 内部创建的:
if (!createTHD())而内部
bool BinlogWriter::createTHD() {
..... m_thd = new THD; 在THD的构造函数里实现如下:
THD::THD()
.........
  /* Call to init() below requires fully initialized Open_tables_state. */
  reset_open_tables_state(this);
  init();
而init内部:
void THD::init(void)
{
  ...........
  reset_current_stmt_binlog_format_row();
}
reset_current_stmt_binlog_format_row是根据系统配置文件设置(或使用默认配置)设置的binlog_format参数设置当前m_thd的current_stmt_binlog_format_row值为TRUE还是FALSE;

 inline void reset_current_stmt_binlog_format_row()
  {
    if (in_sub_stmt == 0)
    {
      if (variables.binlog_format == BINLOG_FORMAT_ROW)
        set_current_stmt_binlog_format_row();
      else if (temporary_tables == NULL)
        clear_current_stmt_binlog_format_row();
    }
    DBUG_VOID_RETURN;
  }
可以在初始化m_thd解决这个问题。
初始化完m_thd后加一句:m_thd->set_current_stmt_binlog_format_row();


Beginning with MySQL 5.5.5, this variable has no effect when the binary log format is ROW or MIXED. (Bug #51291)

binlog_format

Command-Line Format --binlog-format=format
Option-File Format binlog-format=format
Option Sets Variable Yes, binlog_format
Variable Name binlog_format
Variable Scope Global, Session
Dynamic Variable Yes
  Permitted Values
Type enumeration
Default STATEMENT
Valid Values

ROW

STATEMENT

MIXED



mysql-5.1版本默认的binlog_format与各分支版本相关
binlog_format
Version Introduced 5.1.5
Command-Line Format --binlog-format=format
Option-File Format binlog-format=format
Option Sets Variable Yes, binlog_format
Variable Name binlog_format
Variable Scope Global, Session
Dynamic Variable Yes
  Permitted Values (>= 5.1.5, <= 5.1.7)
Type enumeration
Default STATEMENT
Valid Values

ROW

STATEMENT

  Permitted Values (>= 5.1.8, <= 5.1.11)
Type enumeration
Default STATEMENT
Valid Values

ROW

STATEMENT

MIXED

  Permitted Values (>= 5.1.12, <= 5.1.28)
Type enumeration
Default MIXED
Valid Values

ROW

STATEMENT

MIXED

  Permitted Values (>= 5.1.29)
Type enumeration
Default STATEMENT
Valid Values

ROW

STATEMENT

MIXED



关于binlog_format详细资料可参考链接地址:http://codejm.iteye.com/blog/1540046.
  评论这张
 
阅读(1712)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017