暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MySQL存储引擎层的学习笔记①

原创 张伟垚 2020-08-19
760

存储引擎层

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讲》

最后修改时间:2020-08-19 22:09:34
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论

目录
  • 存储引擎层
    • redo log buffer的参数刷新机制
    • binlog
    • binlog和redo log的区别
    • MySQL的两阶段提交
    • 脏页的刷新条件