mysql写⽇志的流程_MySQL中⽇志机制
1、WAL机制
在MySQL中,为了提⾼数据库的性能,MySQL采⽤了WAL(Write-Ahead Logging)机制,即客户端在修改数据的过程后,并不会⽴马对硬盘中的数据进⾏更新。
这样做的原因在于,如果每次客户端进⾏数据更改后,⽴马对磁盘中的数据进⾏更改的话,那么磁盘的压⼒是⾮常⼤的。
想想看,MySQL改数据之前要先定位数据,那么定位数据的过程可能会是磁盘的随机读,随机读的过程是⾮常慢的。
数据库在并发的情况下,⼤量的随机读盘会造成数据库在某⼀时刻的性能将变得很低很低。所以,MySQL要引⼊WAL机制来减少这种情况的发⽣。
WAL机制,主要的操作是先写⽇志,先在⼀个⽇志中记录了MySQL要对硬盘中的存储MySQL数据的数据页中的数据进⾏什么样的更改,等到Mysql空闲的时候再进⾏同步操作到硬盘中。
举个例⼦,就是我们作为开发⼈员,同⼀时间不可能处理10个需求,⽽是需要通过协同⼯具,处理完⼀个再到另外⼀个,这样我们的就不会感到那么累。
当然,在数据库并没有累这⼀说,WAL机制意义就在于“削峰”,这也是我们在处理⾼并发场景下的⼀个解决思路。
可能有⼈会很疑惑,同样是操作磁盘,为什么写⽇志⽐直接改数据会更加⾼效?
答案在于写⽇志是顺序写,直接改磁盘是随机写。所以同样是写,它们写的速度有着天壤之别。这也是WAL的另外⼀个好处。
接下来我们就具体介绍⼀下WAL中涉及到的2个主要的⽇志redolog、binlog。从⽽了解修改语句在MySQL的处理过程中的处理⽅式和⼀些技巧。
2、redolog
redo log我们也称为重做⽇志,我们上⾯所说到数据库先写⽇志再写磁盘的这个特点中的“⽇志”,说的就是redolog。
redo log写⽇志是循环写的,它有2个对象,writepos 和 checkpos。writepos 和 checkpos
数据每次写⼊redo log,writepos就会往前移动,当writepos到达checkpos的时候,checkpos就会往后移动。
除非的英文
在这个移动的过程中(⽐如图中pos 到 pos2的距离,图中所表达的意思是check pos移动到check pos2的距离,不是说redo log有多个checkpos)所涉及的对MySQL硬盘数据页的更改全部实施到响应的页中,这样writepos才有新的空间继续写。
这个时候的数据库的表现就是处理突然变低,如果你发现你的数据库运⾏在某⼀时刻突然性能变低了,可以考虑⼀下是否是这种情况。
redo log的⼤⼩由2个参数控制:
innodb_log_files_in_group #redolog⽂件的个数
innodb_log_file_size #每个redolog⽂件的⼤⼩
redolog总⼤⼩=innodb_log_files_in_group*innodb_log_file_size
⼀般我们设置innodb_log_files_in_group的个数为4个,每个的⼤⼩为1个G。
在MySQL中,除了redo log还有⼀个也很重要的⽇志——bin log,它与redo log相互配合,⼀块来保证数据的⼀致性
3、binlog
binlog也成为⼆进制⽇志,它记录了Mysql中数据的更改,它⼀共有3种格式,分别为:
statement #binlog中记录SQL⽇志。
rows #rows格式记录每⼀个⾏的每⼀个字段的具体改动
mixed #默认记录sql, 由MySQL判断,可能会造成数据不⼀致的情况便会使⽤rows格式进⾏记录。
在性能上statement>mixed>rows, 在数据⼀致性上rows>mixed>statement,很显然数据的⼀致性是数据库中的重中之重,所以⼤家很愿意牺牲⼀点性能来换取数据的可靠性。
到这⾥我们已经对bin log,redo log有了⼀个鸡蛋的了解,接下来我们再来看看,在MySQL中redo log和bin log是如何相互配合⼀起⼯作的。
4、数据是如何保证不会丢失的
MySQL中不管是redo log还是bin log,语句从执⾏到写到磁盘的过程中,都是先要写到cache(redolog称之为buffer)中然后再写到磁盘,换⾔之就是先写内存再写磁盘。
⽽写到磁盘也分2种状态,1是数据在硬盘的paga cache中,这个过程称之为write,2是数据真正持久化到磁盘这个过程称之为fsync。
数据写cache很快,写到硬盘的page cahe也快,真正慢且消耗IO的地⽅再持久化的过程,也就是fsync。
内存空间划分上,redolog buffer是所有事务共⽤的,binlog cache是每个线程分配⼀个。可以通过binlog_cache_size来控制它的⼤⼩,如果事务的binlog⽇志⼤⼩超出了binlog_cache_size的定义的⼤⼩,多出来的部分会存到硬盘中。
事务执⾏的过程中,更改(update、delete、inrt)语句只要执⾏就会⽣成redolog buffer。
事务在执⾏的过程中,只有事务commit了binlog_cache中的数据才会被写到硬盘上,这是为了保证事务的完整性。
硬盘空间划分上,redolog只有⼀个且所有事务共⽤,binlog也是⼀个且所有事务共⽤。(注意:这⾥的⼀个是指⼀个对象,实现上mysql可能会分成多个⽂件去存储)
我们先通过2张图来了解2个⽇志的从写内存到写硬盘的过程。
redolog写⼊过程:redolog写⼊过程
事务任何改变数据的操作都会被记录到redolog buffer中,不管事务有没有提交都会写redolog,然后redolog buffer中的数据会写到硬盘,也就是追加写到硬盘的redo log⽂件。
这⾥有3种情况redolog buffer会写到硬盘:redolog buffer是否超过innodb_log_buffer_size(redolog buffer的总⼤⼩)的⼀半。
事务是否提交
⼀秒⼀次⾃动写
数据从内存写到硬盘的过程中是否能到write或fsync由参数innodb_flush_log_at_trx_commit控制,它有三种可能取值:
0 :表⽰每次事务提交时都只是把 redo log 留在 redo log buffer 中 。
1 :表⽰每次事务提交时都将 redo log 直接持久化到磁盘。
2 :表⽰每次事务提交时都只是把 redo log 写到 page cache。
⼀般这个参数设置为1
这⾥有个特点就是由于事务提交就会写硬盘,那么写硬盘的时候有可能会使还未提交的事务也可能会被写进去redolog⽂件中去。写饺子的作文
下⾯是binlog 写⼊过程:
后进生转化
事务执⾏,产⽣binlog cache,直到事务提交,binlog cache中的⽇志数据会全部写进硬盘binlog中,这个时候数据处于硬盘的page cache中。
充电器接触不良是否fsync由参数 sync_binlog 控制,它的值也有3中可能的状态:
0:表⽰每次提交事务都只 write,不 fsync。
1:表⽰每次提交事务都会执⾏ fsync。
N:表⽰每次提交事务都 write,但累积 N 个事务后才 fsync。
sync_binlog 这个参数⼀般设置为1,与上⾯ innodb_flush_log_at_trx_commit 设置为1⼀起被DBA称为"双1模式"
在了解了它们的落盘过程后我们在来看看它们在事务提交后是如何配合来保护数据不会丢失的。
在事务提交后MySQL是先写redolog,再写binlog。
这个过程再细分后的步骤为,先写redolog这个时候redolog先处于⼀个prepare状态,然后mysql写binl关于学习的文章
og,最后再让redlog处于commit 状态。这个事务就算真正写到磁盘上了。
芝麻酱凉面为什么需要这样做?原因是2个⽇志需要保持⼀致,并且奔溃恢复的逻辑也需要这⼀过程。如MySQL异常重启后,怎么样判断事务有没有⽣效?
MySQL的处理⽅式是如果redo log处于prepare状态,bin log处于commit状态,且2个⽇志中的数据完整,这个情况下的事务是有效的,否则事务就会被回滚。
这个过程称之为两阶段提交。
⽤上⾯redolog和binlog的写⼊过程组合起来的话就如下图所⽰:
第⼀次redo log提交,数据处于prepare状态,然后提交bin log,最后redolog再发送commit表⽰,则代表整个事务被持久化到硬盘。
由图可知,⼀次数据写⼊的过程可能会有3次fsync,对应3三次IO操作。
这样看来,⼀次事务可能会照成3次fsync,你可能会觉得这样弄得话MySQL的性能不就会很烂?实际上,MySQL做了优化,⽤了组提交机制来减少IO的消耗。
MySQL的具体做法是:每个事务在写⼊log都会有⼀个⽇志逻辑序列号(log quence number)称之为LSN。
数据在fsync的过程中,LSN会随着其他事务的提交⽽增长,⽇志fsync完成的时候会提交最新的LSN。
其他LSN为⼩于最新提交的LSN的事务就就不需要fsync了,直接返fsync成功,原因就是已经被较前fsync的事务提交了。
变色龙引导
举个例⼦:事务1的LSN为10,它处于write阶段准备调⽤fsync,在fsync的过程中事务2事务3也提交了等待去fsync,导致事务1携带的LSN增长为了100,那么他fsync的时候顺便会把事务2事务3的数据fsync。这个过程如下图所⽰:
这⾥MySQL充分利⽤了IO的等待时间来减少了IO的消耗。
并且,mysql还做了优化,让binlog的fsync在redolog的fsync之后,这样redo log和binlog fsync都有⼀定的时间让LSN增长,所以都能使⽤组提交的优化。
如果你想⼈为控制这个过程可以使⽤binlog_group_commit_sync_delay与binlog_group_commit_sync_no_delay_count参数来控制
最后我们再将上⾯步骤串联起来,从⽽整理成了下图的流程:
5、总结
到这⾥,redolog与binlog的介绍就结束了,读完这篇⽂章,相信你应该知道。什么是redolog
什么是binlog
开学心得体会redolog和binlog是怎么⾼效配合的。
如果有什么不解之处,或者错误的地⽅,欢迎评论