MySQL如何保证数据不丢失
保证redo log和binlog可以持久化到磁盘,就可以确保MySQL在异常重启后进行数据恢复。
binlog的写入机制
binlog的写入机制逻辑:
操作系统会给每个线程分配binlog cac
如何保证数据不丢失? 保证redo log和binlog可以持久化到磁盘,就可以确保MySQL在异常重启后进行数据恢复。 binlog的写入机制 binlog的写入机制逻辑: 操作系统会给每个线程分配binlog cache,binlog cache的大小由binlog_cache_size参数控制,该参数控制的是单个线程内binlog cache的大小,如果超过了该参数的大小,就需要保存到磁盘。
binlog cache如何写入binlog文件? binlog cache何时write和fsync? write和fsync是由参数sync_binlog进行控制:
redo log写入机制 binlog cache是每一个线程一个,但是redo log buffer是所有线程共用一个。 redo log会在哪些地方存在? redo log会在以下三个地方存在: redo log的写入策略如何控制? redo log写入策略由innodb_flush_log_at_trx_commit参数控制:
InnoDB有一个后台线程,每隔1s,会把redo log buffer中的日志调用write写到page cache,然后调用fsync持久化到磁盘。 事务执行过程中redo log也是直接写入到redo log buffer中能够,这写redo log会因为后台线程会被一起持久化到磁盘(没有提交的事务也会被持久化到磁盘)。 除了后台线程每秒1次的轮询之外,还会有以下两种情况下会将redo log写入磁盘: MySQL 双1配置是? MySQL 双1配置指的就是sync_binlog和innodb_flush_log_at_trx_commit都设置成1,也就是说一个事务完整提交前,需要等待两次刷盘,一次是redo log(prepare阶段),一次是binlog。 什么是日志逻辑序列号(LSN)? LSN是用来对应redo log的一个个写入点,是单调递增的,每次写入长度为length的redo log,LSN的值就会加上length。 LSN也会写到InnoDB的数据页中,来确保数据页不会被多次执行重复的redo log。 什么是组提交(Group Commit)? trx1是第一个到达的,会被选为leader等trx1要开始写盘的时候,该组里有三个事务,此时LSN会变成160trx写盘的时候,带的LSN=160,因此当trx1返回时mysql持久化,所有LSN小于等160的redo log都已经被持久化到磁盘trx2和trx3此时就可以直接返回 一次组提交中,组员越多,越能节约磁盘IOPS。在多事务并发更新场景下,第一个事务写完redo log buffer以后,fsync越晚调用,组员就可能越多,节约IOPS效果越好。 binlog的组提交 上面的组提交是redo log组提交,MySQL为了充分提高性能,binlog也会进行组提交。 上图最后三个步骤是redo log和binlog的两阶段提交(该步骤的触发是事务提交的一个阶段,也就是说我们的客户端执行了MySQL的commit命令),在写binlog的时候实际需要两步操作: 先把binlog从binlog cache中写到磁盘上的binlog文件调用fsync持久化 上图是两阶段提交的细化,可以看出在执行第4步binlog fsync时,如果有多个事务的binlog已经写完,那么是可以一起持久化的,可以降低IOPS的消耗。 由于步骤3的执行较快,binlog write和fsync间隔时间段,所以binlog的组提交效果较差。 binlog组提交效果提升 如果需要提升binlog组提交的效果,可以通过设置binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count参数来实现:
上述两个条件是或关系,只要满足一个就会触发fsync。 redo log的commit阶段 根据两阶段提交的细化流程图,我们可以发现redo log的commit只写了page cache,并没有进行fsync,这是因为借助每秒1次的后台轮询刷盘,再加上崩溃恢复逻辑,InnoDB认为在redo log commit的时候就不需要fsync,只需要写到page cache即可。 (编辑:武汉站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |