本篇为自己笔记,还未深入了解,浏览者不用看
首先我们要知道 mysql 的预写日志 wtite ahead log (WAL)机制,在mysql中redo日志相当于wal,即客户端操作命令先写入 redo 日志,然后再写入内存缓冲区,返回客户端, 最后再由操作系统写入硬盘。这样的好处是能保证事物。
当写入 redo 日志时服务器宕机,重启服务器时,则mysql会执行redo日志,这样就会保质和客户端得到的返回结果一致。
当然还有undo日志,事物回滚时使用。当重启服务器时,发现
当然高可用是由 binlog 实现的,那么binlog和事物日志的顺序是怎么样的呢
下面来看 mysql 各种日志的顺序
- undo日志(记录事物未执行之前数据库值)
- 将多个事物操作语句按顺序写入redo
- biglog日志 (整个一次写入,所以当开启binlog时会对性能有点影响)
- 事物commit
- 返回用户
其中在mysql 5.5之前,写入binlog之后是异步写入 mysql 从机的,那么这时候如果主库宕机,binlog还未写入从库,就会造成主从数据不一致。这时候如果要将从库升级为主库,则需要恢复主库后,使用 pt-table-checksum 等一致性检测工具检测主从一致性,并使用 pt-table-sync 恢复一致性
为了解决这个问题,mysql5.5后增加了半同步复制,binlog写入后,会同步等待从库返回,从库返沪后才返回给用户。
具体可百度 mysql半同步一致性。 里面的问题 mysql半同步一致性回滚 ,mysql脑裂问题 ,解决了这两个问题才算是解决了mysql的高可用问题。 具体分析参见 mysql半同步一致性探讨
但 mongodb 副本集 已经解决了 脑裂 问题(有待考证) 使用 bully共识算法
raft协议也解决了脑裂问题 raft算法
关于mongodb是如何解决一致性的可以参见这篇文章 mongodb丢数据问题
经验 对于支付等系统,在使用mysql半同步复制时,超时请使用无限长,避免退化成异步复制,当所有从库都没有响应时,就会提交失败,这样就避免了数据不一致的现象。