集群方案:

对于先写后读的情况,会出现数据延迟,怎么解决?

  • 强制走主库,应用层决定
  • 异步化,后续再读取

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 threadSQL thread)
    • I/O thread:从 master 请求 binlog,并保存到 relay log
    • SQL thread:检测和读取 relaylog,并在本地做 redo 操作,完成后删除当前 relaylog

集群 - 图1

主从同步延迟:

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 后支持多线程复制

全量备份和增量备份: