MySQL日志之二进制日志binlog

1.1 MySQL为什么需要binlog

  MySQL与Oracle等数据库不同,Redo log不会作为归档,仅做Failover等作用;MySQL引用了binlog来实现归档日志,提供复制、恢复、审计功能。
在MySQL中,Redo log和binlog有以下三点不同:

  • Redo log 是 InnoDB 引擎层面的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  • Redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
  • Redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

1.2 什么是binlog

  binlog是记录所有数据库结构变更(例如CREATE、ALTER TABLE…)以及表数据修改(INSERT、UPDATE、DELETE…)的二进制日志。binlog不会记录SELECT和SHOW这类操作,因为这类操作对数据本身并没有修改,但可以通过查询日志general_log来查看MySQL执行过的所有语句。
三个重要用途:

  • 复制
      复制源服务器上的二进制日志提供要发送到副本的数据更改的记录。源将其二进制日志中包含的信息通过dump线程发送到其副本,副本通过IO线程接受这些事务,然后通过SQL线程以进行与源上相同的数据更改。

  • 恢复
      某些数据恢复操作需要使用二进制日志。恢复备份后,将重新执行备份后在二进制日志中记录的事件。这些事件使数据库从备份时起是最新的。

  • 审计
      用户可以通过二进制日志中的信息来进行审计,判断是否有对数据库进行注入攻击。

1.3 binlog结构

  binlog是一组文件,由一组二进制日志文件和一个索引文件组成。

  • 索引文件(文件名后缀为.index)用于记录哪些日志文件正在被使用
  • 日志文件(文件名后缀为.00000*)记录数据库所有的变更(除了数据查询语句)语句事件。
    在这里插入图片描述

binlog文件

binlog cache:实际上就是参数binlog_cache_size指定的大小,它指定的是一段内存空间用于存储生成的binlog event。
binlog cache 临时文件:实际上就是参数max_binlog_cache_size指定的大小,它指定是一个临时磁盘文件存储由于binlog cache不足溢出的binlog event,其名字由"ML"打头。
binlog file:代表就是我们平时说的binglog 文件,由max_binlog_size指定大小。
binlog event:代表是各种各样的binlog中的记录比如MAP_EVENT/QUERY EVENT/XID EVENT/WRITE EVENT等。

binlog event
binlog源码文件在binlog_event.h

 
enum Log_event_type {
      if a event type before is deprecated and removed directly from
    - Fix Format_description_event::Format_description_event().
  UNKNOWN_EVENT = 0,
  START_EVENT_V3 = 1,
  QUERY_EVENT = 2,
  STOP_EVENT = 3,
  ROTATE_EVENT = 4,
  INTVAR_EVENT = 5,
  SLAVE_EVENT = 7,
  APPEND_BLOCK_EVENT = 9,
  DELETE_FILE_EVENT = 11,
  RAND_EVENT = 13,
  USER_VAR_EVENT = 14,
  FORMAT_DESCRIPTION_EVENT = 15,
  XID_EVENT = 16,
  BEGIN_LOAD_QUERY_EVENT = 17,
  EXECUTE_LOAD_QUERY_EVENT = 18,
  TABLE_MAP_EVENT = 19,
    The V1 event numbers are used from 5.1.16 until mysql-5.6.
  WRITE_ROWS_EVENT_V1 = 23,
  UPDATE_ROWS_EVENT_V1 = 24,
  DELETE_ROWS_EVENT_V1 = 25,
  INCIDENT_EVENT = 26,
    Heartbeat event to be send by master at its idle time
  HEARTBEAT_LOG_EVENT = 27,
  IGNORABLE_LOG_EVENT = 28,
  ROWS_QUERY_LOG_EVENT = 29,
  /** Version 2 of the Row events */
  WRITE_ROWS_EVENT = 30,
  UPDATE_ROWS_EVENT = 31,
  DELETE_ROWS_EVENT = 32,
  GTID_LOG_EVENT = 33,
  ANONYMOUS_GTID_LOG_EVENT = 34,
  PREVIOUS_GTIDS_LOG_EVENT = 35,
  TRANSACTION_CONTEXT_EVENT = 36,
  VIEW_CHANGE_EVENT = 37,
  /* Prepared XA transaction terminal event similar to Xid */
  XA_PREPARE_LOG_EVENT = 38,
    Extension of UPDATE_ROWS_EVENT, allowing partial values according
  PARTIAL_UPDATE_ROWS_EVENT = 39,
  TRANSACTION_PAYLOAD_EVENT = 40,
    Add new events here - right above this comment!
    Existing events (except ENUM_END_EVENT) should never change their numbers
  ENUM_END_EVENT /* end marker */
  Struct to pass basic information about a event: type, query, is it ignorable

1.4 binlog生成过程

1、开启事务

2、执行dml语句,在dml语句第一次执行的时候会分配内存空间binlog cache
,执行dml语句期间生成的event不断写入到binlog cache。

3、如果binlog cache的空间已经满了,则将binlog cache的数据写入到binlog临时文件,同时清空binlog cache。如果binlog临时文件的大小大于max_binlog_cache_size的设置则抛错MySQL error code 1197 (ER_TRANS_CACHE_FULL): Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage; increase this mysqld variable and try again

4、事物提交,整个binlog cache和binlog临时文件数据全部写入到binlog file中进行固化,释放binlog cache和binlog临时文件。但是注意此时binlog cache的内存空间留用供下次事物使用,但是binlog临时文件被截断为0,保留文件描述符。

5、断开连接,这个过程会释放IO_CACHE同时释放其持有的binlog cache内存空间以及持有的binlog 临时文件。

1.5 binlog 三种格式

format 定义 优点 缺点
statement 记录的是修改SQL语句 日志文件小,节约IO,提高性能 准确性差,对一些系统函数不能准确复制或不能复制,如now()、uuid()等
row 记录的是每行实际数据的变更 准确性强,能准确复制数据的变更 日志文件大,较大的网络IO和磁盘IO
mixed statement和row模式的混合 准确性强,文件大小适中 有可能发生主从不一致问题

无特殊情况,推荐使用row模式

1.6 相关变量

mysql> show variables like '%binlog%';
+------------------------------------------------+----------------------+
| Variable_name                                  | Value                |
+------------------------------------------------+----------------------+
| binlog_cache_size                              | 4194304              |
| binlog_checksum                                | CRC32                |
| binlog_direct_non_transactional_updates        | OFF                  |
| binlog_encryption                              | OFF                  |
| binlog_error_action                            | ABORT_SERVER         |
| binlog_expire_logs_seconds                     | 604800               |
| binlog_format                                  | ROW                  |
| binlog_group_commit_sync_delay                 | 0                    |
| binlog_group_commit_sync_no_delay_count        | 0                    |
| binlog_gtid_simple_recovery                    | ON                   |
| binlog_max_flush_queue_time                    | 0                    |
| binlog_order_commits                           | ON                   |
| binlog_rotate_encryption_master_key_at_startup | OFF                  |
| binlog_row_event_max_size                      | 8192                 |
| binlog_row_image                               | FULL                 |
| binlog_row_metadata                            | MINIMAL              |
| binlog_row_value_options                       |                      |
| binlog_rows_query_log_events                   | OFF                  |
| binlog_stmt_cache_size                         | 32768                |
| binlog_transaction_compression                 | OFF                  |
| binlog_transaction_compression_level_zstd      | 3                    |
| binlog_transaction_dependency_history_size     | 25000                |
| binlog_transaction_dependency_tracking         | COMMIT_ORDER         |
| innodb_api_enable_binlog                       | OFF                  |
| log_statements_unsafe_for_binlog               | ON                   |
| max_binlog_cache_size                          | 2147483648           |
| max_binlog_size                                | 1073741824           |
| max_binlog_stmt_cache_size                     | 18446744073709547520 |
| sync_binlog                                    | 1                    |
+------------------------------------------------+----------------------+
29 rows in set (0.00 sec)

mysql> show variables like '%log_bin%';
+---------------------------------+----------------------------------+
| Variable_name                   | Value                            |
+---------------------------------+----------------------------------+
| log_bin                         | ON                               |
| log_bin_basename                | /data/mysql8/binlog/binlog       |
| log_bin_index                   | /data/mysql8/binlog/binlog.index |
| log_bin_trust_function_creators | OFF                              |
| log_bin_use_v1_row_events       | OFF                              |
| sql_log_bin                     | ON                               |
+---------------------------------+----------------------------------+
6 rows in set (0.01 sec)

参数名 含义
log_bin 指定实例是否启动二进制日志
log_bin_basename 指定binlog文件名称:路径+名称
log_bin_index 指定binlog索引文件名称:路径+名称
log_bin_trust_function_creators 用于控制MySQL对存储函数和触发器创建的限制
sql_log_bin 控制是否开启对二进制日志的日志记录功能
binlog_cache_size 设置binlog_cache_size大小
max_binlog_cache_size 指定二进制日志缓存最大大小
binlog_checksum 为二进制日志中的每个事件写入校验和
binlog_encryption binlog加密
expire_logs_days 设置binlog过期天数
binlog_expire_logs_seconds 设置binlog过期秒数
binlog_format binlog格式
binlog_group_commit_sync_delay 控制在将二进制日志文件同步到磁盘之前等待多少微秒以把事务合并到一个
binlog_group_commit_sync_no_delay_count 在binlog­group­commit­sync­delay指定的延迟时间之内,一次组提交允许等待的 大事务数量,超过这个数量则不会进行组提交,不会再进行等待
binlog_order_commits 用于控制主库中binlog的提交顺序是否需要和redo log的提交顺序保持一致
binlog_row_image 控制binlog记录的前后镜像内容
sync_binlog 指定binlog刷盘机制
binlog_rows_query_log_events 控制是否记录用户原生SQL的参数到binlog file
max_binlog_size 单个文件最大大小

1.7 常用命令

查看binlog信息

mysql> show master status\G
*************************** 1. row ***************************
             File: binlog.000013
         Position: 196
     Binlog_Do_DB:
 Binlog_Ignore_DB:
Executed_Gtid_Set: 6ac2c3ad-c5b7-11ea-8d1a-00163e0c8a51:1-403
1 row in set (0.00 sec)

mysql> show master logs;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000004 |      2466 | No        |
| binlog.000005 |      1997 | No        |
| binlog.000006 |       196 | No        |
| binlog.000007 |      2736 | No        |
| binlog.000008 |       419 | No        |
| binlog.000009 |      1713 | No        |
| binlog.000010 |       908 | No        |
| binlog.000011 |     20821 | No        |
+---------------+-----------+-----------+
8 rows in set (0.15 sec)

mysql> show binlog events in 'binlog.000011';
+---------------+-------+----------------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name      | Pos   | Event_type     | Server_id | End_log_pos | Info                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+---------------+-------+----------------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| binlog.000011 |     4 | Format_desc    |     33071 |         125 | Server ver: 8.0.21, Binlog ver: 4                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| binlog.000011 |   125 | Previous_gtids |     33071 |         196 | 6ac2c3ad-c5b7-11ea-8d1a-00163e0c8a51:1-338                                                                                                                                                                                                                                                                                                                                                                                                                            |
| binlog.000011 |   196 | Gtid           |     33071 |         273 | SET @@SESSION.GTID_NEXT= '6ac2c3ad-c5b7-11ea-8d1a-00163e0c8a51:339'                                                                                                                                                                                                                                                                                                                                                                                                   |
| binlog.000011 |   273 | Query          |     33071 |         382 | use `test`; create table test_t1 like t1 /* xid=4111 */                                                                                                                                                                                                                                                                                                                                                                                                               |
| binlog.000011 |   382 | Gtid           |     33071 |         461 | SET @@SESSION.GTID_NEXT= '6ac2c3ad-c5b7-11ea-8d1a-00163e0c8a51:340'                                                                                                                                                                                                                                                                                                                                                                                                   |
| binlog.000011 |   461 | Query          |     33071 |         544 | BEGIN                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| binlog.000011 |   544 | Table_map      |     33071 |         622 | table_id: 120 (test.test_t1)                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| binlog.000011 |   622 | Write_rows     |     33071 |        1778 | table_id: 120 flags: STMT_END_F                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| binlog.000011 |  1778 | Xid            |     33071 |        1809 | COMMIT /* xid=4112 */   

命令行查看mysqlbinlog

mysqlbinlog --no-defaults -vvv mysql-bin.000458 --start-datetime="2020-04-18 16:15:00" 

备份binlog

以前备份binlog时,都是先在本地进行备份压缩,然后发送到远程服务器中。但是这其中还是有一定风险的,因为日志的备份都是周期性的,如果在某个周期中,服务器宕机了,硬盘损坏了,就可能导致这段时间的binlog就丢失了。
而且,以前用脚本对远程服务器进行备份的方式,有个缺点:无法对MySQL服务器当前正在写的二进制日志文件进行备份。所以,只能等到MySQL服务器全部写完才能进行备份。而写完一个binlog的时间并不固定,这就导致备份周期的不确定。
从MySQL5.6开始,mysqlbinlog支持将远程服务器上的binlog实时复制到本地服务器上。
mysqlbinlog的实时二进制复制功能并非简单的将远程服务器的日志复制过来,它是通过MySQL 5.6公布的Replication API实时获取二进制事件。本质上,就相当于MySQL的从服务器。与普通服务器类似,主服务器发生事件后,一般都会在0.5~1秒内进行备份。

mysqlbinlog --read-from-remote-server --raw --host=192.168.244.145 --port=3306 --user=repl --password=repl --stop-never  mysql-bin.000001

清理binlog

PURGE { BINARY | MASTER } LOGS {
    TO 'log_name'
  | BEFORE datetime_expr

猜你喜欢

转载自blog.csdn.net/qq_42979842/article/details/107940264