mysql引擎层存储层_MySQL存储引擎层的学习笔记①

存储引擎层

InnoDB存储引擎-对于MySQL的提交机制学习

redo log buffer的参数刷新机制

Innodb_flush_log_at_trx_commit=0,1,2

0的含义 redo log thread 每隔1s将redo log buffer写入到redo log中,同时进行脏数据刷脏,不保证每次提交时都会触发redo log thread将redo log buffer写入到redo log中。也就是故障情况下可能丢失最多1s的数据。(数据库性能最好,安全性最低)

1的含义 每次commit时,都会触发redo log thread将redo log buffer写入到redo log中,并且将脏数据刷入到磁盘中。(安全性最高,数据库性能最慢)

2的含义 每次commit时,都会触发redo log thread将redo log buffer写入到redo log中,但是不会将脏数据同时刷入到磁盘中。(这里和Oracle的commit机制好像一样?介于以上两者之间)

binlog

功能应用:备份恢复和主从复制

binlog cache 写入到binlog中。

sync_log决定binlog写入方式

0的含义 每次commit时,MySQL不做fync之类磁盘同步,也就是不保证binlog cache写入到binlog中,而是由filesystem或者cache满了之后刷到磁盘

n的含义 每n次commit时,做一次binlog cache写入到binlog中

1的含义 每次commit时,都做binlog cache写入到binlog中。

binlog和redo log的区别

redo log是InnoDB引擎特有的日志,而server层的日志是binlog。

binlog为逻辑日志,记录所有数据的改变信息(针对所有引擎)

redo log为物理日志,记录InnoDB表数据的改变信息,也就是在某个数据页上做了什么修改。(针对InnoDB存储引擎)

binlog记录commit完毕之后的DML和DDL

redo log记录事务发起后的DML和DDL(无论commit与否)

binlog非循环使用,写满或者实例重启后生成新的文件

redo log循环使用,发生日志切换

binlog可以作备份恢复,主从搭建(在这里和Oracle的归档日志文件一样?)

redo log作实例恢复

MySQL的两阶段提交

准备阶段

事务SQL语句写入到redo log buffer中,做一个事物准备的标记(放在哪里?应该是redo log里),再将redo log buffer写入到redo log中

提交阶段

将事物产生的binlog cache写入binlog,在redo log中做一个事物已提交标记,把binlog写成功的标记一并写入到redo log中。(事务SQL语句 && 事务已提交标记 && binlog写成功反馈)

举例一个update语句的过程

客户端通过server层的连接器通过用户密码,权限验证等成功连接到MySQL服务端

用户发起一个update语句,通过server层的分析器(语法语义分析)、通过优化器(执行计划的生成),也就是如果buffer里面有这行数据则直接反馈给执行器,如果没有,则从磁盘中缓存在buffer里再反馈给执行器

执行器得到这行数据,给这行数据做修改之后得到一行的修改之后的新数据,再调用引擎接口写入此行数据

引擎将这行新数据更新到buffer中,同时将这个更新操作写到redo log里面,此时redo log处于prepare状态,然后告知执行器执行完成了,下一步可以进行提交事务

提交事务开始,执行器生成这个更新操作的binlog到binlog cache并且写入到binlog中

执行器调用引擎的提交事务接口,引擎把刚刚写入的redo log从prepare改为commit状态,然后反馈提交完成

两阶段提交的必要性(insert语句举例,将redo log和binlog的顺序调换)

insert一条数据事务开始,redo log buffer成功刷新到redo log file上,这时commit,等待在binlog cache写入到binlog的时候发生crash,因为这个时候redo log落盘成功,在实例恢复的时候,对应的insert的数据被恢复出来,但是这是binlog没有对应insert数据的记录,如果备份binlog,在以后进行恢复的时候,就会少一个这时候存在于数据库中的insert数据,对于主从模式中,insert的数据不存在于binlog,所以会出现主库存在,从库不存在的数据不一致现象。

insert一条数据事务开始,插入数据的记录成功写入到binlog,还没有写入到redo log中,此时crash,由于实例恢复是读取的redo log,redo log中并没有此条记录的redo,所以无法前滚重现,但是binlog中存在插入数据的记录,这时候备份binlog,在以后恢复的时候,会比现在多一个这时候存在于binlog但不存在于redo log的数据,对于主从模式中,insert的数据不存在于redo log却存在于redo log,所以会出现主库不存在,从库却存在的数据不一致现象。

所以归根结底,redo log和binlog中的两阶段提交机制,是保证数据的一致性,不仅是当前数据库的一致性,还有主从的一致性以及备份恢复中的一致性。

脏页的刷新条件

日志切换时,发生checkpoint,触发脏页刷新。

通过innodb_max_dirty_pages_pct控制,表明buffer pool中的dirty page所占百分比的阈值。默认75%,一般可以设置25-50%

innodb_adaptive_flushing控制,影响每秒固定刷新脏页的数量,优先级比innodb_max_dirty_pages_pct高。(看到这里发现好像MySQL的ckpt机制比Oracle的情况要少一点,可能是我还没学到多少)

PS:以上均为个人学习之后的理解,如有错误,恳请指正。

学习来源:《MySQL王者晋级之路》、《丁奇45讲》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值