MySQL 二进制日志深入解析与应用

MySQL二进制日志深入解析与应用

1.1 MySQL Binlog 二进制日志概述

这个文件记录了mysql数据库所有的dml,ddl语句事件(不包括select),记录增删改操作,也可以记录SQL语句,也可以记录行变化记录,还可以记录这些操作的时间。

#比如如下这条SQL
update test_t set name='name' where id between 1 and 5;

记录:

  1. 可能是这条语句

  2. 可能是记录5条数据的修改情况

  3. 可能两个都同时记录。

三种日志的区别:

  • general log:记录数据库里面所有的SQL操作记录。
  • redo log:值记录innodb存储引擎的修改日志
  • binlog:只记录数据库server层面内部的修改情况。–select/show不记录

开启binlog二进制日志有什么好处?以应用场景为说明:

  1. MySQL主从复制:通过binlog实现数据复制

  2. 数据恢复:如宕机恢复,异常操作的恢复

​ 不好的地方就是:大概损失1%左右的性能,占用空间。

1.2 MySQL binlog 的三种工作模式

mysql> show variables like '%binlog_format%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

工作模式

  1. row level (默认级别:mysql5.7.6 之后+8.0)

    日志中记录每一行数据修改的情况。

    优点:可以更方便查看每一行数据修改的细节。

    缺点:数据量比较大

    使用场景:希望数据最安全,复制强一致。

  2. statement level (默认级别:mysql5.7.6 之前)

    记录每一条修改的SQL。

    优点:解决了数据量比较大的问题

    缺点:容易出现主从复制不一致

    使用场景:使用mysql的功能比较少,又不使用存储过程/触发器/函数

  3. mixed (混合模式)

    结合row level和statement level的优点

1.3 配置MySQL binlog 二进制日志

mysql> show variables like '%log_bin%'; 
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin                         | OFF   |				#二进制日志是否打开
| log_bin_basename                |       |				#二进制日志的名字
| log_bin_index                   |       |				#二进制日志索引名字
| log_bin_trust_function_creators | OFF   |
| log_bin_use_v1_row_events       | OFF   |
| sql_log_bin                     | ON    |
+---------------------------------+-------+
6 rows in set (0.00 sec)

mysql> show variables like '%binlog_format%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

mysql> show variables like '%binlog_rows_query_log_events%';
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| binlog_rows_query_log_events | OFF   |			#记录的是事件还是语句,打开的话记录会比较详细
+------------------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like 'server_id';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 3306  |
+---------------+-------+
1 row in set (0.00 sec)

#该设置(server_id)只能是数字,建议ip+端口,例如513306,因为一个局域网内IP是不会重复的,配置主从一定要设置server_id,要指定一个不能和其他集群中重名的字符串

修改参数

cat >> /mysql/data/3306/my.cnf << EOF
[mysqld]
log_bin=/mysql/log/3306/binlog/testdb-binlog
log_bin_index=/mysql/log/3306/binlog/testdb-binlog.index
binlog_format='row'
binlog_rows_query_log_events=on
EOF

#创建目录并授权:
mkdir -p /mysql/log/3306/binlog
chown -R mysql:mysql /mysql/log/3306/binlog
chmod -R 755 /mysql/log/3306/binlog

#重启MySQL服务
service mysql restart

检查参数

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

mysql> show variables where Variable_name in ('binlog_format','binlog_rows_query_log_events');
+------------------------------+-------+
| Variable_name                | Value |
+------------------------------+-------+
| binlog_format                | ROW   |
| binlog_rows_query_log_events | ON    |
+------------------------------+-------+
2 rows in set (0.00 sec)

参数说明

  • log_bin=/mysql/log/3306/binlog/testdb-binlog

    这个名字会自动加后缀:.00000*) log_bin默认值为off,我们修改的时候不能写on,要输入具体的binlog的路径和文件名,对应的目录要事先创建好,设置好之后,默认的off就自动变为on了

  • log_bin_index=/mysql/log/3306/binlog/testdb-binlog.index

  • binlog_format=‘row’

    可设置的值为:row,statement,mixed,默认就是行模式

  • log_bin_basename

    basename参数我们不能手动设置,log_bin设置了binlog的路径后,转为on,log_bin_basename参数就会自动填充binlog的路径信息

查看二进制日志文件

#服务器上生成的文件
[root@centos7 binlog]# pwd
/mysql/log/3306/binlog
[root@centos7 binlog]# ll -h
total 8.0K
-rw-r----- 1 mysql mysql 154 Aug 13 18:01 testdb-binlog.000001
-rw-r----- 1 mysql mysql  44 Aug 13 18:01 testdb-binlog.index
[root@centos7 binlog]# 

[root@centos7 binlog]# mysqlbinlog testdb-binlog.000001
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
DELIMITER /*!*/;
# at 4
#230813 18:01:13 server id 3306  end_log_pos 123 CRC32 0x09afc30a       Start: binlog v 4, server v 5.7.43-log created 230813 18:01:13 at startup
# Warning: this binlog is either in use or was not closed properly.
ROLLBACK/*!*/;
BINLOG '
6anYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAADpqdhkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
AQrDrwk=
'/*!*/;
# at 123
#230813 18:01:13 server id 3306  end_log_pos 154 CRC32 0x5a309a75       Previous-GTIDs
# [empty]
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 


#刷新日志
mysql> flush logs;
Query OK, 0 rows affected (0.01 sec)

#如下刷新日志后生成了新的二进制日志
[root@centos7 binlog]# ll -h
total 12K
-rw-r----- 1 mysql mysql 205 Aug 13 18:13 testdb-binlog.000001
-rw-r----- 1 mysql mysql 154 Aug 13 18:13 testdb-binlog.000002
-rw-r----- 1 mysql mysql  88 Aug 13 18:13 testdb-binlog.index
[root@centos7 binlog]# 

1.4 MySQL Binary 日志相关参数详解

1.4.1 常用必配参数

show variables like '%log_bin%';
show variables like '%binlog%';
show variables like '%server%';


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

mysql> show variables like '%binlog%';
+--------------------------------------------+----------------------+
| Variable_name                              | Value                |
+--------------------------------------------+----------------------+
| binlog_cache_size                          | 32768                |
| binlog_checksum                            | CRC32                |
| binlog_direct_non_transactional_updates    | OFF                  |
| binlog_error_action                        | ABORT_SERVER         |
| 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_row_image                           | FULL                 |
| binlog_rows_query_log_events               | ON                   |
| binlog_stmt_cache_size                     | 32768                |
| binlog_transaction_dependency_history_size | 25000                |
| binlog_transaction_dependency_tracking     | COMMIT_ORDER         |
| innodb_api_enable_binlog                   | OFF                  |
| innodb_locks_unsafe_for_binlog             | OFF                  |
| log_statements_unsafe_for_binlog           | ON                   |
| max_binlog_cache_size                      | 18446744073709547520 |
| max_binlog_size                            | 1073741824           |
| max_binlog_stmt_cache_size                 | 18446744073709547520 |
| sync_binlog                                | 1                    |
+--------------------------------------------+----------------------+
22 rows in set (0.01 sec)

mysql> show variables like '%server%';
+---------------------------------+--------------------------------------+
| Variable_name                   | Value                                |
+---------------------------------+--------------------------------------+
| character_set_server            | utf8                                 |
| collation_server                | utf8_general_ci                      |
| innodb_ft_server_stopword_table |                                      |
| server_id                       | 3306                                 |
| server_id_bits                  | 32                                   |
| server_uuid                     | e2646e6f-38d6-11ee-b291-000c29151c55 |
+---------------------------------+--------------------------------------+
6 rows in set (0.00 sec)

mysql> 

1.4.2 文件相关参数

show variables like '%binlog%';

参数说明

  1. max_binlog_size

    范围4K-1G,默认1G。但如果一个SQL 事务太大,比如这个SQL 产生5G 日志,binlog 也会达到5G。

    mysql> show variables like '%max_binlog_size%';
    +-----------------+------------+
    | Variable_name   | Value      |
    +-----------------+------------+
    | max_binlog_size | 1073741824 |
    +-----------------+------------+
    1 row in set (0.00 sec)
    
    mysql> select round(1073741824/1024/1024/1024,0) "size/GB";
    +---------+
    | size/GB |
    +---------+
    |       1 |
    +---------+
    1 row in set (0.00 sec)
    
  2. binlog_row_image

    针对binlog_format='row’格式来设置记录的日志范围:

    默认是full, 还可以是minimal,noblob

    mysql> show variables like '%binlog_row_image%';
    +------------------+-------+
    | Variable_name    | Value |
    +------------------+-------+
    | binlog_row_image | FULL  |
    +------------------+-------+
    1 row in set (0.00 sec)
    
  3. binlog_gtid_simple_recovery

    在主从复制时有影响,现在是on,用于重启/清理时数据库只打开最老和最新的两个binlog 计算gtid_purged 和gtid_executed,不需要打开所有的文件。如果主从复制计算gtid 出错,改为off,需要打开所有文件计算,影响性能。

    mysql> show variables like '%binlog_gtid_simple_recovery%';
    +-----------------------------+-------+
    | Variable_name               | Value |
    +-----------------------------+-------+
    | binlog_gtid_simple_recovery | ON    |
    +-----------------------------+-------+
    1 row in set (0.00 sec)
    

1.4.3 缓存大小

1. binlog_cache_size:

二进制日志写缓存区大小,默认32K

mysql> show variables like 'binlog_cache_size';
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| binlog_cache_size | 32768 |
+-------------------+-------+
1 row in set (0.00 sec)

mysql> select 32768/1024;
+------------+
| 32768/1024 |
+------------+
|    32.0000 |
+------------+
1 row in set (0.00 sec)

写binlog 的流程:

数据在buffer pool中排序和其他操作,并在二进制日志缓存中记录,在我们提交之前,会先将二进制日志缓存写到磁盘系统缓存中,当提交的时候再写到二进制日志文件里面去。

数据操作buffer pool > binlog buffer > file system buffer > commit > binlog file

状态监控

mysql> show status like 'binlog_cache%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Binlog_cache_disk_use | 0     |
| Binlog_cache_use      | 0     |
+-----------------------+-------+
2 rows in set (0.00 sec)

Binlog_cache_use 表示用到binlog 缓存区的次数。

Binlog_cache_disk_use 表示使用临时文件来存放binlog 缓存的次数,该值过多就需要提高binlog_cache_size的值,让它刷的少一点。

2. max_binlog_cache_size

mysql> show variables like 'max_binlog_cache_size';
+-----------------------+----------------------+
| Variable_name         | Value                |
+-----------------------+----------------------+
| max_binlog_cache_size | 18446744073709547520 |
+-----------------------+----------------------+
1 row in set (0.00 sec)
mysql> select round(18446744073709547520/1024/1024/1024,2) "size/GB";
+----------------+
| size/GB        |
+----------------+
| 17179869184.00 |
+----------------+
1 row in set (0.00 sec)

3. binlog_stmt_cache_size

非事务语句文件缓存大小,默认32K

mysql> show variables like 'binlog_stmt_cache_size';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| binlog_stmt_cache_size | 32768 |
+------------------------+-------+
1 row in set (0.00 sec)

mysql> select 32768/1024;
+------------+
| 32768/1024 |
+------------+
|    32.0000 |
+------------+
1 row in set (0.00 sec)

4. max_binlog_stmt_cache_size

mysql> show variables like 'max_binlog_stmt_cache_size';
+----------------------------+----------------------+
| Variable_name              | Value                |
+----------------------------+----------------------+
| max_binlog_stmt_cache_size | 18446744073709547520 |
+----------------------------+----------------------+
1 row in set (0.00 sec)

1.4.4 flush disk 相关的

1. sync_binlog:

 mysql> show variables like 'sync_binlog';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sync_binlog   | 1     |
+---------------+-------+
1 row in set (0.00 sec)

写binlog 的流程:

数据在buffer pool中排序和其他操作,并在二进制日志缓存中记录,在我们提交之前,会先将二进制日志缓存写到磁盘系统缓存中,当提交的时候再写到二进制日志文件里面去。

数据操作buffer pool > binlog buffer > file system buffer > commit > binlog file

在写binlog file 之前commit 有3 种模式,分别是:0,1,N

  • sync_binlog=0

    mysql 不会主动同步binlog 内容到磁盘文件中,而是依赖操作系统刷新文件的机制来刷binlog file.一般是1秒 刷一次

  • sync_binlog=1

    默认值,mysql 主动刷新file system buffer 到磁盘上的binlog file中,每1 次commit,就主动fsync 一次

  • sync_binlog=N(不是0,也不是1,自定义设置的值,比如5)

    mysql 主动刷新file system buff 到磁盘上的binlog file 中,每N 次commit,就主动fsync 一次,

数据库先写redo log 还是先写binlog?

先写redo log,再写binlog。

2. innodb_flush_log_at_trx_commit

mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name                  | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1     |
+--------------------------------+-------+
1 row in set (0.00 sec)

sync_binlog 配合另一个参数innodb_flush_log_at_trx_commit;如果都是1,数据库挂了以后,最多只丢一条语句或一个事务的数据。

1.5 MySQL Binlog 二进制格式详解

涉及到3 个参数:

  • binlog_format=‘row’ – (row,statement,mixed)
  • binlog_row_image=full – (full,minimal,noblob)
  • binlog_rows_query_log_events=on – (on,off)

1.5.1 binlog_format=‘statement’

#修改行格式
mysql> set session binlog_format='statement';
Query OK, 0 rows affected (0.00 sec)

mysql> set global binlog_format='statement';
Query OK, 0 rows affected (0.00 sec)

mysql> select @@global.binlog_format,@@binlog_format;
+------------------------+-----------------+
| @@global.binlog_format | @@binlog_format |
+------------------------+-----------------+
| STATEMENT              | STATEMENT       |
+------------------------+-----------------+
1 row in set (0.00 sec)


#修改隔离级别为重复读
set session transaction_isolation='repeatable-read';
set global transaction_isolation='repeatable-read';   # 新的设置方法
#set global tx_isolation='repeatable-read';   # 旧的设置方法


mysql> select @@global.transaction_isolation,@@transaction_isolation;
+--------------------------------+-------------------------+
| @@global.transaction_isolation | @@transaction_isolation |
+--------------------------------+-------------------------+
| REPEATABLE-READ                | REPEATABLE-READ         |
+--------------------------------+-------------------------+
1 row in set (0.00 sec)


#查看当前的日志状态
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000002 |      154 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#刷新日志
mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |      154 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#刷新日志的目的是保证后续的所有操作都记录到003这个二进制日志里面(一个新的二进制日志)

模拟DDL与DML操作:

#创建测试表
create database testdb;
use testdb
create table test_t (
`id` int(11) primary key not null auto_increment,
`rowformat` varchar(50) not null,
`uuids` varchar(50) not null,
`timepoint` datetime not null default current_timestamp,
CurrentVersion timestamp not null default current_timestamp on update
current_timestamp
) engine=innodb;
#插入数据
mysql> insert into test_t(rowformat,uuids) select 'test',uuid();
Query OK, 1 row affected, 1 warning (0.05 sec)
Records: 1  Duplicates: 0  Warnings: 1
#有个警告,查看警告的信息
mysql> show warnings\G
*************************** 1. row ***************************
  Level: Note
   Code: 1592
Message: Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. Statement is unsafe because it uses a system function that may return a different value on the slave.
1 row in set (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |     1121 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

如上position由之前的154变为了1121,154~1121之间就记录了我们上面的操作。

接下来看154~1121 之间的操作记录,用mysqlbinlog 读取。

[root@centos7 binlog]# pwd
/mysql/log/3306/binlog
[root@centos7 binlog]# mysqlbinlog --start-position=154 --stop-position=1121 testdb-binlog.000003 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 20:15:46 server id 3306  end_log_pos 123 CRC32 0x4780b5e1       Start: binlog v 4, server v 5.7.43-log created 230813 20:15:46
     6  # Warning: this binlog is either in use or was not closed properly.
     7  BINLOG '
     8  csnYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     9  AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    10  AeG1gEc=
    11  '/*!*/;
    12  # at 154
    13  #230813 20:17:46 server id 3306  end_log_pos 219 CRC32 0x35f420b2       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    14  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    15  # at 219
    16  #230813 20:17:46 server id 3306  end_log_pos 319 CRC32 0x28367c06       Query   thread_id=3     exec_time=0     error_code=0
    17  SET TIMESTAMP=1691929066/*!*/;
    18  SET @@session.pseudo_thread_id=3/*!*/;
    19  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    20  SET @@session.sql_mode=1436549120/*!*/;
    21  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    22  /*!\C utf8 *//*!*/;
    23  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    24  SET @@session.lc_time_names=0/*!*/;
    25  SET @@session.collation_database=DEFAULT/*!*/;
    26  create database testdb
    27  /*!*/;
    28  # at 319
    29  #230813 20:18:06 server id 3306  end_log_pos 384 CRC32 0x906cd222       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=no
    30  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    31  # at 384
    32  #230813 20:18:06 server id 3306  end_log_pos 760 CRC32 0x646a3091       Query   thread_id=3     exec_time=0     error_code=0
    33  use `testdb`/*!*/;
    34  SET TIMESTAMP=1691929086/*!*/;
    35  SET @@session.explicit_defaults_for_timestamp=1/*!*/;
    36  create table test_t (
    37  `id` int(11) primary key not null auto_increment,
    38  `rowformat` varchar(50) not null,
    39  `uuids` varchar(50) not null,
    40  `timepoint` datetime not null default current_timestamp,
    41  CurrentVersion timestamp not null default current_timestamp on update
    42  current_timestamp
    43  ) engine=innodb
    44  /*!*/;
    45  # at 760
    46  #230813 20:18:58 server id 3306  end_log_pos 825 CRC32 0x127a1ece       Anonymous_GTID  last_committed=2        sequence_number=3    rbr_only=no
    47  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    48  # at 825
    49  #230813 20:18:58 server id 3306  end_log_pos 916 CRC32 0xf3544700       Query   thread_id=3     exec_time=0     error_code=0
    50  SET TIMESTAMP=1691929138/*!*/;
    51  SET @@session.time_zone='SYSTEM'/*!*/;
    52  BEGIN
    53  /*!*/;
    54  # at 916
    55  # at 948
    56  #230813 20:18:58 server id 3306  end_log_pos 948 CRC32 0x489e144a       Intvar
    57  SET INSERT_ID=1/*!*/;
    58  #230813 20:18:58 server id 3306  end_log_pos 1090 CRC32 0x17060eb7      Query   thread_id=3     exec_time=0     error_code=0
    59  SET TIMESTAMP=1691929138/*!*/;
    60  insert into test_t(rowformat,uuids) select 'test',uuid()
    61  /*!*/;
    62  # at 1090
    63  #230813 20:18:58 server id 3306  end_log_pos 1121 CRC32 0xc6d7e6b3      Xid = 54
    64  COMMIT/*!*/;
    65  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    66  DELIMITER ;
    67  # End of log file
    68  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    69  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 



#如上GTID_NEXT就表示一个事务的结束,开启了一个新的事务
#如上26行、33行、36行、60行、64行,刚所做的操作


#delete操作
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |     1121 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> delete from test_t where id=1;
Query OK, 1 row affected (0.00 sec)

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |     1407 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


[root@centos7 binlog]# mysqlbinlog --start-position=1121 --stop-position=1407 testdb-binlog.000003 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 20:15:46 server id 3306  end_log_pos 123 CRC32 0x4780b5e1       Start: binlog v 4, server v 5.7.43-log created 230813 20:15:46
     6  # Warning: this binlog is either in use or was not closed properly.
     7  BINLOG '
     8  csnYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     9  AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    10  AeG1gEc=
    11  '/*!*/;
    12  # at 1121
    13  #230813 20:30:56 server id 3306  end_log_pos 1186 CRC32 0x5d6e4264      Anonymous_GTID  last_committed=3        sequence_number=4    rbr_only=no
    14  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    15  # at 1186
    16  #230813 20:30:56 server id 3306  end_log_pos 1269 CRC32 0xa9e57e03      Query   thread_id=3     exec_time=0     error_code=0
    17  SET TIMESTAMP=1691929856/*!*/;
    18  SET @@session.pseudo_thread_id=3/*!*/;
    19  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    20  SET @@session.sql_mode=1436549120/*!*/;
    21  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    22  /*!\C utf8 *//*!*/;
    23  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    24  SET @@session.lc_time_names=0/*!*/;
    25  SET @@session.collation_database=DEFAULT/*!*/;
    26  BEGIN
    27  /*!*/;
    28  # at 1269
    29  #230813 20:30:56 server id 3306  end_log_pos 1376 CRC32 0x70277753      Query   thread_id=3     exec_time=0     error_code=0
    30  use `testdb`/*!*/;
    31  SET TIMESTAMP=1691929856/*!*/;
    32  delete from test_t where id=1
    33  /*!*/;
    34  # at 1376
    35  #230813 20:30:56 server id 3306  end_log_pos 1407 CRC32 0x3b117e96      Xid = 64
    36  COMMIT/*!*/;
    37  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    38  DELIMITER ;
    39  # End of log file
    40  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    41  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 




#drop操作
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |     1407 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> drop table test_t;
Query OK, 0 rows affected (0.01 sec)

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |     1595 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

[root@centos7 binlog]# mysqlbinlog --start-position=1407 --stop-position=1595 testdb-binlog.000003 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 20:15:46 server id 3306  end_log_pos 123 CRC32 0x4780b5e1       Start: binlog v 4, server v 5.7.43-log created 230813 20:15:46
     6  # Warning: this binlog is either in use or was not closed properly.
     7  BINLOG '
     8  csnYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     9  AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    10  AeG1gEc=
    11  '/*!*/;
    12  # at 1407
    13  #230813 20:33:29 server id 3306  end_log_pos 1472 CRC32 0xd5d84f49      Anonymous_GTID  last_committed=4        sequence_number=5    rbr_only=no
    14  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    15  # at 1472
    16  #230813 20:33:29 server id 3306  end_log_pos 1595 CRC32 0x00bc24a8      Query   thread_id=3     exec_time=0     error_code=0
    17  use `testdb`/*!*/;
    18  SET TIMESTAMP=1691930009/*!*/;
    19  SET @@session.pseudo_thread_id=3/*!*/;
    20  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    21  SET @@session.sql_mode=1436549120/*!*/;
    22  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    23  /*!\C utf8 *//*!*/;
    24  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    25  SET @@session.lc_time_names=0/*!*/;
    26  SET @@session.collation_database=DEFAULT/*!*/;
    27  DROP TABLE `test_t` /* generated by server */
    28  /*!*/;
    29  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    30  DELIMITER ;
    31  # End of log file
    32  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    33  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 

总结:
binlog_format=‘statement’ 的时候,DDL及DML都是明文按SQL记录存储
对主从复制的影响:

  1. 对有些参数,在不用的服务器和不用的时间,执行结果不一样,会导致主从不一致
  2. 特别是一些函数:uuid(),user(),时间函数,now(),等等
  3. 性能问题(同步到从库的全部是SQL语句,假设主库的某条SQL性能差,在从库也会执行这条性能差的语句,这就会导致性能差)
  4. 数据异常(假设主端插入了某张表的数据而数据量异常,从端也就跟着异常)

每一条会修改数据的sql语句会记录到binlog中,slave在复制的时候sql进程会解析成master端执行过的相同的sql在slave库上再次执行。

  • **优点:**statement level下的优点首先就是解决了row level下的缺点,不需要每一条sql语句和记录每一行的变化,较少binlog日志量,节约IO,提高性能(从库应用日志快)。因为它只需要记录在master上所执行的语句的细节,以及执行语句时候的上下文信息。
  • **缺点:**由于它是记录执行语句,所以,为了让这些语句在slave端也能正确执行,那么它还必须记录每条语句在执行的时候的一些相关信息,也就是上下文信息,来保证所有语句在slave端能够得到和在master端相同的执行结果。由于mysql更新较快,使mysql的赋值遇到了不小的挑战,自然赋值的时候就会涉及到越复杂的内容,bug也就容易出现。在statement level下,目前就已经发现了不少情况会造成mysql的复制出现问题,主要是修改数据的时候使用了某些特定的函数或者功能的时候会出现。比如:sleep()函数在有些版本中就不能正确赋值,在存储过程中使用了last_insert_id()函数,以及user-defined functions(udf)等,可能会使slave和master上得到不一致的id等等。由于row level是基于每一行记录的裱花,所以不会出现类似的问题。

1.5.2 binlog_format=‘row’

1.5.2.1 binlog_row_image=full,binlog_rows_query_log_events=off
#修改行格式
set session binlog_format='row';
set global binlog_format='row';
set session binlog_rows_query_log_events=0; -- 默认
set global binlog_rows_query_log_events=0; -- 默认
set session binlog_row_image=full; -- 默认
set global binlog_row_image=full; -- 默认

mysql> select @@global.binlog_format,@@binlog_format,@@global.binlog_rows_query_log_events,@@binlog_rows_query_log_events,@@global.binlog_row_image,@@binlog_row_image\G
*************************** 1. row ***************************
               @@global.binlog_format: ROW
                      @@binlog_format: ROW
@@global.binlog_rows_query_log_events: 0
       @@binlog_rows_query_log_events: 0
            @@global.binlog_row_image: FULL
                   @@binlog_row_image: FULL
1 row in set (0.00 sec)

#修改隔离级别为重复读
set session transaction_isolation='repeatable-read';
set global transaction_isolation='repeatable-read'; -- 新的设置方法
-- set global tx_isolation='repeatable-read'; -- 旧的设置方法
mysql> select @@global.transaction_isolation,@@transaction_isolation;
+--------------------------------+-------------------------+
| @@global.transaction_isolation | @@transaction_isolation |
+--------------------------------+-------------------------+
| REPEATABLE-READ                | REPEATABLE-READ         |
+--------------------------------+-------------------------+
1 row in set (0.00 sec)


mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000004 |      154 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

模拟DDL 与DML 操作

use testdb
create table test_t1 (
`id` int(11) primary key not null auto_increment,
`rowformat` varchar(50) not null,
`uuids` varchar(50) not null,
`timepoint` datetime not null default current_timestamp,
CurrentVersion timestamp not null default current_timestamp on update
current_timestamp
) engine=innodb;
insert into test_t1(rowformat,uuids) select 'test',uuid();
insert into test_t1(rowformat,uuids) select 'test',uuid();

mysql> select * from test_t1;
+----+-----------+--------------------------------------+---------------------+---------------------+
| id | rowformat | uuids                                | timepoint           | CurrentVersion      |
+----+-----------+--------------------------------------+---------------------+---------------------+
|  1 | test      | d818bfdd-39d6-11ee-8bb8-000c29151c55 | 2023-08-13 20:42:20 | 2023-08-13 20:42:20 |
|  2 | test      | d8c09cf1-39d6-11ee-8bb8-000c29151c55 | 2023-08-13 20:42:21 | 2023-08-13 20:42:21 |
+----+-----------+--------------------------------------+---------------------+---------------------+
2 rows in set (0.00 sec)

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000004 |     1258 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

接下来看154~1258之间的操作记录,用mysqlbinlog 读取。

[root@centos7 binlog]# mysqlbinlog --start-position=154 --stop-position=1258 testdb-binlog.000004 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 20:39:53 server id 3306  end_log_pos 123 CRC32 0x38b62d6f       Start: binlog v 4, server v 5.7.43-log created 230813 20:39:53
     6  # Warning: this binlog is either in use or was not closed properly.
     7  BINLOG '
     8  Gc/YZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     9  AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    10  AW8ttjg=
    11  '/*!*/;
    12  # at 154
    13  #230813 20:42:14 server id 3306  end_log_pos 219 CRC32 0x3b927b87       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    14  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    15  # at 219
    16  #230813 20:42:14 server id 3306  end_log_pos 596 CRC32 0x48ff9e90       Query   thread_id=3     exec_time=0     error_code=0
    17  use `testdb`/*!*/;
    18  SET TIMESTAMP=1691930534/*!*/;
    19  SET @@session.pseudo_thread_id=3/*!*/;
    20  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    21  SET @@session.sql_mode=1436549120/*!*/;
    22  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    23  /*!\C utf8 *//*!*/;
    24  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    25  SET @@session.lc_time_names=0/*!*/;
    26  SET @@session.collation_database=DEFAULT/*!*/;
    27  SET @@session.explicit_defaults_for_timestamp=1/*!*/;
    28  create table test_t1 (
    29  `id` int(11) primary key not null auto_increment,
    30  `rowformat` varchar(50) not null,
    31  `uuids` varchar(50) not null,
    32  `timepoint` datetime not null default current_timestamp,
    33  CurrentVersion timestamp not null default current_timestamp on update
    34  current_timestamp
    35  ) engine=innodb
    36  /*!*/;
    37  # at 596
    38  #230813 20:42:20 server id 3306  end_log_pos 661 CRC32 0x1c7489f5       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    39  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    40  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    41  # at 661
    42  #230813 20:42:20 server id 3306  end_log_pos 743 CRC32 0x1cce2d0c       Query   thread_id=3     exec_time=0     error_code=0
    43  SET TIMESTAMP=1691930540/*!*/;
    44  SET @@session.time_zone='SYSTEM'/*!*/;
    45  BEGIN
    46  /*!*/;
    47  # at 743
    48  #230813 20:42:20 server id 3306  end_log_pos 805 CRC32 0x140aa72f       Table_map: `testdb`.`test_t1` mapped to number 111
    49  # at 805
    50  #230813 20:42:20 server id 3306  end_log_pos 896 CRC32 0xdbeb9eaa       Write_rows: table id 111 flags: STMT_END_F
    51
    52  BINLOG '
    53  rM/YZBPqDAAAPgAAACUDAAAAAG8AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAFAw8PEhEGlgCWAAAA
    54  AC+nChQ=
    55  rM/YZB7qDAAAWwAAAIADAAAAAG8AAAAAAAEAAgAF/+ABAAAABHRlc3QkZDgxOGJmZGQtMzlkNi0x
    56  MWVlLThiYjgtMDAwYzI5MTUxYzU1mbDbSpRk2M+sqp7r2w==
    57  '/*!*/;
    58  # at 896
    59  #230813 20:42:20 server id 3306  end_log_pos 927 CRC32 0x34570eae       Xid = 85
    60  COMMIT/*!*/;
    61  # at 927
    62  #230813 20:42:21 server id 3306  end_log_pos 992 CRC32 0xfc5364e0       Anonymous_GTID  last_committed=2        sequence_number=3    rbr_only=yes
    63  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    64  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    65  # at 992
    66  #230813 20:42:21 server id 3306  end_log_pos 1074 CRC32 0x074ad55a      Query   thread_id=3     exec_time=0     error_code=0
    67  SET TIMESTAMP=1691930541/*!*/;
    68  BEGIN
    69  /*!*/;
    70  # at 1074
    71  #230813 20:42:21 server id 3306  end_log_pos 1136 CRC32 0x16b6ac5b      Table_map: `testdb`.`test_t1` mapped to number 111
    72  # at 1136
    73  #230813 20:42:21 server id 3306  end_log_pos 1227 CRC32 0x73f114f0      Write_rows: table id 111 flags: STMT_END_F
    74
    75  BINLOG '
    76  rc/YZBPqDAAAPgAAAHAEAAAAAG8AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAFAw8PEhEGlgCWAAAA
    77  AFusthY=
    78  rc/YZB7qDAAAWwAAAMsEAAAAAG8AAAAAAAEAAgAF/+ACAAAABHRlc3QkZDhjMDljZjEtMzlkNi0x
    79  MWVlLThiYjgtMDAwYzI5MTUxYzU1mbDbSpVk2M+t8BTxcw==
    80  '/*!*/;
    81  # at 1227
    82  #230813 20:42:21 server id 3306  end_log_pos 1258 CRC32 0xc7ebc97c      Xid = 86
    83  COMMIT/*!*/;
    84  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    85  DELIMITER ;
    86  # End of log file
    87  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    88  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 



#如上17行、28行,28行可以看出创建表的语句是明文的
#如上50行、73行  Write_rows表示插入数据,插入的数据是密文

update操作

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000004 |     1258 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)

mysql> update test_t1 set rowformat='1111111' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> delete from test_t1 where id=1;
Query OK, 1 row affected (0.00 sec)

mysql> drop table test_t1;
Query OK, 0 rows affected (0.02 sec)

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000004 |     2156 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)





[root@centos7 binlog]# mysqlbinlog --start-position=1258 --stop-position=2156 testdb-binlog.000004 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 20:39:53 server id 3306  end_log_pos 123 CRC32 0x38b62d6f       Start: binlog v 4, server v 5.7.43-log created 230813 20:39:53
     6  # Warning: this binlog is either in use or was not closed properly.
     7  BINLOG '
     8  Gc/YZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     9  AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    10  AW8ttjg=
    11  '/*!*/;
    12  # at 1258
    13  #230813 20:50:04 server id 3306  end_log_pos 1323 CRC32 0xf49fe531      Anonymous_GTID  last_committed=3        sequence_number=4    rbr_only=yes
    14  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    15  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    16  # at 1323
    17  #230813 20:50:04 server id 3306  end_log_pos 1397 CRC32 0x33cbd9f4      Query   thread_id=3     exec_time=0     error_code=0
    18  SET TIMESTAMP=1691931004/*!*/;
    19  SET @@session.pseudo_thread_id=3/*!*/;
    20  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    21  SET @@session.sql_mode=1436549120/*!*/;
    22  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    23  /*!\C utf8 *//*!*/;
    24  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    25  SET @@session.lc_time_names=0/*!*/;
    26  SET @@session.collation_database=DEFAULT/*!*/;
    27  BEGIN
    28  /*!*/;
    29  # at 1397
    30  #230813 20:50:04 server id 3306  end_log_pos 1459 CRC32 0x01e91b52      Table_map: `testdb`.`test_t1` mapped to number 111
    31  # at 1459
    32  #230813 20:50:04 server id 3306  end_log_pos 1610 CRC32 0x6d382dcc      Update_rows: table id 111 flags: STMT_END_F
    33
    34  BINLOG '
    35  fNHYZBPqDAAAPgAAALMFAAAAAG8AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAFAw8PEhEGlgCWAAAA
    36  AFIb6QE=
    37  fNHYZB/qDAAAlwAAAEoGAAAAAG8AAAAAAAEAAgAF///gAQAAAAR0ZXN0JGQ4MThiZmRkLTM5ZDYt
    38  MTFlZS04YmI4LTAwMGMyOTE1MWM1NZmw20qUZNjPrOABAAAABzExMTExMTEkZDgxOGJmZGQtMzlk
    39  Ni0xMWVlLThiYjgtMDAwYzI5MTUxYzU1mbDbSpRk2NF8zC04bQ==
    40  '/*!*/;
    41  # at 1610
    42  #230813 20:50:04 server id 3306  end_log_pos 1641 CRC32 0xc3c2435e      Xid = 90
    43  COMMIT/*!*/;
    44  # at 1641
    45  #230813 20:50:11 server id 3306  end_log_pos 1706 CRC32 0x41285694      Anonymous_GTID  last_committed=4        sequence_number=5    rbr_only=yes
    46  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    47  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    48  # at 1706
    49  #230813 20:50:11 server id 3306  end_log_pos 1780 CRC32 0x23a20b10      Query   thread_id=3     exec_time=0     error_code=0
    50  SET TIMESTAMP=1691931011/*!*/;
    51  BEGIN
    52  /*!*/;
    53  # at 1780
    54  #230813 20:50:11 server id 3306  end_log_pos 1842 CRC32 0x6430e979      Table_map: `testdb`.`test_t1` mapped to number 111
    55  # at 1842
    56  #230813 20:50:11 server id 3306  end_log_pos 1936 CRC32 0x6dbf6048      Delete_rows: table id 111 flags: STMT_END_F
    57
    58  BINLOG '
    59  g9HYZBPqDAAAPgAAADIHAAAAAG8AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAFAw8PEhEGlgCWAAAA
    60  AHnpMGQ=
    61  g9HYZCDqDAAAXgAAAJAHAAAAAG8AAAAAAAEAAgAF/+ABAAAABzExMTExMTEkZDgxOGJmZGQtMzlk
    62  Ni0xMWVlLThiYjgtMDAwYzI5MTUxYzU1mbDbSpRk2NF8SGC/bQ==
    63  '/*!*/;
    64  # at 1936
    65  #230813 20:50:11 server id 3306  end_log_pos 1967 CRC32 0x26a95f6d      Xid = 91
    66  COMMIT/*!*/;
    67  # at 1967
    68  #230813 20:50:16 server id 3306  end_log_pos 2032 CRC32 0x3bb38644      Anonymous_GTID  last_committed=5        sequence_number=6    rbr_only=no
    69  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    70  # at 2032
    71  #230813 20:50:16 server id 3306  end_log_pos 2156 CRC32 0xb299b69f      Query   thread_id=3     exec_time=0     error_code=0
    72  use `testdb`/*!*/;
    73  SET TIMESTAMP=1691931016/*!*/;
    74  DROP TABLE `test_t1` /* generated by server */
    75  /*!*/;
    76  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    77  DELIMITER ;
    78  # End of log file
    79  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    80  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 




#如上32行,update也是加密的
#56行,delete也是加密的
#74行,drop是明文的

针对加密的操作反解析加参数-v

mysqlbinlog --base64-output=decode-rows -v --start-position=1258 --stop-position=2156 testdb-binlog.000004 > 1.txt
[root@centos7 binlog]# mysqlbinlog --base64-output=decode-rows -v --start-position=1258 --stop-position=2156 testdb-binlog.000004 > 1.txt
[root@centos7 binlog]# 
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 1258
     5  #230813 20:50:04 server id 3306  end_log_pos 1323 CRC32 0xf49fe531      Anonymous_GTID  last_committed=3        sequence_number=4    rbr_only=yes
     6  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
     7  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
     8  # at 1323
     9  #230813 20:50:04 server id 3306  end_log_pos 1397 CRC32 0x33cbd9f4      Query   thread_id=3     exec_time=0     error_code=0
    10  SET TIMESTAMP=1691931004/*!*/;
    11  SET @@session.pseudo_thread_id=3/*!*/;
    12  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    13  SET @@session.sql_mode=1436549120/*!*/;
    14  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    15  /*!\C utf8 *//*!*/;
    16  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    17  SET @@session.lc_time_names=0/*!*/;
    18  SET @@session.collation_database=DEFAULT/*!*/;
    19  BEGIN
    20  /*!*/;
    21  # at 1397
    22  #230813 20:50:04 server id 3306  end_log_pos 1459 CRC32 0x01e91b52      Table_map: `testdb`.`test_t1` mapped to number 111
    23  # at 1459
    24  #230813 20:50:04 server id 3306  end_log_pos 1610 CRC32 0x6d382dcc      Update_rows: table id 111 flags: STMT_END_F
    25  ### UPDATE `testdb`.`test_t1`
    26  ### WHERE
    27  ###   @1=1
    28  ###   @2='test'
    29  ###   @3='d818bfdd-39d6-11ee-8bb8-000c29151c55'
    30  ###   @4='2023-08-13 20:42:20'
    31  ###   @5=1691930540
    32  ### SET
    33  ###   @1=1
    34  ###   @2='1111111'
    35  ###   @3='d818bfdd-39d6-11ee-8bb8-000c29151c55'
    36  ###   @4='2023-08-13 20:42:20'
    37  ###   @5=1691931004
    38  # at 1610
    39  #230813 20:50:04 server id 3306  end_log_pos 1641 CRC32 0xc3c2435e      Xid = 90
    40  COMMIT/*!*/;
    41  # at 1641
    42  #230813 20:50:11 server id 3306  end_log_pos 1706 CRC32 0x41285694      Anonymous_GTID  last_committed=4        sequence_number=5    rbr_only=yes
    43  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    44  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    45  # at 1706
    46  #230813 20:50:11 server id 3306  end_log_pos 1780 CRC32 0x23a20b10      Query   thread_id=3     exec_time=0     error_code=0
    47  SET TIMESTAMP=1691931011/*!*/;
    48  BEGIN
    49  /*!*/;
    50  # at 1780
    51  #230813 20:50:11 server id 3306  end_log_pos 1842 CRC32 0x6430e979      Table_map: `testdb`.`test_t1` mapped to number 111
    52  # at 1842
    53  #230813 20:50:11 server id 3306  end_log_pos 1936 CRC32 0x6dbf6048      Delete_rows: table id 111 flags: STMT_END_F
    54  ### DELETE FROM `testdb`.`test_t1`
    55  ### WHERE
    56  ###   @1=1
    57  ###   @2='1111111'
    58  ###   @3='d818bfdd-39d6-11ee-8bb8-000c29151c55'
    59  ###   @4='2023-08-13 20:42:20'
    60  ###   @5=1691931004
    61  # at 1936
    62  #230813 20:50:11 server id 3306  end_log_pos 1967 CRC32 0x26a95f6d      Xid = 91
    63  COMMIT/*!*/;
    64  # at 1967
    65  #230813 20:50:16 server id 3306  end_log_pos 2032 CRC32 0x3bb38644      Anonymous_GTID  last_committed=5        sequence_number=6    rbr_only=no
    66  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    67  # at 2032
    68  #230813 20:50:16 server id 3306  end_log_pos 2156 CRC32 0xb299b69f      Query   thread_id=3     exec_time=0     error_code=0
    69  use `testdb`/*!*/;
    70  SET TIMESTAMP=1691931016/*!*/;
    71  DROP TABLE `test_t1` /* generated by server */
    72  /*!*/;
    73  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    74  DELIMITER ;
    75  # End of log file
    76  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    77  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 


#如上25~31行是更新前的值
#33行-37行是更新后的值

#54~60行,是delete的记录

总结:

binlog_format=‘row’,其它参数默认,ddl操作是明文的,而dml操作是加密的吗,但是只记录行的操作,不记录SQL语句。

mysql> show binlog events in 'testdb-binlog.000004';

image-20230813210029419

对主从复制的影响:

  1. 同步最安全

  2. 不管是更新还是删除,或者批量录数据,都是按行进行,依次处理所有行的记录,而不是整条SQL

1.5.2.2 binlog_rows_query_log_events=on
#修改行格式
set session binlog_rows_query_log_events=1;
set global binlog_rows_query_log_events=1;
select @@global.binlog_rows_query_log_events,@@binlog_rows_query_log_events;

mysql> select @@global.binlog_rows_query_log_events,@@binlog_rows_query_log_events;
+---------------------------------------+--------------------------------+
| @@global.binlog_rows_query_log_events | @@binlog_rows_query_log_events |
+---------------------------------------+--------------------------------+
|                                     1 |                              1 |
+---------------------------------------+--------------------------------+
1 row in set (0.00 sec)

mysql> flush logs;
Query OK, 0 rows affected (0.00 sec)

mysql> show master status; 
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000005 |      154 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

模拟DDL 与DML 操作

create table test_t (
`id` int(11) primary key not null auto_increment,
`rowformat` varchar(50) not null,
`uuids` varchar(50) not null,
`timepoint` datetime not null default current_timestamp,
CurrentVersion timestamp not null default current_timestamp on update
current_timestamp
) engine=innodb;
insert into test_t(rowformat,uuids) select 'test',uuid();
insert into test_t(rowformat,uuids) select 'test',uuid();
select * from test_t;
update test_t set rowformat='test_update' where id=1;
delete from test_t where id=1;
drop table test_t;

mysql> show master status; 
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000005 |     2447 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

查看154~2447

mysqlbinlog --base64-output=decode-rows -v -v --start-position=154 --stop-position=2447 testdb-binlog.000005

[root@centos7 binlog]# mysqlbinlog --base64-output=decode-rows -v -v --start-position=154 --stop-position=2447 testdb-binlog.000005 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 154
     5  #230813 21:06:41 server id 3306  end_log_pos 219 CRC32 0x055c5b56       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
     6  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
     7  # at 219
     8  #230813 21:06:41 server id 3306  end_log_pos 595 CRC32 0xbe79b944       Query   thread_id=3     exec_time=0     error_code=0
     9  use `testdb`/*!*/;
    10  SET TIMESTAMP=1691932001/*!*/;
    11  SET @@session.pseudo_thread_id=3/*!*/;
    12  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    13  SET @@session.sql_mode=1436549120/*!*/;
    14  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    15  /*!\C utf8 *//*!*/;
    16  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    17  SET @@session.lc_time_names=0/*!*/;
    18  SET @@session.collation_database=DEFAULT/*!*/;
    19  SET @@session.explicit_defaults_for_timestamp=1/*!*/;
    20  create table test_t (
    21  `id` int(11) primary key not null auto_increment,
    22  `rowformat` varchar(50) not null,
    23  `uuids` varchar(50) not null,
    24  `timepoint` datetime not null default current_timestamp,
    25  CurrentVersion timestamp not null default current_timestamp on update
    26  current_timestamp
    27  ) engine=innodb
    28  /*!*/;
    29  # at 595
    30  #230813 21:06:46 server id 3306  end_log_pos 660 CRC32 0x160a5f00       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    31  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    32  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    33  # at 660
    34  #230813 21:06:46 server id 3306  end_log_pos 742 CRC32 0xc875902d       Query   thread_id=3     exec_time=0     error_code=0
    35  SET TIMESTAMP=1691932006/*!*/;
    36  SET @@session.time_zone='SYSTEM'/*!*/;
    37  BEGIN
    38  /*!*/;
    39  # at 742
    40  #230813 21:06:46 server id 3306  end_log_pos 822 CRC32 0x4824b43a       Rows_query
    41  # insert into test_t(rowformat,uuids) select 'test',uuid()
    42  # at 822
    43  #230813 21:06:46 server id 3306  end_log_pos 883 CRC32 0x8d5bc9a4       Table_map: `testdb`.`test_t` mapped to number 112
    44  # at 883
    45  #230813 21:06:46 server id 3306  end_log_pos 974 CRC32 0xfc87e974       Write_rows: table id 112 flags: STMT_END_F
    46  ### INSERT INTO `testdb`.`test_t`
    47  ### SET
    48  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    49  ###   @2='test' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    50  ###   @3='41cc8806-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    51  ###   @4='2023-08-13 21:06:46' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
    52  ###   @5=1691932006 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
    53  # at 974
    54  #230813 21:06:46 server id 3306  end_log_pos 1005 CRC32 0xfd2a0b05      Xid = 102
    55  COMMIT/*!*/;
    56  # at 1005
    57  #230813 21:06:47 server id 3306  end_log_pos 1070 CRC32 0x005e6701      Anonymous_GTID  last_committed=2        sequence_number=3    rbr_only=yes
    58  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    59  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    60  # at 1070
    61  #230813 21:06:47 server id 3306  end_log_pos 1152 CRC32 0x8734898d      Query   thread_id=3     exec_time=0     error_code=0
    62  SET TIMESTAMP=1691932007/*!*/;
    63  BEGIN
    64  /*!*/;
    65  # at 1152
    66  #230813 21:06:47 server id 3306  end_log_pos 1232 CRC32 0x2a55a475      Rows_query
    67  # insert into test_t(rowformat,uuids) select 'test',uuid()
    68  # at 1232
    69  #230813 21:06:47 server id 3306  end_log_pos 1293 CRC32 0xaac8d3ec      Table_map: `testdb`.`test_t` mapped to number 112
    70  # at 1293
    71  #230813 21:06:47 server id 3306  end_log_pos 1384 CRC32 0xe8430487      Write_rows: table id 112 flags: STMT_END_F
    72  ### INSERT INTO `testdb`.`test_t`
    73  ### SET
    74  ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
    75  ###   @2='test' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    76  ###   @3='42462284-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    77  ###   @4='2023-08-13 21:06:47' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
    78  ###   @5=1691932007 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
    79  # at 1384
    80  #230813 21:06:47 server id 3306  end_log_pos 1415 CRC32 0xa1039ab5      Xid = 103
    81  COMMIT/*!*/;
    82  # at 1415
    83  #230813 21:06:56 server id 3306  end_log_pos 1480 CRC32 0x35523673      Anonymous_GTID  last_committed=3        sequence_number=4    rbr_only=yes
    84  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    85  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    86  # at 1480
    87  #230813 21:06:56 server id 3306  end_log_pos 1554 CRC32 0x9b25c7f2      Query   thread_id=3     exec_time=0     error_code=0
    88  SET TIMESTAMP=1691932016/*!*/;
    89  BEGIN
    90  /*!*/;
    91  # at 1554
    92  #230813 21:06:56 server id 3306  end_log_pos 1630 CRC32 0xea07258b      Rows_query
    93  # update test_t set rowformat='test_update' where id=1
    94  # at 1630
    95  #230813 21:06:56 server id 3306  end_log_pos 1691 CRC32 0x84a5b22e      Table_map: `testdb`.`test_t` mapped to number 112
    96  # at 1691
    97  #230813 21:06:56 server id 3306  end_log_pos 1846 CRC32 0x8405f560      Update_rows: table id 112 flags: STMT_END_F
    98  ### UPDATE `testdb`.`test_t`
    99  ### WHERE
   100  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
   101  ###   @2='test' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   102  ###   @3='41cc8806-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   103  ###   @4='2023-08-13 21:06:46' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
   104  ###   @5=1691932006 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
   105  ### SET
   106  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
   107  ###   @2='test_update' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   108  ###   @3='41cc8806-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   109  ###   @4='2023-08-13 21:06:46' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
   110  ###   @5=1691932016 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
   111  # at 1846
   112  #230813 21:06:56 server id 3306  end_log_pos 1877 CRC32 0x1d6230cd      Xid = 105
   113  COMMIT/*!*/;
   114  # at 1877
   115  #230813 21:07:03 server id 3306  end_log_pos 1942 CRC32 0xc6c4f5cc      Anonymous_GTID  last_committed=4        sequence_number=5    rbr_only=yes
   116  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
   117  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
   118  # at 1942
   119  #230813 21:07:03 server id 3306  end_log_pos 2016 CRC32 0x6fb13330      Query   thread_id=3     exec_time=0     error_code=0
   120  SET TIMESTAMP=1691932023/*!*/;
   121  BEGIN
   122  /*!*/;
   123  # at 2016
   124  #230813 21:07:03 server id 3306  end_log_pos 2069 CRC32 0x0158585c      Rows_query
   125  # delete from test_t where id=1
   126  # at 2069
   127  #230813 21:07:03 server id 3306  end_log_pos 2130 CRC32 0x376dba32      Table_map: `testdb`.`test_t` mapped to number 112
   128  # at 2130
   129  #230813 21:07:03 server id 3306  end_log_pos 2228 CRC32 0xcf02a748      Delete_rows: table id 112 flags: STMT_END_F
   130  ### DELETE FROM `testdb`.`test_t`
   131  ### WHERE
   132  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
   133  ###   @2='test_update' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   134  ###   @3='41cc8806-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   135  ###   @4='2023-08-13 21:06:46' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
   136  ###   @5=1691932016 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
   137  # at 2228
   138  #230813 21:07:03 server id 3306  end_log_pos 2259 CRC32 0x1df900c9      Xid = 106
   139  COMMIT/*!*/;
   140  # at 2259
   141  #230813 21:07:07 server id 3306  end_log_pos 2324 CRC32 0xc0fc0508      Anonymous_GTID  last_committed=5        sequence_number=6    rbr_only=no
   142  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
   143  # at 2324
   144  #230813 21:07:07 server id 3306  end_log_pos 2447 CRC32 0xb84eedef      Query   thread_id=3     exec_time=0     error_code=0
   145  SET TIMESTAMP=1691932027/*!*/;
   146  DROP TABLE `test_t` /* generated by server */
   147  /*!*/;
   148  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
   149  DELIMITER ;
   150  # End of log file
   151  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
   152  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 




#如上46~52行  可以看出insert更详细的信息
这就是binlog_rows_query_log_events=on开启下能看到更详细的信息。
mysql> show binlog events in 'testdb-binlog.000005';

image-20230813211707279

总结:

binlog_rows_query_log_events=on,这个参数为on 的时候,不但可以记录行的操作,而且记录这条SQL 语句。

1.5.2.3 binlog_row_image=full,minimal,noblob

1. binlog_row_image=full

set session binlog_row_image=full;
set global binlog_row_image=full;
select @@global.binlog_row_image,@@binlog_row_image;

mysql> select @@global.binlog_row_image,@@binlog_row_image;
+---------------------------+--------------------+
| @@global.binlog_row_image | @@binlog_row_image |
+---------------------------+--------------------+
| FULL                      | FULL               |
+---------------------------+--------------------+
1 row in set (0.00 sec)



[root@centos7 binlog]# mysqlbinlog --base64-output=decode-rows -v -v --start-position=154 --stop-position=2447 testdb-binlog.000005 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 154
     5  #230813 21:06:41 server id 3306  end_log_pos 219 CRC32 0x055c5b56       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
     6  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
     7  # at 219
     8  #230813 21:06:41 server id 3306  end_log_pos 595 CRC32 0xbe79b944       Query   thread_id=3     exec_time=0     error_code=0
     9  use `testdb`/*!*/;
    10  SET TIMESTAMP=1691932001/*!*/;
    11  SET @@session.pseudo_thread_id=3/*!*/;
    12  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    13  SET @@session.sql_mode=1436549120/*!*/;
    14  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    15  /*!\C utf8 *//*!*/;
    16  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    17  SET @@session.lc_time_names=0/*!*/;
    18  SET @@session.collation_database=DEFAULT/*!*/;
    19  SET @@session.explicit_defaults_for_timestamp=1/*!*/;
    20  create table test_t (
    21  `id` int(11) primary key not null auto_increment,
    22  `rowformat` varchar(50) not null,
    23  `uuids` varchar(50) not null,
    24  `timepoint` datetime not null default current_timestamp,
    25  CurrentVersion timestamp not null default current_timestamp on update
    26  current_timestamp
    27  ) engine=innodb
    28  /*!*/;
    29  # at 595
    30  #230813 21:06:46 server id 3306  end_log_pos 660 CRC32 0x160a5f00       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    31  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    32  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    33  # at 660
    34  #230813 21:06:46 server id 3306  end_log_pos 742 CRC32 0xc875902d       Query   thread_id=3     exec_time=0     error_code=0
    35  SET TIMESTAMP=1691932006/*!*/;
    36  SET @@session.time_zone='SYSTEM'/*!*/;
    37  BEGIN
    38  /*!*/;
    39  # at 742
    40  #230813 21:06:46 server id 3306  end_log_pos 822 CRC32 0x4824b43a       Rows_query
    41  # insert into test_t(rowformat,uuids) select 'test',uuid()
    42  # at 822
    43  #230813 21:06:46 server id 3306  end_log_pos 883 CRC32 0x8d5bc9a4       Table_map: `testdb`.`test_t` mapped to number 112
    44  # at 883
    45  #230813 21:06:46 server id 3306  end_log_pos 974 CRC32 0xfc87e974       Write_rows: table id 112 flags: STMT_END_F
    46  ### INSERT INTO `testdb`.`test_t`
    47  ### SET
    48  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    49  ###   @2='test' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    50  ###   @3='41cc8806-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    51  ###   @4='2023-08-13 21:06:46' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
    52  ###   @5=1691932006 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
    53  # at 974
    54  #230813 21:06:46 server id 3306  end_log_pos 1005 CRC32 0xfd2a0b05      Xid = 102
    55  COMMIT/*!*/;
    56  # at 1005
    57  #230813 21:06:47 server id 3306  end_log_pos 1070 CRC32 0x005e6701      Anonymous_GTID  last_committed=2        sequence_number=3    rbr_only=yes
    58  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    59  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    60  # at 1070
    61  #230813 21:06:47 server id 3306  end_log_pos 1152 CRC32 0x8734898d      Query   thread_id=3     exec_time=0     error_code=0
    62  SET TIMESTAMP=1691932007/*!*/;
    63  BEGIN
    64  /*!*/;
    65  # at 1152
    66  #230813 21:06:47 server id 3306  end_log_pos 1232 CRC32 0x2a55a475      Rows_query
    67  # insert into test_t(rowformat,uuids) select 'test',uuid()
    68  # at 1232
    69  #230813 21:06:47 server id 3306  end_log_pos 1293 CRC32 0xaac8d3ec      Table_map: `testdb`.`test_t` mapped to number 112
    70  # at 1293
    71  #230813 21:06:47 server id 3306  end_log_pos 1384 CRC32 0xe8430487      Write_rows: table id 112 flags: STMT_END_F
    72  ### INSERT INTO `testdb`.`test_t`
    73  ### SET
    74  ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
    75  ###   @2='test' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    76  ###   @3='42462284-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    77  ###   @4='2023-08-13 21:06:47' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
    78  ###   @5=1691932007 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
    79  # at 1384
    80  #230813 21:06:47 server id 3306  end_log_pos 1415 CRC32 0xa1039ab5      Xid = 103
    81  COMMIT/*!*/;
    82  # at 1415
    83  #230813 21:06:56 server id 3306  end_log_pos 1480 CRC32 0x35523673      Anonymous_GTID  last_committed=3        sequence_number=4    rbr_only=yes
    84  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    85  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    86  # at 1480
    87  #230813 21:06:56 server id 3306  end_log_pos 1554 CRC32 0x9b25c7f2      Query   thread_id=3     exec_time=0     error_code=0
    88  SET TIMESTAMP=1691932016/*!*/;
    89  BEGIN
    90  /*!*/;
    91  # at 1554
    92  #230813 21:06:56 server id 3306  end_log_pos 1630 CRC32 0xea07258b      Rows_query
    93  # update test_t set rowformat='test_update' where id=1
    94  # at 1630
    95  #230813 21:06:56 server id 3306  end_log_pos 1691 CRC32 0x84a5b22e      Table_map: `testdb`.`test_t` mapped to number 112
    96  # at 1691
    97  #230813 21:06:56 server id 3306  end_log_pos 1846 CRC32 0x8405f560      Update_rows: table id 112 flags: STMT_END_F
    98  ### UPDATE `testdb`.`test_t`
    99  ### WHERE
   100  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
   101  ###   @2='test' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   102  ###   @3='41cc8806-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   103  ###   @4='2023-08-13 21:06:46' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
   104  ###   @5=1691932006 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
   105  ### SET
   106  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
   107  ###   @2='test_update' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   108  ###   @3='41cc8806-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   109  ###   @4='2023-08-13 21:06:46' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
   110  ###   @5=1691932016 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
   111  # at 1846
   112  #230813 21:06:56 server id 3306  end_log_pos 1877 CRC32 0x1d6230cd      Xid = 105
   113  COMMIT/*!*/;
   114  # at 1877
   115  #230813 21:07:03 server id 3306  end_log_pos 1942 CRC32 0xc6c4f5cc      Anonymous_GTID  last_committed=4        sequence_number=5    rbr_only=yes
   116  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
   117  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
   118  # at 1942
   119  #230813 21:07:03 server id 3306  end_log_pos 2016 CRC32 0x6fb13330      Query   thread_id=3     exec_time=0     error_code=0
   120  SET TIMESTAMP=1691932023/*!*/;
   121  BEGIN
   122  /*!*/;
   123  # at 2016
   124  #230813 21:07:03 server id 3306  end_log_pos 2069 CRC32 0x0158585c      Rows_query
   125  # delete from test_t where id=1
   126  # at 2069
   127  #230813 21:07:03 server id 3306  end_log_pos 2130 CRC32 0x376dba32      Table_map: `testdb`.`test_t` mapped to number 112
   128  # at 2130
   129  #230813 21:07:03 server id 3306  end_log_pos 2228 CRC32 0xcf02a748      Delete_rows: table id 112 flags: STMT_END_F
   130  ### DELETE FROM `testdb`.`test_t`
   131  ### WHERE
   132  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
   133  ###   @2='test_update' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   134  ###   @3='41cc8806-39da-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
   135  ###   @4='2023-08-13 21:06:46' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
   136  ###   @5=1691932016 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
   137  # at 2228
   138  #230813 21:07:03 server id 3306  end_log_pos 2259 CRC32 0x1df900c9      Xid = 106
   139  COMMIT/*!*/;
   140  # at 2259
   141  #230813 21:07:07 server id 3306  end_log_pos 2324 CRC32 0xc0fc0508      Anonymous_GTID  last_committed=5        sequence_number=6    rbr_only=no
   142  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
   143  # at 2324
   144  #230813 21:07:07 server id 3306  end_log_pos 2447 CRC32 0xb84eedef      Query   thread_id=3     exec_time=0     error_code=0
   145  SET TIMESTAMP=1691932027/*!*/;
   146  DROP TABLE `test_t` /* generated by server */
   147  /*!*/;
   148  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
   149  DELIMITER ;
   150  # End of log file
   151  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
   152  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 

如上46行~52行

binlog_row_image=full会详细记录值的内容(insert记录新值的详细内容,update记录旧值和新值的详细内容,delete)

2. binlog_row_image=minimal

set session binlog_row_image=minimal;
set global binlog_row_image=minimal;
select @@global.binlog_row_image,@@binlog_row_image;

mysql> select @@global.binlog_row_image,@@binlog_row_image;
+---------------------------+--------------------+
| @@global.binlog_row_image | @@binlog_row_image |
+---------------------------+--------------------+
| MINIMAL                   | MINIMAL            |
+---------------------------+--------------------+
1 row in set (0.00 sec)

flush logs;

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000006 |      154 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

测试

create table test_t (
`id` int(11) primary key not null auto_increment,
`rowformat` varchar(50) not null,
`uuids` varchar(50) not null,
`timepoint` datetime not null default current_timestamp,
CurrentVersion timestamp not null default current_timestamp on update
current_timestamp
) engine=innodb;
insert into test_t(rowformat,uuids) select 'test',uuid();
select * from test_t;
update test_t set rowformat='test_update' where id=1;
delete from test_t where id=1;
show master status;

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000006 |     1694 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

查看日志信息

mysqlbinlog --base64-output=decode-rows -v -v --start-position=154 --stop-position=1694 testdb-binlog.000006


[root@centos7 binlog]# mysqlbinlog --base64-output=decode-rows -v -v --start-position=154 --stop-position=1694 testdb-binlog.000006 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 154
     5  #230813 21:28:25 server id 3306  end_log_pos 219 CRC32 0x15443c8b       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
     6  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
     7  # at 219
     8  #230813 21:28:25 server id 3306  end_log_pos 595 CRC32 0xa4d48a1f       Query   thread_id=3     exec_time=0     error_code=0
     9  use `testdb`/*!*/;
    10  SET TIMESTAMP=1691933305/*!*/;
    11  SET @@session.pseudo_thread_id=3/*!*/;
    12  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    13  SET @@session.sql_mode=1436549120/*!*/;
    14  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    15  /*!\C utf8 *//*!*/;
    16  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    17  SET @@session.lc_time_names=0/*!*/;
    18  SET @@session.collation_database=DEFAULT/*!*/;
    19  SET @@session.explicit_defaults_for_timestamp=1/*!*/;
    20  create table test_t (
    21  `id` int(11) primary key not null auto_increment,
    22  `rowformat` varchar(50) not null,
    23  `uuids` varchar(50) not null,
    24  `timepoint` datetime not null default current_timestamp,
    25  CurrentVersion timestamp not null default current_timestamp on update
    26  current_timestamp
    27  ) engine=innodb
    28  /*!*/;
    29  # at 595
    30  #230813 21:28:30 server id 3306  end_log_pos 660 CRC32 0x061238dd       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    31  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    32  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    33  # at 660
    34  #230813 21:28:30 server id 3306  end_log_pos 742 CRC32 0x03b11e08       Query   thread_id=3     exec_time=0     error_code=0
    35  SET TIMESTAMP=1691933310/*!*/;
    36  SET @@session.time_zone='SYSTEM'/*!*/;
    37  BEGIN
    38  /*!*/;
    39  # at 742
    40  #230813 21:28:30 server id 3306  end_log_pos 822 CRC32 0x7f386f1d       Rows_query
    41  # insert into test_t(rowformat,uuids) select 'test',uuid()
    42  # at 822
    43  #230813 21:28:30 server id 3306  end_log_pos 883 CRC32 0x281a62fa       Table_map: `testdb`.`test_t` mapped to number 113
    44  # at 883
    45  #230813 21:28:30 server id 3306  end_log_pos 974 CRC32 0x85d713b3       Write_rows: table id 113 flags: STMT_END_F
    46  ### INSERT INTO `testdb`.`test_t`
    47  ### SET
    48  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    49  ###   @2='test' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    50  ###   @3='4ac94ef1-39dd-11ee-8bb8-000c29151c55' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    51  ###   @4='2023-08-13 21:28:30' /* DATETIME(0) meta=0 nullable=0 is_null=0 */
    52  ###   @5=1691933310 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
    53  # at 974
    54  #230813 21:28:30 server id 3306  end_log_pos 1005 CRC32 0x85070359      Xid = 120
    55  COMMIT/*!*/;
    56  # at 1005
    57  #230813 21:28:40 server id 3306  end_log_pos 1070 CRC32 0x9314d909      Anonymous_GTID  last_committed=2        sequence_number=3    rbr_only=yes
    58  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    59  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    60  # at 1070
    61  #230813 21:28:40 server id 3306  end_log_pos 1144 CRC32 0xabef0383      Query   thread_id=3     exec_time=0     error_code=0
    62  SET TIMESTAMP=1691933320/*!*/;
    63  BEGIN
    64  /*!*/;
    65  # at 1144
    66  #230813 21:28:40 server id 3306  end_log_pos 1220 CRC32 0x67bb9e1d      Rows_query
    67  # update test_t set rowformat='test_update' where id=1
    68  # at 1220
    69  #230813 21:28:40 server id 3306  end_log_pos 1281 CRC32 0xeb5a8fda      Table_map: `testdb`.`test_t` mapped to number 113
    70  # at 1281
    71  #230813 21:28:40 server id 3306  end_log_pos 1339 CRC32 0x69c1b046      Update_rows: table id 113 flags: STMT_END_F
    72  ### UPDATE `testdb`.`test_t`
    73  ### WHERE
    74  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    75  ### SET
    76  ###   @2='test_update' /* VARSTRING(150) meta=150 nullable=0 is_null=0 */
    77  ###   @5=1691933320 /* TIMESTAMP(0) meta=0 nullable=0 is_null=0 */
    78  # at 1339
    79  #230813 21:28:40 server id 3306  end_log_pos 1370 CRC32 0x48fe8129      Xid = 122
    80  COMMIT/*!*/;
    81  # at 1370
    82  #230813 21:28:46 server id 3306  end_log_pos 1435 CRC32 0x2d69f8df      Anonymous_GTID  last_committed=3        sequence_number=4    rbr_only=yes
    83  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    84  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    85  # at 1435
    86  #230813 21:28:46 server id 3306  end_log_pos 1509 CRC32 0xb7a6a571      Query   thread_id=3     exec_time=0     error_code=0
    87  SET TIMESTAMP=1691933326/*!*/;
    88  BEGIN
    89  /*!*/;
    90  # at 1509
    91  #230813 21:28:46 server id 3306  end_log_pos 1562 CRC32 0xe08b5a4a      Rows_query
    92  # delete from test_t where id=1
    93  # at 1562
    94  #230813 21:28:46 server id 3306  end_log_pos 1623 CRC32 0xc8d05b2e      Table_map: `testdb`.`test_t` mapped to number 113
    95  # at 1623
    96  #230813 21:28:46 server id 3306  end_log_pos 1663 CRC32 0x727fefb1      Delete_rows: table id 113 flags: STMT_END_F
    97  ### DELETE FROM `testdb`.`test_t`
    98  ### WHERE
    99  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
   100  # at 1663
   101  #230813 21:28:46 server id 3306  end_log_pos 1694 CRC32 0x5ea127b6      Xid = 123
   102  COMMIT/*!*/;
   103  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
   104  DELIMITER ;
   105  # End of log file
   106  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
   107  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 


#如上45行~52行  insert这里没啥变化
#如上72行~77行  update的信息变少了,只记录了变化的信息,没有变化前的信息了
#如上97~99行,  delete的信息也变少了

3. binlog_row_image=noblob

set session binlog_row_image=noblob;
set global binlog_row_image=noblob;
select @@global.binlog_row_image,@@binlog_row_image;

不记录blog字段的信息,待测试!!!

总结:

  • binlog_row_image=full,insert/update语句的set部分是全部的新纪录,delete/update的where部分是全部的旧记录
  • binlog_row_image=minimal,则update语句只有修改的列内容,delete及update的where部分都没有(如果是主键或唯一索引会有)
  • binlog_row_image=noblog,待测试!!!

不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table的时候会让日志暴涨。日志中会记录成每一行数据修改的形式,然后在slave端再对相同的数据进行修改。

  • **优点:**在row level的模式下,binlog中可以不记录执行的sql语句的上下文信息,仅仅只需要记录哪一条记录被修改,修改成什么样。所以row level的日志内容会非常清楚的记录每一行数据修改的细节,非常容易理解。而且不会出现某些特定情况下的存储过程,或fuction,以及trigger的调用或触发无法被正确复制的问题。
  • 缺点:row level模式下,所有的执行语句都会记录到日志中,同时都会以每行记录修改的来记录,这样可能会产生大量的日志内容

1.5.3 binlog_format=mixed

理解了statement和row模式以后,mixed=statement和row

以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式,也是在statement和row之间选择一种。

新版本中的mysql中对row level模式也做了优化,并不是所有的修改都会以row level来记录,像遇到表结构变更的时候就会以statement模式来记录,如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。

大多数情况下是以statement记录binlog,当隔离级别是读提交的时候,则为row的方式记录。

#修改回参数

#修改行格式
set session binlog_format='row';
set global binlog_format='row';
set session binlog_rows_query_log_events=1;
set global binlog_rows_query_log_events=1;
set session binlog_row_image=full;
set global binlog_row_image=full;
select
@@global.binlog_format,@@binlog_format,@@global.binlog_rows_query_log_events,@@binlog_rows_query_log_events,
@@global.binlog_row_image,@@binlog_row_image;

mysql> select
    -> @@global.binlog_format,@@binlog_format,@@global.binlog_rows_query_log_events,@@binlog_rows_query_log_events,
    -> @@global.binlog_row_image,@@binlog_row_image\G
*************************** 1. row ***************************
               @@global.binlog_format: ROW
                      @@binlog_format: ROW
@@global.binlog_rows_query_log_events: 1
       @@binlog_rows_query_log_events: 1
            @@global.binlog_row_image: FULL
                   @@binlog_row_image: FULL
1 row in set (0.00 sec)


#修改隔离级别为读已提交
set session transaction_isolation='read-committed';
set global transaction_isolation='read-committed';
select @@global.transaction_isolation,@@transaction_isolation;

mysql> select @@global.transaction_isolation,@@transaction_isolation;
+--------------------------------+-------------------------+
| @@global.transaction_isolation | @@transaction_isolation |
+--------------------------------+-------------------------+
| READ-COMMITTED                 | READ-COMMITTED          |
+--------------------------------+-------------------------+
1 row in set (0.00 sec)

不建议随便去修改binlog 格式(数据库级别,非要修改建议修改session级别)(修改后可能应用程序不兼容就会出现很多乱码、高IO、主从复制延迟高等问题)

1.5.4 binlog日志的清理的方法

#日志过期天数
mysql> show variables like 'expire_logs_days';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| expire_logs_days | 90    |			#90天到期后,90天之前的日志会被自动删除
+------------------+-------+
1 row in set (0.00 sec)

#清除过期日志,从库没有同步的一定不能清除
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000006 |     1694 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#手动清理日志
purge binary logs to 'xxx';
show binary logs;

mysql> show binary logs;
+----------------------+-----------+
| Log_name             | File_size |
+----------------------+-----------+
| testdb-binlog.000001 |       205 |
| testdb-binlog.000002 |       205 |
| testdb-binlog.000003 |      1646 |
| testdb-binlog.000004 |      2207 |
| testdb-binlog.000005 |      2498 |
| testdb-binlog.000006 |      1694 |
+----------------------+-----------+
6 rows in set (0.00 sec)

[root@centos7 binlog]# ll -h
total 28K
-rw-r----- 1 mysql mysql  205 Aug 13 18:13 testdb-binlog.000001
-rw-r----- 1 mysql mysql  205 Aug 13 20:15 testdb-binlog.000002
-rw-r----- 1 mysql mysql 1.7K Aug 13 20:39 testdb-binlog.000003
-rw-r----- 1 mysql mysql 2.2K Aug 13 21:04 testdb-binlog.000004
-rw-r----- 1 mysql mysql 2.5K Aug 13 21:26 testdb-binlog.000005
-rw-r----- 1 mysql mysql 1.7K Aug 13 21:28 testdb-binlog.000006
-rw-r----- 1 mysql mysql  264 Aug 13 21:26 testdb-binlog.index
[root@centos7 binlog]# cat testdb-binlog.index
/mysql/log/3306/binlog/testdb-binlog.000001
/mysql/log/3306/binlog/testdb-binlog.000002
/mysql/log/3306/binlog/testdb-binlog.000003
/mysql/log/3306/binlog/testdb-binlog.000004
/mysql/log/3306/binlog/testdb-binlog.000005
/mysql/log/3306/binlog/testdb-binlog.000006
[root@centos7 binlog]# 

mysql> purge binary logs to 'testdb-binlog.000005';
Query OK, 0 rows affected (0.00 sec)

mysql> show binary logs;
+----------------------+-----------+
| Log_name             | File_size |
+----------------------+-----------+
| testdb-binlog.000005 |      2498 |
| testdb-binlog.000006 |      1694 |
+----------------------+-----------+
2 rows in set (0.00 sec)

[root@centos7 binlog]# ll -h
total 12K
-rw-r----- 1 mysql mysql 2.5K Aug 13 21:26 testdb-binlog.000005
-rw-r----- 1 mysql mysql 1.7K Aug 13 21:28 testdb-binlog.000006
-rw-r----- 1 mysql mysql   88 Aug 13 21:46 testdb-binlog.index
[root@centos7 binlog]# cat testdb-binlog.index
/mysql/log/3306/binlog/testdb-binlog.000005
/mysql/log/3306/binlog/testdb-binlog.000006
[root@centos7 binlog]# 


#全部清理二进制日志
mysql> reset master;
Query OK, 0 rows affected (0.00 sec)

mysql> show binary logs;
+----------------------+-----------+
| Log_name             | File_size |
+----------------------+-----------+
| testdb-binlog.000001 |       154 |
+----------------------+-----------+
1 row in set (0.00 sec)

[root@centos7 binlog]# ll -h
total 8.0K
-rw-r----- 1 mysql mysql 154 Aug 13 21:47 testdb-binlog.000001
-rw-r----- 1 mysql mysql  44 Aug 13 21:47 testdb-binlog.index
[root@centos7 binlog]# cat testdb-binlog.index 
/mysql/log/3306/binlog/testdb-binlog.000001
[root@centos7 binlog]# 

参考资料

https://blog.csdn.net/weixin_33989058/article/details/92452951

1.6 MySQL binlog 查看工具及使用案例

1.6.1 show binlog

show binlog events;

1. in ‘日志文件’,指定要查询的binlog 文件名,不指定就默认看第一个。

mysql> show binlog events in 'testdb-binlog.000001';
+----------------------+-----+----------------+-----------+-------------+---------------------------------------+
| Log_name             | Pos | Event_type     | Server_id | End_log_pos | Info                                  |
+----------------------+-----+----------------+-----------+-------------+---------------------------------------+
| testdb-binlog.000001 |   4 | Format_desc    |      3306 |         123 | Server ver: 5.7.43-log, Binlog ver: 4 |
| testdb-binlog.000001 | 123 | Previous_gtids |      3306 |         154 |                                       |
+----------------------+-----+----------------+-----------+-------------+---------------------------------------+
2 rows in set (0.00 sec)

Pos表示日志的起始点,也就是从什么地方开始的
Event_type 表示日志类型
End_log_pos 表示日志的终点



#ddl和dml操作
mysql> create table test(id int);
Query OK, 0 rows affected (0.02 sec)

mysql> insert into test values (1);
Query OK, 1 row affected (0.00 sec)

mysql> delete from test;
Query OK, 1 row affected (0.01 sec)

mysql> drop table test;
Query OK, 0 rows affected (0.01 sec)

image-20230813215505968

如上pos 154是一个标识,标志下一个事务,219322是建表的事务,387632是insert的事务,697~931是delete的事务,如果需要回退操作可以关注对于的pos段

2. from pos,指定从哪个pos 起始点开始查起。

mysql> show binlog events in 'testdb-binlog.000001' from 697;
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
| Log_name             | Pos | Event_type     | Server_id | End_log_pos | Info                                                      |
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
| testdb-binlog.000001 | 697 | Query          |      3306 |         771 | BEGIN                                                     |
| testdb-binlog.000001 | 771 | Rows_query     |      3306 |         811 | # delete from test                                        |
| testdb-binlog.000001 | 811 | Table_map      |      3306 |         860 | table_id: 114 (testdb.test)                               |
| testdb-binlog.000001 | 860 | Delete_rows    |      3306 |         900 | table_id: 114 flags: STMT_END_F                           |
| testdb-binlog.000001 | 900 | Xid            |      3306 |         931 | COMMIT /* xid=152 */                                      |
| testdb-binlog.000001 | 931 | Anonymous_Gtid |      3306 |         996 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                      |
| testdb-binlog.000001 | 996 | Query          |      3306 |        1117 | use `testdb`; DROP TABLE `test` /* generated by server */ |
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------------------------+
7 rows in set (0.00 sec)

3. limit row_count,查询总条数

mysql> show binlog events in 'testdb-binlog.000001' limit 5;
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| Log_name             | Pos | Event_type     | Server_id | End_log_pos | Info                                    |
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| testdb-binlog.000001 |   4 | Format_desc    |      3306 |         123 | Server ver: 5.7.43-log, Binlog ver: 4   |
| testdb-binlog.000001 | 123 | Previous_gtids |      3306 |         154 |                                         |
| testdb-binlog.000001 | 154 | Anonymous_Gtid |      3306 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
| testdb-binlog.000001 | 219 | Query          |      3306 |         322 | use `testdb`; create table test(id int) |
| testdb-binlog.000001 | 322 | Anonymous_Gtid |      3306 |         387 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------+
5 rows in set (0.00 sec)

mysql> show binlog events in 'testdb-binlog.000001' from 219 limit 2;
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| Log_name             | Pos | Event_type     | Server_id | End_log_pos | Info                                    |
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------+
| testdb-binlog.000001 | 219 | Query          |      3306 |         322 | use `testdb`; create table test(id int) |
| testdb-binlog.000001 | 322 | Anonymous_Gtid |      3306 |         387 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'    |
+----------------------+-----+----------------+-----------+-------------+-----------------------------------------+
2 rows in set (0.00 sec)

4. limit offset,偏移量,从某一个位置开始,查多少条

#从第5行偏移一行
mysql> show binlog events in 'testdb-binlog.000001' limit 5,1;
+----------------------+-----+------------+-----------+-------------+-------+
| Log_name             | Pos | Event_type | Server_id | End_log_pos | Info  |
+----------------------+-----+------------+-----------+-------------+-------+
| testdb-binlog.000001 | 387 | Query      |      3306 |         461 | BEGIN |
+----------------------+-----+------------+-----------+-------------+-------+
1 row in set (0.00 sec)


#从219开始查3行后偏移显示紧接着的2行
mysql> show binlog events in 'testdb-binlog.000001' from 219 limit 3,2;
+----------------------+-----+------------+-----------+-------------+-------------------------------+
| Log_name             | Pos | Event_type | Server_id | End_log_pos | Info                          |
+----------------------+-----+------------+-----------+-------------+-------------------------------+
| testdb-binlog.000001 | 461 | Rows_query |      3306 |         512 | # insert into test values (1) |
| testdb-binlog.000001 | 512 | Table_map  |      3306 |         561 | table_id: 114 (testdb.test)   |
+----------------------+-----+------------+-----------+-------------+-------------------------------+
2 rows in set (0.00 sec)

1.6.2 mysqlbinlog

恢复的时候、用于闪回、可以读取日志内容。

帮助信息
[root@centos7 ~]# mysqlbinlog --help
mysqlbinlog Ver 3.4 for linux-glibc2.12 at x86_64
Copyright (c) 2000, 2023, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Dumps a MySQL binary log in a format usable for viewing or for piping to
the mysql command line client.

Usage: mysqlbinlog [options] log-files
  -?, --help          Display this help and exit.
  --base64-output=name 				#编码格式
                      Determine when the output statements should be
                      base64-encoded BINLOG statements: 'never' disables it and
                      works only for binlogs without row-based events;
                      'decode-rows' decodes row events into commented
                      pseudo-SQL statements if the --verbose option is also
                      given; 'auto' prints base64 only when necessary (i.e.,
                      for row-based events and format description events).  If
                      no --base64-output[=name] option is given at all, the
                      default is 'auto'.
  --bind-address=name IP address to bind to.		#IP地址
  --character-sets-dir=name 						#字符集
                      Directory for character set files.
  -d, --database=name List entries for just this database (local log only).		#数据库名
  --rewrite-db=name   Rewrite the row event to point so that it can be applied
                      to a new database
  -#, --debug[=#]     This is a non-debug version. Catch this and exit.
  --debug-check       This is a non-debug version. Catch this and exit.
  --debug-info        This is a non-debug version. Catch this and exit.
  --default-auth=name Default authentication client-side plugin to use.
  -D, --disable-log-bin 		#禁止恢复过程中产生日志
                      Disable binary log. This is useful, if you enabled
                      --to-last-log and are sending the output to the same
                      MySQL server. This way you could avoid an endless loop.
                      You would also like to use it when restoring after a
                      crash to avoid duplication of the statements you already
                      have. NOTE: you will need a SUPER privilege to use this
                      option.
  -F, --force-if-open Force if binlog was not closed properly.
                      (Defaults to on; use --skip-force-if-open to disable.)
  -f, --force-read    Force reading unknown binlog events.
  -H, --hexdump       Augment output with hexadecimal and ASCII event dump.
  -h, --host=name     Get the binlog from server.
  -i, --idempotent    Notify the server to use idempotent mode before applying
                      Row Events
  -l, --local-load=name 
                      Prepare local temporary files for LOAD DATA INFILE in the
                      specified directory.
  -o, --offset=#      Skip the first N entries.
  -p, --password[=name] 
                      Password to connect to remote server.
  --plugin-dir=name   Directory for client-side plugins.
  -P, --port=#        Port number to use for connection or 0 for default to, in
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
                      /etc/services, built-in default (3306).
  --protocol=name     The protocol to use for connection (tcp, socket, pipe,
                      memory).
  -R, --read-from-remote-server 
                      Read binary logs from a MySQL server. This is an alias
                      for read-from-remote-master=BINLOG-DUMP-NON-GTIDS.
  --read-from-remote-master=name 
                      Read binary logs from a MySQL server through the
                      COM_BINLOG_DUMP or COM_BINLOG_DUMP_GTID commands by
                      setting the option to either BINLOG-DUMP-NON-GTIDS or
                      BINLOG-DUMP-GTIDS, respectively. If
                      --read-from-remote-master=BINLOG-DUMP-GTIDS is combined
                      with --exclude-gtids, transactions can be filtered out on
                      the master avoiding unnecessary network traffic.
  --raw               Requires -R. Output raw binlog data instead of SQL
                      statements, output is to log files.
  -r, --result-file=name 
                      Direct output to a given file. With --raw this is a
                      prefix for the file names.
  --secure-auth       Refuse client connecting to server if it uses old
                      (pre-4.1.1) protocol. Deprecated. Always TRUE
  --server-id=#       Extract only binlog entries created by the server having
                      the given id.
  --server-id-bits=#  Set number of significant bits in server-id
  --set-charset=name  Add 'SET NAMES character_set' to the output.
  -s, --short-form    Just show regular queries: no extra info and no row-based
                      events. This is for testing only, and should not be used
                      in production systems. If you want to suppress
                      base64-output, consider using --base64-output=never
                      instead.
  -S, --socket=name   The socket file to use for connection.
  --ssl-mode=name     SSL connection mode.
  --ssl               Deprecated. Use --ssl-mode instead.
                      (Defaults to on; use --skip-ssl to disable.)
  --ssl-verify-server-cert 
                      Deprecated. Use --ssl-mode=VERIFY_IDENTITY instead.
  --ssl-ca=name       CA file in PEM format.
  --ssl-capath=name   CA directory.
  --ssl-cert=name     X509 cert in PEM format.
  --ssl-cipher=name   SSL cipher to use.
  --ssl-key=name      X509 key in PEM format.
  --ssl-crl=name      Certificate revocation list.
  --ssl-crlpath=name  Certificate revocation list path.
  #ssl相关的加密信息
  --tls-version=name  TLS version to use, permitted values are: TLSv1, TLSv1.1,
                      TLSv1.2
  --server-public-key-path=name 
                      File path to the server public RSA key in PEM format.
  --get-server-public-key 
                      Get server public key
  --start-datetime=name 			#从什么时间点开始读取日志的
                      Start reading the binlog at first event having a datetime
                      equal or posterior to the argument; the argument must be
                      a date and time in the local time zone, in any format
                      accepted by the MySQL server for DATETIME and TIMESTAMP
                      types, for example: 2004-12-25 11:25:56 (you should
                      probably use quotes for your shell to set it properly).
  -j, --start-position=# 			#开始的位置
                      Start reading the binlog at position N. Applies to the
                      first binlog passed on the command line.
  --stop-datetime=name 				#什么时间点结束的
                      Stop reading the binlog at first event having a datetime
                      equal or posterior to the argument; the argument must be
                      a date and time in the local time zone, in any format
                      accepted by the MySQL server for DATETIME and TIMESTAMP
                      types, for example: 2004-12-25 11:25:56 (you should
                      probably use quotes for your shell to set it properly).
  --stop-never        Wait for more data from the server instead of stopping at
                      the end of the last log. Implicitly sets --to-last-log
                      but instead of stopping at the end of the last log it
                      continues to wait till the server disconnects.
  --stop-never-slave-server-id=# 
                      The slave server_id used for --read-from-remote-server
                      --stop-never. This option cannot be used together with
                      connection-server-id.
  --connection-server-id=# 
                      The slave server_id used for --read-from-remote-server.
                      This option cannot be used together with
                      stop-never-slave-server-id.
  --stop-position=#   Stop reading the binlog at position N. Applies to the last binlog passed on the command line.
  #结束的位置
  -t, --to-last-log   Requires -R. Will not stop at the end of the requested
                      binlog but rather continue printing until the end of the
                      last binlog of the MySQL server. If you send the output
                      to the same MySQL server, that may lead to an endless
                      loop.
  -u, --user=name     Connect to the remote server as username.		#远程访问需要输入用户名
  -v, --verbose       Reconstruct pseudo-SQL statements out of row events. -v
                      -v adds comments on column data types.
  -V, --version       Print version and exit.
  --open-files-limit=# 
                      Used to reserve file descriptors for use by this program.
  -c, --verify-binlog-checksum 
                      Verify checksum binlog events.
  --binlog-row-event-max-size=# 
                      The maximum size of a row-based binary log event in
                      bytes. Rows will be grouped into events smaller than this
                      size if possible. This value must be a multiple of 256.
  --skip-gtids        Do not preserve Global Transaction Identifiers; instead
                      make the server execute the transactions as if they were
                      new.
  --include-gtids=name 
                      Print events whose Global Transaction Identifiers were
                      provided.
  --exclude-gtids=name 
                      Print all events but those whose Global Transaction
                      Identifiers were provided.

Variables (--variable-name=value)
and boolean options {FALSE|TRUE}  Value (after reading options)
--------------------------------- ----------------------------------------
base64-output                     (No default value)
bind-address                      (No default value)
character-sets-dir                (No default value)
database                          (No default value)
rewrite-db                        (No default value)
default-auth                      (No default value)
disable-log-bin                   FALSE
force-if-open                     TRUE
force-read                        FALSE
hexdump                           FALSE
host                              (No default value)
idempotent                        FALSE
local-load                        (No default value)
offset                            0
plugin-dir                        (No default value)
port                              0
read-from-remote-server           FALSE
read-from-remote-master           (No default value)
raw                               FALSE
result-file                       (No default value)
secure-auth                       TRUE
server-id                         0
server-id-bits                    32
set-charset                       (No default value)
short-form                        FALSE
socket                            (No default value)
ssl                               TRUE
ssl-verify-server-cert            FALSE
ssl-ca                            (No default value)
ssl-capath                        (No default value)
ssl-cert                          (No default value)
ssl-cipher                        (No default value)
ssl-key                           (No default value)
ssl-crl                           (No default value)
ssl-crlpath                       (No default value)
tls-version                       (No default value)
server-public-key-path            (No default value)
get-server-public-key             FALSE
start-datetime                    (No default value)
start-position                    4
stop-datetime                     (No default value)
stop-never                        FALSE
stop-never-slave-server-id        -1
connection-server-id              -1
stop-position                     18446744073709551615
to-last-log                       FALSE
user                              (No default value)
open-files-limit                  64
verify-binlog-checksum            FALSE
binlog-row-event-max-size         4294967040
skip-gtids                        FALSE
include-gtids                     (No default value)
exclude-gtids                     (No default value)
[root@centos7 ~]# 
默认查看日志
reset master;
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000001 |      154 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

use testdb
create table test_t (id int);
insert into test_t values(1);

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000001 |      638 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


#默认查看日志
[root@centos7 binlog]# mysqlbinlog testdb-binlog.000001 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 22:31:30 server id 3306  end_log_pos 123 CRC32 0x68ee453e       Start: binlog v 4, server v 5.7.43-log created 230813 22:31:30 at startup
     6  # Warning: this binlog is either in use or was not closed properly.
     7  ROLLBACK/*!*/;
     8  BINLOG '
     9  QunYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    10  AAAAAAAAAAAAAAAAAABC6dhkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    11  AT5F7mg=
    12  '/*!*/;
    13  # at 123
    14  #230813 22:31:30 server id 3306  end_log_pos 154 CRC32 0xcd2300de       Previous-GTIDs
    15  # [empty]
    16  # at 154
    17  #230813 22:33:22 server id 3306  end_log_pos 219 CRC32 0x43fb0e59       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    18  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    19  # at 219
    20  #230813 22:33:22 server id 3306  end_log_pos 325 CRC32 0x3f787d12       Query   thread_id=3     exec_time=0     error_code=0
    21  use `testdb`/*!*/;
    22  SET TIMESTAMP=1691937202/*!*/;
    23  SET @@session.pseudo_thread_id=3/*!*/;
    24  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    25  SET @@session.sql_mode=1436549120/*!*/;
    26  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    27  /*!\C utf8 *//*!*/;
    28  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    29  SET @@session.lc_time_names=0/*!*/;
    30  SET @@session.collation_database=DEFAULT/*!*/;
    31  create table test_t (id int)
    32  /*!*/;
    33  # at 325
    34  #230813 22:33:25 server id 3306  end_log_pos 390 CRC32 0xfdb90f5a       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    35  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    36  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    37  # at 390
    38  #230813 22:33:25 server id 3306  end_log_pos 464 CRC32 0x868ba03f       Query   thread_id=3     exec_time=0     error_code=0
    39  SET TIMESTAMP=1691937205/*!*/;
    40  BEGIN
    41  /*!*/;
    42  # at 464
    43  # at 516
    44  #230813 22:33:25 server id 3306  end_log_pos 567 CRC32 0xeeeacf88       Table_map: `testdb`.`test_t` mapped to number 115
    45  # at 567
    46  #230813 22:33:25 server id 3306  end_log_pos 607 CRC32 0x194fb475       Write_rows: table id 115 flags: STMT_END_F
    47
    48  BINLOG '
    49  tenYZBPqDAAAMwAAADcCAAAAAHMAAAAAAAEABnRlc3RkYgAGdGVzdF90AAEDAAGIz+ru
    50  tenYZB7qDAAAKAAAAF8CAAAAAHMAAAAAAAEAAgAB//4BAAAAdbRPGQ==
    51  '/*!*/;
    52  # at 607
    53  #230813 22:33:25 server id 3306  end_log_pos 638 CRC32 0x5d7f5c93       Xid = 168
    54  COMMIT/*!*/;
    55  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    56  DELIMITER ;
    57  # End of log file
    58  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    59  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 

#如上46~50行加密的insert 信息

输出二进制格式

[root@centos7 binlog]# mysqlbinlog -H testdb-binlog.000001 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 22:31:30 server id 3306  end_log_pos 123 CRC32 0x68ee453e 
     6  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
     7  #        4 42 e9 d8 64   0f   ea 0c 00 00   77 00 00 00   7b 00 00 00   01 00
     8  #       17 04 00 35 2e 37 2e 34 33  2d 6c 6f 67 00 00 00 00 |..5.7.43.log....|
     9  #       27 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 |................|
    10  #       37 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 |................|
    11  #       47 00 00 00 00 42 e9 d8 64  13 38 0d 00 08 00 12 00 |....B..d.8......|
    12  #       57 04 04 04 04 12 00 00 5f  00 04 1a 08 00 00 00 08 |................|
    13  #       67 08 08 02 00 00 00 0a 0a  0a 2a 2a 00 12 34 00 01 |.............4..|
    14  #       77 3e 45 ee 68                                      |.E.h|
    15  #       Start: binlog v 4, server v 5.7.43-log created 230813 22:31:30 at startup
    16  # Warning: this binlog is either in use or was not closed properly.
    17  ROLLBACK/*!*/;
    18  BINLOG '
    19  QunYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    20  AAAAAAAAAAAAAAAAAABC6dhkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    21  AT5F7mg=
    22  '/*!*/;
    23  # at 123
    24  #230813 22:31:30 server id 3306  end_log_pos 154 CRC32 0xcd2300de 
    25  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
    26  #       7b 42 e9 d8 64   23   ea 0c 00 00   1f 00 00 00   9a 00 00 00   80 00
    27  #       8e 00 00 00 00 00 00 00 00  de 00 23 cd             |............|
    28  #       Previous-GTIDs
    29  # [empty]
    30  # at 154
    31  #230813 22:33:22 server id 3306  end_log_pos 219 CRC32 0x43fb0e59 
    32  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
    33  #       9a b2 e9 d8 64   22   ea 0c 00 00   41 00 00 00   db 00 00 00   00 00
    34  #       ad 01 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 |................|
    35  #       bd 00 00 00 00 00 00 00 00  00 02 00 00 00 00 00 00 |................|
    36  #       cd 00 00 01 00 00 00 00 00  00 00 59 0e fb 43       |..........Y..C|
    37  #       Anonymous_GTID  last_committed=0        sequence_number=1       rbr_only=no
    38  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    39  # at 219
    40  #230813 22:33:22 server id 3306  end_log_pos 325 CRC32 0x3f787d12 
    41  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
    42  #       db b2 e9 d8 64   02   ea 0c 00 00   6a 00 00 00   45 01 00 00   00 00
    43  #       ee 03 00 00 00 00 00 00 00  06 00 00 23 00 00 00 00 |................|
    44  #       fe 00 00 01 00 00 a0 55 00  00 00 00 06 03 73 74 64 |......U......std|
    45  #      10e 04 21 00 21 00 21 00 0c  01 74 65 73 74 64 62 00 |.........testdb.|
    46  #      11e 74 65 73 74 64 62 00 63  72 65 61 74 65 20 74 61 |testdb.create.ta|
    47  #      12e 62 6c 65 20 74 65 73 74  5f 74 20 28 69 64 20 69 |ble.test.t..id.i|
    48  #      13e 6e 74 29 12 7d 78 3f                             |nt...x.|
    49  #       Query   thread_id=3     exec_time=0     error_code=0
    50  use `testdb`/*!*/;
    51  SET TIMESTAMP=1691937202/*!*/;
    52  SET @@session.pseudo_thread_id=3/*!*/;
    53  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    54  SET @@session.sql_mode=1436549120/*!*/;
    55  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    56  /*!\C utf8 *//*!*/;
    57  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    58  SET @@session.lc_time_names=0/*!*/;
    59  SET @@session.collation_database=DEFAULT/*!*/;
    60  create table test_t (id int)
    61  /*!*/;
    62  # at 325
    63  #230813 22:33:25 server id 3306  end_log_pos 390 CRC32 0xfdb90f5a 
    64  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
    65  #      145 b5 e9 d8 64   22   ea 0c 00 00   41 00 00 00   86 01 00 00   00 00
    66  #      158 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00 |................|
    67  #      168 00 00 00 00 00 00 00 00  00 02 01 00 00 00 00 00 |................|
    68  #      178 00 00 02 00 00 00 00 00  00 00 5a 0f b9 fd       |..........Z...|
    69  #       Anonymous_GTID  last_committed=1        sequence_number=2       rbr_only=yes
    70  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    71  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    72  # at 390
    73  #230813 22:33:25 server id 3306  end_log_pos 464 CRC32 0x868ba03f 
    74  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
    75  #      186 b5 e9 d8 64   02   ea 0c 00 00   4a 00 00 00   d0 01 00 00   08 00
    76  #      199 03 00 00 00 00 00 00 00  06 00 00 1a 00 00 00 00 |................|
    77  #      1a9 00 00 01 00 00 a0 55 00  00 00 00 06 03 73 74 64 |......U......std|
    78  #      1b9 04 21 00 21 00 21 00 74  65 73 74 64 62 00 42 45 |.......testdb.BE|
    79  #      1c9 47 49 4e 3f a0 8b 86                             |GIN....|
    80  #       Query   thread_id=3     exec_time=0     error_code=0
    81  SET TIMESTAMP=1691937205/*!*/;
    82  BEGIN
    83  /*!*/;
    84  # at 464
    85  # at 516
    86  #230813 22:33:25 server id 3306  end_log_pos 567 CRC32 0xeeeacf88 
    87  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
    88  #      204 b5 e9 d8 64   13   ea 0c 00 00   33 00 00 00   37 02 00 00   00 00
    89  #      217 73 00 00 00 00 00 01 00  06 74 65 73 74 64 62 00 |s........testdb.|
    90  #      227 06 74 65 73 74 5f 74 00  01 03 00 01 88 cf ea ee |.test.t.........|
    91  #       Table_map: `testdb`.`test_t` mapped to number 115
    92  # at 567
    93  #230813 22:33:25 server id 3306  end_log_pos 607 CRC32 0x194fb475 
    94  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
    95  #      237 b5 e9 d8 64   1e   ea 0c 00 00   28 00 00 00   5f 02 00 00   00 00
    96  #      24a 73 00 00 00 00 00 01 00  02 00 01 ff fe 01 00 00 |s...............|
    97  #      25a 00 75 b4 4f 19                                   |.u.O.|
    98  #       Write_rows: table id 115 flags: STMT_END_F
    99
   100  BINLOG '
   101  tenYZBPqDAAAMwAAADcCAAAAAHMAAAAAAAEABnRlc3RkYgAGdGVzdF90AAEDAAGIz+ru
   102  tenYZB7qDAAAKAAAAF8CAAAAAHMAAAAAAAEAAgAB//4BAAAAdbRPGQ==
   103  '/*!*/;
   104  # at 607
   105  #230813 22:33:25 server id 3306  end_log_pos 638 CRC32 0x5d7f5c93 
   106  # Position  Timestamp   Type   Master ID        Size      Master Pos    Flags 
   107  #      25f b5 e9 d8 64   10   ea 0c 00 00   1f 00 00 00   7e 02 00 00   00 00
   108  #      272 a8 00 00 00 00 00 00 00  93 5c 7f 5d             |............|
   109  #       Xid = 168
   110  COMMIT/*!*/;
   111  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
   112  DELIMITER ;
   113  # End of log file
   114  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
   115  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 
指定数据库
mysqlbinlog -d testdb testdb-binlog.000001
mysqlbinlog --database testdb testdb-binlog.000001


[root@centos7 binlog]# mysqlbinlog -d testdb testdb-binlog.000001 > 1.txt
WARNING: The option --database has been used. It may filter parts of transactions, but will include the GTIDs in any case. If you want to exclude or include transactions, you should use the options --exclude-gtids or --include-gtids, respectively, instead.
[root@centos7 binlog]# 
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 22:31:30 server id 3306  end_log_pos 123 CRC32 0x68ee453e       Start: binlog v 4, server v 5.7.43-log created 230813 22:31:30 at startup
     6  # Warning: this binlog is either in use or was not closed properly.
     7  ROLLBACK/*!*/;
     8  BINLOG '
     9  QunYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    10  AAAAAAAAAAAAAAAAAABC6dhkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    11  AT5F7mg=
    12  '/*!*/;
    13  # at 123
    14  #230813 22:31:30 server id 3306  end_log_pos 154 CRC32 0xcd2300de       Previous-GTIDs
    15  # [empty]
    16  # at 154
    17  #230813 22:33:22 server id 3306  end_log_pos 219 CRC32 0x43fb0e59       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    18  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    19  # at 219
    20  #230813 22:33:22 server id 3306  end_log_pos 325 CRC32 0x3f787d12       Query   thread_id=3     exec_time=0     error_code=0
    21  use `testdb`/*!*/;
    22  SET TIMESTAMP=1691937202/*!*/;
    23  SET @@session.pseudo_thread_id=3/*!*/;
    24  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    25  SET @@session.sql_mode=1436549120/*!*/;
    26  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    27  /*!\C utf8 *//*!*/;
    28  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    29  SET @@session.lc_time_names=0/*!*/;
    30  SET @@session.collation_database=DEFAULT/*!*/;
    31  create table test_t (id int)
    32  /*!*/;
    33  # at 325
    34  #230813 22:33:25 server id 3306  end_log_pos 390 CRC32 0xfdb90f5a       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    35  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    36  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    37  # at 390
    38  #230813 22:33:25 server id 3306  end_log_pos 464 CRC32 0x868ba03f       Query   thread_id=3     exec_time=0     error_code=0
    39  SET TIMESTAMP=1691937205/*!*/;
    40  BEGIN
    41  /*!*/;
    42  # at 464
    43  # at 516
    44  #230813 22:33:25 server id 3306  end_log_pos 567 CRC32 0xeeeacf88       Table_map: `testdb`.`test_t` mapped to number 115
    45  # at 567
    46  #230813 22:33:25 server id 3306  end_log_pos 607 CRC32 0x194fb475       Write_rows: table id 115 flags: STMT_END_F
    47
    48  BINLOG '
    49  tenYZBPqDAAAMwAAADcCAAAAAHMAAAAAAAEABnRlc3RkYgAGdGVzdF90AAEDAAGIz+ru
    50  tenYZB7qDAAAKAAAAF8CAAAAAHMAAAAAAAEAAgAB//4BAAAAdbRPGQ==
    51  '/*!*/;
    52  # at 607
    53  #230813 22:33:25 server id 3306  end_log_pos 638 CRC32 0x5d7f5c93       Xid = 168
    54  COMMIT/*!*/;
    55  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    56  DELIMITER ;
    57  # End of log file
    58  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    59  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 
禁止恢复过程中产生日志
mysqlbinlog -D testdb-binlog.000001 > 1.txt
mysqlbinlog --disable-log-bin testdb-binlog.000001 > 1.txt


[root@centos7 binlog]# mysqlbinlog -D testdb-binlog.000001 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!32316 SET @OLD_SQL_LOG_BIN=@@SQL_LOG_BIN, SQL_LOG_BIN=0*/;
     3  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     4  DELIMITER /*!*/;
     5  # at 4
     6  #230813 22:31:30 server id 3306  end_log_pos 123 CRC32 0x68ee453e       Start: binlog v 4, server v 5.7.43-log created 230813 22:31:30 at startup
     7  # Warning: this binlog is either in use or was not closed properly.
     8  ROLLBACK/*!*/;
     9  BINLOG '
    10  QunYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    11  AAAAAAAAAAAAAAAAAABC6dhkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    12  AT5F7mg=
    13  '/*!*/;
    14  # at 123
    15  #230813 22:31:30 server id 3306  end_log_pos 154 CRC32 0xcd2300de       Previous-GTIDs
    16  # [empty]
    17  # at 154
    18  #230813 22:33:22 server id 3306  end_log_pos 219 CRC32 0x43fb0e59       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    19  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    20  # at 219
    21  #230813 22:33:22 server id 3306  end_log_pos 325 CRC32 0x3f787d12       Query   thread_id=3     exec_time=0     error_code=0
    22  use `testdb`/*!*/;
    23  SET TIMESTAMP=1691937202/*!*/;
    24  SET @@session.pseudo_thread_id=3/*!*/;
    25  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    26  SET @@session.sql_mode=1436549120/*!*/;
    27  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    28  /*!\C utf8 *//*!*/;
    29  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    30  SET @@session.lc_time_names=0/*!*/;
    31  SET @@session.collation_database=DEFAULT/*!*/;
    32  create table test_t (id int)
    33  /*!*/;
    34  # at 325
    35  #230813 22:33:25 server id 3306  end_log_pos 390 CRC32 0xfdb90f5a       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    36  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    37  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    38  # at 390
    39  #230813 22:33:25 server id 3306  end_log_pos 464 CRC32 0x868ba03f       Query   thread_id=3     exec_time=0     error_code=0
    40  SET TIMESTAMP=1691937205/*!*/;
    41  BEGIN
    42  /*!*/;
    43  # at 464
    44  # at 516
    45  #230813 22:33:25 server id 3306  end_log_pos 567 CRC32 0xeeeacf88       Table_map: `testdb`.`test_t` mapped to number 115
    46  # at 567
    47  #230813 22:33:25 server id 3306  end_log_pos 607 CRC32 0x194fb475       Write_rows: table id 115 flags: STMT_END_F
    48
    49  BINLOG '
    50  tenYZBPqDAAAMwAAADcCAAAAAHMAAAAAAAEABnRlc3RkYgAGdGVzdF90AAEDAAGIz+ru
    51  tenYZB7qDAAAKAAAAF8CAAAAAHMAAAAAAAEAAgAB//4BAAAAdbRPGQ==
    52  '/*!*/;
    53  # at 607
    54  #230813 22:33:25 server id 3306  end_log_pos 638 CRC32 0x5d7f5c93       Xid = 168
    55  COMMIT/*!*/;
    56  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    57  DELIMITER ;
    58  # End of log file
    59  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    60  /*!32316 SET SQL_LOG_BIN=@OLD_SQL_LOG_BIN*/;
    61  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 



#到最后一个文件
mysqlbinlog -to-last-log testdb-binlog.000001 > 1.txt
在输出时控制内容的编码显示格式
--base64-output:auto,never,decode-rows,unspec
-v (-verbose)
-vv




[root@centos7 binlog]# mysqlbinlog --base64-output=auto testdb-binlog.000001 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 22:31:30 server id 3306  end_log_pos 123 CRC32 0x68ee453e       Start: binlog v 4, server v 5.7.43-log created 230813 22:31:30 at startup
     6  # Warning: this binlog is either in use or was not closed properly.
     7  ROLLBACK/*!*/;
     8  BINLOG '
     9  QunYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    10  AAAAAAAAAAAAAAAAAABC6dhkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    11  AT5F7mg=
    12  '/*!*/;
    13  # at 123
    14  #230813 22:31:30 server id 3306  end_log_pos 154 CRC32 0xcd2300de       Previous-GTIDs
    15  # [empty]
    16  # at 154
    17  #230813 22:33:22 server id 3306  end_log_pos 219 CRC32 0x43fb0e59       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    18  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    19  # at 219
    20  #230813 22:33:22 server id 3306  end_log_pos 325 CRC32 0x3f787d12       Query   thread_id=3     exec_time=0     error_code=0
    21  use `testdb`/*!*/;
    22  SET TIMESTAMP=1691937202/*!*/;
    23  SET @@session.pseudo_thread_id=3/*!*/;
    24  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    25  SET @@session.sql_mode=1436549120/*!*/;
    26  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    27  /*!\C utf8 *//*!*/;
    28  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    29  SET @@session.lc_time_names=0/*!*/;
    30  SET @@session.collation_database=DEFAULT/*!*/;
    31  create table test_t (id int)
    32  /*!*/;
    33  # at 325
    34  #230813 22:33:25 server id 3306  end_log_pos 390 CRC32 0xfdb90f5a       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    35  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    36  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    37  # at 390
    38  #230813 22:33:25 server id 3306  end_log_pos 464 CRC32 0x868ba03f       Query   thread_id=3     exec_time=0     error_code=0
    39  SET TIMESTAMP=1691937205/*!*/;
    40  BEGIN
    41  /*!*/;
    42  # at 464
    43  # at 516
    44  #230813 22:33:25 server id 3306  end_log_pos 567 CRC32 0xeeeacf88       Table_map: `testdb`.`test_t` mapped to number 115
    45  # at 567
    46  #230813 22:33:25 server id 3306  end_log_pos 607 CRC32 0x194fb475       Write_rows: table id 115 flags: STMT_END_F
    47
    48  BINLOG '
    49  tenYZBPqDAAAMwAAADcCAAAAAHMAAAAAAAEABnRlc3RkYgAGdGVzdF90AAEDAAGIz+ru
    50  tenYZB7qDAAAKAAAAF8CAAAAAHMAAAAAAAEAAgAB//4BAAAAdbRPGQ==
    51  '/*!*/;
    52  # at 607
    53  #230813 22:33:25 server id 3306  end_log_pos 638 CRC32 0x5d7f5c93       Xid = 168
    54  COMMIT/*!*/;
    55  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    56  DELIMITER ;
    57  # End of log file
    58  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    59  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 
#如上46~50行可以看出--base64-output=auto的时候,dml的sql语句是加密的




mysqlbinlog --base64-output=decode-rows -v testdb-binlog.000001> 1.txt
[root@centos7 binlog]# mysqlbinlog --base64-output=decode-rows -v testdb-binlog.000001> 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 22:31:30 server id 3306  end_log_pos 123 CRC32 0x68ee453e       Start: binlog v 4, server v 5.7.43-log created 230813 22:31:30 at startup
     6  # Warning: this binlog is either in use or was not closed properly.
     7  ROLLBACK/*!*/;
     8  # at 123
     9  #230813 22:31:30 server id 3306  end_log_pos 154 CRC32 0xcd2300de       Previous-GTIDs
    10  # [empty]
    11  # at 154
    12  #230813 22:33:22 server id 3306  end_log_pos 219 CRC32 0x43fb0e59       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    13  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    14  # at 219
    15  #230813 22:33:22 server id 3306  end_log_pos 325 CRC32 0x3f787d12       Query   thread_id=3     exec_time=0     error_code=0
    16  use `testdb`/*!*/;
    17  SET TIMESTAMP=1691937202/*!*/;
    18  SET @@session.pseudo_thread_id=3/*!*/;
    19  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    20  SET @@session.sql_mode=1436549120/*!*/;
    21  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    22  /*!\C utf8 *//*!*/;
    23  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    24  SET @@session.lc_time_names=0/*!*/;
    25  SET @@session.collation_database=DEFAULT/*!*/;
    26  create table test_t (id int)
    27  /*!*/;
    28  # at 325
    29  #230813 22:33:25 server id 3306  end_log_pos 390 CRC32 0xfdb90f5a       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    30  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    31  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    32  # at 390
    33  #230813 22:33:25 server id 3306  end_log_pos 464 CRC32 0x868ba03f       Query   thread_id=3     exec_time=0     error_code=0
    34  SET TIMESTAMP=1691937205/*!*/;
    35  BEGIN
    36  /*!*/;
    37  # at 464
    38  # at 516
    39  #230813 22:33:25 server id 3306  end_log_pos 567 CRC32 0xeeeacf88       Table_map: `testdb`.`test_t` mapped to number 115
    40  # at 567
    41  #230813 22:33:25 server id 3306  end_log_pos 607 CRC32 0x194fb475       Write_rows: table id 115 flags: STMT_END_F
    42  ### INSERT INTO `testdb`.`test_t`
    43  ### SET
    44  ###   @1=1
    45  # at 607
    46  #230813 22:33:25 server id 3306  end_log_pos 638 CRC32 0x5d7f5c93       Xid = 168
    47  COMMIT/*!*/;
    48  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    49  DELIMITER ;
    50  # End of log file
    51  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    52  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 

#如上41~44行 --base64-output=decode-rows同时加一个v,信息稍微详细一点




mysqlbinlog --base64-output=decode-rows -v -v testdb-binlog.000001> 1.txt
[root@centos7 binlog]# mysqlbinlog --base64-output=decode-rows -v -v testdb-binlog.000001> 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 22:31:30 server id 3306  end_log_pos 123 CRC32 0x68ee453e       Start: binlog v 4, server v 5.7.43-log created 230813 22:31:30 at startup
     6  # Warning: this binlog is either in use or was not closed properly.
     7  ROLLBACK/*!*/;
     8  # at 123
     9  #230813 22:31:30 server id 3306  end_log_pos 154 CRC32 0xcd2300de       Previous-GTIDs
    10  # [empty]
    11  # at 154
    12  #230813 22:33:22 server id 3306  end_log_pos 219 CRC32 0x43fb0e59       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    13  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    14  # at 219
    15  #230813 22:33:22 server id 3306  end_log_pos 325 CRC32 0x3f787d12       Query   thread_id=3     exec_time=0     error_code=0
    16  use `testdb`/*!*/;
    17  SET TIMESTAMP=1691937202/*!*/;
    18  SET @@session.pseudo_thread_id=3/*!*/;
    19  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    20  SET @@session.sql_mode=1436549120/*!*/;
    21  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    22  /*!\C utf8 *//*!*/;
    23  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    24  SET @@session.lc_time_names=0/*!*/;
    25  SET @@session.collation_database=DEFAULT/*!*/;
    26  create table test_t (id int)
    27  /*!*/;
    28  # at 325
    29  #230813 22:33:25 server id 3306  end_log_pos 390 CRC32 0xfdb90f5a       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    30  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    31  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    32  # at 390
    33  #230813 22:33:25 server id 3306  end_log_pos 464 CRC32 0x868ba03f       Query   thread_id=3     exec_time=0     error_code=0
    34  SET TIMESTAMP=1691937205/*!*/;
    35  BEGIN
    36  /*!*/;
    37  # at 464
    38  #230813 22:33:25 server id 3306  end_log_pos 516 CRC32 0xf97e6695       Rows_query
    39  # insert into test_t values(1)
    40  # at 516
    41  #230813 22:33:25 server id 3306  end_log_pos 567 CRC32 0xeeeacf88       Table_map: `testdb`.`test_t` mapped to number 115
    42  # at 567
    43  #230813 22:33:25 server id 3306  end_log_pos 607 CRC32 0x194fb475       Write_rows: table id 115 flags: STMT_END_F
    44  ### INSERT INTO `testdb`.`test_t`
    45  ### SET
    46  ###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
    47  # at 607
    48  #230813 22:33:25 server id 3306  end_log_pos 638 CRC32 0x5d7f5c93       Xid = 168
    49  COMMIT/*!*/;
    50  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    51  DELIMITER ;
    52  # End of log file
    53  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    54  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 

#如上43~46行 --base64-output=decode-rows,同时加了两个v,把更详细的信息打出来,包括具体执行的SQL语句
跳过前N 个条目显示
mysqlbinlog -o 20 testdb-binlog.000001 > 1.txt

#跳过前面20行记录,从21行记录开始显示
[root@centos7 binlog]# mysqlbinlog -o 20 testdb-binlog.000001 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 22:31:30 server id 3306  end_log_pos 123 CRC32 0x68ee453e       Start: binlog v 4, server v 5.7.43-log created 230813 22:31:30 at startup
     6  # Warning: this binlog is either in use or was not closed properly.
     7  ROLLBACK/*!*/;
     8  BINLOG '
     9  QunYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    10  AAAAAAAAAAAAAAAAAABC6dhkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    11  AT5F7mg=
    12  '/*!*/;
    13  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    14  DELIMITER ;
    15  # End of log file
    16  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    17  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 
保存到文件
mysqlbinlog -o 20 testdb-binlog.000001 > 1.txt
mysqlbinlog testdb-binlog.000001 -r 1.txt
mysqlbinlog --server-id=3306 testdb-binlog.000001 -r 1.txt
从一个特定的位置开始提取条目,从一个特定的位置结束提取条目
mysqlbinlog -j 386 testdb-binlog.000001
mysqlbinlog --start-position=386 testdb-binlog.000001
mysqlbinlog --stop-position=386 testdb-binlog.000001
mysqlbinlog --start-position=154  --stop-position=386 testdb-binlog.000001
从一个特定的时间开始提取条目,从一个特定的时间结束提取条目
mysqlbinlog --start-datetime='2023-08-13 14:11:38' testdb-binlog.000001
mysqlbinlog --stop-datetime='2023-08-13 14:16:41' testdb-binlog.000001
mysqlbinlog --start-datetime='2023-08-13 14:11:38' --stop-datetime='2023-08-13 14:17:00' testdb-binlog.000001
从远程获取二进制日志
mysqlbinlog -R -h 192.168.1.51 -p testdb-binlog.000001

1.7 MySQL 通过binlog 日志恢复数据-恢复误删除表

结合备份+binlog恢复数据

场景:

昨天晚上做了全备,今天上午用户不小心误删除某张表

解决方案:

不建议在原生产环境直接恢复,建议在另一台机器恢复全库+日志,然后导出删除的表,导入到生产环境。

解决思路:

早上创建了一张表,昨天晚上做了全备份,今天上午对表进行了更新,中午的时候把表误删除了吗,需要恢复这张表。

案例

第1步: 创建测试表

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-08-13 23:11:36 |
+---------------------+
1 row in set (0.00 sec)

use testdb
create table test_t (
`id` int(10) unsigned not null auto_increment,
`name` varchar(16) not null,
`sex` enum('m','w') not null default 'm',
`age` tinyint(3) unsigned not null,
primary key (`id`)
) engine=innodb default charset=utf8;
insert into testdb.test_t(`name`,`sex`,`age`) values
('test1','w',21),
('test2','m',22),
('test3','w',23),
('test4','m',24),
('test5','w',25);

mysql> select * from test_t;
+----+-------+-----+-----+
| id | name  | sex | age |
+----+-------+-----+-----+
|  1 | test1 | w   |  21 |
|  2 | test2 | m   |  22 |
|  3 | test3 | w   |  23 |
|  4 | test4 | m   |  24 |
|  5 | test5 | w   |  25 |
+----+-------+-----+-----+
5 rows in set (0.00 sec)

第2步: 做备份

[root@centos7 ~]# mysqldump -uroot -prootroot -F -R --all-databases > alldb_bak.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.
[root@centos7 ~]# 

第3步: 上午的业务

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |      154 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-08-13 23:14:05 |
+---------------------+
1 row in set (0.00 sec)

update testdb.test_t set name='test05' where id=5;

mysql> select * from test_t;
+----+--------+-----+-----+
| id | name   | sex | age |
+----+--------+-----+-----+
|  1 | test1  | w   |  21 |
|  2 | test2  | m   |  22 |
|  3 | test3  | w   |  23 |
|  4 | test4  | m   |  24 |
|  5 | test05 | w   |  25 |
+----+--------+-----+-----+
5 rows in set (0.00 sec)



mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-08-13 23:17:06 |
+---------------------+
1 row in set (0.00 sec)

mysql> update testdb.test_t set name='test04' where id=4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from test_t;
+----+--------+-----+-----+
| id | name   | sex | age |
+----+--------+-----+-----+
|  1 | test1  | w   |  21 |
|  2 | test2  | m   |  22 |
|  3 | test3  | w   |  23 |
|  4 | test04 | m   |  24 |
|  5 | test05 | w   |  25 |
+----+--------+-----+-----+
5 rows in set (0.00 sec)


mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |      882 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

第4步: 中午的误删除

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-08-13 23:18:41 |
+---------------------+
1 row in set (0.00 sec)

mysql> drop table test_t;
Query OK, 0 rows affected (0.03 sec)

mysql> select * from test_t;
ERROR 1146 (42S02): Table 'testdb.test_t' doesn't exist
mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000003 |     1070 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

第5步: 在另一台机器恢复(当前案例在本地,生产不要在本地

#将最新的二进制日志做一个备份,然后再分析
[root@centos7 binlog]# pwd
/mysql/log/3306/binlog
[root@centos7 binlog]# cp testdb-binlog.000003 testdb-binlog.000003.bak
[root@centos7 binlog]# ll -h
total 20K
-rw-r----- 1 mysql mysql 1.1K Aug 13 23:13 testdb-binlog.000001
-rw-r----- 1 mysql mysql  205 Aug 13 23:13 testdb-binlog.000002
-rw-r----- 1 mysql mysql 1.1K Aug 13 23:18 testdb-binlog.000003
-rw-r----- 1 root  root  1.1K Aug 13 23:21 testdb-binlog.000003.bak
-rw-r----- 1 mysql mysql  132 Aug 13 23:13 testdb-binlog.index
[root@centos7 binlog]# 


mysql> show binlog events in 'testdb-binlog.000003';
+----------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------+
| Log_name             | Pos | Event_type     | Server_id | End_log_pos | Info                                                        |
+----------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------+
| testdb-binlog.000003 |   4 | Format_desc    |      3306 |         123 | Server ver: 5.7.43-log, Binlog ver: 4                       |
| testdb-binlog.000003 | 123 | Previous_gtids |      3306 |         154 |                                                             |
| testdb-binlog.000003 | 154 | Anonymous_Gtid |      3306 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                        |
| testdb-binlog.000003 | 219 | Query          |      3306 |         293 | BEGIN                                                       |
| testdb-binlog.000003 | 293 | Rows_query     |      3306 |         366 | # update testdb.test_t set name='test05' where id=5         |
| testdb-binlog.000003 | 366 | Table_map      |      3306 |         424 | table_id: 117 (testdb.test_t)                               |
| testdb-binlog.000003 | 424 | Update_rows    |      3306 |         487 | table_id: 117 flags: STMT_END_F                             |
| testdb-binlog.000003 | 487 | Xid            |      3306 |         518 | COMMIT /* xid=635 */                                        |
| testdb-binlog.000003 | 518 | Anonymous_Gtid |      3306 |         583 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                        |
| testdb-binlog.000003 | 583 | Query          |      3306 |         657 | BEGIN                                                       |
| testdb-binlog.000003 | 657 | Rows_query     |      3306 |         730 | # update testdb.test_t set name='test04' where id=4         |
| testdb-binlog.000003 | 730 | Table_map      |      3306 |         788 | table_id: 117 (testdb.test_t)                               |
| testdb-binlog.000003 | 788 | Update_rows    |      3306 |         851 | table_id: 117 flags: STMT_END_F                             |
| testdb-binlog.000003 | 851 | Xid            |      3306 |         882 | COMMIT /* xid=638 */                                        |
| testdb-binlog.000003 | 882 | Anonymous_Gtid |      3306 |         947 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                        |
| testdb-binlog.000003 | 947 | Query          |      3306 |        1070 | use `testdb`; DROP TABLE `test_t` /* generated by server */ |
+----------------------+-----+----------------+-----------+-------------+-------------------------------------------------------------+
16 rows in set (0.01 sec)


#如上882~1070这段就是删除表的事务,恢复到882之前这个事务就可以了


#具体的时间可以使用mysqlbinlog工具根据pos查看时间点
[root@centos7 binlog]# mysqlbinlog testdb-binlog.000003 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230813 23:13:14 server id 3306  end_log_pos 123 CRC32 0x3fcae4d4       Start: binlog v 4, server v 5.7.43-log created 230813 23:13:14
     6  # Warning: this binlog is either in use or was not closed properly.
     7  BINLOG '
     8  CvPYZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
     9  AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    10  AdTkyj8=
    11  '/*!*/;
    12  # at 123
    13  #230813 23:13:14 server id 3306  end_log_pos 154 CRC32 0x473340ea       Previous-GTIDs
    14  # [empty]
    15  # at 154
    16  #230813 23:16:36 server id 3306  end_log_pos 219 CRC32 0x90403097       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=yes
    17  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    18  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    19  # at 219
    20  #230813 23:16:36 server id 3306  end_log_pos 293 CRC32 0xa351b7f1       Query   thread_id=4     exec_time=0     error_code=0
    21  SET TIMESTAMP=1691939796/*!*/;
    22  SET @@session.pseudo_thread_id=4/*!*/;
    23  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    24  SET @@session.sql_mode=1436549120/*!*/;
    25  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    26  /*!\C utf8 *//*!*/;
    27  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    28  SET @@session.lc_time_names=0/*!*/;
    29  SET @@session.collation_database=DEFAULT/*!*/;
    30  BEGIN
    31  /*!*/;
    32  # at 293
    33  # at 366
    34  #230813 23:16:36 server id 3306  end_log_pos 424 CRC32 0x2fc3dbf3       Table_map: `testdb`.`test_t` mapped to number 117
    35  # at 424
    36  #230813 23:16:36 server id 3306  end_log_pos 487 CRC32 0x6b31d0ab       Update_rows: table id 117 flags: STMT_END_F
    37
    38  BINLOG '
    39  1PPYZBPqDAAAOgAAAKgBAAAAAHUAAAAAAAEABnRlc3RkYgAGdGVzdF90AAQDD/4BBDAA9wEA89vD
    40  Lw==
    41  1PPYZB/qDAAAPwAAAOcBAAAAAHUAAAAAAAEAAgAE///wBQAAAAV0ZXN0NQIZ8AUAAAAGdGVzdDA1
    42  Ahmr0DFr
    43  '/*!*/;
    44  # at 487
    45  #230813 23:16:36 server id 3306  end_log_pos 518 CRC32 0x01b34a63       Xid = 635
    46  COMMIT/*!*/;
    47  # at 518
    48  #230813 23:17:23 server id 3306  end_log_pos 583 CRC32 0x353f4d3c       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=yes
    49  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    50  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    51  # at 583
    52  #230813 23:17:23 server id 3306  end_log_pos 657 CRC32 0x2c6e0461       Query   thread_id=4     exec_time=0     error_code=0
    53  SET TIMESTAMP=1691939843/*!*/;
    54  BEGIN
    55  /*!*/;
    56  # at 657
    57  # at 730
    58  #230813 23:17:23 server id 3306  end_log_pos 788 CRC32 0xc210cf79       Table_map: `testdb`.`test_t` mapped to number 117
    59  # at 788
    60  #230813 23:17:23 server id 3306  end_log_pos 851 CRC32 0x135bbcab       Update_rows: table id 117 flags: STMT_END_F
    61
    62  BINLOG '
    63  A/TYZBPqDAAAOgAAABQDAAAAAHUAAAAAAAEABnRlc3RkYgAGdGVzdF90AAQDD/4BBDAA9wEAec8Q
    64  wg==
    65  A/TYZB/qDAAAPwAAAFMDAAAAAHUAAAAAAAEAAgAE///wBAAAAAV0ZXN0NAEY8AQAAAAGdGVzdDA0
    66  ARirvFsT
    67  '/*!*/;
    68  # at 851
    69  #230813 23:17:23 server id 3306  end_log_pos 882 CRC32 0x0ff1cc57       Xid = 638
    70  COMMIT/*!*/;
    71  # at 882
    72  #230813 23:18:55 server id 3306  end_log_pos 947 CRC32 0x81553f96       Anonymous_GTID  last_committed=2        sequence_number=3    rbr_only=no
    73  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    74  # at 947
    75  #230813 23:18:55 server id 3306  end_log_pos 1070 CRC32 0xc37e97a1      Query   thread_id=4     exec_time=0     error_code=0
    76  use `testdb`/*!*/;
    77  SET TIMESTAMP=1691939935/*!*/;
    78  DROP TABLE `test_t` /* generated by server */
    79  /*!*/;
    80  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
    81  DELIMITER ;
    82  # End of log file
    83  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    84  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 

#如上71行   pos:882  可以看出恢复到 2023230813 23:17:23 这个时间点就可以了

恢复方法:

另一台机器装一个数据库,直接恢复单个库

#删除数据库
drop database testdb;
#创建数据库
create database testdb default character set utf8; -- 如果不清楚条件,建议在原库查询
#根据备份恢复
mysql -uroot -prootroot -o testdb < alldb_bak.sql

#如下,恢复后,查不到上午更新的记录
[root@centos7 3306]# mysql -uroot -prootroot testdb -e 'select * from test_t'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+-------+-----+-----+
| id | name  | sex | age |
+----+-------+-----+-----+
|  1 | test1 | w   |  21 |
|  2 | test2 | m   |  22 |
|  3 | test3 | w   |  23 |
|  4 | test4 | m   |  24 |
|  5 | test5 | w   |  25 |
+----+-------+-----+-----+

#通过binlog日志增量恢复表删除之前(也就是上午更新后的数据)
mysqlbinlog --stop-position=882 --database=testdb /mysql/log/3306/binlog/testdb-binlog.000003|mysql -uroot -prootroot testdb

[root@centos7 ~]# mysqlbinlog --stop-position=882 --database=testdb /mysql/log/3306/binlog/testdb-binlog.000003|mysql -uroot -prootroot testdb
mysql: [Warning] Using a password on the command line interface can be insecure.
WARNING: The option --database has been used. It may filter parts of transactions, but will include the GTIDs in any case. If you want to exclude or include transactions, you should use the options --exclude-gtids or --include-gtids, respectively, instead.
[root@centos7 ~]# 

验证数据:

[root@centos7 ~]# mysql -uroot -prootroot testdb -e 'select * from test_t'
mysql: [Warning] Using a password on the command line interface can be insecure.
+----+--------+-----+-----+
| id | name   | sex | age |
+----+--------+-----+-----+
|  1 | test1  | w   |  21 |
|  2 | test2  | m   |  22 |
|  3 | test3  | w   |  23 |
|  4 | test04 | m   |  24 |
|  5 | test05 | w   |  25 |
+----+--------+-----+-----+

然后备份当前表到源库进行恢复

#恢复库导出表数据
mysqldump -uroot -prootroot testdb test_t > test_t.sql



[root@centos7 ~]# cat test_t.sql 
-- MySQL dump 10.13  Distrib 5.7.43, for linux-glibc2.12 (x86_64)
--
-- Host: localhost    Database: testdb
-- ------------------------------------------------------
-- Server version       5.7.43-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `test_t`
--

DROP TABLE IF EXISTS `test_t`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `test_t` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(16) NOT NULL,
  `sex` enum('m','w') NOT NULL DEFAULT 'm',
  `age` tinyint(3) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `test_t`
--

LOCK TABLES `test_t` WRITE;
/*!40000 ALTER TABLE `test_t` DISABLE KEYS */;
INSERT INTO `test_t` VALUES (1,'test1','w',21),(2,'test2','m',22),(3,'test3','w',23),(4,'test04','m',24),(5,'test05','w',25);
/*!40000 ALTER TABLE `test_t` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2023-08-13 23:51:00
[root@centos7 ~]# 





#源库,恢复
mysql -uroot -p testdb < test_t.sql

1.8 MySQL 通过binlog 日志恢复数据-flashback 闪回

场景:

DBA/开发人员,有时候误删除/误更新,特别是批量误操作,这时候生产环境线上业务,影响非常大,这个时间需要快速的回滚。

传统方法:

MySQL 通过binlog 日志恢复数据-恢复误删除表,非常麻烦、费时费力、还需要停机维护

快速的方法:

闪回,通过binlog快速回滚,恢复速度快,不需要停机。(闪回主要是根据数据库的、表的、时间的去做一次过滤,根据它的位置做出一个准确的时间点或者闪回点,通过这个点还原回去,因为数据一直在往表里写,为了确保回滚的SQL不含其他数据,可以根据是不是同一个事务,或者说是找到误删除的行,或者说一些特征来判断我们是要恢复哪些数据,而且回滚的时候只是回滚某张表里面的内容或者和它相关的,要和业务沟通清楚,确定表是否有关联性,比如恢复这张表数据以后有可能导致其他地方的数据异常了)

mysql闪回工具有3类:

  1. 官方mysqlbinlog:解析出文本的二进制格式,然后通过命令或者正则进行匹配/替换,把语句拿到之后执行就可以恢复。

    优点:快速定位,安装和使用都方便,支持离线。用脚本处理binlog的输出,再插回数据库。

    缺点:通用性不好,对技术也有一定要求。

  2. 第三方的mysqlbinlog工具:比官方的工具多了一个闪回功能

  3. 开源的binlog2sql:兼容性比较好,使用难度小,使用简单,前提是MySQL必须开启。

线上环境的闪回:binlog2sql,离线解析:mysqlbinlog/mysqlbinlog_flashback

1.8.1 利用官方mysqlbinlog 闪回批量误删除操作

前提条件:

需要设置好三个参数

#这三个参数需要配置好
binlog_format=row
binlog_row_image=full
binlog_rows_query_log_events=on

创建测试数据

create database testdb;

use testdb
create table test_t (
`id` int(10) unsigned not null auto_increment,
`name` varchar(16) not null,
`sex` enum('m','w') not null default 'm',
`age` tinyint(3) unsigned not null,
primary key (`id`)
) engine=innodb default charset=utf8;

insert into testdb.test_t(`name`,`sex`,`age`) values
('test1','w',21),
('test2','m',22),
('test3','w',23),
('test4','m',24),
('test5','w',25);
select * from testdb.test_t;

mysql> select * from testdb.test_t;
+----+-------+-----+-----+
| id | name  | sex | age |
+----+-------+-----+-----+
|  1 | test1 | w   |  21 |
|  2 | test2 | m   |  22 |
|  3 | test3 | w   |  23 |
|  4 | test4 | m   |  24 |
|  5 | test5 | w   |  25 |
+----+-------+-----+-----+
5 rows in set (0.00 sec)

模拟误操作

#原计划操作
delete from testdb.test_t where id=2;
#实际操作
delete from testdb.test_t;

mysql> select * from testdb.test_t;
Empty set (0.00 sec)

开始恢复

#锁表,只能读不能写
lock tables testdb.test_t read;


mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000001 |     1563 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)


show binlog events in 'testdb-binlog.000001';

image-20230814212327308

如上可以看出第30行就是delete的信息

解析binlog

[root@centos7 binlog]# pwd
/mysql/log/3306/binlog
[root@centos7 binlog]# mysqlbinlog --base64-output=decode-rows -v -v testdb-binlog.000001 > 1.txt
[root@centos7 binlog]# 
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     3  DELIMITER /*!*/;
     4  # at 4
     5  #230814 21:13:36 server id 3306  end_log_pos 123 CRC32 0xb1fa7209       Start: binlog v 4, server v 5.7.43-log created 230814 21:13:36 at startup
     6  # Warning: this binlog is either in use or was not closed properly.
     7  ROLLBACK/*!*/;
     8  # at 123
     9  #230814 21:13:36 server id 3306  end_log_pos 154 CRC32 0xcdcae2cc       Previous-GTIDs
    10  # [empty]
    11  # at 154
    12  #230814 21:16:03 server id 3306  end_log_pos 219 CRC32 0x68be5e7e       Anonymous_GTID  last_committed=0        sequence_number=1    rbr_only=no
    13  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    14  # at 219
    15  #230814 21:16:03 server id 3306  end_log_pos 319 CRC32 0x5a05978d       Query   thread_id=2     exec_time=0     error_code=0
    16  SET TIMESTAMP=1692018963/*!*/;
    17  SET @@session.pseudo_thread_id=2/*!*/;
    18  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    19  SET @@session.sql_mode=1436549120/*!*/;
    20  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    21  /*!\C utf8 *//*!*/;
    22  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    23  SET @@session.lc_time_names=0/*!*/;
    24  SET @@session.collation_database=DEFAULT/*!*/;
    25  create database testdb
    26  /*!*/;
    27  # at 319
    28  #230814 21:16:20 server id 3306  end_log_pos 384 CRC32 0xf221e806       Anonymous_GTID  last_committed=1        sequence_number=2    rbr_only=no
    29  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    30  # at 384
    31  #230814 21:16:20 server id 3306  end_log_pos 693 CRC32 0x2bff4609       Query   thread_id=2     exec_time=0     error_code=0
    32  use `testdb`/*!*/;
    33  SET TIMESTAMP=1692018980/*!*/;
    34  create table test_t (
    35  `id` int(10) unsigned not null auto_increment,
    36  `name` varchar(16) not null,
    37  `sex` enum('m','w') not null default 'm',
    38  `age` tinyint(3) unsigned not null,
    39  primary key (`id`)
    40  ) engine=innodb default charset=utf8
    41  /*!*/;
    42  # at 693
    43  #230814 21:16:52 server id 3306  end_log_pos 758 CRC32 0x4a525dd6       Anonymous_GTID  last_committed=2        sequence_number=3    rbr_only=yes
    44  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    45  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    46  # at 758
    47  #230814 21:16:52 server id 3306  end_log_pos 832 CRC32 0xaeaa2727       Query   thread_id=2     exec_time=0     error_code=0
    48  SET TIMESTAMP=1692019012/*!*/;
    49  BEGIN
    50  /*!*/;
    51  # at 832
    52  #230814 21:16:52 server id 3306  end_log_pos 997 CRC32 0x26b6b2d9       Rows_query
    53  # insert into testdb.test_t(`name`,`sex`,`age`) values
    54  # ('test1','w',21),
    55  # ('test2','m',22),
    56  # ('test3','w',23),
    57  # ('test4','m',24),
    58  # ('test5','w',25)
    59  # at 997
    60  #230814 21:16:52 server id 3306  end_log_pos 1055 CRC32 0xe67a5c79      Table_map: `testdb`.`test_t` mapped to number 109
    61  # at 1055
    62  #230814 21:16:52 server id 3306  end_log_pos 1155 CRC32 0xdfee8b1f      Write_rows: table id 109 flags: STMT_END_F
    63  ### INSERT INTO `testdb`.`test_t`
    64  ### SET
    65  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
    66  ###   @2='test1' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    67  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    68  ###   @4=21 /* TINYINT meta=0 nullable=0 is_null=0 */
    69  ### INSERT INTO `testdb`.`test_t`
    70  ### SET
    71  ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
    72  ###   @2='test2' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    73  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    74  ###   @4=22 /* TINYINT meta=0 nullable=0 is_null=0 */
    75  ### INSERT INTO `testdb`.`test_t`
    76  ### SET
    77  ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
    78  ###   @2='test3' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    79  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    80  ###   @4=23 /* TINYINT meta=0 nullable=0 is_null=0 */
    81  ### INSERT INTO `testdb`.`test_t`
    82  ### SET
    83  ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    84  ###   @2='test4' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    85  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    86  ###   @4=24 /* TINYINT meta=0 nullable=0 is_null=0 */
    87  ### INSERT INTO `testdb`.`test_t`
    88  ### SET
    89  ###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
    90  ###   @2='test5' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    91  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    92  ###   @4=25 /* TINYINT meta=0 nullable=0 is_null=0 */
    93  # at 1155
    94  #230814 21:16:52 server id 3306  end_log_pos 1186 CRC32 0xc0f96fb7      Xid = 16
    95  COMMIT/*!*/;
    96  # at 1186
    97  #230814 21:18:20 server id 3306  end_log_pos 1251 CRC32 0x2c8bac55      Anonymous_GTID  last_committed=3        sequence_number=4    rbr_only=yes
    98  /*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
    99  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
   100  # at 1251
   101  #230814 21:18:20 server id 3306  end_log_pos 1325 CRC32 0x0c6f3c8b      Query   thread_id=2     exec_time=0     error_code=0
   102  SET TIMESTAMP=1692019100/*!*/;
   103  BEGIN
   104  /*!*/;
   105  # at 1325
   106  #230814 21:18:20 server id 3306  end_log_pos 1374 CRC32 0x4844b231      Rows_query
   107  # delete from testdb.test_t
   108  # at 1374
   109  #230814 21:18:20 server id 3306  end_log_pos 1432 CRC32 0xaa189dc9      Table_map: `testdb`.`test_t` mapped to number 109
   110  # at 1432
   111  #230814 21:18:20 server id 3306  end_log_pos 1532 CRC32 0x772e936f      Delete_rows: table id 109 flags: STMT_END_F
   112  ### DELETE FROM `testdb`.`test_t`
   113  ### WHERE
   114  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
   115  ###   @2='test1' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
   116  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
   117  ###   @4=21 /* TINYINT meta=0 nullable=0 is_null=0 */
   118  ### DELETE FROM `testdb`.`test_t`
   119  ### WHERE
   120  ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
   121  ###   @2='test2' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
   122  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
   123  ###   @4=22 /* TINYINT meta=0 nullable=0 is_null=0 */
   124  ### DELETE FROM `testdb`.`test_t`
   125  ### WHERE
   126  ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
   127  ###   @2='test3' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
   128  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
   129  ###   @4=23 /* TINYINT meta=0 nullable=0 is_null=0 */
   130  ### DELETE FROM `testdb`.`test_t`
   131  ### WHERE
   132  ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
   133  ###   @2='test4' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
   134  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
   135  ###   @4=24 /* TINYINT meta=0 nullable=0 is_null=0 */
   136  ### DELETE FROM `testdb`.`test_t`
   137  ### WHERE
   138  ###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
   139  ###   @2='test5' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
   140  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
   141  ###   @4=25 /* TINYINT meta=0 nullable=0 is_null=0 */
   142  # at 1532
   143  #230814 21:18:20 server id 3306  end_log_pos 1563 CRC32 0xc4100f36      Xid = 18
   144  COMMIT/*!*/;
   145  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
   146  DELIMITER ;
   147  # End of log file
   148  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
   149  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 


#如上112~141可以看出做了很多删除行的操作(有几条记录都有几次删除行动作)

使用正则过滤替换处理

#过滤delete部分的语句
[root@centos7 binlog]# sed -n '/### DELETE FROM `testdb`.`test_t`/,/COMMIT/p' 1.txt > test_t-tmp.txt
[root@centos7 binlog]# cat -n test_t-tmp.txt 
     1  ### DELETE FROM `testdb`.`test_t`
     2  ### WHERE
     3  ###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
     4  ###   @2='test1' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
     5  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
     6  ###   @4=21 /* TINYINT meta=0 nullable=0 is_null=0 */
     7  ### DELETE FROM `testdb`.`test_t`
     8  ### WHERE
     9  ###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
    10  ###   @2='test2' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    11  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    12  ###   @4=22 /* TINYINT meta=0 nullable=0 is_null=0 */
    13  ### DELETE FROM `testdb`.`test_t`
    14  ### WHERE
    15  ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
    16  ###   @2='test3' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    17  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    18  ###   @4=23 /* TINYINT meta=0 nullable=0 is_null=0 */
    19  ### DELETE FROM `testdb`.`test_t`
    20  ### WHERE
    21  ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    22  ###   @2='test4' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    23  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    24  ###   @4=24 /* TINYINT meta=0 nullable=0 is_null=0 */
    25  ### DELETE FROM `testdb`.`test_t`
    26  ### WHERE
    27  ###   @1=5 /* INT meta=0 nullable=0 is_null=0 */
    28  ###   @2='test5' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    29  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    30  ###   @4=25 /* TINYINT meta=0 nullable=0 is_null=0 */
    31  # at 1532
    32  #230814 21:18:20 server id 3306  end_log_pos 1563 CRC32 0xc4100f36      Xid = 18
    33  COMMIT/*!*/;
[root@centos7 binlog]# 




#将delete修改为insert
cat test_t-tmp.txt | sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/INSERT INTO/g;s/WHERE/SELECT/g;' | sed -r 's/(@4.*),/\1;/g' | sed 's/@[1-9]=//g' > recover_test_t.sql


[root@centos7 binlog]# cat test_t-tmp.txt | sed -n '/###/p' | sed 's/### //g;s/\/\*.*/,/g;s/DELETE FROM/INSERT INTO/g;s/WHERE/SELECT/g;' | sed -r 's/(@4.*),/\1;/g' | sed 's/@[1-9]=//g' > recover_test_t.sql
[root@centos7 binlog]# 
[root@centos7 binlog]# cat -n recover_test_t.sql
     1  INSERT INTO `testdb`.`test_t`
     2  SELECT
     3    1 ,
     4    'test1' ,
     5    2 ,
     6    21 ;
     7  INSERT INTO `testdb`.`test_t`
     8  SELECT
     9    2 ,
    10    'test2' ,
    11    1 ,
    12    22 ;
    13  INSERT INTO `testdb`.`test_t`
    14  SELECT
    15    3 ,
    16    'test3' ,
    17    2 ,
    18    23 ;
    19  INSERT INTO `testdb`.`test_t`
    20  SELECT
    21    4 ,
    22    'test4' ,
    23    1 ,
    24    24 ;
    25  INSERT INTO `testdb`.`test_t`
    26  SELECT
    27    5 ,
    28    'test5' ,
    29    2 ,
    30    25 ;
[root@centos7 binlog]# 

执行操作

#先解锁表
unlock tables;
#赶紧加写锁,我可以写,别人不能写
lock tables testdb.test_t write;
mysql> source /mysql/log/3306/binlog/recover_test_t.sql
#解锁表
mysql> unlock tables;

#查询
mysql> select * from testdb.test_t;
+----+-------+-----+-----+
| id | name  | sex | age |
+----+-------+-----+-----+
|  1 | test1 | w   |  21 |
|  2 | test2 | m   |  22 |
|  3 | test3 | w   |  23 |
|  4 | test4 | m   |  24 |
|  5 | test5 | w   |  25 |
+----+-------+-----+-----+
5 rows in set (0.00 sec)

1.8.2 利用第三方mysqlbinlog 闪回误删除的表

工具下载地址

https://github.com/58daojia-dba/mysqlbinlog_flashback

#修改权限
chmod 777 mysqlbinlog_flashback

#查看帮助信息
[root@centos7 app]# ./mysqlbinlog_flashback --help
./mysqlbinlog_flashback Ver 3.4 for Linux at x86_64
Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Dumps a MySQL binary log in a format usable for viewing or for piping to
the mysql command line client.

Usage: ./mysqlbinlog_flashback [options] log-files
  -?, --help          Display this help and exit.
  --base64-output=name 
                      Determine when the output statements should be
                      base64-encoded BINLOG statements: 'never' disables it and
                      works only for binlogs without row-based events;
                      'decode-rows' decodes row events into commented
                      pseudo-SQL statements if the --verbose option is also
                      given; 'auto' prints base64 only when necessary (i.e.,
                      for row-based events and format description events).  If
                      no --base64-output[=name] option is given at all, the
                      default is 'auto'.
  --bind-address=name IP address to bind to.
  --character-sets-dir=name 
                      Directory for character set files.
  -d, --database=name List entries for just this database (local log only).
  -#, --debug[=name]  Output debug log.
  --debug-check       Check memory and open file usage at exit .
  --debug-info        Print some debug info at exit.
  --default-auth=name Default authentication client-side plugin to use.
  -D, --disable-log-bin 
                      Disable binary log. This is useful, if you enabled
                      --to-last-log and are sending the output to the same
                      MySQL server. This way you could avoid an endless loop.
                      You would also like to use it when restoring after a
                      crash to avoid duplication of the statements you already
                      have. NOTE: you will need a SUPER privilege to use this
                      option.
  -F, --force-if-open Force if binlog was not closed properly.
                      (Defaults to on; use --skip-force-if-open to disable.)
  -f, --force-read    Force reading unknown binlog events.
  -H, --hexdump       Augment output with hexadecimal and ASCII event dump.
  -h, --host=name     Get the binlog from server.
  -l, --local-load=name 
                      Prepare local temporary files for LOAD DATA INFILE in the
                      specified directory.
  -o, --offset=#      Skip the first N entries.
  -p, --password[=name] 
                      Password to connect to remote server.
  --plugin-dir=name   Directory for client-side plugins.
  -P, --port=#        Port number to use for connection or 0 for default to, in
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
                      /etc/services, built-in default (3306).
  --protocol=name     The protocol to use for connection (tcp, socket, pipe,
                      memory).
  -R, --read-from-remote-server 
                      Read binary logs from a MySQL server. This is an alias
                      for read-from-remote-master=BINLOG-DUMP-NON-GTIDS.
  -B, --flashback     Flashback data to start_postition or start_datetime.
  --read-from-remote-master=name 
                      Read binary logs from a MySQL server through the
                      COM_BINLOG_DUMP or COM_BINLOG_DUMP_GTID commands by
                      setting the option to either BINLOG-DUMP-NON-GTIDS or
                      BINLOG-DUMP-GTIDS, respectively. If
                      --read-from-remote-master=BINLOG-DUMP-GTIDS is combined
                      with --exclude-gtids, transactions can be filtered out on
                      the master avoiding unnecessary network traffic.
  --raw               Requires -R. Output raw binlog data instead of SQL
                      statements, output is to log files.
  -r, --result-file=name 
                      Direct output to a given file. With --raw this is a
                      prefix for the file names.
  --secure-auth       Refuse client connecting to server if it uses old
                      (pre-4.1.1) protocol.
                      (Defaults to on; use --skip-secure-auth to disable.)
  --server-id=#       Extract only binlog entries created by the server having
                      the given id.
  --server-id-bits=#  Set number of significant bits in server-id
  --set-charset=name  Add 'SET NAMES character_set' to the output.
  -s, --short-form    Just show regular queries: no extra info and no row-based
                      events. This is for testing only, and should not be used
                      in production systems. If you want to suppress
                      base64-output, consider using --base64-output=never
                      instead.
  -S, --socket=name   The socket file to use for connection.
  --start-datetime=name 
                      Start reading the binlog at first event having a datetime
                      equal or posterior to the argument; the argument must be
                      a date and time in the local time zone, in any format
                      accepted by the MySQL server for DATETIME and TIMESTAMP
                      types, for example: 2004-12-25 11:25:56 (you should
                      probably use quotes for your shell to set it properly).
  -j, --start-position=# 
                      Start reading the binlog at position N. Applies to the
                      first binlog passed on the command line.
  --stop-datetime=name 
                      Stop reading the binlog at first event having a datetime
                      equal or posterior to the argument; the argument must be
                      a date and time in the local time zone, in any format
                      accepted by the MySQL server for DATETIME and TIMESTAMP
                      types, for example: 2004-12-25 11:25:56 (you should
                      probably use quotes for your shell to set it properly).
  --stop-never        Wait for more data from the server instead of stopping at
                      the end of the last log. Implicitly sets --to-last-log
                      but instead of stopping at the end of the last log it
                      continues to wait till the server disconnects.
  --stop-never-slave-server-id=# 
                      The slave server_id used for --read-from-remote-server
                      --stop-never.
  --connection-server-id=# 
                      The slave server_id used for --read-from-remote-server.
  --stop-position=#   Stop reading the binlog at position N. Applies to the
                      last binlog passed on the command line.
  -t, --to-last-log   Requires -R. Will not stop at the end of the requested
                      binlog but rather continue printing until the end of the
                      last binlog of the MySQL server. If you send the output
                      to the same MySQL server, that may lead to an endless
                      loop.
  -u, --user=name     Connect to the remote server as username.
  -v, --verbose       Reconstruct pseudo-SQL statements out of row events. -v
                      -v adds comments on column data types.
  -V, --version       Print version and exit.
  --open-files-limit=# 
                      Used to reserve file descriptors for use by this program.
  -c, --verify-binlog-checksum 
                      Verify checksum binlog events.
  --binlog-row-event-max-size=# 
                      The maximum size of a row-based binary log event in
                      bytes. Rows will be grouped into events smaller than this
                      size if possible. This value must be a multiple of 256.
  --skip-gtids        Do not print Global Transaction Identifier information
                      (SET GTID_NEXT=... etc).
  --include-gtids=name 
                      Print events whose Global Transaction Identifiers were
                      provided.
  --exclude-gtids=name 
                      Print all events but those whose Global Transaction
                      Identifiers were provided.

Variables (--variable-name=value)
and boolean options {FALSE|TRUE}  Value (after reading options)
--------------------------------- ----------------------------------------
base64-output                     (No default value)
bind-address                      (No default value)
character-sets-dir                (No default value)
database                          (No default value)
debug                             d:t:o,/tmp/mysqlbinlog.trace
debug-check                       FALSE
debug-info                        FALSE
default-auth                      (No default value)
disable-log-bin                   FALSE
force-if-open                     TRUE
force-read                        FALSE
hexdump                           FALSE
host                              (No default value)
local-load                        (No default value)
offset                            0
plugin-dir                        (No default value)
port                              0
read-from-remote-server           FALSE
flashback                         FALSE
read-from-remote-master           (No default value)
raw                               FALSE
result-file                       (No default value)
secure-auth                       TRUE
server-id                         0
server-id-bits                    32
set-charset                       (No default value)
short-form                        FALSE
socket                            (No default value)
start-datetime                    (No default value)
start-position                    4
stop-datetime                     (No default value)
stop-never                        FALSE
stop-never-slave-server-id        -1
connection-server-id              -1
stop-position                     18446744073709551615
to-last-log                       FALSE
user                              (No default value)
open-files-limit                  64
verify-binlog-checksum            FALSE
binlog-row-event-max-size         4294967040
skip-gtids                        FALSE
include-gtids                     (No default value)
exclude-gtids                     (No default value)
[root@centos7 app]# 




#如上该工具比官方的工具对了这么一个参数
通过mysqlbinlog_flashback 闪回,选项-B
-B,  --flashback Flashback data to start_postition or start_datetime.
binlog_format=row,只支持insert/delete/update,不支持ddl操作。可以针对单个event事件,也可以针对多个event事件。

测试

create table test_t1 (
`id` int(10) unsigned not null auto_increment,
`name` varchar(16) not null,
`sex` enum('m','w') not null default 'm',
`age` tinyint(3) unsigned not null,
primary key (`id`)
) engine=innodb default charset=utf8;

insert into testdb.test_t1 (`name`,`sex`,`age`) values
('test1','w',21),
('test2','m',22),
('test3','w',23),
('test4','m',24),
('test5','w',25);

误操作(连错数据库,以为这是测试库,结果把生产这张表做很多增删表)

insert into testdb.test_t1(`name`,`sex`,`age`) values('test100','w',25);
update test_t1 set name='test04' where id=4;
delete from test_t1 where id=3;

恢复过程

#先锁读
lock tables testdb.test_t1 read;

mysql> show master logs;
+----------------------+-----------+
| Log_name             | File_size |
+----------------------+-----------+
| testdb-binlog.000001 |      5293 |
+----------------------+-----------+
1 row in set (0.00 sec)


show binlog events in 'testdb-binlog.000001';
#insert开始的pos为 4294

image-20230814215921171

解析binlog

[root@centos7 binlog]# /mysql/app/mysqlbinlog_flashback -v -v --start-position=4294 --stop-position=5293 testdb-binlog.000001 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!40019 SET @@session.max_insert_delayed_threads=0*/;
     3  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     4  DELIMITER /*!*/;
     5  # at 4
     6  #230814 21:13:36 server id 3306  end_log_pos 123 CRC32 0xb1fa7209       Start: binlog v 4, server v 5.7.43-log created 230814 21:13:36 at startup
     7  # Warning: this binlog is either in use or was not closed properly.
     8  ROLLBACK/*!*/;
     9  BINLOG '
    10  gCjaZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    11  AAAAAAAAAAAAAAAAAACAKNpkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    12  AQly+rE=
    13  '/*!*/;
    14  # at 4294
    15  #230814 21:48:52 server id 3306  end_log_pos 4368 CRC32 0x0c67a9c2      Query   thread_id=3     exec_time=0     error_code=0
    16  SET TIMESTAMP=1692020932/*!*/;
    17  SET @@session.pseudo_thread_id=3/*!*/;
    18  SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
    19  SET @@session.sql_mode=1436549120/*!*/;
    20  SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
    21  /*!\C utf8 *//*!*/;
    22  SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/;
    23  SET @@session.lc_time_names=0/*!*/;
    24  SET @@session.collation_database=DEFAULT/*!*/;
    25  BEGIN
    26  /*!*/;
    27  # at 4368
    28  #230814 21:48:52 server id 3306  end_log_pos 4463 CRC32 0x3c6a9f0a      Rows_query
    29  # insert into testdb.test_t1(`name`,`sex`,`age`)
    30  # values('test100','w',25)
    31  # at 4463
    32  #230814 21:48:52 server id 3306  end_log_pos 4522 CRC32 0x41b54e77      Table_map: `testdb`.`test_t1` mapped to number 110
    33  # at 4522
    34  #230814 21:48:52 server id 3306  end_log_pos 4572 CRC32 0x0383c901      Write_rows: table id 110 flags: STMT_END_F
    35
    36  BINLOG '
    37  xDDaZB3qDAAAXwAAAG8RAACAAEdpbnNlcnQgaW50byB0ZXN0ZGIudGVzdF90MShgbmFtZWAsYHNl
    38  eGAsYGFnZWApCnZhbHVlcygndGVzdDEwMCcsJ3cnLDI1KQqfajw=
    39  xDDaZBPqDAAAOwAAAKoRAAAAAG4AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAEAw/+AQQwAPcBAHdO
    40  tUE=
    41  xDDaZB7qDAAAMgAAANwRAAAAAG4AAAAAAAEAAgAE//AGAAAAB3Rlc3QxMDACGQHJgwM=
    42  '/*!*/;
    43  ### INSERT INTO `testdb`.`test_t1`
    44  ### SET
    45  ###   @1=6 /* INT meta=0 nullable=0 is_null=0 */
    46  ###   @2='test100' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    47  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    48  ###   @4=25 /* TINYINT meta=0 nullable=0 is_null=0 */
    49  # at 4572
    50  #230814 21:48:52 server id 3306  end_log_pos 4603 CRC32 0x3a318f4a      Xid = 47
    51  COMMIT/*!*/;
    52  # at 4603
    53  #230814 21:48:57 server id 3306  end_log_pos 4668 CRC32 0x166dc78e      GTID [commit=no]
    54  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    55  # at 4668
    56  #230814 21:48:57 server id 3306  end_log_pos 4742 CRC32 0x8aa54c34      Query   thread_id=3     exec_time=0     error_code=0
    57  SET TIMESTAMP=1692020937/*!*/;
    58  BEGIN
    59  /*!*/;
    60  # at 4742
    61  #230814 21:48:57 server id 3306  end_log_pos 4809 CRC32 0xbf61fbff      Rows_query
    62  # update test_t1 set name='test04' where id=4
    63  # at 4809
    64  #230814 21:48:57 server id 3306  end_log_pos 4868 CRC32 0xedb93318      Table_map: `testdb`.`test_t1` mapped to number 110
    65  # at 4868
    66  #230814 21:48:57 server id 3306  end_log_pos 4931 CRC32 0xbbb1e163      Update_rows: table id 110 flags: STMT_END_F
    67
    68  BINLOG '
    69  yTDaZB3qDAAAQwAAAMkSAACAACt1cGRhdGUgdGVzdF90MSBzZXQgbmFtZT0ndGVzdDA0JyB3aGVy
    70  ZSBpZD00//thvw==
    71  yTDaZBPqDAAAOwAAAAQTAAAAAG4AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAEAw/+AQQwAPcBABgz
    72  ue0=
    73  yTDaZB/qDAAAPwAAAEMTAAAAAG4AAAAAAAEAAgAE///wBAAAAAV0ZXN0NAEY8AQAAAAGdGVzdDA0
    74  ARhj4bG7
    75  '/*!*/;
    76  ### UPDATE `testdb`.`test_t1`
    77  ### WHERE
    78  ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    79  ###   @2='test4' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    80  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    81  ###   @4=24 /* TINYINT meta=0 nullable=0 is_null=0 */
    82  ### SET
    83  ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    84  ###   @2='test04' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    85  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    86  ###   @4=24 /* TINYINT meta=0 nullable=0 is_null=0 */
    87  # at 4931
    88  #230814 21:48:57 server id 3306  end_log_pos 4962 CRC32 0x792e93c6      Xid = 48
    89  COMMIT/*!*/;
    90  # at 4962
    91  #230814 21:49:01 server id 3306  end_log_pos 5027 CRC32 0x41a44941      GTID [commit=no]
    92  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    93  # at 5027
    94  #230814 21:49:01 server id 3306  end_log_pos 5101 CRC32 0xfac99bc5      Query   thread_id=3     exec_time=0     error_code=0
    95  SET TIMESTAMP=1692020941/*!*/;
    96  BEGIN
    97  /*!*/;
    98  # at 5101
    99  #230814 21:49:01 server id 3306  end_log_pos 5155 CRC32 0xe8e76677      Rows_query
   100  # delete from test_t1 where id=3
   101  # at 5155
   102  #230814 21:49:01 server id 3306  end_log_pos 5214 CRC32 0x5f34f100      Table_map: `testdb`.`test_t1` mapped to number 110
   103  # at 5214
   104  #230814 21:49:01 server id 3306  end_log_pos 5262 CRC32 0x56737b4a      Delete_rows: table id 110 flags: STMT_END_F
   105
   106  BINLOG '
   107  zTDaZB3qDAAANgAAACMUAACAAB5kZWxldGUgZnJvbSB0ZXN0X3QxIHdoZXJlIGlkPTN3Zufo
   108  zTDaZBPqDAAAOwAAAF4UAAAAAG4AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAEAw/+AQQwAPcBAADx
   109  NF8=
   110  zTDaZCDqDAAAMAAAAI4UAAAAAG4AAAAAAAEAAgAE//ADAAAABXRlc3QzAhdKe3NW
   111  '/*!*/;
   112  ### DELETE FROM `testdb`.`test_t1`
   113  ### WHERE
   114  ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
   115  ###   @2='test3' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
   116  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
   117  ###   @4=23 /* TINYINT meta=0 nullable=0 is_null=0 */
   118  # at 5262
   119  #230814 21:49:01 server id 3306  end_log_pos 5293 CRC32 0x3de852a0      Xid = 49
   120  COMMIT/*!*/;
   121  DELIMITER ;
   122  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */;
   123  DELIMITER ;
   124  # End of log file
   125  ROLLBACK /* added by mysqlbinlog */;
   126  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
   127  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 

使用 -B选项

[root@centos7 binlog]# /mysql/app/mysqlbinlog_flashback -B -v -v --start-position=4294 --stop-position=5293 testdb-binlog.000001 > 1.txt
[root@centos7 binlog]# cat -n 1.txt 
     1  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
     2  /*!40019 SET @@session.max_insert_delayed_threads=0*/;
     3  /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
     4  DELIMITER /*!*/;
     5  #230814 21:13:36 server id 3306  end_log_pos 123 CRC32 0xb1fa7209       Start: binlog v 4, server v 5.7.43-log created 230814 21:13:36 at startup
     6  # Warning: this binlog is either in use or was not closed properly.
     7  ROLLBACK/*!*/;
     8  BINLOG '
     9  gCjaZA/qDAAAdwAAAHsAAAABAAQANS43LjQzLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
    10  AAAAAAAAAAAAAAAAAACAKNpkEzgNAAgAEgAEBAQEEgAAXwAEGggAAAAICAgCAAAACgoKKioAEjQA
    11  AQly+rE=
    12  '/*!*/;
    13  #230814 21:48:52 server id 3306  end_log_pos 4463 CRC32 0x3c6a9f0a      Rows_query
    14  # insert into testdb.test_t1(`name`,`sex`,`age`)
    15  # values('test100','w',25)
    16  #230814 21:48:52 server id 3306  end_log_pos 4522 CRC32 0x41b54e77      Table_map: `testdb`.`test_t1` mapped to number 110
    17  #230814 21:48:52 server id 3306  end_log_pos 4603 CRC32 0x3a318f4a      Xid = 47
    18  COMMIT/*!*/;
    19  #230814 21:48:57 server id 3306  end_log_pos 4668 CRC32 0x166dc78e      GTID [commit=no]
    20  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    21  #230814 21:48:57 server id 3306  end_log_pos 4809 CRC32 0xbf61fbff      Rows_query
    22  # update test_t1 set name='test04' where id=4
    23  #230814 21:48:57 server id 3306  end_log_pos 4868 CRC32 0xedb93318      Table_map: `testdb`.`test_t1` mapped to number 110
    24  #230814 21:48:57 server id 3306  end_log_pos 4962 CRC32 0x792e93c6      Xid = 48
    25  COMMIT/*!*/;
    26  #230814 21:49:01 server id 3306  end_log_pos 5027 CRC32 0x41a44941      GTID [commit=no]
    27  SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
    28  #230814 21:49:01 server id 3306  end_log_pos 5155 CRC32 0xe8e76677      Rows_query
    29  # delete from test_t1 where id=3
    30  #230814 21:49:01 server id 3306  end_log_pos 5214 CRC32 0x5f34f100      Table_map: `testdb`.`test_t1` mapped to number 110
    31  #230814 21:49:01 server id 3306  end_log_pos 5293 CRC32 0x3de852a0      Xid = 49
    32  COMMIT/*!*/;
    33  #230814 21:49:01 server id 3306  end_log_pos 5262 CRC32 0x56737b4a      Delete_rows: table id 110 flags: STMT_END_F
    34
    35  BINLOG '
    36  zTDaZB3qDAAANgAAACMUAACAAB5kZWxldGUgZnJvbSB0ZXN0X3QxIHdoZXJlIGlkPTN3Zufo
    37  zTDaZBPqDAAAOwAAAF4UAAAAAG4AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAEAw/+AQQwAPcBAADx
    38  NF8=
    39  zTDaZB7qDAAAMAAAAI4UAAAAAG4AAAAAAAEAAgAE//ADAAAABXRlc3QzAhdKe3NW
    40  '/*!*/;
    41  ### INSERT INTO `testdb`.`test_t1`
    42  ### SET
    43  ###   @1=3 /* INT meta=0 nullable=0 is_null=0 */
    44  ###   @2='test3' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    45  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    46  ###   @4=23 /* TINYINT meta=0 nullable=0 is_null=0 */
    47  #230814 21:48:57 server id 3306  end_log_pos 4931 CRC32 0xbbb1e163      Update_rows: table id 110 flags: STMT_END_F
    48
    49  BINLOG '
    50  yTDaZB3qDAAAQwAAAMkSAACAACt1cGRhdGUgdGVzdF90MSBzZXQgbmFtZT0ndGVzdDA0JyB3aGVy
    51  ZSBpZD00//thvw==
    52  yTDaZBPqDAAAOwAAAAQTAAAAAG4AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAEAw/+AQQwAPcBABgz
    53  ue0=
    54  yTDaZB/qDAAAPwAAAEMTAAAAAG4AAAAAAAEAAgAE///wBAAAAAZ0ZXN0MDQBGPAEAAAABXRlc3Q0
    55  ARhj4bG7
    56  '/*!*/;
    57  ### UPDATE `testdb`.`test_t1`
    58  ### WHERE
    59  ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    60  ###   @2='test04' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    61  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    62  ###   @4=24 /* TINYINT meta=0 nullable=0 is_null=0 */
    63  ### SET
    64  ###   @1=4 /* INT meta=0 nullable=0 is_null=0 */
    65  ###   @2='test4' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    66  ###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    67  ###   @4=24 /* TINYINT meta=0 nullable=0 is_null=0 */
    68  #230814 21:48:52 server id 3306  end_log_pos 4572 CRC32 0x0383c901      Write_rows: table id 110 flags: STMT_END_F
    69
    70  BINLOG '
    71  xDDaZB3qDAAAXwAAAG8RAACAAEdpbnNlcnQgaW50byB0ZXN0ZGIudGVzdF90MShgbmFtZWAsYHNl
    72  eGAsYGFnZWApCnZhbHVlcygndGVzdDEwMCcsJ3cnLDI1KQqfajw=
    73  xDDaZBPqDAAAOwAAAKoRAAAAAG4AAAAAAAEABnRlc3RkYgAHdGVzdF90MQAEAw/+AQQwAPcBAHdO
    74  tUE=
    75  xDDaZCDqDAAAMgAAANwRAAAAAG4AAAAAAAEAAgAE//AGAAAAB3Rlc3QxMDACGQHJgwM=
    76  '/*!*/;
    77  ### DELETE FROM `testdb`.`test_t1`
    78  ### WHERE
    79  ###   @1=6 /* INT meta=0 nullable=0 is_null=0 */
    80  ###   @2='test100' /* VARSTRING(48) meta=48 nullable=0 is_null=0 */
    81  ###   @3=2 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
    82  ###   @4=25 /* TINYINT meta=0 nullable=0 is_null=0 */
    83  DELIMITER ;
    84  SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog *//*!*/;
    85  DELIMITER ;
    86  # End of log file
    87  ROLLBACK /* added by mysqlbinlog */;
    88  /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
    89  /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
[root@centos7 binlog]# 



#如上
14~15行记录原来的insert信息
22行记录原来的update信息
29行记录原来的delete信息

41~46将29行的delete变为了insert
57~67将22行的update再改回去了
77~82将14~15的insert变为了delete


#解锁表
mysql> unlock tables; 

#注意87行是一个 回滚操作,需要手动改为commit,修改好后执行文件进行恢复
[root@centos7 binlog]# mysql -uroot -prootroot testdb < 1.txt 
mysql: [Warning] Using a password on the command line interface can be insecure.
[root@centos7 binlog]# 



#检查
mysql> select * from testdb.test_t1;
+----+-------+-----+-----+
| id | name  | sex | age |
+----+-------+-----+-----+
|  1 | test1 | w   |  21 |
|  2 | test2 | m   |  22 |
|  3 | test3 | w   |  23 |
|  4 | test4 | m   |  24 |
|  5 | test5 | w   |  25 |
+----+-------+-----+-----+
5 rows in set (0.01 sec)

说明:

-B 反转,闪回,如果是insert ,就对应delete,如果是delete,对应insert,如果是update,就将set和where调换

1.8.3 利用开源binlog2sql 闪回误删除的表

提取SQL,生成回滚SQL

使用前提:binlog_format=row,binlog_row_image=full

下载安装:https://github.com/danfengcao/binlog2sql

1.8.3.1 安装步骤:
#文件结构
[root@centos7 app]# pwd
/mysql/app
[root@centos7 app]# tree binlog2sql
binlog2sql
|-- binlog2sql
|   |-- binlog2sql.py
|   |-- binlog2sql_util.py
|   |-- binlog2sql_util.pyc
|   `-- __init__.py
`-- binlog2sql_dependencies
    |-- argparse-1.4.0-py2.py3-none-any.whl
    |-- linecache2-1.0.0-py2.py3-none-any.whl
    |-- mysql-replication-0.9.tar.gz
    |-- pip-9.0.1.tar.gz
    |-- PyMySQL-0.7.8-py2-none-any.whl
    |-- setuptools-0.6c11.tar.gz
    |-- six-1.10.0-py2.py3-none-any.whl
    |-- traceback2-1.4.0-py2.py3-none-any.whl
    |-- unittest2-1.1.0-py2.py3-none-any.whl
    `-- wheel-0.24.0-py2.py3-none-any.whl

2 directories, 14 files


[root@centos7 app]# cd binlog2sql/binlog2sql_dependencies/
[root@centos7 binlog2sql_dependencies]# tar xvf setuptools-0.6c11.tar.gz 
[root@centos7 binlog2sql_dependencies]# cd setuptools-0.6c11
[root@centos7 setuptools-0.6c11]# python setup.py install
......
Installed /usr/lib/python2.7/site-packages/setuptools-0.6c11-py2.7.egg
Processing dependencies for setuptools==0.6c11
Finished processing dependencies for setuptools==0.6c11
[root@centos7 setuptools-0.6c11]# cd ..
[root@centos7 binlog2sql_dependencies]# tar xvf pip-9.0.1.tar.gz
[root@centos7 binlog2sql_dependencies]# cd pip-9.0.1
[root@centos7 pip-9.0.1]# python setup.py install
......
Installed /usr/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg
Processing dependencies for pip==9.0.1
Finished processing dependencies for pip==9.0.1
[root@centos7 pip-9.0.1]# cd ..
[root@centos7 binlog2sql_dependencies]# pip install *.whl mysql-replication-0.9.tar.gz
Processing ./mysql-replication-0.9.tar.gz
Processing ./argparse-1.4.0-py2.py3-none-any.whl
Processing ./linecache2-1.0.0-py2.py3-none-any.whl
Processing ./PyMySQL-0.7.8-py2-none-any.whl
Processing ./six-1.10.0-py2.py3-none-any.whl
Processing ./traceback2-1.4.0-py2.py3-none-any.whl
Processing ./unittest2-1.1.0-py2.py3-none-any.whl
Processing ./wheel-0.24.0-py2.py3-none-any.whl
Installing collected packages: argparse, linecache2, PyMySQL, six, traceback2, unittest2, wheel, mysql-replication
  Found existing installation: six 1.9.0
    Uninstalling six-1.9.0:
      Successfully uninstalled six-1.9.0
  Running setup.py install for mysql-replication ... done
Successfully installed PyMySQL-0.7.8 argparse-1.4.0 linecache2-1.0.0 mysql-replication-0.9 six-1.10.0 traceback2-1.4.0 unittest2-1.1.0 wheel-0.24.0
[root@centos7 binlog2sql_dependencies]# 

#安装完成后,设置环境变量,别名:
alias binlog2sql='python /mysql/app/binlog2sql/binlog2sql/binlog2sql.py'

帮助信息

[root@centos7 ~]# binlog2sql --help
usage: binlog2sql.py [-h HOST] [-u USER] [-p PASSWORD] [-P PORT]
                     [--start-file STARTFILE] [--start-position STARTPOS]
                     [--stop-file ENDFILE] [--stop-position ENDPOS]
                     [--start-datetime STARTTIME] [--stop-datetime STOPTIME]
                     [--stop-never] [--help] [-d [DATABASES [DATABASES ...]]]
                     [-t [TABLES [TABLES ...]]] [-K] [-B]

Parse MySQL binlog to SQL you want

optional arguments:
  --stop-never          Wait for more data from the server. default: stop
                        replicate at the last binlog when you start binlog2sql
  --help                help infomation
  -K, --no-primary-key  Generate insert sql without primary key if exists
  -B, --flashback       Flashback data to start_postition of start_file

connect setting:
  -h HOST, --host HOST  Host the MySQL database server located
  -u USER, --user USER  MySQL Username to log in as
  -p PASSWORD, --password PASSWORD
                        MySQL Password to use
  -P PORT, --port PORT  MySQL port to use

range filter:
  --start-file STARTFILE
                        Start binlog file to be parsed
  --start-position STARTPOS, --start-pos STARTPOS
                        Start position of the --start-file
  --stop-file ENDFILE, --end-file ENDFILE
                        Stop binlog file to be parsed. default: '--start-file'
  --stop-position ENDPOS, --end-pos ENDPOS
                        Stop position of --stop-file. default: latest position
                        of '--stop-file'
  --start-datetime STARTTIME
                        Start reading the binlog at first event having a
                        datetime equal or posterior to the argument; the
                        argument must be a date and time in the local time
                        zone, in any format accepted by the MySQL server for
                        DATETIME and TIMESTAMP types, for example: 2004-12-25
                        11:25:56 (you should probably use quotes for your
                        shell to set it properly).
  --stop-datetime STOPTIME
                        Stop reading the binlog at first event having a
                        datetime equal or posterior to the argument; the
                        argument must be a date and time in the local time
                        zone, in any format accepted by the MySQL server for
                        DATETIME and TIMESTAMP types, for example: 2004-12-25
                        11:25:56 (you should probably use quotes for your
                        shell to set it properly).

schema filter:
  -d [DATABASES [DATABASES ...]], --databases [DATABASES [DATABASES ...]]
                        dbs you want to process
  -t [TABLES [TABLES ...]], --tables [TABLES [TABLES ...]]
                        tables you want to process
[root@centos7 ~]# 
1.8.3.2 案例:
#创建测试表
create table test_t2 (
`id` int(10) unsigned not null auto_increment,
`name` varchar(16) not null,
`sex` enum('m','w') not null default 'm',
`age` tinyint(3) unsigned not null,
primary key (`id`)
) engine=innodb default charset=utf8;

insert into testdb.test_t2(`name`,`sex`,`age`) values
('test1','w',21),
('test2','m',22),
('test3','w',23),
('test4','m',24),
('test5','w',25);

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-08-14 22:44:56 |
+---------------------+
1 row in set (0.00 sec)

误操作

mysql> delete from testdb.test_t2;
Query OK, 5 rows affected (0.01 sec)

mysql> select * from testdb.test_t2;
Empty set (0.00 sec)

恢复

mysql> show master status;
+----------------------+----------+--------------+------------------+-------------------+
| File                 | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------+----------+--------------+------------------+-------------------+
| testdb-binlog.000001 |     7606 |              |                  |                   |
+----------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-08-14 22:46:43 |
+---------------------+
1 row in set (0.00 sec)

5293

show binlog events in 'testdb-binlog.000001' from 6357;

image-20230814225028991

先找到已经被删除的数据:

方法1:按时间点

#2023-08-14 22:44:56 到 2023-08-14 22:46:43


binlog2sql -h192.168.1.10 -P3306 -uroot -proot -dtestdb -t test_t2 --start-file='testdb-binlog.000001' --stop-file='testdb-binlog.000001' --start-datetime='2023-08-14 22:44:56' --stop-datetime='2023-08-14 22:46:43'


[root@centos7 ~]# binlog2sql -h192.168.1.10 -P3306 -uroot -proot -dtestdb -t test_t2 --start-file='testdb-binlog.000001' --stop-file='testdb-binlog.000001' --start-datetime='2023-08-14 22:44:56' --stop-datetime='2023-08-14 22:46:43'
DELETE FROM `testdb`.`test_t2` WHERE `age`=21 AND `sex`='w' AND `id`=1 AND `name`='test1' LIMIT 1; #start 7227 end 7575 time 2023-08-14 22:45:53
DELETE FROM `testdb`.`test_t2` WHERE `age`=22 AND `sex`='m' AND `id`=2 AND `name`='test2' LIMIT 1; #start 7227 end 7575 time 2023-08-14 22:45:53
DELETE FROM `testdb`.`test_t2` WHERE `age`=23 AND `sex`='w' AND `id`=3 AND `name`='test3' LIMIT 1; #start 7227 end 7575 time 2023-08-14 22:45:53
DELETE FROM `testdb`.`test_t2` WHERE `age`=24 AND `sex`='m' AND `id`=4 AND `name`='test4' LIMIT 1; #start 7227 end 7575 time 2023-08-14 22:45:53
DELETE FROM `testdb`.`test_t2` WHERE `age`=25 AND `sex`='w' AND `id`=5 AND `name`='test5' LIMIT 1; #start 7227 end 7575 time 2023-08-14 22:45:53
[root@centos7 ~]# 

方法2:按pos

binlog2sql -h192.168.1.10 -P3306 -uroot -proot -dtestdb -t test_t2 --start-file='testdb-binlog.000001' --stop-file='testdb-binlog.000001' --start-position=7292 --stop-position=7606


[root@centos7 ~]# binlog2sql -h192.168.1.10 -P3306 -uroot -proot -dtestdb -t test_t2 --start-file='testdb-binlog.000001' --stop-file='testdb-binlog.000001' --start-position=7292 --stop-position=7606
DELETE FROM `testdb`.`test_t2` WHERE `age`=21 AND `sex`='w' AND `id`=1 AND `name`='test1' LIMIT 1; #start 7292 end 7575 time 2023-08-14 22:45:53
DELETE FROM `testdb`.`test_t2` WHERE `age`=22 AND `sex`='m' AND `id`=2 AND `name`='test2' LIMIT 1; #start 7292 end 7575 time 2023-08-14 22:45:53
DELETE FROM `testdb`.`test_t2` WHERE `age`=23 AND `sex`='w' AND `id`=3 AND `name`='test3' LIMIT 1; #start 7292 end 7575 time 2023-08-14 22:45:53
DELETE FROM `testdb`.`test_t2` WHERE `age`=24 AND `sex`='m' AND `id`=4 AND `name`='test4' LIMIT 1; #start 7292 end 7575 time 2023-08-14 22:45:53
DELETE FROM `testdb`.`test_t2` WHERE `age`=25 AND `sex`='w' AND `id`=5 AND `name`='test5' LIMIT 1; #start 7292 end 7575 time 2023-08-14 22:45:53
[root@centos7 ~]# 
通过闪回恢复数据

方法1:按时间点

binlog2sql -h192.168.1.10 -P3306 -uroot -proot -dtestdb -t test_t2 --start-file='testdb-binlog.000001' --stop-file='testdb-binlog.000001' --start-datetime='2023-08-14 22:44:56' --stop-datetime='2023-08-14 22:46:43' --flashback > test_t2.txt


[root@centos7 ~]# binlog2sql -h192.168.1.10 -P3306 -uroot -proot -dtestdb -t test_t2 --start-file='testdb-binlog.000001' --stop-file='testdb-binlog.000001' --start-datetime='2023-08-14 22:44:56' --stop-datetime='2023-08-14 22:46:43' --flashback > test_t2.txt
[root@centos7 ~]# cat test_t2.txt
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (25, 'w', 5, 'test5'); #start 7227 end 7575 time 2023-08-14 22:45:53
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (24, 'm', 4, 'test4'); #start 7227 end 7575 time 2023-08-14 22:45:53
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (23, 'w', 3, 'test3'); #start 7227 end 7575 time 2023-08-14 22:45:53
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (22, 'm', 2, 'test2'); #start 7227 end 7575 time 2023-08-14 22:45:53
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (21, 'w', 1, 'test1'); #start 7227 end 7575 time 2023-08-14 22:45:53
[root@centos7 ~]#

方法2:按日志位置

binlog2sql -h192.168.1.10 -P3306 -uroot -proot -dtestdb -t test_t2 --start-file='testdb-binlog.000001' --stop-file='testdb-binlog.000001' --start-position=7292 --stop-position=7606 --flashback > test_t2.txt

[root@centos7 ~]# binlog2sql -h192.168.1.10 -P3306 -uroot -proot -dtestdb -t test_t2 --start-file='testdb-binlog.000001' --stop-file='testdb-binlog.000001' --start-position=7292 --stop-position=7606 --flashback > test_t2.txt
[root@centos7 ~]# cat test_t2.txt
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (25, 'w', 5, 'test5'); #start 7292 end 7575 time 2023-08-14 22:45:53
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (24, 'm', 4, 'test4'); #start 7292 end 7575 time 2023-08-14 22:45:53
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (23, 'w', 3, 'test3'); #start 7292 end 7575 time 2023-08-14 22:45:53
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (22, 'm', 2, 'test2'); #start 7292 end 7575 time 2023-08-14 22:45:53
INSERT INTO `testdb`.`test_t2`(`age`, `sex`, `id`, `name`) VALUES (21, 'w', 1, 'test1'); #start 7292 end 7575 time 2023-08-14 22:45:53
[root@centos7 ~]# 

恢复

mysql -uroot -prootroot testdb < test_t2.txt

#查看数据
mysql> select * from testdb.test_t2;
+----+-------+-----+-----+
| id | name  | sex | age |
+----+-------+-----+-----+
|  1 | test1 | w   |  21 |
|  2 | test2 | m   |  22 |
|  3 | test3 | w   |  23 |
|  4 | test4 | m   |  24 |
|  5 | test5 | w   |  25 |
+----+-------+-----+-----+
5 rows in set (0.00 sec)

1.8.4 binlog_rollback

下载工具

https://github.com/GoDannyLai/binlog_rollback/releases/download/V2.1/binlog_rollback-V2.1-linux64.zip

#帮助信息
[root@centos7 app]# ./binlog_rollback --help

binlog_rollback V2.1 By laijunshou@gmail.com

parse mysql binlog to generate analysis report, redo or rollback sql.
two work mode:
        read binlog from master, work as a fake slave: ./binlog_rollback -m repl opts...
        read binlog from local filesystem: ./binlog_rollback -m file opts... mysql-bin.000010


usage example:
generate redo sql and analysis report:
        ./binlog_rollback -m repl -w 2sql -M mysql -t 4 -mid 3331 -H 127.0.0.1 -P 3306 -u xxx -p xxx -dbs db1,db2 -tbs tb1,tb2 -sbin mysql-bin.000556 -spos 107 -ebin mysql-bin.000559 -epos 4 -e -f -r 20 -k -b 100 -l 10 -o /home/apps/tmp -dj tbs_all_def.json

generate rollback sql and analysis report:
        ./binlog_rollback -m file -w rollback -M mysql -t 4 -H 127.0.0.1 -P 3306 -u xxx -p xxx -dbs db1,db2 -tbs tb1,tb2 -tbs tb1,tb2 -sdt "2017-09-28 13:00:00" -edt "2017-09-28 16:00:00" -e -f -r 20 -k -b 100 -l 10  -o /home/apps/tmp -dj tbs_all_def.json /apps/dbdata/mysqldata_3306/log/mysql-bin.000556

only generate analysis report:
        ./binlog_rollback -m repl -w stats -M mysql -H 127.0.0.1 -P 3306 -u xxx -p xxx -dbs db1,db2 -tbs tb1,tb2 -sbin mysql-bin.000556 -spos 107 -i 20 -b 100 -l 10 -o /home/apps/tmp

suported options:

  -C    works with -w='stats', keep analyzing transations to last binlog for -m=file, and keep analyzing for -m=repl
  -H string
        master host, DONOT need to specify when -w=stats. if mode is file, it can be slave or other mysql contains same schema and table structure, not only master. default 127.0.0.1 (default "127.0.0.1")
  -I    for insert statement when -wtype=2sql, ignore primary key
  -M string
        valid options are:  mysql,mariadb. server of binlog, mysql or mariadb, default mysql (default "mysql")
  -P uint
        master port, default 3306. DONOT need to specify when -w=stats (default 3306)
  -S string
        mysql socket file
  -U    prefer to use unique key instead of primary key to build where condition for delete/update sql
  -a    Works with -w=2sql|rollback. for update sql, include unchanged columns. for update and delete, use all columns to build where condition.
        default false, this is, use changed columns to build set part, use primary/unique key to build where condition
  -b int
        transaction with affected rows greater or equal to this value is considerated as big transaction. Valid values range from 10 to 30000, default 500 (default 500)
  -d    Works with -w=2sql|rollback. Prefix table name with database name in sql, ex: insert into db1.tb1 (x1, x1) values (y1, y1). Default true (default true)
  -dbs string
        only parse database which match any of these regular expressions. The regular expression should be in lower case because database name is translated into lower case and then matched against it. 
                Multi regular expressions is seperated by comma, default parse all databases. Useless when -w=stats
  -dj string
        dump table structure to this file. default tblDef.json (default "tblDef.json")
  -e    Works with -w=2sql|rollback. Print database/table/datetime/binlogposition...info on the line before sql, default false
  -ebin string
        binlog file to stop reading
  -edt string
        Stop reading the binlog at first event having a datetime equal or posterior to the argument, it should be like this: "2004-12-25 11:25:56"
  -epos uint
        Stop reading the binlog at position
  -f    Works with -w=2sql|rollback. one file for one table if true, else one file for all tables. default false. Attention, always one file for one binlog
  -i int
        works with -w='stats', print stats info each PrintInterval. Valid values range from 1 to 600, default 30 (default 30)
  -ies string
        for sql which is error to parsed and matched by this regular expression, just print error info, skip it and continue parsing, otherwise stop parsing and exit.
                The regular expression should be in lower case, because sql is translated into lower case and then matched against it. (default "^create definer.+trigger")
  -k    Works with -w=2sql|rollback. wrap result statements with 'begin...commit|rollback'
  -l int
        transaction with duration greater or equal to this value is considerated as long transaction. Valid values range from 1 to 3600, default 300 (default 300)
  -m string
        valid options are:  repl,file. repl: as a slave to get binlogs from master. file: get binlogs from local filesystem. default file (default "file")
  -mid uint
        works with -m=repl, this program replicates from master as slave to read binlogs. Must set this server id unique from other slaves, default 3320 (default 3320)
  -o string
        result output dir, default current work dir. Attension, result files could be large, set it to a dir with large free space
  -oj
        Only use table structure from -rj, do not get or merge table struct from mysql
  -ors
        for mysql>=5.6.2 and binlog_rows_query_log_events=on, if set, output original sql. default false
  -p string
        mysql user password. DONOT need to specify when -w=stats
  -r int
        Works with -w=2sql|rollback. rows for each insert sql. Valid values range from 1 to 500, default 30 (default 30)
  -rj string
        Works with -w=2sql|rollback, read table structure from this file and merge from mysql
  -sbin string
        binlog file to start reading
  -sdt string
        Start reading the binlog at first event having a datetime equal or posterior to the argument, it should be like this: "2004-12-25 11:25:56"
  -spos uint
        start reading the binlog at position
  -sql string
        valid options are:  insert,update,delete. only parse these types of sql, comma seperated, valid types are: insert, update, delete; default is all(insert,update,delete)
  -stsql
        when -w=2sql, also parse plain sql and write into result file even if binlog_format is not row. default false
  -t uint
        Works with -w=2sql|rollback. threads to run, default 4 (default 2)
  -tbs string
        only parse table which match any of these regular expressions.The regular expression should be in lower case because database name is translated into lower case and then matched against it. 
                 Multi regular expressions is seperated by comma, default parse all tables. Useless when -w=stats
  -tl string
        time location to parse timestamp/datetime column in binlog, such as Asia/Shanghai. default Local (default "Local")
  -u string
        mysql user. DONOT need to specify when -w=stats
  -v    print version
  -w string
        valid options are:  tbldef,stats,2sql,rollback. tbldef: only get table definition structure; 2sql: convert binlog to sqls, rollback: generate rollback sqls, stats: analyze transactions. default: stats (default "stats")
[root@centos7 app]# 

参数说明:

  • -m:file: get binlogs from local filesystem
  • -w:rollback: generate rollback sqls
  • -M:database type mysql or mariadb
  • -t:threads to run
  • -H:host
  • -P:port
  • -u:user
  • -p:password
  • -dbs:database
  • -tbs:tablename
  • -sdt:start time
  • -edt:end time
  • -sql:解析的sql类型,insert,update,delete
  • -d:Prefix table name with database name in sql
  • -e:Print database/table/datetime/binlogposition…info on the line before sql
  • -f:one file for one table if true
  • -r:rows for each insert sql
  • -b:transaction with affected rows greater or equal to this value is considerated as big transaction
  • -l:transaction with duration greater or equal to this value is considerated as long transaction
  • -o:result output dir
  • -dj:dump table structure to this file

案例

create database testdb;
use testdb
create table test_t (id int,name varchar(100));
insert into test_t values(1,'test1');
insert into test_t values(2,'test2');
insert into test_t values(3,'test3');
insert into test_t values(4,'test4');
insert into test_t values(5,'test5');
insert into test_t values(6,'test6');
mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-08-16 20:21:01 |
+---------------------+
1 row in set (0.00 sec)

delete from test_t;

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2023-08-16 20:21:19 |
+---------------------+
1 row in set (0.00 sec)

show binlog events in 'testdb-binlog.000001';

mysql> show binlog events in 'testdb-binlog.000001';
+----------------------+------+----------------+-----------+-------------+--------------------------------------------------------------+
| Log_name             | Pos  | Event_type     | Server_id | End_log_pos | Info                                                         |
+----------------------+------+----------------+-----------+-------------+--------------------------------------------------------------+
| testdb-binlog.000001 |    4 | Format_desc    |      3306 |         123 | Server ver: 5.7.43-log, Binlog ver: 4                        |
| testdb-binlog.000001 |  123 | Previous_gtids |      3306 |         154 |                                                              |
| testdb-binlog.000001 |  154 | Anonymous_Gtid |      3306 |         219 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 |  219 | Query          |      3306 |         319 | create database testdb                                       |
| testdb-binlog.000001 |  319 | Anonymous_Gtid |      3306 |         384 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 |  384 | Query          |      3306 |         508 | use `testdb`; create table test_t (id int,name varchar(100)) |
| testdb-binlog.000001 |  508 | Anonymous_Gtid |      3306 |         573 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 |  573 | Query          |      3306 |         647 | BEGIN                                                        |
| testdb-binlog.000001 |  647 | Rows_query     |      3306 |         707 | # insert into test_t values(1,'test1')                       |
| testdb-binlog.000001 |  707 | Table_map      |      3306 |         761 | table_id: 109 (testdb.test_t)                                |
| testdb-binlog.000001 |  761 | Write_rows     |      3306 |         808 | table_id: 109 flags: STMT_END_F                              |
| testdb-binlog.000001 |  808 | Xid            |      3306 |         839 | COMMIT /* xid=11 */                                          |
| testdb-binlog.000001 |  839 | Anonymous_Gtid |      3306 |         904 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 |  904 | Query          |      3306 |         978 | BEGIN                                                        |
| testdb-binlog.000001 |  978 | Rows_query     |      3306 |        1038 | # insert into test_t values(2,'test2')                       |
| testdb-binlog.000001 | 1038 | Table_map      |      3306 |        1092 | table_id: 109 (testdb.test_t)                                |
| testdb-binlog.000001 | 1092 | Write_rows     |      3306 |        1139 | table_id: 109 flags: STMT_END_F                              |
| testdb-binlog.000001 | 1139 | Xid            |      3306 |        1170 | COMMIT /* xid=12 */                                          |
| testdb-binlog.000001 | 1170 | Anonymous_Gtid |      3306 |        1235 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 | 1235 | Query          |      3306 |        1309 | BEGIN                                                        |
| testdb-binlog.000001 | 1309 | Rows_query     |      3306 |        1369 | # insert into test_t values(3,'test3')                       |
| testdb-binlog.000001 | 1369 | Table_map      |      3306 |        1423 | table_id: 109 (testdb.test_t)                                |
| testdb-binlog.000001 | 1423 | Write_rows     |      3306 |        1470 | table_id: 109 flags: STMT_END_F                              |
| testdb-binlog.000001 | 1470 | Xid            |      3306 |        1501 | COMMIT /* xid=13 */                                          |
| testdb-binlog.000001 | 1501 | Anonymous_Gtid |      3306 |        1566 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 | 1566 | Query          |      3306 |        1640 | BEGIN                                                        |
| testdb-binlog.000001 | 1640 | Rows_query     |      3306 |        1700 | # insert into test_t values(4,'test4')                       |
| testdb-binlog.000001 | 1700 | Table_map      |      3306 |        1754 | table_id: 109 (testdb.test_t)                                |
| testdb-binlog.000001 | 1754 | Write_rows     |      3306 |        1801 | table_id: 109 flags: STMT_END_F                              |
| testdb-binlog.000001 | 1801 | Xid            |      3306 |        1832 | COMMIT /* xid=14 */                                          |
| testdb-binlog.000001 | 1832 | Anonymous_Gtid |      3306 |        1897 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 | 1897 | Query          |      3306 |        1971 | BEGIN                                                        |
| testdb-binlog.000001 | 1971 | Rows_query     |      3306 |        2031 | # insert into test_t values(5,'test5')                       |
| testdb-binlog.000001 | 2031 | Table_map      |      3306 |        2085 | table_id: 109 (testdb.test_t)                                |
| testdb-binlog.000001 | 2085 | Write_rows     |      3306 |        2132 | table_id: 109 flags: STMT_END_F                              |
| testdb-binlog.000001 | 2132 | Xid            |      3306 |        2163 | COMMIT /* xid=15 */                                          |
| testdb-binlog.000001 | 2163 | Anonymous_Gtid |      3306 |        2228 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 | 2228 | Query          |      3306 |        2302 | BEGIN                                                        |
| testdb-binlog.000001 | 2302 | Rows_query     |      3306 |        2362 | # insert into test_t values(6,'test6')                       |
| testdb-binlog.000001 | 2362 | Table_map      |      3306 |        2416 | table_id: 109 (testdb.test_t)                                |
| testdb-binlog.000001 | 2416 | Write_rows     |      3306 |        2463 | table_id: 109 flags: STMT_END_F                              |
| testdb-binlog.000001 | 2463 | Xid            |      3306 |        2494 | COMMIT /* xid=16 */                                          |
| testdb-binlog.000001 | 2494 | Anonymous_Gtid |      3306 |        2559 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS'                         |
| testdb-binlog.000001 | 2559 | Query          |      3306 |        2633 | BEGIN                                                        |
| testdb-binlog.000001 | 2633 | Rows_query     |      3306 |        2675 | # delete from test_t                                         |
| testdb-binlog.000001 | 2675 | Table_map      |      3306 |        2729 | table_id: 109 (testdb.test_t)                                |
| testdb-binlog.000001 | 2729 | Delete_rows    |      3306 |        2836 | table_id: 109 flags: STMT_END_F                              |
| testdb-binlog.000001 | 2836 | Xid            |      3306 |        2867 | COMMIT /* xid=19 */                                          |
+----------------------+------+----------------+-----------+-------------+--------------------------------------------------------------+
48 rows in set (0.00 sec)



#恢复:
/mysql/app/binlog_rollback -m file -w rollback -M mysql -t 4 -H 192.168.1.10 -P 3306 -u root -p 'root' -dbs testdb -tbs test_t -sdt "2023-08-16 20:21:01" -edt "2023-08-16 20:21:19" -sql delete -d -e -f -r 20 -b 100 -l 10 -o /tmp/20230816 -dj tbs_all_def.json testdb-binlog.000001


[root@centos7 binlog]# /mysql/app/binlog_rollback -m file -w rollback -M mysql -t 4 -H 192.168.1.10 -P 3306 -u root -p 'root' -dbs testdb -tbs test_t -sdt "2023-08-16 20:21:01" -edt "2023-08-16 20:21:19" -sql delete -d -e -f -r 20 -b 100 -l 10 -o /tmp/20230816 -dj tbs_all_def.json testdb-binlog.000001
time="2023-08-16_20:28:37" level=info errcode=0 errmsg="start to get table structure from mysql"
time="2023-08-16_20:28:37" level=info errcode=0 errmsg="geting target table names from mysql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="geting table fields from mysql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="geting primary/unique keys from mysql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="successfully get table structure from mysql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="table definition has been dumped to /tmp/20230816/tbs_all_def.json"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start to parse binlog from local files"
time="2023-08-16_20:28:38" level=info errcode=0
start to parse testdb-binlog.000001 4


time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start thread 1 to generate redo/rollback sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start thread to analyze statistics from binlog"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start thread to write redo/rollback sql into file"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start thread 2 to generate redo/rollback sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start thread 3 to generate redo/rollback sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start thread 4 to generate redo/rollback sql"
time="2023-08-16_20:28:38" level=warning errcode=0
testdb-binlog.000002 not exists nor a file


time="2023-08-16_20:28:38" level=info errcode=0 errmsg="finish parsing binlog from local files"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="exit thread 2 to generate redo/rollback sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="exit thread 4 to generate redo/rollback sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="exit thread 3 to generate redo/rollback sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="exit thread to analyze statistics from binlog"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="exit thread 1 to generate redo/rollback sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="finish writing rollback sql into tmp files, start to revert content order of tmp files"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start thread 1 to revert rollback sql files"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="start to revert tmp file /tmp/20230816/.testdb.test_t.rollback.1.sql into /tmp/20230816/testdb.test_t.rollback.1.sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="finish reverting tmp file /tmp/20230816/.testdb.test_t.rollback.1.sql into /tmp/20230816/testdb.test_t.rollback.1.sql"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="exit thread 1 to revert rollback sql files"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="finish reverting content order of tmp files"
time="2023-08-16_20:28:38" level=info errcode=0 errmsg="exit thread to write redo/rollback sql into file"
[root@centos7 binlog]# 



#查看恢复后的文件结构
[root@centos7 ~]# ll /tmp/20230816 
total 20
-rw-r--r-- 1 root root 107 Aug 16 20:28 big_long_trx.txt
-rw-r--r-- 1 root root 291 Aug 16 20:28 binlog_stats.txt
-rw-r--r-- 1 root root  64 Aug 16 20:28 ddl_info.txt
-rw-r--r-- 1 root root 403 Aug 16 20:28 tbs_all_def.json
-rw-r--r-- 1 root root 244 Aug 16 20:28 testdb.test_t.rollback.1.sql
[root@centos7 ~]# 
[root@centos7 ~]# cat /tmp/20230816/big_long_trx.txt 
binlog            starttime           stoptime            startpos   stoppos    rows     duration   tables
[root@centos7 ~]# cat /tmp/20230816/binlog_stats.txt 
binlog            starttime           stoptime            startpos   stoppos    inserts  updates  deletes  database        table               
testdb-binlog.000001 2023-08-16_20:21:13 2023-08-16_20:21:13 2675       2836       0        0        6        testdb          test_t              
[root@centos7 ~]# cat /tmp/20230816/ddl_info.txt
datetime            binlog            startpos   stoppos    sql
[root@centos7 ~]# cat /tmp/20230816/tbs_all_def.json
{
        "testdb.test_t": {
                "_/0/0": {
                        "database": "testdb",
                        "table": "test_t",
                        "columns": [
                                {
                                        "column_name": "id",
                                        "column_type": "int"
                                },
                                {
                                        "column_name": "name",
                                        "column_type": "varchar"
                                }
                        ],
                        "primary_key": null,
                        "unique_keys": null,
                        "ddl_info": {
                                "binlog": "_",
                                "start_position": 0,
                                "stop_position": 0,
                                "ddl_sql": ""
                        }
                }
        }
}[root@centos7 ~]# cat /tmp/20230816/testdb.test_t.rollback.1.sql
INSERT INTO `testdb`.`test_t` (`id`,`name`) VALUES (1,'test1'), (2,'test2'), (3,'test3'), (4,'test4'), (5,'test5'), (6,'test6');
# datetime=2023-08-16_20:21:13 database=testdb table=test_t binlog=testdb-binlog.000001 startpos=2675 stoppos=2836
[root@centos7 ~]# 

1.9 防止误删sql_safe_updates 参数

sql_safe_updates:控制权限,防止误删除。

#开启这个功能
#1、修改参数(不能加入到my.cnf 里面)
set global sql_safe_updates=1;

#2、登录的时候添加选项,对当前会话有效
mysql -uroot -prootroot --safe-updates


#测试
mysql> delete from testdb.test_t2;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column. 
mysql> 

1.10 binlog 日志突然爆增怎么分析?

场景:

日志突然增大,分析为什么?

针对binlog 日志对表的增删改统计分析:

mysqlbinlog --no-defaults --base64-output=decode-rows -vv testdb-binlog.000001| awk '/UPDATE|INSERT|DELETE/{gsub("###","");gsub("INSERT.*INTO","INSERT");gsub("DELETE.*FROM","DELETE");count[$1" "$2]++}END{for(i in count)print i,"\t",count[i]}' |sort -k3nr|head -n 10


[root@centos7 binlog]# mysqlbinlog --no-defaults --base64-output=decode-rows -vv testdb-binlog.000001| awk '/UPDATE|INSERT|DELETE/{gsub("###","");gsub("INSERT.*INTO","INSERT");gsub("DELETE.*FROM","DELETE");count[$1" "$2]++}END{for(i in count)print i,"\t",count[i]}' |sort -k3nr|head -n 10
# INSERT         10
INSERT `testdb`.`test_t`         10
INSERT `testdb`.`test_t2`        10
INSERT `testdb`.`test_t1`        7
DELETE `testdb`.`test_t2`        5
DELETE `testdb`.`test_t`         5
DELETE `testdb`.`test_t1`        2
UPDATE `testdb`.`test_t1`        2
[root@centos7 binlog]# 

其他分析binlog命令

mysqlbinlog -vv   mysql-bin.000039    |  \
   grep -i -e "^update" -e "^insert" -e "^delete" -e "^replace" -e "^alter"  | \
   cut -c1-100 | tr '[A-Z]' '[a-z]' |  \
   sed -e "s/\t/ /g;s/\`//g;s/(.*$//;s/ set .*$//;s/ as .*$//" | sed -e "s/ where .*$//" |  \
   sort | uniq -c | sort -nr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值