美文网首页
MySQL binlog专题补充内容

MySQL binlog专题补充内容

作者: 这货不是王马勺 | 来源:发表于2024-09-08 15:38 被阅读0次

binlog基本概念

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

binlog特点

  • 1.binlog是在MySQL的server层实现的,是所有存储引擎共用的;
  • 2.binlog是逻辑日志,,记录的是一条SQL语句的原始逻辑;
  • 3.binlog是追加写入的,不会覆盖之前的日志。

binlog使用场景

  • 1.主从复制:详见主从复制篇;
  • 2.数据恢复:除了redolog在数据库崩溃后恢复时会用xid向binlog确认事务完整性以外,还有通过mysqlbinlog工具来进行数据恢复的场景。经常使用的第三方工具reverse_sql也是通过binlog解析出回滚用的反向SQL。

binlog记录内容和模式

SQL语句记录内容

  • DDL:原封不动的记录当前DDL(statement语句方式)
  • DCL:原封不动的记录当前DCL(statement语句方式)
  • DML:只记录已经提交的事务DML(insert update delete)

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

  • mixed(混合)MBR(mixed based replication):混合模式,一般情况用statement模式,对于statement无法复制的用ROW模式,一般不用混合模式。
  • statement:优点是可读性较高,日志量少,减少io。但缺点是不够严谨,记录仅是每条修改数据的SQL(如果是批量修改,则记录的不是单条SQL,而是批量修改SQL语句的事件),在使用一些函数时会导致主从不一致。
  • ROW:缺点是可读性很低,日志量大,但足够严禁,记录的是行变化。生产环境我们希望数据最大化的一致,因此建议使用ROW模式。
    row模式优点是能清楚记录每一行数据修改细节,能完全实现(包括存储过程及触发器)主从数据同步和数据恢复。我们很多基于binlog的工具都要求必须采用ROW模式。

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%';
  • sync_binlog = 0:每次提交事务都只write,不fsync,不建议设置为0,丢失的数据不可控。
  • sync_binlog = 1:每次提交事务都fsync,生产环境若要保证最高安全性则设为1。
  • sync_binlog = n(n>1):每次提交事务都write,但积累n个事务才fsync到磁盘,一般设为100~1000中某个值,在崩溃时最多丢失n个事务,丢失量可控。

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中的数据都恢复到内存就可以了。

相关文章

网友评论

      本文标题:MySQL binlog专题补充内容

      本文链接:https://www.haomeiwen.com/subject/futwcjtx.html