当前位置: 首页 > 后端技术 > Java

面试官:MySQL的三大日志是什么?面试必问!

时间:2023-04-02 01:41:10 Java

转载自:陈天明\链接:https://juejin.im/post/686025...日志是mysql数据库的重要组成部分,记录了数据库运行过程中的各种状态信息。MySQL日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志。作为开发,我们需要重点关注二进制日志(binlog)和事务日志(包括redolog和undolog)。本文将详细介绍这三类日志。binlogbinlog用于记录数据库执行的写操作(不包括查询)信息,并以二进制形式保存在磁盘上。binlog是mysql的逻辑日志,由server层记录,使用任何存储引擎的mysql数据库都会记录binlog日志。逻辑日志:可以简单理解为记录sql语句。物理日志:MySQL数据最终存储在数据页中,物理日志记录了数据页的变化。binlog是通过append的方式写的。您可以通过max_binlog_size参数设置每个binlog文件的大小。当文件大小达到给定值时,将生成一个新文件来保存日志。Binlog使用场景在实际应用中,binlog主要有两种使用场景,分别是主从复制和数据恢复。Master-slavereplication:在Master端开启binlog,然后将binlog发送给各个Slave端,Slave端重放binlog,实现主从数据一致性。数据恢复:使用mysqlbinlog工具恢复数据。binlog刷盘时机对于InnoDB存储引擎来说,biglog只有在事务提交的时候才会被记录下来。此时记录还在内存中,那么biglog什么时候刷到磁盘呢?mysql通过sync_binlog参数控制biglogflush的时机,取值范围0-N:0:无强制要求,系统判断何时写入磁盘;1:每次commit时将binlog写入磁盘;N:每N个事务将binlog写入磁盘。从上面可以看出,sync_binlog最安全的设置是1,这也是MySQL5.7.7之后版本的默认值。但是设置较大的值可以提高数据库性能,所以在实际中也可以适当调整该值,牺牲一定的一致性来获得更好的性能。binlog日志格式binlog日志有三种格式,分别是STATMENT、ROW和MIXED。MySQL5.7.7之前,默认格式为STATEMENT,MySQL5.7.7之后,默认为ROW。日志格式由binlog-format指定。STATMENT:基于SQL语句的复制(statement-basedreplication,SBR),每条修改数据的SQL语句都会记录在binlog中。优点:不需要记录每一行的变化,减少了binlog日志量,节省了IO,从而提高了性能;缺点:在某些情况下,会造成主从数据不一致,比如执行sysdate()、sleepp()等。ROW:基于行的复制(RBR),不记录每条SQL语句的上下文信息,只需要记录修改了哪些数据即可。优点:不会出现某些情况下存储过程、函数或者触发器调用和触发器无法正确复制的问题;缺点:会产生大量日志,尤其是altertable时会导致日志暴涨MIXED:基于STATEMENT和ROW两种模式的Mixed-basedreplication(MBR),一般replication使用STATEMENT模式保存binlog,以及对于STATEMENT方式无法复制的操作,使用ROW方式保存binlog。为什么redolog需要redolog?我们都知道事务数据库的四大特性之一就是持久化。具体来说,只要事务提交成功,对数据库所做的修改就会被永久保存,并且不可能以任何理由恢复到原来的状态。那么mysql是如何保证一致性的呢?最简单的方法是每次提交事务时,将事务涉及的所有数据页刷新到磁盘。但是这样做会造成严重的性能问题,主要体现在两个方面:因为Innodb以页为单位与磁盘进行交互,而一个事务可能只修改一个数据页中的几个字节,这时候就完全可以了将数据页刷新到磁盘会浪费资源!一个事务可能涉及修改多个数据页,而这些数据页在物理上并不连续,使用随机IO写入性能太差!因此mysql设计了redolog。具体来说,它只记录事务对数据页所做的更改,这样就可以完美解决性能问题(相对来说文件更小,而且是顺序IO)。重做日志的基本概念重做日志由两部分组成:一是内存中的日志缓冲区(redologbuffer),二是磁盘上的日志文件(redologfile)。mysql每执行一条DML语句,先将记录写入redologbuffer,然后在某个时间点将多条操作记录写入redolog文件。这种先写入日志再写入磁盘的技术就是MySQL中经常提到的WAL(Write-AheadLogging)技术。在计算机操作系统中,用户空间(userspace)中的缓冲区数据一般不能直接写入磁盘,必须经过操作系统内核空间(kernelspace)缓冲区(OSBuffer)。因此,将redologbuffer写入redologfile实际上是先写入OSBuffer,然后通过系统调用fsync()刷新到redolog文件。过程如下:mysql支持三种方式将redologbuffer写入redolog文件的时机可以通过innodb_flush_log_at_trx_commit参数进行配置。各个参数值??的含义如下:前面已经提到了redolog的记录格式,redolog实际记录的是数据页的变化,不需要保存所有这样的变化记录,所以实现了redolog采用固定大小、循环书写的方法。写到最后,会回到开头,循环写入日志。如下图所示:同时,我们可以很容易的知道,在InnoDB中,既需要刷新redolog,也需要刷新数据页。redolog存在的意义主要是减少刷新数据页的要求**。上图中writepos表示redolog当前记录的LSN(逻辑序号)位置,checkpoint表示数据页变化记录flush后对应redolog的LSN(逻辑序号)位置.writepos和checkpoint之间的部分是redolog的空部分,用来记录新的记录;checkpoint和writepos之间的部分是要放入redolog的数据页的变更记录。当writepos追上checkpoint时,会先把checkpoint往前推,为新的log腾出空间。在启动innodb时,不管上次是正常关机还是异常关机,总会进行一次recovery操作。因为重做日志记录的是数据页的物理变化,所以恢复速度比逻辑日志(如binlog)要快很多。当innodb重启时,首先会检查磁盘中数据页的LSN。如果数据页的LSN小于日志中的LSN,就会从checkpoint中回收。另一种情况,在crash之前,checkpoint在刷盘过程中,datapage的刷盘进度超过了logpage的刷盘进度。此时数据页中记录的LSN大于日志中的LSN。超过日志进度的部分是不会重做的,因为这本身就意味着有些事情已经做了,没必要重做。redolog和binlog的区别从binlog和redolog的区别可以看出:binlog日志只是用来归档的,单独的binlog不具备crash-safe能力。但是只有redolog是不行的,因为redolog是InnoDB特有的,log上的记录放到磁盘后会被覆盖。所以需要同时记录binlog和redolog,保证数据库宕机重启时不会丢失数据。undolog数据库事务的四大特点之一是原子性。具体来说,原子性是指对数据库的一系列操作,要么全部成功,要么全部失败,不可能部分成功。其实底层的原子性是通过undolog来实现的。undolog主要记录数据的逻辑变化。例如,一条INSERT语句对应一个DELETEundolog,而对于每条UPDATE语句,对应一个相反的UPDATEundolog,这样当出现错误时,可以回滚到事务数据之前的状态。同时undolog也是实现MVCC(多版本并发控制)的关键。近期热点文章推荐:1.1,000+Java面试题及答案(2021最新版)2.别在满屏的if/else中,试试策略模式,真的很好吃!!3.操!Java中xx≠null的新语法是什么?4、SpringBoot2.5发布,深色模式太炸了!5.《Java开发手册(嵩山版)》最新发布,赶快下载吧!感觉不错,别忘了点赞+转发!