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 瓶颈。

posted @ 2022-10-23 17:17  菜乌  阅读(70)  评论(0编辑  收藏  举报