binlog_format=ROW/STATEMENT/MIX 对记录不存在的对比

昨天一台(slave)不停的出现包含HA_ERR_KEY_NOT_FOUND的复制错误

  1. Include/my_base.sh (376行)  #define HA_ERR_KEY_NOT_FOUND    120     /* Didn’t find key on read or update */

翻译的意思是查询或者更新操作找不到键值,实际进行测试的时候 ,where查询条件为索引和普通列值的时候,当主库binlog_format=row的时候,slave也会报错HA_ERR_KEY_NOT_FOUND

改slave对应的主库binlog_format=ROW

  1. 2. 测试重现

v031082.sqa.cm4   搞两个mysql实例   做主备

主库 /u01/mysql 3306    binlog_format=ROW

备库 /u01/mysql2 3309  binlog_format=STATEMENT

主库 create table t1(id int ,name varchar(100);

Insert into table t1 (name) value (‘mysql’);

Insert into table t1 (name) value (‘hbase’);

Insert into table t1 (name) value (‘oracle’);

主备库确认三条记录都在,备库清空t1表 .

备库 show slave status\G无告警

ROWSTATEMENT的类似操作对比

MySQL 主库 Binlog_format=row 主库的binlog_format=MIX/statement;
v031082.sqa.cm4 3306 Master delete from t1 where ;

delete from t1 where name=’hbase’;

Delete from t1 where name=’mysql’
v031082.sqa.cm4 3309 Slave 备库此时show slave status ;会出现

Could not execute Update_rows event on table test.t1;

Can’t find record in ‘t1′, Error_code: 1032;

handler error HA_ERR_KEY_NOT_FOUND;

the event’s master log mysql-bin.000001, end_log_pos 3499

备库没有错误信息 (目前线上大部分的MySQL 主库binlog_format=statement,如果TC迁移到MySQL,需要考虑好到底是采用MIX还是ROW)

源码剖析

storage/innodb_plugin/handler/ha_innodb.cc 这里包含index_read(),index_first(),index_last()函数,这些函数都会判断记录是否存在

/**********************************************************************//**

Positions an index cursor to the index specified in the handle. Fetches the

row if any.

@return  0, HA_ERR_KEY_NOT_FOUND, or error number */

UNIV_INTERN

Int ha_innobase::index_read(

case DB_RECORD_NOT_FOUND:

error = HA_ERR_KEY_NOT_FOUND;

table->status = STATUS_NOT_FOUND;

break;

}

/********************************************************************//**

Positions a cursor on the first record in an index and reads the

corresponding row to buf.

@return 0, HA_ERR_END_OF_FILE, or error code */

UNIV_INTERN Int ha_innobase::index_first(

if (error == HA_ERR_KEY_NOT_FOUND) {

error = HA_ERR_END_OF_FILE;

}

)

/********************************************************************//**

Positions a cursor on the last record in an index and reads the

corresponding row to buf.

@return 0, HA_ERR_END_OF_FILE, or error code */

UNIV_INTERN  int  ha_innobase::index_last(

if (error == HA_ERR_KEY_NOT_FOUND) {

error = HA_ERR_END_OF_FILE;

}

)

Leave a Reply