加入收藏 | 设为首页 | 会员中心 | 我要投稿 南平站长网 (https://www.0599zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL如何保证数据不丢失

发布时间:2022-11-06 14:02:00 所属栏目:MySql教程 来源:未知
导读: 如何保证数据不丢失?
保证redo log和binlog可以持久化到磁盘,就可以确保MySQL在异常重启后进行数据恢复。
binlog的写入机制
binlog的写入机制逻辑:
操作系统会给每个线程分配binlog cac

如何保证数据不丢失?

保证redo log和binlog可以持久化到磁盘,就可以确保MySQL在异常重启后进行数据恢复。

binlog的写入机制

binlog的写入机制逻辑:

操作系统会给每个线程分配binlog cache,binlog cache的大小由binlog_cache_size参数控制,该参数控制的是单个线程内binlog cache的大小,如果超过了该参数的大小,就需要保存到磁盘。

show global variables like 'binlog_cache_size';

binlog cache如何写入binlog文件?

mysql持久化_mysql front连接mysql_姜承尧mysql技术内幕:sql编程^^^mysql内核:i

binlog cache何时write和fsync?

write和fsync是由参数sync_binlog进行控制:

show global variables like 'sync_binlog';

redo log写入机制

binlog cache是每一个线程一个,但是redo log buffer是所有线程共用一个。

redo log会在哪些地方存在?

mysql持久化_姜承尧mysql技术内幕:sql编程^^^mysql内核:i_mysql front连接mysql

redo log会在以下三个地方存在:

redo log的写入策略如何控制?

redo log写入策略由innodb_flush_log_at_trx_commit参数控制:

show global variables like '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)?

mysql front连接mysql_姜承尧mysql技术内幕:sql编程^^^mysql内核:i_mysql持久化

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也会进行组提交。

mysql持久化_姜承尧mysql技术内幕:sql编程^^^mysql内核:i_mysql front连接mysql

上图最后三个步骤是redo log和binlog的两阶段提交(该步骤的触发是事务提交的一个阶段,也就是说我们的客户端执行了MySQL的commit命令),在写binlog的时候实际需要两步操作:

先把binlog从binlog cache中写到磁盘上的binlog文件调用fsync持久化

mysql front连接mysql_姜承尧mysql技术内幕:sql编程^^^mysql内核:i_mysql持久化

上图是两阶段提交的细化,可以看出在执行第4步binlog fsync时,如果有多个事务的binlog已经写完,那么是可以一起持久化的,可以降低IOPS的消耗。

由于步骤3的执行较快,binlog write和fsync间隔时间段,所以binlog的组提交效果较差。

binlog组提交效果提升

如果需要提升binlog组提交的效果,可以通过设置binlog_group_commit_sync_delay和binlog_group_commit_sync_no_delay_count参数来实现:

show global variables like 'binlog_group_commit_sync_delay';
show global variables like '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即可。

(编辑:南平站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!