[Mysql]两阶段提交和崩溃恢复

两阶段提交 innodb和bin log需要进行两阶段提交(Two-Phase Commit Protocol,2PC),目的是为了保证日志一致性,要么都存在,要么都不存在。 要说明的是,两阶段提交不止redo log和binlog有关,undo log也是参与者。 XID是事务根据事务第一条query生成的id,通过XID将redo log和binlog关联起来。在上一篇的binlog日志里也能看到XID的身影。 两阶段提交,其实就是innodb prepare,写binlog,innodb commit; 具体是, prepare阶段,redo log写入根据事务提交时的刷盘策略决定是否刷盘,然后将log segment(不是回滚段!!!)标为TRX_UNDO_PREPARED;binlog不做任何事 commit阶段,binlog写入binlog日志;接着innodb将修改undo log segment状态,并在redo log写入一个commit log。 如果没有两阶段提交,redo log和binlog各写各的,中间发生崩溃,就会出现不一致的情况。 先写binlog,再写redo log:如果redo log没写成功,就会造成崩溃恢复的时候,主库没有、从库有的情况,主从不一致。 先写redo log,再写binlog:如果binlog没写成功,就会造成崩溃恢复的时候,主库有、从库没有的情况,主从不一致。 说白了,为了保证事务,总是得做一些冗余的操作,例如tcp多次握手挥手,都是通过冗余操作来保证两个业务之间一致。 redo log和binlog顺序不一致的问题 两阶段的提交不只如此,如果只是像上面那样,还会出现主从不一致的情况。 热备问题 T1 (--prepare--binlog[pos100]--------------------------------------------commit) T2 (-----prepare-----binlog[pos200]----------commit) T3 (--------prepare-------binlog[pos300]------commit) online-backup(----------------------------------------------backup------------) 假设3个事务如上,那么 redo log prepare的顺序:T1 --> T2 --> T3 binlog的写入顺序: T1 --> T2 --> T3 redo log commit的顺序: T2 --> T3 --> T1 可以看到redo log提交的顺序和bin log不一致了,这是不允许的,会导致主从不一致。 online-backup表示热备,因为从库在建立的时候需要对主库进行一次备份。当T2,T3提交后,这时热备来读位置,读到最后一个提交的事务T3,由于这个阶段不是读binlog的,所以T1没有被复制到,接下来的binlog复制从T3开始,所以会漏掉T1的数据。 复制问题 《MySQL5.7 核心技术揭秘:MySQL Group commit》(见参考)举了一个例子,就是有一行数据,x=1,y=1 T1:x=y+1,y=x+1; T2:y=x+1,x=y+1;...

June 5, 2020

[Mysql]查询条件的类型强转

网上看到的类型强转的引起了慢查询,自己建表试了一下果真如此。 ...

March 23, 2018 · 土川