PMS启动过程

MYSQL的MVCC

  返回  

MYSQL的日志

2021/7/21 0:22:02 浏览:

在数据库的世界里,数据从来都不重要,日志才是最重要的,有了日志就有了一切。日志是MySQL数据库的重要组成部分,Mysql日志的分类有:

  • 错误日志:错误日志是开启的,且无法被禁止
  • 查询日志:general log,查询日志里面记录了数据库执行的所有命令,不管语句是否正确,都会被记录。日志量大,不建议开启。
  • 慢查询日志:可以让MySQL记录下查询超过指定时间(默认10s)的语句,优化数据库和sql性能。
  • 事务日志:Redo log & Undo log
  • 二进制日志:Bin log
  • 中继日志:Relay log,复制过程中产生的日志,是从库服务器I/O线程将主库服务器的二进制日志读取过来记录到从库服务器本地文件,然后从库的SQL线程会读取relay-log日志的内容并应用到从库服务器上。

本文主要分析学习redo log,undo log和bin log。

一.WAL机制

Write-Ahead Logging,先写日志,再写磁盘,即客户端在修改数据的过程后,并不会立马对硬盘中的数据进行更,InnoDB引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做。这样做的原因在于,如果每次客户端进行数据更改后,立马对磁盘中的数据进行更改的话,那么磁盘的压力是非常大的。
Mysql使用日志来减少提交事务时的开销。因为日志中已经记录了事务,就无须在每个事务提交时把缓冲池的脏块刷新(flush)到磁盘中。事务修改的数据和索引通常会映射到表空间的随机位置,所以刷新这些变更到磁盘需要很多随机IO。InnoDB假设使用常规磁盘,随机IO比顺序IO昂贵得多,InnoDB用日志把随机IO变成顺序IO。一旦日志安全写到磁盘,事务就持久化了,即使断电了,InnoDB可以重放日志并且恢复已经提交的事务。这样的机制大大提高了数据库的读写性能。

二.redolog

1.基本概念

重做日志,是innodb存储引擎层的日志,记载的是物理修改的内容(xxxx页修改了xxx)。 当我们提交一个事务时,InnoDB会先去把要修改的数据写入日志,然后再去修改缓冲池里面的真正数据页。包括两部分:

  • 一是内存中的日志缓冲(redo log buffer),该部分日志是易失性的;
  • 二是磁盘上的重做日志文件(redo log file),该部分日志是持久的,并且是事务的记录是顺序追加的。

作用:确保事务的持久性。如果写入内存成功,但数据还没真正刷到磁盘,如果此时的数据库挂了,我们可以靠redo log来恢复内存的数据,这个能力称为 crash-safe

2.写入机制

1)redo log buffer --> redo log file

在一个事务中的每一次SQL操作之后都会写入一个redo log buffer中,然后在某一个合适的时间点,将buffer中的数据刷入到redo log file中,这个合适的时间点究竟是什么时候呢?

  • MySQL 正常关闭的时候;
  • MySQL 的后台线程每隔一段时间定时的讲 redo log buffer 刷入到磁盘,默认是每隔 1s 刷一次;
  • 当 redo log buffer 中的日志写入量超过 redo log buffer 内存的一半时,即超过 8MB 时,会触发 redo log buffer 的刷盘;
  • 当事务提交时,根据配置的参数 innodb_flush_log_at_trx_commit 来决定是否刷盘。如果 innodb_flush_log_at_trx_commit 参数配置为 0,表示事务提交时,不进行 redo log buffer 的刷盘操作;如果配置为 1,表示事务提交时,会将此时事务所对应的 redo log 所在的 redo log block 从内存写入到磁盘,同时调用 fysnc,确保数据落入到磁盘;如果配置为 2,表示只是将日志写入到操作系统的缓存,而不进行 fysnc 操作。(进程在向磁盘写入数据时,是先将数据写入到操作系统的缓存中:os cache,再调用 fsync 方法,才会将数据从 os cache 中刷新到磁盘上)

2)redo log file --> MySQL磁盘

接下来,InnoDB引擎会在适当的时候,将redo log file中的操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做。InnoDB 的 redo log file是固定大小的,一组redo log文件是一个类似环形的状态,循环利用,如下图所示。
在这里插入图片描述

三.binlog

1.基本概念

归档日志,server层日志,用于记录数据库执行的写入性操作( update/delete/insert/truncate/create,不包括查询)信息,以二进制的形式保存在磁盘中。binlog是mysql的逻辑日志,并且由Server层进行记录,使用任何存储引擎的mysql数据库都会记录binlog日志,存储着每条变更的SQL语句,比如:给 ID=1 这一行的 c 字段加 1。
主要作用:复制和恢复数据 。

2.写入机制

binlog 的写入逻辑比较简单,事务执行过程中,先把日志写到 binlog cache,事务提交的时候,再把 binlog cache 写到 binlog 文件中。

四.binglog和redolog的区别

  • 第一:redo log是在InnoDB存储引擎层产生,而binlog是MySQL server层的日志
  • 第二:两种日志记录的内容形式不同。MySQL的binlog是逻辑日志,其记录是对应的SQL语句。而redolog是物理日志,即在xxxx页修改了xxx。
  • 第三:两种日志与记录写入日志磁盘的时间点不同,bin log只在事务提交完成后进行一次写入,并且对于每一个事务,仅包含对应事务的一个日志。而redo log写入日志磁盘的时机与配置有关,在事务进行中不断地被写入,不是随事务提交的顺序进行写入的。
  • 第四:bin log不是循环使用,在写满或者重启之后,会生成新的bin log文件,redo log是循环使用。
  • 第五:binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。

五.两阶段提交

1.基本概念

阶段1:redo log 写盘,处于 prepare 状态
阶段2:binlog 写盘,redo log 处于 commit 状态
使用两阶段提交,当MySQL断电时,恢复(crash recovery)的过程:
如果 redo log 已经 commit,那毫不犹豫的,把事务提交;
如果 redo log 处于 prepare,则去判断事务对应的 binlog 是不是完整的;
是,则把事务提交;
否,则事务回滚。

2.作用

两阶段提交是为了保证redolog和binlog的数据一致性,只有在这两个日志文件逻辑上高度一致了。你才能放心地使用redolog帮你将数据库中的状态恢复成crash之前的状态,使用binlog实现数据备份、恢复、以及主从复制。作用

  • 事务提交过程中任何阶段,MySQL突然奔溃,重启后都能保证事务的完整性,已提交的数据不会丢失,未提交完整的数据会自动进行回滚。
  • 保证主从数据库的一致性。举例说明:当只有redo log,binlog失效时,会导致主库可以通过redo log来重做,而从库因为没有及时获取到binlog而不能进行回放,导致主从数据不一致。这样会出现 redo log 写入到磁盘了,但是 binlog 还没写入磁盘,于是当发生 crash recovery 时,恢复后,主库会应用redo log,恢复数据,但是由于没有 binlog,从库就不会同步这些数据,主库比从库“新”,造成主从不一致。反过来,binlog写入磁盘,redolog没有写入,造成从库比主库“新”,也会造成主从不一致。

六.undolog

Innodb存储引擎维护,在数据修改的时候,不仅记录了redo log,还记录undo log。undo log主要存储的也是逻辑日志,可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。
作用:事务回滚和多版本控制(MVCC),保证事务的原子性(要么都成功,要么都失败)
undo log的存储方式:回滚段(rollback segment)

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号