主从不一致场景分析及如何避免
来源:互联网 发布:辐射4画面优化补丁 编辑:程序博客网 时间:2024/06/05 18:52
master库写redo、binlog不实时丢数据的场景
redo的ib_logfile与binlog日志如果被设置非实时flush,就有可能存在丢数据的情况:
- redo未写入磁盘,但binlog写入磁盘,造成从库数据量比主库多。
- redo写入了磁盘,但是binlog未写入,造成从库数据量比主库少。
从目前来看,只能牺牲性能去换取数据的安全性,必须要设置redo和binlog为实时刷盘,如果对性能要求很高,则考虑使用SSD:
sync_binlog = 1innodb_flush_log_at_trx_commit = 1
slave库写redo、binlog不实时丢数据的场景
slave读取master的binlog日志后,需要落地3个文件:relay log
、relay log info
、master info
:
relay log:即读取过来的master的binlog,内容与格式与master的binlog一致。
relay log info:记录SQL Thread应用的relay log的位置、文件号等信息。
master info:记录IO Thread读取master的binlog的位置、文件号、延迟等信息。
因此如果当这3个文件如果不及时落地,则主机crash后会导致数据的不一致。
MySQL 5.6 针对复制功能提供了新特性: slave支持crash-safe. 该功能可以解决之前版本中系统异常断电可能导致的SQL thread 信息不准确的问题。
在MySQL 5.6.2之前,slave记录的master信息以及slave应用binlog的信息存放在文件中,即master.info与relay-log.info。在5.6.2版本之后,允许记录到table中,参数设置如下:
master-info-repository = TABLE relay-log-info-repository = TABLE
对应的表分别为mysql.slave_master_info
与mysql.slave_relay_log_info
,且这两个表均为innodb引擎表。
master info与relay info还有3个参数控制刷新:
● sync_relay_log:这个参数和sync_binlog是一样的,当设置为1时,slave的I/O线程每次接收到master发送过来的binlog日志都要写入系统缓冲区,然后刷入relay log中继日志里,这样是最安全的,因为在崩溃的时候,你最多会丢失一个事务,但会造成磁盘的大量I/O。当设置为0时,并不是马上就刷入中继日志里,而是由操作系统决定何时来写入,虽然安全性降低了,但减少了大量的磁盘I/O操作。这个值默认是0,可动态修改,建议采用默认值。默认为10000,即每10000次sync_relay_log事件会刷新到磁盘。为0则表示不刷新,交由OS的cache控制。
● sync_master_info:若master-info-repository为FILE,当设置为0,则每次sync_master_info事件都会刷新到磁盘,默认为10000次刷新到磁盘;若master-info-repository为TABLE,当设置为0,则表不做任何更新,设置为1,则每次事件会更新表 #默认为10000
● sync_relay_log_info:若relay_log_info_repository为FILE,当设置为0,交由OS刷新磁盘,默认为10000次刷新到磁盘;若relay_log_info_repository为TABLE,且为INNODB存储,则无论为任何值,则都每次evnet都会更新表。
建议参数设置如下:
sync_relay_log = 1 sync_master_info = 1 sync_relay_log_info = 1 master-info-repository = TABLE relay-log-info-repository = TABLE
当这样设置,导致调用fsync()/fdatasync()随着master的事务的增加而增加,且若slave的binlog和redo也实时刷新的话,会带来很严重的IO性能瓶颈。
同时,通过MySQL 5.5版本开始提供的参数relay_log_recovery,当slave发生crash后重启之后重连master时,slave不根据master-info.log的信息进行重连,而是根据relay-info中执行到master的位置信息重新开始拉master上的日志数据。
总结:crash-safe + relay_log_recovery
复制有延迟的情况下主库宕机造成的数据丢失
当master出现故障后,binlog未及时传到slave,或者各个slave收到的binlog不一致。且master无法在第一时间恢复,这个时候怎么办?
如果master不切换,则整个数据库只能只读,影响应用的运行。
如果将别的slave提升为新的master,那么原master未来得及传到slave的binlog的数据则会丢失,并且还涉及到下面2个问题。
1.各个slave之间接收到的binlog不一致,如果强制拉起一个slave,则slave之间数据会不一致。
2.原master恢复正常后,由于新的master日志丢弃了部分原master的binlog日志,这些多出来的binlog日志怎么处理,重新搭建环境?
对于上面出现的问题,一种方法是确保binlog传到从库,或者说保证主库的binlog有多个拷贝。第二种方法就是允许数据丢失,制定一定的策略,保证最小化丢失数据。
如何确保binlog全部传到从库?
方案一:使用semi sync(半同步)或增强型半同步方式,事务提交后,必须要传到slave,事务才能算结束。对性能影响很大,依赖网络适合小tps系统。当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,单位是毫秒,默认为10000,即10s),会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为半同步复制。由参数rpl_semi_sync_master_wait_point控制,取值为AFTER_SYNC (默认值)何AFTER_COMMIT
方案二:双写binlog,通过DBDR OS层的文件系统复制到备机,或者使用共享盘保存binlog日志。
方案三:在数据层做文章,比如保证数据库写成功后,再异步队列的方式写一份,部分业务可以借助设计和数据流解决。
- 主从不一致场景分析及如何避免
- MySQL丢数据及主从数据不一致的场景
- MySQL丢数据及主从数据不一致的场景
- MySQL丢数据及主从数据不一致的场景
- MySQL丢数据及主从数据不一致的场景
- MySQL丢数据及主从数据不一致的场景(转)--------非常重要
- 如何处理mysql数据库主从不一致
- mysql主从同步异步场景的分析
- 如何避免使用try catch语句块,及性能分析
- 如何避免不同应用更改数据,导致的数据不一致。
- mysql主从不一致
- mysql 主从不一致解决方法
- mysql主从不一致解决方法
- 死锁及如何避免死锁
- loadrunner 分析及监视场景
- MySQL主从不一致的情况
- solr主从节点数据不一致
- mysql主从备份及原理分析
- 【LeetCode笔记】Convert Sorted Array to Binary Search Tree 通过有序数列建立二叉搜索树
- 剑指offer : 二维数组中的查找
- Codeforces 629D
- Vue.js 知识点罗列
- ubuntu 16.04 composer安装
- 主从不一致场景分析及如何避免
- ZOJ2971-Give Me the Number
- 数据库连接池
- 单调栈总结
- FastDFS 分布式系统需求分析
- SQL删除重复数据只保留一条
- 搭建hadoop集群
- HDUoj- 1004 -Let the Balloon Rise ( map
- Openstack : 2、devstack创建虚拟主机