MySQL怎么保证数据不丢失?
只要 redo log 和 binlog 保证持久化到磁盘,就能确保 MySQL 异常重启后,数据可以恢复。
那MySQL的binlog 和 redo log写出流程是什么样子的呢?
binlog的写入机制:
在事物执行的过程中,先把日志写到binlog cache中,等待事物提交,再把binlog cache写到binlog文件中。一个事物的binlog是不能被拆开的,不论这个事物多大,也要确保一次性写入。这就涉及到了binlog cache的保存问题。系统给 binlog cache 分配了一片内存,每个线程一个,参数 binlog_cache_size 用于控制单个线程内 binlog cache 所占内存的大小。如果超过了这个参数规定的大小,就要暂存到磁盘。
redo log的写入机制:
事物在执行的过程中,生成的redo log是要先写到redo log buffer里的。然后在根据情况写入到磁盘中:情况一,redo log buffer 占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动写盘。情况二,并行的事务提交的时候,顺带将这个事务的 redo log buffer 持久化到磁盘。
如果你的 MySQL 现在出现了性能瓶颈,而且瓶颈在 IO 上,可以通过哪些方法来提升性能呢?
设置 binlog_group_commit_sync_delay 和 binlog_group_commit_sync_no_delay_count 参数,减少 binlog 的写盘次数。这个方法是基于“额外的故意等待”来实现的,因此可能会增加语句的响应时间,但没有丢失数据的风险。
将 sync_binlog 设置为大于 1 的值(比较常见是 100~1000)。这样做的风险是,主机掉电时会丢 binlog 日志。
将innodb_flush_log_at_trx_commit 设置为 2。这样做的风险是,主机掉电的时候会丢数据。