mysql如何保证redolog和binlog的一致性,安全性,效率。
和数据安转相关的参数
sync_binlog:控制binlog的刷新方式(写入到磁盘)
innodb_flush_log_at_trx_commit:在innodb下控制着redo的写入方式
innodb_support_xa:外部事务,用来保证binlog和redo一致性的,俗称两段式提交
binlog_order_commits:按照binlog的写入顺序提交事务,保证redo和binlog的已执行
binlog_max_flush_queue_time: leader线程搜集binlog的超时时间
2pc提交(官方支持)
(redo日志在prepare阶段就已经sync),绝大部分都比较支持这种说法
http://dev.mysql.com/doc/refman/5.6/en/binary-log.html
http://blog.itpub.net/15480802/viewspace-1411356
http://www.linuxidc.com/Linux/2015-11/124942.htm
http://www.2cto.com/database/201306/221413.html
2pc流程:(sync_binlog = 1,innodb_flush_log_at_trx_commit = 1 )
1.prepare阶段:sync redo 日志(未sync的redo存放于innodb_log_buffer_size中),系统自动完成
获取prepare_commit_mutex(一个全局锁,一次只能被一个事务获取)
2.生成binlog,将binlog写入文件系统(未提交之前binlog存放在binlog_cache_size中),sync binlog,这一步受sync_binlog控制
3.提交commit 将commit标志sync ,释放prepare_commit_mutex(这一步应该受innodb_flush_log_at_trx_commit的控制)
违背了这个参数的定义:innodb_flush_log_at_trx_commit
观点二:redo日志在最后的commit的时候才sync
http://blog.itpub.net/28218939/viewspace-1975809
2pc流程:(官方没有明显的支持这种说法)
1.prepare阶段:获取prepare_commit_mutex
2.生成binlog,将binlog写入文件系统(未提交之前binlog存放在binlog_cache_size中),sync binlog
3.提交commit 将redo log sync ,释放prepare_commit_mutex
这种方式会造成binlog的日志记录多余redo日志记录,在恢复的时候是如何恢复? 难道是以binlog为准,
不管这个事务的redo有没有提交 ,只要写binlog就认为该事务以提交(现阶段还没有找到有关该说法).
innodb数据恢复流程
1.查找未提交的redo日志(找xid)
2.用xid去binlog查找对应的日志记录
3.如果有就认为这个事务是提交的,并补充commit。如果没有就认为是没有提交的,在恢复的时候就rollback事务
###################################################################################################
以上2pc日志写入方式是在 mysql5.6之前的方式,当sync_binlog=1的时候 系统的性能非常糟糕。
从5.6 之后就开始采用BLGC方式写2pc日志,来提升性能
BLGC具体流程如下:(每一个阶段只有一个活跃的线程)
flush stage:搜集多个线程产生的binlog,依次放入flush队列的末尾,
sync stage:flush队列超时(binlog_max_flush_queue_time)或者没有线程产生binlog了 ,flush队列开始sync队列,将binlog写入磁盘(合并io)
commit stage:队列进入提交阶段(这里只做提交操作,redo日志的写入已经在prepare写入)
个人理解:
flush stage:队列中的第一个线程为leader线程,后面的线程为follower线程,leader线程主要负责收集待提交binlog的线程,并且放入
flush 队列的末尾,直到没有找到需要提交binog的线程,或者超时(binlog_max_flush_queue_time),才进入sync stage
sync stage:如果flush stage队列为空,则之前leader线程依然为leader线程,负责binlog的sync,否则变成follower线程(合并执行sync)
commit stage:sync完binlog的线程被放入commit队列的末尾,等待提交
5.7 的组提交:
Step1. InnoDB Prepare,记录当前的LSN到thd中。
Step2. 进入 Group Commit 的flush stage;Leader搜集队列,同时算出队列中最大的LSN。
Step3. 将InnoDB的redo log write/fsync到指定的LSN
Step4. 写Binlog并进行随后的工作(sync Binlog, InnoDB commit
也就是将 redo log的write/sync延迟到了 binlog group commit的 flush stage 之后,sync binlog之前。
通过延迟写redo log的方式,显式的为redo log做了一次组写入(redo log group write),并减少了(redo log) log_sys->mutex的竞争。
组提交
http://www.tuicool.com/articles/rEZr2q
http://mysqllover.com/?p=581
http://www.csdn.net/article/2015-01-16/2823591(淘宝内部mysql交流)
innodb数据丢失的问题:
http://www.360doc.com/content/14/1019/00/12904276_418041635.shtml
组提交的理解:
http://www.bitscn.com/pdb/mysql/201407/226226.html
本文出自 “SQLServer MySQL” 博客,请务必保留此出处http://dwchaoyue.blog.51cto.com/2826417/1784509
mysql如何保证redolog和binlog的一致性,安全性,效率。
标签:mysql 原理
小编还为您整理了以下内容,可能对您也有帮助:
汗颜!工作10年去面试,被“MySQL怎么保证事物一致性”难倒了
阿牛去一家中意的公司面试,本以为凭借以往丰富的经验,肯定手到擒来,结果第一个问题,我就“出门右拐”了。
问题就是:MySQL是怎么保证事务一致性的?
回到家阿牛翻阅资料,终于搞懂了,在这里分享给大家。
定义
在搞清楚问题答案之前,先搞清楚以下几个名词以及大致的用处
redo log:
通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)、Innodb特有的,他在存储引擎层。循环写的,空间固定会用完。作用是crash-safe能力
binlog:
是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ” 是 MySQL 的 Server 层实现的,所有引擎都可以使用。是可以追加写入的,“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。作用是数据归档
undo log:
有两个作用:提供回滚和多个行版本控制(MVCC)。
在数据修改的时候,不仅记录了redo,还记录了相对应的undo,如果因为某些原因导致事务失败或回滚了,可以借助该undo进行回滚。
SQL执行的过程
了解了以上名词之后,让我们看一下“一条更新SQL语句执行的过程是什么?”
如图1有几个关键步骤:
1、先查找记录所在的Innodb页在不在内存里;如果不在内存里则将记录所在的页加载在内存里;根据SQL语句在内存中将记录更新
2、将更新前的记录写入undolog
3、根据记录的更新值将变更写入redolog(buffer)中,并将状态变更为prepare
4、将变更记录到逻辑日志
5、redolog日志中的状态修改为commit,返回结束
至此:一条更新语句的过程结束
上面的步骤中有些同学可能会有一些疑问:为什么更新一条记录要把一整页数据加载到内存里答:因为Innodb引擎中,最小的存储单位是页为什么一定要加载到内存里?答:因为所有的计算操作都是在内存里,操作完成后最终才写回磁盘为什么要写入redolog,直接写入磁盘,然后写入binlog就好了啊?答:这将在下面会提到,请往后看
为了加深理解,准备了下面2张图辅助理解
以图3为例,让我们看看在每个步骤出现异常的时候,到底怎么保证事物一致性的吧!1、步骤123,所有的操作最多还只是内存里,如果出现宕机、断电等异常, 记录不会有任何变动,事物是一致的2、步骤4刚执行完,断电了,因为redolog还处在prepare状态, 这时候事物也是一致的3、步骤5记录binlog的过程中断电了,这时候要保证主从一致性, 事物也是不生效的,最终也是一致的4、步骤6、7如果中间任何一个时刻断电了,这时候情况就不一样了,事物是生效的,因为redolog、binlog的数据都是完整的,服务器重启后可以按照xid来去查看binlog、redolog中是否都存在, 都存在该事物就是生效的。上面就是怎么保证事务一致性的根本原因
为什么要使用redolog?
回答这个问题之前,我们先看看redolog用图形表示的
图4是redolog的形象一点的表现,并不是说redolog 长这个样子,只是为了更形象;一般情况下redolog一组4个文件,每个文件1个G,其中write pos是指redolog当前写到什么位置了,check point是指上次刷脏结束的位置,当write log和check point重合时,所有的进程停止,开始新一轮的刷脏操作。刷完后redolog清空开始下一轮的写入,往返重复。
可能这样表示有点抽象,让我们看下图5
从上图中可以看的更形象一点,在sql执行的时候,会有磁盘IO将数据页加载到内存,然后在内存中将数据修改,修改后的数据页在内存中叫做脏页(叫脏页因为和磁盘中的数据不一致啊),又因为在内存中容易丢失,所以将数据页的变更记录如redolog中,随着记录插入、更新等操作的增多,redolog空间慢慢的满了,这时候就开始刷脏操作了,page cleaner thread线程会将所有的脏页数据刷新到磁盘,使得变更最终被持久化到磁盘。
讲到这里一定还会有人不太理解,刷脏之前断电了咋办?
这就是redolog的另一个重要的作用,crash-safe能力,实现的逻辑是这样的,断电后内存的数据都没了,重启后读取redolog文件,因为redolog文件记录的是在Innodb页x的m处做了y的修改,所以根据redolog将涉及到的Innodb页重新加载到内存,根据redolog的记录将内存中的数据重新修改,这样就能恢复断电前的数据了。
完
下期预告:还是MySQL,敬请期待
本文首发自: 程序员阿牛
mysql是怎么保证事务 server层的binlog和引擎层的redolog 一致的
内部xa事务主要是mysql内部为了保证binlog与redo log之间数据的一致性而存在的,这也是由其架构决定的(binlog在mysql层,而redo log 在存储引擎层);
外部xa事务则是指支持多实例分布式事务,这个才算是真正的分布式事务。
既然是xa事务,必然涉及到两阶段提交,对于内部xa而言,同样存在着提交的两个阶段。
mysql 如何解决数据一致性
现在常用的MySQL高可用方案,十有*是基于 MySQL的主从复制(replication)来设计的,包括常规的一主一从、双主模式,或者半同步复制(semi-sync replication)。
我们常常把MySQL replication说成是MySQL同步(sync),但事实上这个过程是异步(async)的。大概过程是这样的:
在master上提交事务后,并且写入binlog,返回事务成功标记;
将binlog发送到slave,转储成relay log;
在slave上再将relay log读取出来应用。
步骤1和步骤3之间是异步进行的,无需等待确认各自的状态,所以说MySQL replication是异步的。
MySQL semi-sync replication在之前的基础上做了加强完善,整个流程变成了下面这样:
首先,master和至少一个slave都要启用semi-sync replication模式;
某个slave连接到master时,会主动告知当前自己是否处于semi-sync模式;
在master上提交事务后,写入binlog后,还需要通知至少一个slave收到该事务,等待写入relay log并成功刷新到磁盘后,向master发送“slave节点已完成该事务”确认通知;
master收到上述通知后,才可以真正完成该事务提交,返回事务成功标记;
在上述步骤中,当slave向master发送通知时间超过rpl_semi_sync_master_timeout设定值时,主从关系会从semi-sync模式自动调整成为传统的异步复制模式。
半同步复制看起来很美好有木有,但如果网络质量不高,是不是出现抖动,触发上述第5条的情况,会从半同步复制降级为普通复制;此外,采用半同步复制,会导致master上的tps性能下降非常严重,最严重的情况下可能会损失50%以上。
这样来看,除非需要非常严格保证数据一致性等迫不得已的场景,就不太建议使用半同步复制了。当然了,事实上我们也可以通过加强程序端的逻辑控制,来避免主从数据不一致时发生逻辑错误,比如说如果在从上读取到的数据和主不一致的话,那么就触发主从间的一次数据修复工作。或者,我们也可以用 pt-table-checksum & pt-table-sync 两个工具来校验并修复数据,只要运行频率适当,是可行的。
真想要提高多节点间的数据一致性,可以考虑采用PXC方案。现在已知用PXC规模较大的有qunar、sohu,如果团队里初期没有人能比较专注PXC的话,还是要谨慎些,毕竟和传统的主从复制差异很大,出现问题时需要花费更多精力去排查解决。
如何保证主从复制数据一致性
上面说完了异步复制、半同步复制、PXC,我们回到主题:在常规的主从复制场景里,如何能保证主从数据的一致性,不要出现数据丢失等问题呢?
在MySQL中,一次事务提交后,需要写undo、写redo、写binlog,写数据文件等等。在这个过程中,可能在某个步骤发生crash,就有可能导致主从数据的不一致。为了避免这种情况,我们需要调整主从上面相关选项配置,确保即便发生crash了,也不能发生主从复制的数据丢失。
1. 在master上修改配置
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
上述两个选项的作用是:保证每次事务提交后,都能实时刷新到磁盘中,尤其是确保每次事务对应的binlog都能及时刷新到磁盘中,只要有了binlog,InnoDB就有办法做数据恢复,不至于导致主从复制的数据丢失。
2. 在slave上修改配置
master_info_repository = "TABLE"
relay_log_info_repository = "TABLE"
relay_log_recovery = 1
上述前两个选项的作用是:确保在slave上和复制相关的元数据表也采用InnoDB引擎,受到InnoDB事务安全的保护,而后一个选项的作用是开启relay log自动修复机制,发生crash时,会自动判断哪些relay log需要重新从master上抓取回来再次应用,以此避免部分数据丢失的可能性。
通过上面几个选项的调整,就可以确保主从复制数据不会发生丢失了。但是,这并不能保证主从数据的绝对一致性,因为,有可能设置了ignoredo ewrite等replication规则,或者某些SQL本身存在不确定因素,或者人为在slave上修改数据,最终导致主从数据不一致。这种情况下,可以采用pt-table-checksum 和 pt-table-sync 工具来进行数据的校验和修复。
mysql 如何解决数据一致性
现在常用的MySQL高可用方案,十有*是基于 MySQL的主从复制(replication)来设计的,包括常规的一主一从、双主模式,或者半同步复制(semi-sync replication)。
我们常常把MySQL replication说成是MySQL同步(sync),但事实上这个过程是异步(async)的。大概过程是这样的:
在master上提交事务后,并且写入binlog,返回事务成功标记;
将binlog发送到slave,转储成relay log;
在slave上再将relay log读取出来应用。
步骤1和步骤3之间是异步进行的,无需等待确认各自的状态,所以说MySQL replication是异步的。
MySQL semi-sync replication在之前的基础上做了加强完善,整个流程变成了下面这样:
首先,master和至少一个slave都要启用semi-sync replication模式;
某个slave连接到master时,会主动告知当前自己是否处于semi-sync模式;
在master上提交事务后,写入binlog后,还需要通知至少一个slave收到该事务,等待写入relay log并成功刷新到磁盘后,向master发送“slave节点已完成该事务”确认通知;
master收到上述通知后,才可以真正完成该事务提交,返回事务成功标记;
在上述步骤中,当slave向master发送通知时间超过rpl_semi_sync_master_timeout设定值时,主从关系会从semi-sync模式自动调整成为传统的异步复制模式。
半同步复制看起来很美好有木有,但如果网络质量不高,是不是出现抖动,触发上述第5条的情况,会从半同步复制降级为普通复制;此外,采用半同步复制,会导致master上的tps性能下降非常严重,最严重的情况下可能会损失50%以上。
这样来看,除非需要非常严格保证数据一致性等迫不得已的场景,就不太建议使用半同步复制了。当然了,事实上我们也可以通过加强程序端的逻辑控制,来避免主从数据不一致时发生逻辑错误,比如说如果在从上读取到的数据和主不一致的话,那么就触发主从间的一次数据修复工作。或者,我们也可以用 pt-table-checksum & pt-table-sync 两个工具来校验并修复数据,只要运行频率适当,是可行的。
真想要提高多节点间的数据一致性,可以考虑采用PXC方案。现在已知用PXC规模较大的有qunar、sohu,如果团队里初期没有人能比较专注PXC的话,还是要谨慎些,毕竟和传统的主从复制差异很大,出现问题时需要花费更多精力去排查解决。
如何保证主从复制数据一致性
上面说完了异步复制、半同步复制、PXC,我们回到主题:在常规的主从复制场景里,如何能保证主从数据的一致性,不要出现数据丢失等问题呢?
在MySQL中,一次事务提交后,需要写undo、写redo、写binlog,写数据文件等等。在这个过程中,可能在某个步骤发生crash,就有可能导致主从数据的不一致。为了避免这种情况,我们需要调整主从上面相关选项配置,确保即便发生crash了,也不能发生主从复制的数据丢失。
1. 在master上修改配置
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1
上述两个选项的作用是:保证每次事务提交后,都能实时刷新到磁盘中,尤其是确保每次事务对应的binlog都能及时刷新到磁盘中,只要有了binlog,InnoDB就有办法做数据恢复,不至于导致主从复制的数据丢失。
2. 在slave上修改配置
master_info_repository = "TABLE"
relay_log_info_repository = "TABLE"
relay_log_recovery = 1
上述前两个选项的作用是:确保在slave上和复制相关的元数据表也采用InnoDB引擎,受到InnoDB事务安全的保护,而后一个选项的作用是开启relay log自动修复机制,发生crash时,会自动判断哪些relay log需要重新从master上抓取回来再次应用,以此避免部分数据丢失的可能性。
通过上面几个选项的调整,就可以确保主从复制数据不会发生丢失了。但是,这并不能保证主从数据的绝对一致性,因为,有可能设置了ignoredo ewrite等replication规则,或者某些SQL本身存在不确定因素,或者人为在slave上修改数据,最终导致主从数据不一致。这种情况下,可以采用pt-table-checksum 和 pt-table-sync 工具来进行数据的校验和修复。
97 基于Binlog实现MySQL与Redis数据一致性问题
mysql 与Redis 数据一致性问题 直接将Redis清空
中间件 canal框架 基于 docker环境构建
canal 框架 原理:
<u>https://gitee.com/mirrors/canal?utm_source=alading&utm_campaign=repo</u>
canal 框架原理
1,canal伪装成mysql从节点 订阅mysql 主节点的binlog文件
2,当我们的mysql 主节点 binlog 文件发生了变化,则将binlog 文件发送给canal服务器端
3,canal 服务器端将该binlog 文件二进制转换成json格式给canal客户端
4,canal客户端在将改数据同步到Redis/ES
基于Binlog 开启方式
1.mysql 开启binlog 文件配置
windows 配置
查询 my.ini配置文件位置
C:\ProgramData\MySQL\MySQL Server 5.7
2, linux mysql
安装canal
进入容器
编辑配置文件
重启canal
Docker-compose 构建canal
canal.instance.mysql.slaveId:slaveId不能与mysql的serverId一样
canal.instance.master.address:mysql地址
canal.instance.dbUsername:mysql账号
canal.instance.dbPassword:mysql密码
mysql主从怎么保证数据一致性
MySQL作为一个可插拔的数据库系统,支持插件式的存储引擎,在设计上分为Server层和Storage Engine层。
在Server层,MySQL以events的形式记录数据库各种操作的Binlog二进制日志,其基本核心作用有:复制和备份。
除此之外,我们结合多样化的业务场景需求,基于Binlog的特性构建了强大的MySQL生态,如:DTS、单元化、异构系统之间实时同步等等,Binlog早已成为MySQL生态中不可缺少的模块。
而在Storage Engine层,InnoDB作为比较通用的存储引擎,其在高可用和高性能两方面作了较好的平衡,早已经成为使用MySQL的首选。
和大多数关系型数据库一样,InnoDB采用WAL技术,即InnoDB Redo Log记录了对数据文件的物理更改,并保证总是日志先行,在持久化数据文件前,保证之前的redo日志已经写到磁盘。
Binlog和InnoDB Redo Log是否落盘将直接影响实例在异常宕机后数据能恢复到什么程度。InnoDB提供了相应的参数来控制事务提交时,写日志的方式和策略。
mysql主从怎么保证数据一致性
MySQL作为一个可插拔的数据库系统,支持插件式的存储引擎,在设计上分为Server层和Storage Engine层。
在Server层,MySQL以events的形式记录数据库各种操作的Binlog二进制日志,其基本核心作用有:复制和备份。
除此之外,我们结合多样化的业务场景需求,基于Binlog的特性构建了强大的MySQL生态,如:DTS、单元化、异构系统之间实时同步等等,Binlog早已成为MySQL生态中不可缺少的模块。
而在Storage Engine层,InnoDB作为比较通用的存储引擎,其在高可用和高性能两方面作了较好的平衡,早已经成为使用MySQL的首选。
和大多数关系型数据库一样,InnoDB采用WAL技术,即InnoDB Redo Log记录了对数据文件的物理更改,并保证总是日志先行,在持久化数据文件前,保证之前的redo日志已经写到磁盘。
Binlog和InnoDB Redo Log是否落盘将直接影响实例在异常宕机后数据能恢复到什么程度。InnoDB提供了相应的参数来控制事务提交时,写日志的方式和策略。
技术分享 | Xtrabackup 不备份 binlog 怎么保证一致性?
已知:MySQL 的内部两阶段提交,是为了解决 binlog 和 redo log 的一致性(在 crash recovery 的过程中, 如果发现某个事务的 redo log 已经完成 prepare 阶段, 但未完成 commit,那么会验证该事务是否在 binlog 中,如存在,则进行提交,否则进行回滚)。
又已知:Xtrabackup 在恢复备份后,会进行类似于 crash recovery 的动作(将备份的 redo log 的内容回放到数据中, 并对事务进行提交/回滚),那么 Xtrabackup 为什么不需要备份 binlog 文件?
想了一下好像不是能一句话说清楚的,我来尝试解答下。
备份时全局锁阶段做的操作:
这里最主要是要保证两点:
其中 FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS,是防止 innodb_flush_log_at_trx_commit 不等于 1 ,redo log没有刷到磁盘。而 SHOW MASTER STATUS 则是为了获取 binlog 位点。
关键在:xtrabackup 只需要保证“数据和 binlog 位点的一致”,而不是“数据和 binlog 的一致”。
crash recovery 过程要保证“数据和binlog的一致”,因为 crash 后不能出现事务重做提交而 binlog 没记录的情况,这样会导致从库丢失数据。那备份需要考虑的是什么?有两点:
其实这两点都一样,就是要保证备份时 “数据和 binlog 位点的一致”。xtrabackup 是怎么实现的呢?
首先我们得知道事务二阶段提交过程中的3个队列 flush、sync、commit 都有排他锁,一个大事务 commit 可能需要几秒钟,那么此时执行 FTWRL 是会被阻塞的,commit 结束后才能取得全局锁,取得全局锁后,执行 commit 会被阻塞:
这保证了 xtrabackup 备份的 redo log 中只有两种事务:已经完成提交的,和还没开始提交的(未执行 commit 的事务可能被后台线程刷盘),不会出现 prepare 状态的事务。另外还有一个知识点:GTID 的生成和写 binlog 缓存是在二阶段提交的 binlog flush 阶段做的。结合起来则说明:FTWRL 后 执行 show master status 获取 binlog 位点,只有完成提交的事务才会在其中,所以这保证了 binlog 位点和 binlog 的一致。
所以在 xtrabackup 的恢复过程,不需要处理 prepare 状态的事务,也就不需要再验证该事务是否在 binlog 中了。
mysql如何备份最安全
Mysql数据库备份的方法:
方法一:如果你使用的是虚拟主机,可以用使用phpmyadmin来备份数据库。
1、登陆phpmyadmin。登陆后左边会出现数据库列表,单击要备份的数据库。
2、在弹出的页面中,右侧上部单击“导出”按钮,一般保持默认选项,最下面“另存为文件”,选择“ZIP压缩”,最后单击执行按钮。
3、弹出保存文件后,保存文件即可。
mysql如何备份最安全
Mysql数据库备份的方法:
方法一:如果你使用的是虚拟主机,可以用使用phpmyadmin来备份数据库。
1、登陆phpmyadmin。登陆后左边会出现数据库列表,单击要备份的数据库。
2、在弹出的页面中,右侧上部单击“导出”按钮,一般保持默认选项,最下面“另存为文件”,选择“ZIP压缩”,最后单击执行按钮。
3、弹出保存文件后,保存文件即可。
mysql 怎样保证事务不丢
redo log + bin log 是现在 mysql 常用的一种配置,在 innerdb 没有成为 mysql 的默认引擎之前,mysql 已经又了 binlog 这种日志格式,它在 server 层。innerdb 有自己的 redo log 支持崩溃恢复,后面成为 mysql 的引擎过后,整个事务的过程变成一种两阶段提交的方式:
现在设想两种情况:
A.如果已经写了 redo log,redo log 处于 prepare 阶段,写 binlog 之前崩溃了
答:此时 binlog 还没写,redo log 也没提交,所以崩溃恢复的时候,整个事务会回滚。这时 binlog 还没写,如果是主从复制的架构,binlog 的数据也不会传递到备库里。
B.如果是已经写了 binlog,但是 redo log 还没提交
答:mysql 目前的崩溃规则如下:
追问 B:处于 prepare 阶段的 redo log 加上完整的 binlog,重启就能恢复,mysql 为什么要这样设计
答:这个问题与数据与备份的一致性有关。如果写 binlog 后 mysql 崩溃,但是因为已经写入了,binlog 会被从库消费使用(或者使用 binlog 恢复库),所以主库上也要提交这个事务,保证主从一致性。
mysql 怎样保证事务不丢
redo log + bin log 是现在 mysql 常用的一种配置,在 innerdb 没有成为 mysql 的默认引擎之前,mysql 已经又了 binlog 这种日志格式,它在 server 层。innerdb 有自己的 redo log 支持崩溃恢复,后面成为 mysql 的引擎过后,整个事务的过程变成一种两阶段提交的方式:
现在设想两种情况:
A.如果已经写了 redo log,redo log 处于 prepare 阶段,写 binlog 之前崩溃了
答:此时 binlog 还没写,redo log 也没提交,所以崩溃恢复的时候,整个事务会回滚。这时 binlog 还没写,如果是主从复制的架构,binlog 的数据也不会传递到备库里。
B.如果是已经写了 binlog,但是 redo log 还没提交
答:mysql 目前的崩溃规则如下:
追问 B:处于 prepare 阶段的 redo log 加上完整的 binlog,重启就能恢复,mysql 为什么要这样设计
答:这个问题与数据与备份的一致性有关。如果写 binlog 后 mysql 崩溃,但是因为已经写入了,binlog 会被从库消费使用(或者使用 binlog 恢复库),所以主库上也要提交这个事务,保证主从一致性。
在数据库中,binlog和redolog有什么区别
说说binlog
当启动Binlog后,事务会产生BinlogEvent,这些Event被看做事务数据的一部分。因此要保证事务的BinlogEvent和InnoDB引擎中的数据的一致性。所以带Binlog的CrashSafe要求MySQL宕机重启后能够保证:
- 所有已经提交的事务的数据仍然存在。
- 所有没有提交的事务的数据自动回滚。
- 所有已经提交了的事务的Binlog Event也仍然存在。
- 所有没有提交事务没有记录Binlog Event。
这些要求很好理解,如果重启后数据还在,但是Binlog Event没有了,就没办法复制到其他节点上了。如果重启后,数据没了,但是Binlog Event还在,那么不存在的数据就会被复制到其他节点上,从而导致主从的不一致。
为了保证带Binlog的CrashSafe,MySQL内部使用的两阶段提交(Two Phase Commit)。
Redo Log记录的是redo,那么redo是什么呢?通俗来讲,redo记录的是对应的记录改变的物理操作。说实话,过去的很长一段时间内,我对redo的认识也仅限于此,并没有好好深入理解redo记录的到底是什么。这次从redo的物理结构上深入理解下redo到底是什么。
Redo Log逻辑&物理结构
从逻辑上来讲,redo log记录是连续递增的,但是对应到物理文件就不一样了,考虑到磁盘空间,redo log被设计成了多个可循环写入的文件。InnoDB要求Redo Log,文件至少有2个,初始文件为 ib_logfile0和 ib_logfile1, ib_logfile0写完以后写 ib_logfile1,等到 ib_logfile1也写完了,从头又开始写 ib_logfile0,这样就形成了一个环形写入的结构。但是覆盖写入的前提是要确定哪个位置点是可以覆盖写的,哪些位置是不能覆盖写的,这个就是check point的工作了
在数据库中,binlog和redolog有什么区别
说说binlog
当启动Binlog后,事务会产生BinlogEvent,这些Event被看做事务数据的一部分。因此要保证事务的BinlogEvent和InnoDB引擎中的数据的一致性。所以带Binlog的CrashSafe要求MySQL宕机重启后能够保证:
- 所有已经提交的事务的数据仍然存在。
- 所有没有提交的事务的数据自动回滚。
- 所有已经提交了的事务的Binlog Event也仍然存在。
- 所有没有提交事务没有记录Binlog Event。
这些要求很好理解,如果重启后数据还在,但是Binlog Event没有了,就没办法复制到其他节点上了。如果重启后,数据没了,但是Binlog Event还在,那么不存在的数据就会被复制到其他节点上,从而导致主从的不一致。
为了保证带Binlog的CrashSafe,MySQL内部使用的两阶段提交(Two Phase Commit)。
Redo Log记录的是redo,那么redo是什么呢?通俗来讲,redo记录的是对应的记录改变的物理操作。说实话,过去的很长一段时间内,我对redo的认识也仅限于此,并没有好好深入理解redo记录的到底是什么。这次从redo的物理结构上深入理解下redo到底是什么。
Redo Log逻辑&物理结构
从逻辑上来讲,redo log记录是连续递增的,但是对应到物理文件就不一样了,考虑到磁盘空间,redo log被设计成了多个可循环写入的文件。InnoDB要求Redo Log,文件至少有2个,初始文件为 ib_logfile0和 ib_logfile1, ib_logfile0写完以后写 ib_logfile1,等到 ib_logfile1也写完了,从头又开始写 ib_logfile0,这样就形成了一个环形写入的结构。但是覆盖写入的前提是要确定哪个位置点是可以覆盖写的,哪些位置是不能覆盖写的,这个就是check point的工作了
怎么避免mysql从库同步 怎么保证数据一致性
用 pt-table-checksum 时,会不会影响业务性能?
实验
实验开始前,给大家分享一个小经验:任何性能评估,不要相信别人的评测结果,要在自己的环境上测试,并(大概)知晓原理。
我们先建一对主从:
然后用 mysqlslap跑一个持续的压力:
开另外一个会话,将 master 上的 general log 打开:
然后通过 pt-table-checksum 进行一次比较:
查看 master 的 general log,由于 mysqlslap 的影响,general log 中有很多内容,我们找到与 pt-table-checksum 相关的线程:
将该线程的操作单独列出来:
操作比较多,我们一点一点来说明:
这里工具调小了 innodb 锁等待时间。使得之后的操作,只要在 innodb 上稍微有锁等待,就会马上放弃操作,对业务影响很小。
另外工具调小了 wait_timeout 时间,倒是没有特别的作用。
工具将隔离级别调整为了 RR 级别,事务的维护代价会比 RC 要高,不过后面我们会看到工具使用的每个事务都很小,加上之前提到 innodb 锁等待时间调到很小,对线上业务产生的成本比较小。
RR 级别是数据对比的基本要求。
工具通过一系列操作,了解表的概况。工具是一个数据块一个数据块进行校验,这里获取了第一个数据块的下边界。
接下来工具获取了下一个数据块的下边界,每个 SQL前都会 EXPLAIN 一下,看一下执行成本,非常小心翼翼。
之后工具获取了一个数据块的 checksum,这个数据块不大,如果跟业务流量有冲突,会马上出发 innodb 的锁超时,立刻退让。
以上是 pt-table-checksum 的一些设计,可以看到这几处都是精心维护了业务流量不受影响。
工具还设计了其他的一些机制保障业务流量,比如参数 --max-load 和 --pause-file 等,还有精心设计的数据块划分方法,索引选择方法等。大家根据自己的情况配合使用即可达到很好的效果。
总结
本期我们介绍了简单分析 pt-table-checksum 是否会影响业务流量,坊间会流传工具的各种参数建议或者不建议使用,算命的情况比较多,大家都可以用简单的实验来分析其中机制。
还是那个观点,性能测试不能相信道听途说,得通过实验去分析。
怎么避免mysql从库同步 怎么保证数据一致性
用 pt-table-checksum 时,会不会影响业务性能?
实验
实验开始前,给大家分享一个小经验:任何性能评估,不要相信别人的评测结果,要在自己的环境上测试,并(大概)知晓原理。
我们先建一对主从:
然后用 mysqlslap跑一个持续的压力:
开另外一个会话,将 master 上的 general log 打开:
然后通过 pt-table-checksum 进行一次比较:
查看 master 的 general log,由于 mysqlslap 的影响,general log 中有很多内容,我们找到与 pt-table-checksum 相关的线程:
将该线程的操作单独列出来:
操作比较多,我们一点一点来说明:
这里工具调小了 innodb 锁等待时间。使得之后的操作,只要在 innodb 上稍微有锁等待,就会马上放弃操作,对业务影响很小。
另外工具调小了 wait_timeout 时间,倒是没有特别的作用。
工具将隔离级别调整为了 RR 级别,事务的维护代价会比 RC 要高,不过后面我们会看到工具使用的每个事务都很小,加上之前提到 innodb 锁等待时间调到很小,对线上业务产生的成本比较小。
RR 级别是数据对比的基本要求。
工具通过一系列操作,了解表的概况。工具是一个数据块一个数据块进行校验,这里获取了第一个数据块的下边界。
接下来工具获取了下一个数据块的下边界,每个 SQL前都会 EXPLAIN 一下,看一下执行成本,非常小心翼翼。
之后工具获取了一个数据块的 checksum,这个数据块不大,如果跟业务流量有冲突,会马上出发 innodb 的锁超时,立刻退让。
以上是 pt-table-checksum 的一些设计,可以看到这几处都是精心维护了业务流量不受影响。
工具还设计了其他的一些机制保障业务流量,比如参数 --max-load 和 --pause-file 等,还有精心设计的数据块划分方法,索引选择方法等。大家根据自己的情况配合使用即可达到很好的效果。
总结
本期我们介绍了简单分析 pt-table-checksum 是否会影响业务流量,坊间会流传工具的各种参数建议或者不建议使用,算命的情况比较多,大家都可以用简单的实验来分析其中机制。
还是那个观点,性能测试不能相信道听途说,得通过实验去分析。