| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> MySQL深度剖析之undo log & redo log & binlog专题(2021) -> 正文阅读 |
|
[大数据]MySQL深度剖析之undo log & redo log & binlog专题(2021) |
因为每次对磁盘随机读写影响性能,尤其是高并发的时候,所以引入了Buffer Pool, 即只要更新Buffer Pool中的记录,则算更新成功,那如果更新完了还没有flush到磁盘则宕机了,此时内存的这些修改后的记录就会丢失。所以引入了redo log,在写入内存的时候,同样写入到redo log。 如果在事务期间,需要执行多条SQL,如果更新某一条SQL失败,需要回滚,这时候前面的已经写入到内存了,怎么回滚呢? 所以引入了undo log, 在写入内存之前,记录修改数据之前的记录。 一 redo log1.1 redo log 格式MySQL记录修改后或者新增的数据,是直接把数据写入redo log吗?肯定不是,那么需要记录哪些内容呢? #1 日志类型 #2 表空间ID(记录位于哪一个表空间,如果存在多个) #3 数据页号(位于表空间中哪一个数据页) #4 数据页中的偏移量 #5修改的数据的长度(可选,一般针对string类型,不知道修改了多少字节数据) #6 具体修改的数据(修改的数据) 1.2 redo log buffer和redo log blockredo log是产生一条,写入一条到磁盘吗? 不是的,它是在数据库启动的时候,根据redo log buffer大小(innodb_log_file_size)分配内存空间,然后写入一个512字节大小日志块(redo log block), redo log block包括12字节的块头,496字节的body和4字节的尾部,如图所示: 如果redo log block写满了则在创建一个 redo log buffer继续写,当redo log buffer写满了则刷到磁盘。另外redo log block的header主要包括以下信息: #1 block_no: 块号 #2 data_length: 当前写入了多少字节的数据 first_record_group: 一个事务可能有多个redo log, 一个事务就属于一个redo log分组,第一组redo log的偏移量 checkpoint_no: 检查点号 1.3 redo log buffer刷盘时机#1 如果写入的redo log已经超过了redo log buffer的一半 #2 提交事务的时候会把redo log block写入磁盘 #3 有后台线程定时刷新 #4 MySQL实例停止 1.4 如果redo log file文件满了怎么办redo log文件默认有2个文件,ib_logfile0和ib_logfile1,当ib_logfile0写满了则写入ib_logfile1,当ib_logfile1写满了则写入ib_logfile0,如此循环 二 undo log2.1 undo log格式2.2 undo log 回滚流程#1 从undo log找到刚刚执行的操作 #2 如果是新增,则根据主键删除;如果是更新则根据id和旧值还原 三 binlogbinlog是归档日志,是MySQL服务器的通用日志,主要是记录的是偏逻辑性质的数据,而不是物理数据。在提交事务的时候,先把redo log刷盘之后,就把binlog cache刷盘,然后再确认对redo log的刷盘 3.1 binlog有哪些格式3.1.1 statement完全照搬执行的语句,不作任何压缩等,即SQL语句是什么,这里就记录什么,不会记录多余的元数据 优点: #1 没有额外的信息,所以更加节省空间 #2 没有额外的信息,则在提交事务时候fsync刷盘的性能更好 缺点: 没有记录相对位置等元数据,很容易造成主从同步的时候主从不一致的情况,比如delete from test limit 10;时还会产生一个警告,大意就是使用statement格式时执行limit语句可能造成主从同步不一致。因为limit语句只是指定了删除10条记录,但没有指定具体是哪10条,当mysql在两次执行时选择了不同的索引进行操作时,删除的记录就是不同的。 3.1.2 row对于DDL操作记录执行的SQL语句,但是对于DML语句则记录具体的数据行一般生产环境采用这种格式 优点: 可以屏蔽statement缺点,不会造成主从不一致 缺点: #1 由于记录了每条数据的内容变更,导致了binlog日志占用了很大的空间,由于fsync时一次写入数据过多,在一定程度上影响了性能。 #2 另外,binlog 日志文件在写入日志的时候会被锁住,如果数据太多可能会导致性能问题。可以添加参数 binlog_row_image=minimal 来减少这个缺点 3.1.3 mixed对于DDL,只记录SQL语句;对于DML,则根据判断是否有可能造成主从不一致,如果有可能则使用row这种格式,否则使用statement 优点: 相对节省空间,提高了性能;也可以避免主从同步不一致 3.2 binlog cache和临时文件当执行增删改SQL语句时候,会为当前线程分配一块叫做binlog cache的内存块,用于缓存执行SQL语句产生的binlog event事件,大小由binlog_cache_size控制。如果binlog cache达到binlog_cache_size,则将binlog cache内容移到一个临时文件中保存,但是这个文件不能超过max_binlog_cache_size,如果超过则报错;客户端断开连接,binlog cache释放 3.3 binlog的刷盘时机和策略binlog在事务提交的时候,且在redo log buffer里的数据刷到磁盘(prepare阶段),再将binlog刷入磁盘。 binlog的刷盘策略可以通过sync_binlog参数来控制: sync_binlog = 0: 表示每次提交事务都只 write,不 fsync。即提交事务时候,将binlog写入磁盘并不是直接写入,而是写入操作系统缓存,即os cache中,当然如果这个时候宕机,os cache中的binlog会丢失 sync_binlog = 1: 表示每次提交事务都会执行 fsync。即此时会在提交事务的时候强制将binlog刷入磁盘文件,这样宕机了也不怕binlog丢失 sync_binlog = N: 表示累计N个事务后才会执行fsync,即刷入磁盘 四 redo log和binlog比较#1 一个存储的是偏逻辑的日志;一个存储的是偏物理的日志 #2 binlog一般用于备份和同步;redo log一般用于数据重启恢复 #3 提交事务的时候一般是先写redo log,再写binlog #4 binlog 和 redo log都有缓存,不同的是binlog是每一个线程或者事务都有自己的binlog cache,但是binlog 是共享缓存 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 2:56:00- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |