集群方案:
- MyCat + Zookeeper + HAProxy
- https://juejin.im/post/6844904160660471821
对于先写后读的情况,会出现数据延迟,怎么解决?
- 强制走主库,应用层决定
- 异步化,后续再读取
MySQL 集群,当主库宕机后,集群会自动将一个从库升级为主库。
读写分离:写走主库,读走从库
binlog
MySQL 主从同步是基于 binlog 文件主从复制实现的。
binlog 日志用于记录所有更新了数据或者已经潜在更新了数据的所有语句。
binlog 日志格式:
- statement:记录每一条 sql
- 优点:binlog 文件较小,节约 IO,性能较高
- 缺点:不是所有的数据更改都会写入 binlog 文件中,尤其是使用了函数和一些不确定的语句操作,比如 LOAD_FILE()、UUID()、DATE() 等,从而导致主从数据不一致。
- row:不记录 sql,只记录每行数据的更改细节
- 优点:绝对的数据一致
- 缺点:会产生大量的 binlog 日志内容,性能不佳,并且会增大主从同步延迟出现的几率
- mixed:一般的语句使用 statement,而像函数操作等,则采用 row 格式保存 binlog
主从复制模式:
- 异步复制:
- 默认,主库在执行完事务后,直接返回,并不关心从库是否同步完成
- 全同步复制:
- 主库执行完事务后,还要等全部从库都执行完,才响应客户端
- 半同步复制:
- 主库执行完事务后,等待至少一个从库接收并写到 relaylog 中,才响应客户端
主从复制原理:
主从复制需要三个线程:
- master(binlog dump thread)
- 通知 slave 并传输 binlog
- slave(I/O thread、SQL thread)
- I/O thread:从 master 请求 binlog,并保存到 relay log
- SQL thread:检测和读取 relaylog,并在本地做 redo 操作,完成后删除当前 relaylog
主从同步延迟:
DDL:Data Definition Language,数据定义语言
- DDL不需要commit.
- CREATE、ALTER、DROP、TRUNCATE、COMMENT、RENAME
DML:Data Manipulation Language,数据操作语言
- 需要commit.
- SELECT、INSERT、UPDATE、DELETE、MERGE、CALL、EXPLAIN PLAN、LOCK TABLE
DCL:Data Control Language,数据库控制语言
- 授权、角色控制等
- GRANT 授权、REVOKE 取消授权
TCL:Transaction Control Language,事务控制语言
- SAVEPOINT 设置保存点、ROLLBACK 回滚、SET TRANSACTION
在 slave 执行 DDL 和 DML 的 IO 操作是随机的,不是顺序的,成本高很多,还可能存在竞争 lock 的情况。
由于 SQL thread 也是单线程的,所以一个 DDL 卡住,会拖慢后续的执行,这就导致了延时。
- 当主库的 TPS 较高时,产生的 DDL 数量超过 slave 的一个 SQL thread 所能承受的范围,延迟就产生了。
- 除此之外,还有可能与 slave 的大型 query 语句产生了锁等待导致。
- 大事务
解决:
- DAO 层分库,将数据分散到多个主库
- 引入 Redis 或 Memcache 等缓存层,降低 MySQL 的读压力
- 5.6 后支持多线程复制
全量备份和增量备份: