SHOW VARIABLES LIKE 'log_bin_basename'; 可以找到binlog文件保存的目录位置。比如说/var/lib/mysql/mysql-bin表示目录为/var/lib/mysql/下的以mysql-bin为前缀的文件。
我们通过文件的最后修改时间,可以看出binlog覆盖的时间范围。一般后缀的数字越大,表示越新。
mysql> SHOWVARIABLESLIKE'log_bin_basename'; +------------------+--------------------------+ | Variable_name | Value | +------------------+--------------------------+ | log_bin_basename | /var/lib/mysql/mysql-bin | +------------------+--------------------------+ 1 row in set (0.00 sec)
bash-4.2# ls /var/lib/mysql/mysql-bin* -alh -rw-r----- 1 mysql mysql 1.1G Sep 9 02:28 /var/lib/mysql/mysql-bin.000200 -rw-r----- 1 mysql mysql 1.1G Sep 9 02:32 /var/lib/mysql/mysql-bin.000201 -rw-r----- 1 mysql mysql 1.1G Sep 9 02:39 /var/lib/mysql/mysql-bin.000202 -rw-r----- 1 mysql mysql 1.1G Sep 9 02:45 /var/lib/mysql/mysql-bin.000203 -rw-r----- 1 mysql mysql 1.1G Sep 9 07:52 /var/lib/mysql/mysql-bin.000204 -rw-r----- 1 mysql mysql 1.1G Sep 9 12:10 /var/lib/mysql/mysql-bin.000205 -rw-r----- 1 mysql mysql 1.1G Sep 10 04:40 /var/lib/mysql/mysql-bin.000206 -rw-r----- 1 mysql mysql 1.2G Sep 10 07:00 /var/lib/mysql/mysql-bin.000207 -rw-r----- 1 mysql mysql 1.1G Sep 11 07:54 /var/lib/mysql/mysql-bin.000208 -rw-r----- 1 mysql mysql 1.1G Sep 12 03:03 /var/lib/mysql/mysql-bin.000209 -rw-r--r-- 1 root root 24M Sep 11 09:06 /var/lib/mysql/mysql-bin.000209.event.log -rw-r----- 1 mysql mysql 1.1G Sep 12 03:30 /var/lib/mysql/mysql-bin.000210 -rw-r----- 1 mysql mysql 1.1G Sep 12 08:33 /var/lib/mysql/mysql-bin.000211 -rw-r----- 1 mysql mysql 1.1G Sep 12 08:35 /var/lib/mysql/mysql-bin.000212 -rw-r----- 1 mysql mysql 1.1G Sep 12 22:00 /var/lib/mysql/mysql-bin.000213 -rw-r----- 1 mysql mysql 1.1G Sep 13 10:26 /var/lib/mysql/mysql-bin.000214 -rw-r----- 1 mysql mysql 1.1G Sep 13 10:29 /var/lib/mysql/mysql-bin.000215 -rw-r----- 1 mysql mysql 1.1G Sep 14 01:42 /var/lib/mysql/mysql-bin.000216 -rw-r----- 1 mysql mysql 637M Sep 14 06:11 /var/lib/mysql/mysql-bin.000217 -rw-r----- 1 mysql mysql 4.1K Sep 14 01:42 /var/lib/mysql/mysql-bin.index
我们可以找到insert into person values (1, 'first'),并且分别在前后的BEGIN和COMMIT找到position。
BEGIN往前找有一个position at 219,COMMIT往后找有一个position at 445,这就是插入语句的实际binlog范围。
# at 219 #240914 17:14:26 server id 1 end_log_pos 300 CRC32 0xb8159bc1 Query thread_id=1267 exec_time=0 error_code=0 SETTIMESTAMP=1726305266/*!*/; SET @@session.pseudo_thread_id=1267/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1436549120/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/; # at 300 #240914 17:14:26 server id 1 end_log_pos 414 CRC32 0xb7e0263b Query thread_id=1267 exec_time=0 error_code=0 use`tests`/*!*/; SETTIMESTAMP=1726305266/*!*/; insertinto person values (1, 'first') /*!*/; # at 414 #240914 17:14:26 server id 1 end_log_pos 445 CRC32 0x9345e6ca Xid = 30535 COMMIT/*!*/; # at 445
BEGIN往前找有一个position at 219,COMMIT往后找有一个position at 426,这就是插入语句的实际binlog范围。
# at 219 #240914 17:16:36 server id 1 end_log_pos 292 CRC32 0xe9082d52 Query thread_id=20 exec_time=0 error_code=0 SETTIMESTAMP=1726305396/*!*/; SET @@session.pseudo_thread_id=20/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1436549120/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; BEGIN /*!*/; # at 292 #240914 17:16:36 server id 1 end_log_pos 345 CRC32 0x1832ced4 Table_map: `tests`.`person` mapped to number 111 # at 345 #240914 17:16:36 server id 1 end_log_pos 395 CRC32 0x32d6a21b Write_rows: table id 111 flags: STMT_END_F ### INSERT INTO `tests`.`person` ### SET ### @1=1 ### @2='first' # at 395 #240914 17:16:36 server id 1 end_log_pos 426 CRC32 0x07619928 Xid = 149 COMMIT/*!*/; # at 426
我们可以看到binlog只保存了一句 delete from person。很遗憾,啥数据都没有,也没办法根据它生成逆向操作。
# at 445 #240914 17:15:13 server id 1 end_log_pos 510 CRC32 0x6a7a66e4 Anonymous_GTID last_committed=1 sequence_number=2 rbr_only=no SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/; # at 510 #240914 17:15:13 server id 1 end_log_pos 591 CRC32 0x55e4225b Query thread_id=1267 exec_time=0 error_code=0 SETTIMESTAMP=1726305313/*!*/; BEGIN /*!*/; # at 591 #240914 17:15:13 server id 1 end_log_pos 685 CRC32 0x10938b9d Query thread_id=1267 exec_time=0 error_code=0 SETTIMESTAMP=1726305313/*!*/; deletefrom person /*!*/; # at 685 #240914 17:15:13 server id 1 end_log_pos 716 CRC32 0x1ea4a681 Xid = 30610 COMMIT/*!*/; # at 716
# at 1574 #240914 17:16:38 server id 1 end_log_pos 1642 CRC32 0x944b1b94 Query thread_id=20 exec_time=1260 error_code=0 SETTIMESTAMP=1726305398/*!*/; BEGIN /*!*/; # at 1642 #240914 17:16:38 server id 1 end_log_pos 1695 CRC32 0x435282e2 Table_map: `tests`.`person` mapped to number 111 # at 1695 #240914 17:16:38 server id 1 end_log_pos 1745 CRC32 0x3063bf8c Delete_rows: table id 111 flags: STMT_END_F ### DELETE FROM `tests`.`person` ### WHERE ### @1=1 ### @2='first' # at 1745 #240914 17:16:38 server id 1 end_log_pos 1776 CRC32 0x086c2270 Xid = 3391 COMMIT/*!*/;
> python binlog2sql.py -h127.0.0.1 -P13306 -uroot -p --start-file=mysql-bin.000002 Password: INSERT INTO `tests`.`person`(`id`, `name`) VALUES (1, 'first'); #start 4 end 395 time 2024-09-14 17:16:36 DELETE FROM `tests`.`person` WHERE `id`=1 AND `name`='first' LIMIT 1; #start 426 end 667 time 2024-09-14 17:16:38
通过命令,输入用户名、密码、端口号、地址等,并且指定binlog文件
通过输出,可以看出所有正向操作,以及每个正向操作的时间、binlog位置
获取逆向操作:
> python binlog2sql.py -h127.0.0.1 -P13306 -uroot -p --start-file=mysql-bin.000002 --flashback Password: INSERT INTO `tests`.`person`(`id`, `name`) VALUES (1, 'first'); #start 426 end 667 time 2024-09-14 17:16:38 DELETE FROM `tests`.`person` WHERE `id`=1 AND `name`='first' LIMIT 1; #start 4 end 395 time 2024-09-14 17:16:36