MySQL binlog专题补充内容

2024-09-08  本文已影响0人  这货不是王马勺

binlog基本概念

binlog是一个二进制格式的文件,用于记录用户对数据库更新的SQL语句信息(DDL,DCL,DML),不记录查询语句(select、show这类的操作)。

binlog特点

binlog使用场景

binlog记录内容和模式

SQL语句记录内容

DML记录模式
记录模式由binlog_format(binlog的记录格式)参数影响
statement(5.6默认)SBR(statement based replication):语句模式原封不动地记录当前DML
ROW(5.7默认)RBR(ROW based replication):记录实际开机的变化,用户看不懂,需要工具分析

binlog写入流程

binlog文件结构
主要是log event,不同的修改操作对应不同的log event。
比较常见的log event有:query event,ROW event,XID event等等。
文件结构参考下图:

binlog落盘策略
binlog写入顺序:binlog cache(write) → OS cache → fsync()写入磁盘
binlog刷数据到磁盘是由一个参数控制的:sync_binlog

show variables like '%sync_binlog%';

binlog写入流程描述
参考下图:

1.根据操作和记录模式触发event事件,生成log event;
2.事务执行过程中,先把日志写到binlog cache,每个事务都会被分配一个binlog cache内存空间。事务提交的时候,再把日志写到binlog文件当中。binlog文件是只有一份的,共用的。
3.事务提交,执行器会把binlog cache里的完整事务写入binlog文件,然后执行器会清空binlog cache。

查看binlog

启用binlog
向配置文件my.cnf增加几个基本参数:

binlog_format=row
log_bin=/binlog/mysqlbin
log_bin_index=/binlog/mysql-bin.index

重启后生效。(8.0默认开启,且保存在数据目录下)
检查是否生效:

show variables like '%log_bin%';

这里补充常用的binlog和复制参数:

# 二进制日志文件的缓存大小
binlog_cache_size = 131072
# 验证binlog的完整性,默认CRC32,此处禁用校验
binlog_checksum=NONE    
# 二进制日志文件过期时间,两参数配置一个即可
binlog_expire_logs_seconds=172800
expire_logs_days = 3
# 记录每一行数据被修改的形式
binlog_format=row
# 二进制日志记录的行数据格式
# binlog_row_image='minimal' 
# 开启记录详细的行操作信息
binlog_rows_query_log_events =1
# 开启记录详细的行操作信息
enforce_gtid_consistency=ON
# 启用GTID
gtid_mode=ON
# 启用binlog的开关,并指定binlog名称。
log_bin=/binlog/mysqlbin
# 指定二进制日志的索引文件名称。
log_bin_index=/binlog/mysql-bin.index
# 从服务器上记录二进制日志的方式,记录所有从服务器的更新操作到主服务器,默认关闭
log_slave_updates=OFF
# 二进制日志中主服务器的相关信息存储位置,将主服务器的二进制日志信息存储在MySQL的数据表中。
master_info_repository=TABLE
# 只读,一般从节点会配置,MGR不用主动配置
read_only=1
# 设定从服务器的中继日志中的相关信息存储位置,将中继日志信息存储在MySQL的数据表中
relay_log_info_repository=TABLE
# 部分复制的参数
replicate-do-db=需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可
replicate-ignore-db=需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可
# 实例启动时不自动启动复制线程
skip_slave_start
# 指定从服务器在进行并行复制时的行为,使用逻辑时钟进行并行复制。这意味着从服务器会根据主服务器上的时间戳来执行复制操作,而不是物理时间。
slave_paralle_type=LOGICAL_CLOCK
# 从服务器在进行并行复制时使用的线程数
slave_paralle_workers=4
# 主从复制过程中从服务器可以自动跳过的错误号
slave_skip_errors = 1032,1062,1053,1146
# 每个事务提交时将二进制日志同步到磁盘
sync_binlog=1

使用SQL命令查看binlog
查看binlog文件列表:

show binary logs;

查看正在写入的binlog

show master status;

查看binlog文件信息

show binlog events;

其中
Log_name是当前事件所在binlog名称,
Pos是当前事件起始位置,即起始position号,
Event_type是事件类型,如Query、Table_map、Update_rows、Xid等等...
Server_id,
End_log_pos是当前事件结束位置,用End_log_pos减去Pos则是占用字节数,
Info是具体信息。

查看指定文件内容

show binlog events in 'mysqlbinlog.000001'\G

或使用mysqlbinlog命令来查看,专门用于查看binlog的工具。一般需要导出到文件。

mysqlbinlog mysqlbinlog.000001
mysqlbinlog mysql-bin.000002 >/tmp/a.sql 

binlog与redolog

1.redolog是innodb特有的。而binlog是MySQL server层实现的,因此所有引擎都能使用。
2.redolog是物理日志,记录的是xxx表空间xx页在xxx偏移量做了什么修改,值是多少,记录内容相对较少。而binlog是逻辑日志,记录SQL语句相关信息。
3.redolog是循环写入,空间一定是会被用完的,会产生覆盖,需要write pos和checkpoint搭配使用。binlog是追加写,写到一定大小会切换到下一个日志文件,但不会覆盖之前的,日志是全量保存的。
4.redolog作为服务器异常宕机后事务数据自动恢复时使用,具备crash-safe能力(所有已提交事务在mysql宕机重启后仍然存在,所有没提交的事务数据自动回滚)。binlog可以在主从复制和数据恢复使用,但不具备crash-safe能力。

为什么崩溃恢复不使用binlog?
1.恢复机制:mysql可以根据redo日志中的各种信息,来确定恢复的起点和终点,redo是以哈希表的方式记录的。
2.binlog恢复:binlog主要用于人工恢复数据,redolog是对用户不可读的,是mysql自己使用的,用于保证在数据库崩溃时的事务持久性。当数据库崩溃后,想要恢复未刷盘但已经写入redo log和binlog的数据到内存时,binlog是无法恢复的,虽然binlog拥有全量的数据,但是没有一个标识让innodb判断哪些数据已经写入表(写入磁盘表空间),哪些数据还没写入。
比如,binlog记录了两条日志
- 记录1:给id=2这一行的c字段+1
- 记录2:给id=2这一行的c字段+1
在记录1入表之后,记录2还没有入表时,数据库挂了。重启后,如果只是通过binlog无法判断两条记录哪条写入磁盘了,哪条没写,不管是两条都恢复至内存还是都不恢复,都不对。
但如果有了redolog,只要刷入磁盘的数据都会从redolog抹除掉。数据库重启之后,直接把redolog中的数据都恢复到内存就可以了。

上一篇 下一篇

猜你喜欢

热点阅读