my2sql是go版MySQL binlog解析工具,通过解析MySQL binlog ,可以生成原始SQL、回滚SQL、去除主键的INSERT SQL等,也可以生成DML统计信息。类似工具有binlog2sql、MyFlash、my2fback等,本工具基于my2fback、binlog_rollback工具二次开发而来。
git clone https://github.com/liuhr/my2sql.git cd my2sql/ go build .
二进制文件下载地址
https://github.com/liuhr/my2sql/blob/master/releases/centOS_release_7.x/my2sql
复制到我的docker中
#1、把my2sql 二进制文件复制到mysql8的容器中 docker cp /usr/local/bin/my2sql mysql8:/usr/local/bin #2、进入容器 docker exec -it mysql8 bash chmod +x /usr/local/bin/my2sql
mysql> show variables like 'binlog_format'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | binlog_format | ROW | +---------------+-------+ 1 row in set (0.00 sec) mysql> show master status; +----------+----------+--------------+------------------+--------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +----------+----------+--------------+------------------+----------------------------------------------+ | 1.000001 | 1021 | | | ecd66956-f106-11ec-bb85-0242ac110005:1-19718 | +----------+----------+--------------+------------------+----------------------------------------------+ 1 row in set (0.00 sec) mysql> flush logs; Query OK, 0 rows affected (0.71 sec) mysql> show master status; +----------+----------+--------------+------------------+----------------------------------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +----------+----------+--------------+------------------+----------------------------------------------+ | 1.000002 | 193 | | | ecd66956-f106-11ec-bb85-0242ac110005:1-19718 | +----------+----------+--------------+------------------+----------------------------------------------+ 1 row in set (0.00 sec) mysql> show variables like 'innodb_log_group_home_dir'; +---------------------------+-------+ | Variable_name | Value | +---------------------------+-------+ | innodb_log_group_home_dir | ./ | +---------------------------+-------+ 1 row in set (0.01 sec) mysql> show variables like '%datadir%'; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | datadir | /var/lib/mysql/ | +---------------+-----------------+ 1 row in set (0.00 sec)
-- 查看测试表结构 mysql> show create table sbtest.sbtest1\G; *************************** 1. row *************************** Table: sbtest1 Create Table: CREATE TABLE `sbtest1` ( `id` int NOT NULL AUTO_INCREMENT, `k` int NOT NULL DEFAULT '0', `c` char(120) COLLATE utf8mb4_0900_bin NOT NULL DEFAULT '', `pad` char(60) COLLATE utf8mb4_0900_bin NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=100001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_bin 1 row in set (0.00 sec)
--查看测试表行数 mysql> select count(*) from sbtest.sbtest1; +----------+ | count(*) | +----------+ | 100000 | +----------+ 1 row in set (0.00 sec)
--查看测试表的检验值 mysql> checksum table sbtest.sbtest1; +----------------+------------+ | Table | Checksum | +----------------+------------+ | sbtest.sbtest1 | 4167997150 | +----------------+------------+ 1 row in set (0.09 sec)
-- 删除5万行数据 mysql> delete from sbtest.sbtest1 where id<50000; 【这里删除了49999行数据】 Query OK, 49999 rows affected (7.72 sec) --再次看测试表的检验值 mysql> checksum table sbtest.sbtest1; +----------------+------------+ | Table | Checksum | +----------------+------------+ | sbtest.sbtest1 | 1629663751 | +----------------+------------+ 1 row in set (0.04 sec)
#解析binglog文件 [email protected]:/tmp# my2sql -user root -password ****** -host 127.0.0.1 -port 3306 -databases sbtest -tables sbtest1 -mode repl -work-type 2sql -start-file 1.000002 -output-dir /tmp [2022/07/28 10:26:42] [info] binlogsyncer.go:144 create BinlogSyncer with config {1113306 mysql 127.0.0.1 3306 root utf8 false false <nil> false UTC false 0 0s 0s 0 false false 0} [2022/07/28 10:26:42] [info] events.go:60 start thread 1 to generate redo/rollback sql [2022/07/28 10:26:42] [info] binlogsyncer.go:360 begin to sync binlog from position (1.000002, 4) [2022/07/28 10:26:42] [info] stats_process.go:166 start thread to analyze statistics from binlog [2022/07/28 10:26:42] [info] events.go:210 start thread to write redo/rollback sql into file [2022/07/28 10:26:42] [info] events.go:60 start thread 2 to generate redo/rollback sql [2022/07/28 10:26:42] [info] repl.go:16 start to get binlog from mysql [2022/07/28 10:26:42] [info] binlogsyncer.go:777 rotate to (1.000002, 4) [2022/07/28 10:26:50] [info] repl.go:84 deadline exceeded. [2022/07/28 10:26:50] [info] repl.go:18 finish getting binlog from mysql [2022/07/28 10:26:50] [info] stats_process.go:266 exit thread to analyze statistics from binlog [2022/07/28 10:26:50] [info] events.go:185 exit thread 1 to generate redo/rollback sql [2022/07/28 10:26:50] [info] events.go:185 exit thread 2 to generate redo/rollback sql [2022/07/28 10:26:50] [info] events.go:274 finish writing redo/forward sql into file [2022/07/28 10:26:50] [info] events.go:277 exit thread to write redo/rollback sql into file [email protected]:/tmp# ls -lrt total 2392 -rw-r--r-- 1 root root 261 Jul 28 10:26 biglong_trx.txt -rw-r--r-- 1 root root 2438845 Jul 28 10:26 forward.2.sql -rw-r--r-- 1 root root 288 Jul 28 10:26 binlog_status.txt
--文件binlog_status.txt和biglong_trx.txt是事务的统计信息 [email protected]:/tmp# cat binlog_status.txt binlog starttime stoptime startpos stoppos inserts updates deletes database table 1.000002 2022-07-28_10:24:06 2022-07-28_10:24:06 341 9536267 0 0 49999 sbtest sbtest1 [email protected]:/tmp# cat biglong_trx.txt binlog starttime stoptime startpos stoppos rows duration tables 1.000002 2022-07-28_10:24:06 2022-07-28_10:24:06 269 9536294 49999 0 [sbtest.sbtest1(inserts=0, updates=0, deletes=49999)]
--文件forward.2.sql是binlog解析之后的sql [email protected]:/tmp# more -10 forward.2.sql DELETE FROM `sbtest`.`sbtest1` WHERE `id`=1; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=2; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=3; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=4; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=5; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=6; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=7; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=8; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=9; DELETE FROM `sbtest`.`sbtest1` WHERE `id`=10; --More--(0%)
[email protected]:/tmp# my2sql -user root -password ****** -host 127.0.0.1 -port 3306 -databases sbtest -tables sbtest1 -mode repl -work-type rollback -start-file 1.000002 -output-dir /tmp/flashback/ [2022/07/28 10:42:55] [info] events.go:60 start thread 1 to generate redo/rollback sql [2022/07/28 10:42:55] [info] events.go:210 start thread to write redo/rollback sql into file [2022/07/28 10:42:55] [info] binlogsyncer.go:144 create BinlogSyncer with config {1113306 mysql 127.0.0.1 3306 root utf8 false false <nil> false UTC false 0 0s 0s 0 false false 0} [2022/07/28 10:42:55] [info] events.go:60 start thread 2 to generate redo/rollback sql [2022/07/28 10:42:55] [info] stats_process.go:166 start thread to analyze statistics from binlog [2022/07/28 10:42:55] [info] binlogsyncer.go:360 begin to sync binlog from position (1.000002, 4) [2022/07/28 10:42:55] [info] repl.go:16 start to get binlog from mysql [2022/07/28 10:42:55] [info] binlogsyncer.go:777 rotate to (1.000002, 4) [2022/07/28 10:43:00] [info] repl.go:84 deadline exceeded. [2022/07/28 10:43:00] [info] repl.go:18 finish getting binlog from mysql [2022/07/28 10:43:00] [info] stats_process.go:266 exit thread to analyze statistics from binlog [2022/07/28 10:43:00] [info] events.go:185 exit thread 1 to generate redo/rollback sql [2022/07/28 10:43:00] [info] events.go:185 exit thread 2 to generate redo/rollback sql [2022/07/28 10:43:00] [info] events.go:259 finish writing rollback sql into tmp files, start to revert content order of tmp files [2022/07/28 10:43:00] [info] rollback_process.go:15 start thread 1 to revert rollback sql files [2022/07/28 10:43:00] [info] rollback_process.go:41 start to revert tmp file /tmp/flashback/.rollback.2.sql into /tmp/flashback/rollback.2.sql [2022/07/28 10:43:00] [info] rollback_process.go:156 finish reverting tmp file /tmp/flashback/.rollback.2.sql into /tmp/flashback/rollback.2.sql [2022/07/28 10:43:00] [info] rollback_process.go:25 exit thread 1 to revert rollback sql files [2022/07/28 10:43:00] [info] events.go:272 finish reverting content order of tmp files [2022/07/28 10:43:00] [info] events.go:277 exit thread to write redo/rollback sql into file
[email protected]:/tmp/flashback# ls -lrt total 12596 -rw-r--r-- 1 root root 261 Jul 28 10:42 biglong_trx.txt -rw-r--r-- 1 root root 288 Jul 28 10:43 binlog_status.txt -rw-r--r-- 1 root root 12888636 Jul 28 10:43 rollback.2.sql
[email protected]:/tmp/flashback# cat biglong_trx.txt binlog starttime stoptime startpos stoppos rows duration tables 1.000002 2022-07-28_10:24:06 2022-07-28_10:24:06 269 9536294 49999 0 [sbtest.sbtest1(inserts=0, updates=0, deletes=49999)]
[email protected]:/tmp/flashback# cat binlog_status.txt binlog starttime stoptime startpos stoppos inserts updates deletes database table 1.000002 2022-07-28_10:24:06 2022-07-28_10:24:06 341 9536267 0 0 49999 sbtest sbtest1
[email protected]:/tmp/flashback# more -10 rollback.2.sql INSERT INTO `sbtest`.`sbtest1` (`id`,`k`,`c`,`pad`) VALUES (49999,33022,'82276829554-28600016482-71437056503-67189283057-49828408020-97469013057-54486869404-00631592142 -97314346455-10619483378','14496218158-82953408254-72982060504-31493955809-57788873512'); INSERT INTO `sbtest`.`sbtest1` (`id`,`k`,`c`,`pad`) VALUES (49998,50244,'96937339387-30971064351-79066739653-24906328840-02614118448-07131634761-96921531810-30574594369 -22852947139-53163560618','11061918782-99235282357-54725926348-09882016546-43656283296'); INSERT INTO `sbtest`.`sbtest1` (`id`,`k`,`c`,`pad`) VALUES (49997,49958,'23875561992-79383179714-31844019265-78678195929-11039506986-44432953782-19018620372-45679869851 -21838821757-54316746647','72021998255-21544610411-49097617755-83325624702-67496909817'); INSERT INTO `sbtest`.`sbtest1` (`id`,`k`,`c`,`pad`) VALUES (49996,49784,'64121185719-74243968401-44193775190-53796401184-56297492349-79981936074-03057285270-03714583251 -22209198873-10937378934','77159337465-83656217977-70877234699-71552982384-42185635425'); INSERT INTO `sbtest`.`sbtest1` (`id`,`k`,`c`,`pad`) VALUES (49995,49750,'32364537835-96169411677-52025383891-99856461851-54876781624-38035712955-18254695168-34412213489 -24174915574-41228645716','40846762001-49118260546-21871620253-63339659850-56585169893'); --More--(0%)
mysql -uroot -p****** -P3306 -h127.0.0.1 sbtest < /tmp/flashback/rollback.2.sql
mysql> select count(*) from sbtest.sbtest1; +----------+ | count(*) | +----------+ | 100000 | +----------+ 1 row in set (0.01 sec)
mysql> checksum table sbtest.sbtest1; +----------------+------------+ | Table | Checksum | +----------------+------------+ | sbtest.sbtest1 | 4167997150 | +----------------+------------+ 1 row in set (0.08 sec)
my2sql -user greatsql -password ****** -host 127.0.0.1 -port 3306 -mode repl -work-type 2sql -start-file binlog.000001 [2022/07/28 10:00:01] [fatal] context.go:575 Connect mysql failed this authentication plugin is not supported
解决
#修改 ALTER USER 'username'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password'; FLUSH PRIVILEGES;
my2sql -user greatsql -password ****** 127.0.0.1 -port 3306 -mode repl -work-type 2sql -start-file binlog.000001 [2022/07/28 09:35:08] [fatal] context.go:575 Connect mysql failed this user requires mysql native password authentication.
解决
#mysql配置文件中增加以下配置项并重启 default_authentication_plugin=mysql_native_password
my2sql除了可以用来做binlog的解析、闪回,还提供主从切换后新master丢数据的修复、大事务和长事务的分析、主从延迟分析等,后面有空继续分享my2sql在事务方面的应用,大家也可以自己动手实践一下。
https://github.com/liuhr/my2sql/blob/master/README.md
Enjoy GreatSQL