比较简洁大方的网站,关键字排名查询工具,专业柳州网站建设推荐,西双版纳建设厅网站文章目录 三大日志#xff1a;binlog#xff08;归档日志#xff09;、redo log#xff08;重做日志#xff09;、undo log#xff08;回滚日志#xff09;redo log刷盘机制日志文件组 binlog记录格式写入机制 两阶段提交undo log提供回滚操作提供MVCC#xff08;多版本… 文章目录 三大日志binlog归档日志、redo log重做日志、undo log回滚日志redo log刷盘机制日志文件组 binlog记录格式写入机制 两阶段提交undo log提供回滚操作提供MVCC多版本并发控制 三大日志binlog归档日志、redo log重做日志、undo log回滚日志
redo log
redo log是一个重做日志是InnoDB引擎独有的是用于MySQL在挂了之后或者宕机之后恢复数据使用的保证了数据的持久性和一致性。在MySQL中数据都是以页为单位的默认一页16kb这个参数在配置MySQL的时候可以设置加载出来的数据页会放入Buffer Pool中当查询数据的时候会先去Buffer Pool缓冲池中查找数据如果没有Buffer Pool会从硬盘中加载进来之后进行修改数据时也是修改的Buffer Pool中的数据然后将修改的记录记录在redo log buffer重做日志缓存中定期将redo log buffer中的数据同步到redo log中刷盘机制。
刷盘机制
一般在这几种情况下会进行刷盘通过innodb_flush_log_at_trx_commit参数进行控制
当事务提交的时候的时候会将redo log buffer中的数据刷新到redo.file文件中。redo log buffer的空间占总容量的一半以上就需要把这些日志刷新到磁盘中。InnoDB使用了一个事务日志缓冲区transaction log buffer来暂时存储事务重做日志当这个缓冲区满的时候会触发刷盘机制。InnoDB会定期执行检查点操作Chechpoint进行刷盘操作同时将相关重做日志一同刷新。InnoDB 启动了一个后台线程负责周期性每隔 1 秒的刷盘同时将相关重做日志一同刷新。正常关闭服务器MySQL 关闭的时候会进行刷盘。 通过设置参数innodb_flush_log_at_trx_commit 可以有不同的刷盘时机设置为0每次提交事务不进行刷盘操作这种性能高但是安全性低因为这种只能等redo log buffer缓存占一半或InnoDB定期刷盘如果宕机可能会丢失1S内的事务。设置为1每次提交事务都会进行刷盘操作这种性能低但是安全性高因为只要提交事务就会进行刷盘不会有数据丢失。 如果事务执行期间MySQL挂了或宕机这部分日志丢了但是事务并没有提交所以日志丢了也不会有损失。设置为2每次提交事务都只会把redo log buffer 中的内容写到page cache(文件系统缓存)page cache 是专门用来缓存文件的这里被缓存的文件就是 redo log 文件。这种方式的性能和安全性都介于前两者中间。刷盘机制innodb_flush_log_at_trx_commit 的默认值为 1设置为 1 的时候才不会丢失任何数据。为了保证事务的持久性我们必须将其设置为 1。
日志文件组
硬盘上存储的redo log日志文件不止一个而是通过一个日志文件组的形式出现的每一个日志文件的大小相同通过环形拼接而成。
在日志文件组中还有两个重要属性write pos、checkpoint相当于头尾指针write pos 是当前记录的位置一边写一边后移checkpoint 是当前要擦除的位置也是往后推移每次刷盘记录redo logwrite pos位置就会后移每次MySQL加载日志文件组恢复数据时会清空加载过得redo log数据checkpoint就会后移。如果write pos后移追上checkpoint表示日志文件组满了需要清空一些记录然后将checkpoint后移。MySQL 8.0.30 及之后的版本中文件数固定为了32可以指定innodb_redo_log_capacity的值来设置每个文件的大小即innodb_redo_log_capacity/32。 只要每次把修改后的数据页直接刷盘不就好了还有 redo log 什么事 数据页刷盘是随机写因为一个数据页对应的位置可能在硬盘文件的随机位置所以性能是很差。如果是写 redo log一行记录可能就占几十 Byte只包含表空间号、数据页号、磁盘文件偏移 量、更新值再加上是顺序写所以刷盘速度很快。所以用 redo log 形式记录修改内容性能会远远超过刷数据页的方式这也让数据库的并发能力更强。
binlog
redo log是物理日志记录的是在什么数据上做了什么修改属于InnoDB引擎。binlog属于逻辑日志主要记录的是原始的逻辑语句不管什么存储引擎只要发生了表数据更新操作都会产生binlog日志binlog主要用于数据库的备份主从数据同步之类的用来保证数据的一致性。
记录格式
binlog日志有三种格式可以通过binlog_format参数指定。statement row mixed。
如果指定statementbinlog中记录的就是sql语句原文在同步数据的时候会执行sql语句。但是当遇到像记录当前时间的sql如果是直接执行sql语句的话就会和原数据不一致。指定为row就不仅仅是记录执行的sql语句在记录的时候还会包括具体的数据这样就保证了记录数据的一致性通常情况下都是指定为row但是这种格式需要更大的容量来记录比较占用空间恢复与同步数据时会更消耗IO资源影响执行速度。指定为mixed是前两种的折中方案当设置为mixed的时候binlog中的记录是前两种的混合记录在记录之前MySQL会先判断这条sql语句是否会引起数据不一致然后根据判断结果记录相应的格式。
写入机制
binlog写入的过程是在事务执行过程中先把日志写到binlog cache中事务提交的时候再将binlog cache写入到binlog文件中。可以通过binlog_cache_size参数配置binlog cache的大小如果存储的内容超过这个容量就需要将内容暂时存储在磁盘中。
将数据写入到page cache中是比较快的只有数据从page cache写入到binlog中才是真正的持久化磁盘的操作。至于这两者的时机由参数sync_binlog控制默认是1。
当这个参数为0的时候每次提交事务都只会将binlog cache中的记录写入page cache具体什么时候从page cache写入binglog由系统自行判断。虽然性能得到提升但是机器宕机page cache里面的 binlog 会丢失。当参数设置为1的时候每次提交事务都会将binlog cache中的记录写入page cache并且刷盘到磁盘binlog中。还有一种方式就是可以设置参数为n表示每提交n个事务之后进行一次刷盘操作。但是如果机器宕机就会丢失最近n个事务的binlog日志。
两阶段提交 redo log重做日志让InnoDB引擎拥有崩溃恢复的能力binlog归档日志保证了MySQL集群架构的数据一致性。虽然都是属于持久化的保证但是两者的侧重点不同。 在执行更新语句过程中会记录redo log和binlog两个日志以基本的事务为单位redo log在事务执行过程中可以不断写入而binlog只有在事务提交时候才写入所以redo log和binlog写入时机不一样。 因为两者的写入时机不一致所以会出现一些问题。比如当执行某update语句将一个n从0修改为了1在事务提交前redo log日志记录了这次操作而在事务提交后写入binlog时发生了异常。之后恢复数据的时候主库使用redo log恢复数据n1而从库使用binlog恢复数据n0出现了数据不一致。
为了解决两份日志之间的逻辑一致问题InnoDB存储引擎使用两阶段提交方案。 原理很简单将redo log的写入拆成了两个步骤prepare和commit这就是两阶段提交。
在事务执行过程中redo log写入会先处于prepare状态当事务提交记录binlog日志时就会将redo log改为commit状态。在宕机恢复数据时会查看redo log日志的状态如果发现redo log日志处于prepare状态并且没有对应的binlog日志就会回滚该事务。如果redo log在设置commit阶段发生异常在恢复数据时虽然redo log是出于prepare状态但是能通过事务id找到对应的binlog日志所以就认为事务是完整的不会发生回滚直接提交事务恢复数据。
undo log
我们知道如果想要保证事务的原子性就需要在异常发生时对已经执行的操作进行回滚在 MySQL 中恢复机制是通过 回滚日志undo log 实现的所有事务进行的修改都会先记录到这个回滚日志中然后再执行相关的操作。如果执行过程中遇到异常的话我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可并且回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况当用户再次启动数据库的时候数据库还能够通过查询回滚日志来回滚将之前未完成的事务。
提供回滚操作
在数据修改的时候不仅记录了redo log还记录了相对应的undo log如果因为某些原因导致事务执行失败了可以借助undo log进行回滚。
undo log 和 redo log 记录物理日志不一样它是逻辑日志。可以认为当delete一条记录时, undo log中会记录一条对应的insert记录反之亦然当update一条记录时它记录一条对应相反的update记录。
提供MVCC多版本并发控制
MVCC即多版本控制。在MySQL数据库InnoDB存储引擎中用undo Log来实现多版本并发控制(MVCC)。当读取的某一行被其他事务锁定时它可以从undo log中分析出该行记录以前的数据版本是怎样的从而让用户能够读取到当前事务操作之前的数据【快照读】。
快照读 SQL读取的数据是快照版本【可见版本】也就是历史版本不用加锁普通的SELECT就是快照读。
当前读 SQL读取的数据是最新版本(最新版本指的是修改且已经提交的数据)。除了在执行修改语句的时候需要执行当前读然后再更新数据之外select语句也有可能是当前读,比如: select … lock in share mode、select … for update。
在更新数据之前MySQL会提前生成undo log日志当事务提交的时候并不会立即删除undo log因为后面可能需要进行回滚操作要执行回滚rollback操作时从缓存中读取数据。undo log日志的删除是通过通过后台purge线程进行回收处理的。
事务A执行update更新操作在事务没有提交之前会将旧版本数据备份到对应的undo buffer中然后再由undo buffer持久化到磁盘中的undo log文件中之后才会对user进行更新操作然后持久化到磁盘。