mysql 丢失表_MySQL ddl丢表

MySQL ddl丢表:

MySQL server层为了和innodb层保持数据一致性,在写binlog和redo log时,引入了两阶段提交,但不同的变更产生的日志并非都使用这种策略。

下面就来看看ddl语句产生的binlog日志写入交互过程,从源码的角度理解大家熟知的MySQL ddl丢表。

测试:

create table mm(id int primary key, name varchar(100));

注意:测试在MySQL的5.5.18版本。因为dll语句默认提交,所以环境变量autocommit,tx_isolation不影响。

步骤:

1. 解析SQL语句

HA_CREATE_INFO create_info(lex->create_info);

Alter_info alter_info(lex->alter_info, thd->mem_root);

生成ddl语句需要的数据结构。

注意:在这个过程中,ddl语句进行了隐式提交

if (trans_commit_implicit(thd)):  隐式提交

thd->mdl_context.release_transactional_locks();  释放mdl锁

2. innodb创建表

函数:mysql_create_table_no_lock:

调用innodb引擎的创建表结构,具体步骤此次省略,我们的重点主要是binlog写入的交互

3. server写入binlog

1. 生成binlog日志

write_bin_log

THD::binlog_query

Query_log_event qinfo(this, query_arg, query_len, is_trans, direct,suppress_use, errcode);ddl产生的mysql binlog event的类型是Query_log_event

2. 写入binlog cache

file= &log_file; 使用mysql_bin_log全局的IO_CACHE.

mysql_mutex_lock(&LOCK_log)

event_info->write(file)

Query_log_event::write根据event的内容,按照小端字节法,写入buff内存中,然后flush到mysql_bin_log对应的io_cache中。

3. 同步日志

binlog写入完成后,使用flush_and_sync,持久化到binlog文件中,最后释放lock_log.

mysql_file_sync

mysql_mutex_unlock(&LOCK_log);

最后的结果是:

mysql> show binlog events in 'binlog.000013';+---------------+-----+-------------+-----------+-------------+------------------------------------------------------------------------+

| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |

+---------------+-----+-------------+-----------+-------------+------------------------------------------------------------------------+

| binlog.000013 | 4 | Format_desc | 100 | 107 | Server ver: 5.5.18.....................................................|

| binlog.000013 | 107 | Query | 100 | 228 | use `xpchild`; create table mm(id int primary key , name varchar(100)) |

了解了上面的函数调用过程,下面我们模拟一下丢表的情形:

在第二步结束后,kill mysqld模拟mysql crash的情形,然后重启,就会看到:

show tables:显示存在表 mm

show binlog:没有create table mm的query event出现。

这样,主库和备库就在不一致的状态。

思考:为什么ddl不使用事务性语句的binlog写入策略?因为ddl默认不需要commit,无法介入到两阶段?

后记:除了ddl产生的不一致的问题,MySQL的字典表,因为没有使用事务引擎来存储,也会出现数据不一致的情况。

不过,最近有消息传MySQL有意使用innodb引擎来保存字典表。

下篇将介绍下事务性dml语句的日志写入策略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值