Mysql 系列 | 性能优化 - 数据可靠性
前面了解了 WAL 机制知道,只要 redo log 和 binlog 持久化到磁盘,就能确保 Mysql 重启后,数据可以恢复。
binlog 写入机制
-
事务执行过程中,日志先写入 binlog cache,事务提交时,再把 binlog cache 写入 binlog 文件中,并清空 cache。
-
一个事务的 binlog 不能拆开,所以要确保一次性写入。
-
系统为每个线程分配一块 binlog cache 内存,超出则暂存在磁盘。有参数
binlog_cache_size
决定。 -
日志写入文件系统也分两步,先放在 page cache,然后再放入正式 binlog 文件。这两步的时机由参数
sync_binlog
决定 -
sync_binlog
取值,-
0,每次事务提交时只放入 page cache
-
1,每次事务提交都持久化到 binlog
-
N,每次事务提交都放入 page cache,累计 N 个事务后才持久化到 binlog
-
-
IO 瓶颈时,sync_binlog 设置为比较大的值,可提升性能。实际场景中,一般不建议设置为 0,避免日志丢失。常见的设为 100~1000。此时异常重启后会丢失近 N 个事务的日志。
redo log 写入机制
-
redo log 的三种状态,
-
存在 redo log buffer 中,物理上实在 Mysql 进程内存中。
-
写入磁盘但没有持久化,此时存在 page cache 中。
-
持久化到磁盘。
-
-
日志写入 redo log buffer 和 page cache 都很快,持久化速度会慢很多。InnoDB 控制写入策略的参数
innodb_flush_log_at_trx_commit
,-
0,每次事务提交 redolog 留在 redolog buffer 中
-
1,每次事务提交 redolog 都持久化到磁盘
-
2,每次事务提交都只写入 page cache
-
-
IO 瓶颈时,
innodb_flush_log_at_trx_commit
可设置为 2。为 0 时 log 只保存在内存中,数据库重启会丢数据;redolog 写入 page cache 比起 buffer 性能差不多,而且 Mysql 异常重启时不会丢数据。
crash-safe
-
Mysql 中 crash-safe 能够保证,
-
客户端收到事务成功的消息,事务就一定持久化了
-
客户端收到事务失败(主键冲突、回滚等),事务就一定失败了
-
客户端收到执行异常的消息,需要重连后维持后续逻辑。此时只要保证数据库内部(数据和日志、主库和备库)一致就可以了
-
合理设置参数,能很好的提升性能,打破 IO 瓶颈。