Mysql备份与恢复——日志

Mysql日志

Buffer Pool

Innodb 存储引擎设计了一个缓冲池(Buffer Pool),来提高数据库的读写性能。

Mysql中比较重要的日志包括:二进制日志 binlog(归档日志)和 redo log(重做日志)和 undo log(回滚日志)

redo log 重做日志

redo log(重做日志)是InnoDB存储引擎独有的,它让MySQL拥有了崩溃恢复能力。

Mysql一开始进行查询数据的时候,会从硬盘把数据加载出来,会放入到缓冲池 Buffer Pool 中。后续的查询都是先从缓冲池 Buffer Pool 中找,没有命中再去硬盘加载,减少硬盘 IO 开销,提升性能。更新表数据的时候,也是如此,发现 Buffer Pool 里存在要更新的数据,就直接在 Buffer Pool 里更新。同时会把“在某个数据页上做了什么修改这样的更新信息,即重做日志”记录到重做日志缓存(redo log buffer)里,接着刷盘到重做日志文件(redo log)里。这样做的目的就是让数据库具有崩溃恢复的能力。因为缓冲池的数据可能丢失,而及时的同步到磁盘又很耗时,因为磁盘是随机写的。而redo log日志是随机写的,速度比较快。

刷盘时机

(刷盘:即重做日志redo log从重做日志缓存刷新到重做日志缓存文件中)

1、事务提交:当事务提交时,重做日志缓存redo log buffer 里的 redo log 会被刷新到磁盘。

2、log buffer 空间不足时:重做日志缓存的重做日志已经占满了重做日志缓存总容量的大约一半左右,就需要把这些日志刷新到磁盘上。

3、事务日志缓冲区满:InnoDB 使用一个事务日志缓冲区(transaction log buffer)来暂时存储事务的重做日志条目。当缓冲区满时,会触发日志的刷新,将日志写入磁盘

4、Checkpoint(检查点):InnoDB 定期会执行检查点操作,将内存中的脏数据(已修改但尚未写入磁盘的数据)刷新到磁盘,并且会将相应的重做日志一同刷新,以确保数据的一致性。

5、后台刷新线程:InnoDB 启动了一个后台线程,负责周期性(每隔 1 秒)地将脏页(已修改但尚未写入磁盘的数据页)刷新到磁盘,并将相关的重做日志一同刷新。

6、正常关闭服务器:MySQL 关闭的时候,重做日志redo log 都会刷入到磁盘里去。

另外,InnoDB 存储引擎有一个后台线程,每隔1 秒,就会把 redo log buffer 中的内容写到文件系统缓存(page cache),然后调用 fsync 刷盘。

也就是说,一个没有提交事务的 redo log 记录,也可能会刷盘。

为什么说一个没有提交事务的 redo log 记录,也可能会刷盘?

1、因为在事务执行过程 redo log 记录是会写入redo log buffer 中,这些 redo log 记录会被后台线程写入到文件系统缓存page cache中,然后刷新到磁盘中。

2、当 redo log buffer 占用的空间即将达到 innodb_log_buffer_size 一半的时候,后台线程会主动刷盘。

只要每次把修改后的数据页直接刷盘不就好了,还有 redo log 什么事?

即:

为什么要使用重做日志文件(redo log)?

这样做的目的就是让数据库具有崩溃恢复的能力。因为缓冲池的数据可能丢失,而及时的同步到磁盘又很耗时,因为磁盘是随机写的。而redo log日志是随机写的,速度比较快。

redo log文件写满了怎么办?

默认情况下,InnoDB 存储引擎有1个重做日志文件组,是由两个 redo log 文件组成的,这两个文件是以循环写的方式进行工作的,当缓存池的数据同步到磁盘后,对应的重做日志文件的数据就会被擦除。

binlog(归档日志)

redo log 它是物理日志,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎。

而 binlog 是逻辑日志,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于MySQL Server 层。

不管用什么存储引擎,只要发生了表数据更新,都会产生 binlog 日志。

binlog****会记录所有涉及更新数据的逻辑操作,并且是顺序写。

记录格式binlog 日志有三种格式,可以通过binlog_format参数指定。

statement:记录的内容是SQL语句原文。

row:记录的内容不再是简单的SQL语句了,还包含操作的具体数据。但是这种格式,需要更大的容量来记录,比较占用空间,恢复与同步时会更消耗IO资源,影响执行速度。

mixed:是一种折中的方案,MySQL会判断这条SQL语句是否可能引起数据不一致,如果是,就用row格式,否则就用statement格式。

写入机制:****binlog的写入时机也非常简单,事务执行过程中,先把日志写到binlog cache,事务提交的时候,再把binlog cache写到binlog文件中。

因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。

上图的 write,是指把日志写入到文件系统的 page cache,并没有把数据持久化到磁盘,所以速度比较快。

上图的 fsync,才是将数据持久化到磁盘的操作。

redo log重做日志和bin log 归档日志的区别?

1、适用对象不同:重做日志 是 InnoDB 引擎特有的; 归档日志是 MySQL 的 Server 层实现的,所有引擎都可以使用,MySQL数据库中的任何存储引擎对于数据库的更改都会产生binlog。

2、文件格式不同:重做日志是物理日志,记录的是 “ 在某个数据页上做了什么修改 ” ;归档日志是逻辑日志,记录的是这个语句的原始逻辑,比如 “ 给 ID=2 这一行的 c 字段加 1 ”。

binlog 记录的都是事务操作内容,binlog 有三种模式:Statement(基于 SQL 语句的复制)、Row(基于行的复制) 以及 Mixed(混合模式)。具体这三种模式的区别请看主从同步和主备同步专栏。

3、 重做日志是循环写的(类似一个循环队列),因为它的空间固定会用完; 归档日志是可以追加写入的。 “ 追加写 ” 是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

4、重做日志在事务执行过程中可以刷盘写入,而归档日志是在 事务最终提交时才能刷盘写入。

5、虽然它们都属于持久化的保证,但是侧重点不同,redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力,binlog(归档日志)保证了MySQL集群架构的数据一致性。****redolog相当于是数据修改后,崩溃了,修改的丢失了,所以进行恢复,而binlog可以恢复到特定的位置的数据。

如何实现使用binlog日志实习主从复制的?

具体详细过程如下:

  • MySQL 主库在收到客户端提交事务的请求之后,会先写入 binlog,再提交事务,更新存储引擎中的数据,事务提交完成后,返回给客户端“操作成功“的响应。
  • 从库会创建一个专门的I/0 线程,连接主库的 log dump 线程,来接收主库的 binlog 日志,再把binlog 信息写入 relay log 的中继日志里,再返回给主库“复制成功”的响应。
  • 从库会创建一个用于回放 binlog 的线程,去读 relay log 中继日志,然后回放 binlog 更新存储引擎中的数据,最终实现主从的数据一致性。

两阶段提交

redo log(重做日志)让InnoDB存储引擎拥有了崩溃恢复能力,即具有持久性。binlog(归档日志)保证了MySQL集群架构的数据一致性。虽然它们都属于持久化的保证,但是侧重点不同。在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的写入时机不一样。

原理:

因为redo log影响主库的数据,binlog影响从库的数据,如果这两个日志在进行刷盘的时候有一个失败了,那么在数据恢复的时候,就会造成主从数据不一致的现象,所以InnoDB存储引擎使用两阶段提交方案。

MySQL 为了避免出现两份日志之间的不一致的问题,使用了「两阶段提交」来解决,即让redo log和binlog提交要么全都成果要么全都失败。

原理很简单,将重做日志的写入拆成了两个步骤prepare和commit阶段,中间穿插写入binlog,首先在prepare阶段把redolog日志写入磁盘,并设置为prepare状态,然后在commit阶段把binlog写入磁盘,然后再把redolog的状态设置为commit。

当发生异常重启的时候,就会进行判断:如果 redo log 只是预提交但不是 commit 状态,这个时候就会去判断 binlog 是否完整,如完整就设置为commit状态,不完整就回滚事务。也就是同时成功或者失败。

undo log 回滚日志

回滚日志,作用包含两个 : 提供回滚保证事务的原子性 和 MVCC(多版本并发控制) 。它主要记录的是逻辑日志,所有事务进行的修改都会先记录到这个回滚日志中,然后再执行相关的操作。如果执行过程中遇到异常的话,我们直接利用 回滚日志 中的信息将数据回滚到修改之前的样子即可!

undo log和redo log的区别

总结

MySQL InnoDB 引擎使用 redo log(重做日志) 保证事务的持久性,使用 undo log(回滚日志) 来保证事务的原子性。

MySQL数据库的数据备份、主备、主主、主从都离不开归档日志binlog,需要依靠binlog来同步数据,保证数据一致性

Buffer Pool的一些知识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值