mysql如何保证数据不丢失_Mysql是如何保证数据不丢失的

2ff34e647e2e3cdfd8dca593e17d9b0a.png

binlog事务执行过程中binlog写入到binlog cache,事务提交时写入到binlog文件中。

事务的原子性决定这无论事务有多大,binlogcahe都要一次性完整的写入到binlog文件中,写入方式如下:系统为每个binlog_cache开辟了一片内存(每个线程都有一个),参数是blong_cache_size,超过这个阈值的会保存在临时文件中

事务提交时候,出于性能的考虑回将bionlog_cache都write到文件系统的page_cache中,在通过fsync刷新到磁盘文件中。如下图所示是binlog的同步机制。

如图:只有fsnyc刷盘这不操作才会占用IOPS。

write和fsync的时机是用binglog_sync参数来控制的=0 每次事务提交时候都只write不sync

=1 每次事务提交都sync

=N(N>1) 每次事务提交都write,积攒到N时候才会fsync

在IO出现瓶颈时候我们可以设置一个较大的值来提升性能(个人不是很推荐做,如果出现这种情况建议从业务考虑优化数据库)

redolog的写入机制

redolog从写入到最终写入到磁盘中会经历如下的阶段:写入redolog-buffer中–>在事务提交、或者一定时机(见下面)下:redolog-buffer写入到文件系统的pagecache(write)–>文件系统pagecache写入到磁盘中(fsnyc),这样的操作的意义是为了提高mysql的吞吐的,具体的机制见下面:

一个事务会产生很多条redolog如果每次直接持久化磁盘会消耗大量的磁盘IO,所以redolog会先写入redolog-buffer中,之后在write文件系统的到pagecache中,这俩步是内存操作很快。

是否会影响数据的持久化,比如mysql在事务进行中crash了,这时候redolog-buffer中的数据丢失怎么办?答案是由于事物没有提交,所以事物会进行回滚。

redolog-buffer持久化的条件和机制:受参数innodb_flush_log_at_tx_commit的控制:=0:每次提交都只停留在redolog-buffer中;

=1:每次提交都会持久化到磁盘中;

=2:每次提交都只会写入到文件的pagecache中;

innodb后台会有一个线程每秒一次,会把redolog-buffer中的日志,调用write写到pagecahe中,在fsync到磁盘中;

其他场景触发redolog的持久化当redolog-buffer占到了innodb_log_buffer_size的一半时候,会调用write将buffer中的log写入到文件系统的pagecache中

另一种是并行事物提交时候,如果innodb_flush_log_at_tx_commit设置为1时候会,即时当前事物没有commit,也会将redolog写入到文件系统中。

双1设置

即:binlogsnyc=1,innodb_flush_log_at_tx_commit也设置为1。

由于innodb的事物提交redolog和binlog是2PC。

所以当redolog在prepare时候,为了故障恢复一定会持久化一次,所以这时候需要fsync到磁盘中。

binlog在进行fsync到磁盘中

这时候事物在redolog在commit时候,mysql由于有奔溃恢复机制和后台线程每秒轮训一次刷盘会认为redolog没有必要在fsync一次到磁盘了,只会写入到文件的pagecache中。

gourp commit机制

一个事物的提交由于redolog和binglog都要持久化,磁盘IO还是很大Mysql是如何优化这部分呢。这里mysql采用了组提交(group commit)的方式。

如图所示:首先介绍下LSN(log sequence number),一个单调递增的序号,用来对应redolog的一个个写入点。当然也会写入到数据页中,用于flush脏盘时候避免重复执行(不在讨论范围内)

如图,当3个事务同时都写完redolog-buffer 并且处于prepare阶段时候,这时候就构成了一个gourp第一个先到达的trx1,成为组里的leader,LSN=50;

等trx1开始写盘时候,组里已经有其他俩个事物,这时候LSN=160;

trx1开始写盘,所有lsn<160的日志都会被写入到磁盘中;

trx3,trx4就可以直接返回了;

所以在并发事物中,当写完redolog,越晚调用fsync,带的log越多性能也就越好;mysql在这方法采用的是拖时间的策略,即:在双1配置下

redolog-prepare(write)–>binglog(write)–>redolog-prepare(fsync)–>binlog(fsnyc)–>redolog commit(write)

如图:

5ddea4803f925.png如上图所示,由于redolog在write和fsnyc中有一个binlog-write的过程,所以在持久化磁盘时候你可以带上更多的log;

另外:binlog也可以采用组提交,只不过由于这俩个阶段间隔短可能没有redolog那么明显binlog的gruop commit的参数如下:binlog_group_commit_sync_delay:表示延迟多少微妙后就会调用fsnyc

binlog_gourp_commit_sync_no_delay_count:表示累计多少次后才调用fsync

俩个参数是or的关系,不过如果binlog_group_commit_sync_delay设置为0,binlog_gourp_commit_sync_no_delay_count就无效了

综上所述:mysql的WAL机制是由于redolog和binlog都是顺序写,保证了高吞吐;

同时采用了组提交的方式,来减少了IOPS;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值