第17章_其他数据库日志(1)https://developer.aliyun.com/article/1530736
5.4 使用日志恢复数据
mysqlbinlog恢复数据的语法如下:
mysqlbinlog [option] filename|mysql –uuser -ppass;
这个命令可以这样理解:使用mysqlbinlog命令来读取filename中的内容,然后使用mysql命令将这些内容
恢复到数据库中。
filename
:是日志文件名。option
:可选项,比较重要的两对option参数是–start-date、–stop-date 和 --start-position、–stop-position。
- ``–start-date
和
–stop-date` :可以指定恢复数据库的起始时间点和结束时间点。 - ``–start-position
和
–stop-position` :可以指定恢复数据的开始位置和结束位置
注意:使用mysqlbinlog命令进行恢复操作时,必须是编号小的先恢复,例如atguigu-bin.000001必
须在atguigu-bin.000002之前恢复。
5.5 删除二进制日志
MySQL的二进制文件可以配置自动删除,同时MySQL也提供了安全的手动删除二进制文件的方法。
PURGE MASTER LOGS 只删除指定部分的二进制日志文件, RESET MASTER 删除所有的二进制日志文
件。具体如下:
- PURGE MASTER LOGS:删除指定日志文件
PURGE {MASTER | BINARY} LOGS TO ‘指定日志文件名’ PURGE {MASTER | BINARY} LOGS BEFORE ‘指定日期’
5.6 其它场景
二进制日志可以通过数据库的 全量备份 和二进制日志中保存的 增量信息 ,完成数据库的 无损失恢复 。
但是,如果遇到数据量大、数据库和数据表很多(比如分库分表的应用)的场景,用二进制日志进行数
据恢复,是很有挑战性的,因为起止位置不容易管理。
在这种情况下,一个有效的解决办法是 配置主从数据库服务器 ,甚至是 一主多从 的架构,把二进制日志
文件的内容通过中继日志,同步到从数据库服务器中,这样就可以有效避免数据库故障导致的数据异常
等问题。
6.再谈二进制日志(binlog)
6.1 写入机制
binlog的写入时机也非常简单,事务执行过程中,先把日志写到 binlog cache ,事务提交的时候,再
把binlog cache写到binlog文件中。因为一个事务的binlog不能被拆开,无论这个事务多大,也要确保一
次性写入,所以系统会给每个线程分配一个块内存作为binlog cache。
write和fsync的时机,可以由参数 sync_binlog
控制,默认是 0 。为0的时候,表示每次提交事务都只
write,由系统自行判断什么时候执行fsync。虽然性能得到提升,但是机器宕机,``page cache`里面的
binglog 会丢失。如下图:
为了安全起见,可以设置为 1 ,表示每次提交事务都会执行fsync,就如同redo log 刷盘流程一样。
最后还有一种折中方式,可以设置为N(N>1),表示每次提交事务都write,但累积N个事务后才fsync。
在出现IO瓶颈的场景里,将sync_binlog设置成一个比较大的值,可以提升性能。同样的,如果机器宕
机,会丢失最近N个事务的binlog日志。
6.2 binlog与redolog对比
- redo log 它是 物理日志 ,记录内容是“在某个数据页上做了什么修改”,属于 InnoDB 存储引擎层产生
的。 - 而 binlog 是 逻辑日志 ,记录内容是语句的原始逻辑,类似于“给 ID=2 这一行的 c 字段加 1”,属于
MySQL Server 层。
6.3 两阶段提交
在执行更新语句过程,会记录redo log与binlog两块日志,以基本的事务为单位,redo log在事务执行过程
中可以不断写入,而binlog只有在提交事务时才写入,所以redo log与binlog的 写入时机 不一样。
redo log与binlog两份日志之间的逻辑不一致,会出现什么问题?
由于binlog没写完就异常,这时候binlog里面没有对应的修改记录。
为了解决两份日志之间的逻辑一致问题,InnoDB存储引擎使用两阶段提交方案
使用两阶段提交后,写入binlog时发生异常也不会有影响
另一个场景,redo log设置commit阶段发生异常,那会不会回滚事务呢?
不会回滚事务,它会执行上图框住的逻辑,虽然redo log是处于prepare阶段,但是能通过事务id找到对
应的binlog日志,所以MySQL认为是完整的,就会提交事务恢复数据。
7.中继日志(relay log)
7.1 介绍
中继日志只在主从服务器架构的从服务器上存在。从服务器为了与主服务器保持一致,要从主服务器读
取二进制日志的内容,并且把读取到的信息写入 本地的日志文件中,这个从服务器本地的日志文件就叫
中继日志 。然后,从服务器读取中继日志,并根据中继日志的内容对从服务器的数据进行更新,完成主
从服务器的 数据同步 。
搭建好主从服务器之后,中继日志默认会保存在从服务器的数据目录下。
文件名的格式是: 从服务器名 -relay-bin.序号
。中继日志还有一个索引文件:`` 从服务器名 -relay-
bin.index `,用来定位当前正在使用的中继日志。
7.2 查看中继日志
中继日志与二进制日志的格式相同,可以用 mysqlbinlog 工具进行查看。下面是中继日志的一个片
段:
SET TIMESTAMP=1618558728/*!*/; BEGIN /*!*/; # at 950 #210416 15:38:48 server id 1 end_log_pos 832 CRC32 0xcc16d651 Table_map: `atguigu`.`test` mapped to number 91 # at 1000 #210416 15:38:48 server id 1 end_log_pos 872 CRC32 0x07e4047c Delete_rows: table id 91 flags: STMT_END_F -- server id 1 是主服务器,意思是主服务器删了一行数据 BINLOG ' CD95YBMBAAAAMgAAAEADAAAAAFsAAAAAAAEABGRlbW8ABHRlc3QAAQMAAQEBAFHWFsw= CD95YCABAAAAKAAAAGgDAAAAAFsAAAAAAAEAAgAB/wABAAAAfATkBw== '/*!*/; # at 1040
这一段的意思是,主服务器(“server id 1”)对表 atguigu.test 进行了 2 步操作:
定位到表 atguigu.test 编号是 91 的记录,日志位置是 832; 删除编号是 91 的记录,日志位置是 872。
7.3 恢复的典型错误
如果从服务器宕机,有的时候为了系统恢复,要重装操作系统,这样就可能会导致你的服务器名称 与之
前 不同 。而中继日志里是 包含从服务器名 的。在这种情况下,就可能导致你恢复从服务器的时候,无法
从宕机前的中继日志里读取数据,以为是日志文件损坏了,其实是名称不对了。
解决的方法也很简单,把从服务器的名称改回之前的名称
ped to number 91
at 1000
#210416 15:38:48 server id 1 end_log_pos 872 CRC32 0x07e4047c Delete_rows: table id 91 flags: STMT_END_F – server id 1 是主服务器,意思是主服务器删了一行数据 BINLOG ’ CD95YBMBAAAAMgAAAEADAAAAAFsAAAAAAAEABGRlbW8ABHRlc3QAAQMAAQEBAFHWFsw= CD95YCABAAAAKAAAAGgDAAAAAFsAAAAAAAEAAgAB/wABAAAAfATkBw== '/!/;
at 1040
这一段的意思是,主服务器(“server id 1”)对表 atguigu.test 进行了 2 步操作:
定位到表 atguigu.test 编号是 91 的记录,日志位置是 832;
删除编号是 91 的记录,日志位置是 872。
### 7.3 恢复的典型错误 如果从服务器宕机,有的时候为了系统恢复,要重装操作系统,这样就可能会导致你的==服务器名称== 与之 前 不同 。而中继日志里是 ==包含从服务器名== 的。在这种情况下,就可能导致你恢复从服务器的时候,无法 从宕机前的中继日志里读取数据,以为是日志文件损坏了,其实是名称不对了。 解决的方法也很简单,把从服务器的名**称改回之前的名称**