十万火急,有关从二进制日志中恢复SQL的问题

时间:2022-09-14 00:28:44
我们的Mysql数据库硬盘坏了,现在只能二进制日志文件,数据库只丢失了一个表,这个表记录不全,我现在从二进制文件中生成了.sql文件,此文件接近1G,我现在想找一个程序可以将.sql文件中涉及my_dt表的insert,update,delete提取出来,请问有这样的工具吗?

9 个解决方案

#1


楼主要是在linux下面可以用grep 来操作my_dt表的所有数据;

#2


我需要的数据都在
/*!*/;
/*!*/;
之间,里面包括
insert into my_dt
update my_dt
delete my_dt
但有二种情况。

第一种情况,在二者之间还包括一个SET INSERT_ID=8435595/*!*/;这样的语句,它以/*!*/;结尾,所以要考虑以/*!*/;为结尾的不算不符合。
/*!*/;
# at 3610618
#101223 18:36:53 server id 1  end_log_pos 3610646  Intvar
SET INSERT_ID=8435595/*!*/;  
# at 3610646
#101223 18:36:53 server id 1  end_log_pos 3611055  Query thread_id=6634974 exec_time=0 error_code=0
SET TIMESTAMP=1293100613/*!*/;
INSERT INTO my_dt(fid, tid, first, author)

VALUES ('674', '834775', '0')
/*!*/;

另外一种为正常情况:
/*!*/;
# at 1209
#101230 15:54:34 server id 1  end_log_pos 1577  Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1293695674/*!*/;
UPDATE my_dt SET count=count+1 WHERE (type='total' AND variable='hits')
/*!*/;
# at 1577
#101230 15:54:34 server id 1  end_log_pos 1710  Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1293695674/*!*/;
UPDATE xxx SET views=views+1 WHERE tid='319162'
/*!*/;
此种情况只需要提取:
/*!*/;
# at 1209
#101230 15:54:34 server id 1  end_log_pos 1577  Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1293695674/*!*/;
UPDATE my_dt SET count=count+1 WHERE (type='total' AND variable='hits')
/*!*/;
即可

#3


如果你有mingw等工具,直接进入mingw下,使用grep命令,可以过滤出所有my_dt表的相关数据。

#4


第一种情况的INSERT INTO my_dt(fid, tid, first, author) VALUES ('674', '834775', '0') 该数据不取?

楼主为什么不直接grep -i "my_dt" data.sql | grep ....| grep  .. 这样来取

#5


我需要包含my_dt的整个一段
例如:
/*!*/;
SET TIMESTAMP=1293695674/*!*/;
UPDATE my_dt SET count=count+1 WHERE (type='total' AND variable='hits')
/*!*/;

#6


MYSQL本身没有这种工具。

常见的方法是先找一个空数据库服务器,然后把数据恢复在这台机器上,再把需要的表复制出来就行了。

#7


不知道这样可以不:

root@mablevi-desktop:~/shell_test# cat test 
BEGIN
/*!*/;
# at 51315
#101210 16:22:36 server id 1  end_log_pos 51343       Intvar
SET INSERT_ID=328/*!*/;
# at 51343
#101210 16:22:36 server id 1  end_log_pos 51548       Query thread_id=835       exec_time=0     error_code=0
SET TIMESTAMP=1291969356/*!*/;
INSERT INTO order_size_amount (order_id, amount, rule_id, size_id, company_id, member_id) VALUES ('499', '3', 153, '311', '36', '63')
/*!*/;
# at 51548
#101210 16:22:36 server id 1  end_log_pos 51575       Xid = 11333
COMMIT/*!*/;
# at 51575
#101210 16:22:36 server id 1  end_log_pos 51652       Query thread_id=835       exec_time=0     error_code=0
SET TIMESTAMP=1291969356/*!*/;
BEGIN
/*!*/;
# at 51652
#101210 16:22:36 server id 1  end_log_pos 51680       Intvar
SET INSERT_ID=154/*!*/;
# at 51680
#101210 16:22:36 server id 1  end_log_pos 51908       Query thread_id=835       exec_time=0     error_code=0
SET TIMESTAMP=1291969356/*!*/;
INSERT INTO order_rule (assembly_id, per_size, memo, order_id, order_amount_desc_id, company_id, member_id) VALUES ('347', '11', '', '499', 115, '36', '63')
/*!*/;
# at 51908
#101210 16:22:36 server id 1  end_log_pos 51935       Xid = 11334
COMMIT/*!*/;


结果这样:
root@mablevi-desktop:~/shell_test# grep -i -C1 "INSERT INTO" test 
SET TIMESTAMP=1291969356/*!*/;
INSERT INTO order_size_amount (order_id, amount, rule_id, size_id, company_id, member_id) VALUES ('499', '3', 153, '311', '36', '63')
/*!*/;
--
SET TIMESTAMP=1291969356/*!*/;
INSERT INTO order_rule (assembly_id, per_size, memo, order_id, order_amount_desc_id, company_id, member_id) VALUES ('347', '11', '', '499', 115, '36', '63')
/*!*/;

#8


引用 6 楼 acmain_chm 的回复:
 

常见的方法是先找一个空数据库服务器,然后把数据恢复在这台机器上,再把需要的表复制出来就行了。


 我想说的,被斑竹说了

#9


引用楼主 yjdabc 的回复:
我们的Mysql数据库硬盘坏了,现在只能二进制日志文件,数据库只丢失了一个表,这个表记录不全,我现在从二进制文件中生成了.sql文件,此文件接近1G,我现在想找一个程序可以将.sql文件中涉及my_dt表的insert,update,delete提取出来,请问有这样的工具吗?

最快的,最有效就是找一台专用空服务器,将你的数据恢复在空服务器上,然后拿出你my_dt表的所有数据。

#1


楼主要是在linux下面可以用grep 来操作my_dt表的所有数据;

#2


我需要的数据都在
/*!*/;
/*!*/;
之间,里面包括
insert into my_dt
update my_dt
delete my_dt
但有二种情况。

第一种情况,在二者之间还包括一个SET INSERT_ID=8435595/*!*/;这样的语句,它以/*!*/;结尾,所以要考虑以/*!*/;为结尾的不算不符合。
/*!*/;
# at 3610618
#101223 18:36:53 server id 1  end_log_pos 3610646  Intvar
SET INSERT_ID=8435595/*!*/;  
# at 3610646
#101223 18:36:53 server id 1  end_log_pos 3611055  Query thread_id=6634974 exec_time=0 error_code=0
SET TIMESTAMP=1293100613/*!*/;
INSERT INTO my_dt(fid, tid, first, author)

VALUES ('674', '834775', '0')
/*!*/;

另外一种为正常情况:
/*!*/;
# at 1209
#101230 15:54:34 server id 1  end_log_pos 1577  Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1293695674/*!*/;
UPDATE my_dt SET count=count+1 WHERE (type='total' AND variable='hits')
/*!*/;
# at 1577
#101230 15:54:34 server id 1  end_log_pos 1710  Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1293695674/*!*/;
UPDATE xxx SET views=views+1 WHERE tid='319162'
/*!*/;
此种情况只需要提取:
/*!*/;
# at 1209
#101230 15:54:34 server id 1  end_log_pos 1577  Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1293695674/*!*/;
UPDATE my_dt SET count=count+1 WHERE (type='total' AND variable='hits')
/*!*/;
即可

#3


如果你有mingw等工具,直接进入mingw下,使用grep命令,可以过滤出所有my_dt表的相关数据。

#4


第一种情况的INSERT INTO my_dt(fid, tid, first, author) VALUES ('674', '834775', '0') 该数据不取?

楼主为什么不直接grep -i "my_dt" data.sql | grep ....| grep  .. 这样来取

#5


我需要包含my_dt的整个一段
例如:
/*!*/;
SET TIMESTAMP=1293695674/*!*/;
UPDATE my_dt SET count=count+1 WHERE (type='total' AND variable='hits')
/*!*/;

#6


MYSQL本身没有这种工具。

常见的方法是先找一个空数据库服务器,然后把数据恢复在这台机器上,再把需要的表复制出来就行了。

#7


不知道这样可以不:

root@mablevi-desktop:~/shell_test# cat test 
BEGIN
/*!*/;
# at 51315
#101210 16:22:36 server id 1  end_log_pos 51343       Intvar
SET INSERT_ID=328/*!*/;
# at 51343
#101210 16:22:36 server id 1  end_log_pos 51548       Query thread_id=835       exec_time=0     error_code=0
SET TIMESTAMP=1291969356/*!*/;
INSERT INTO order_size_amount (order_id, amount, rule_id, size_id, company_id, member_id) VALUES ('499', '3', 153, '311', '36', '63')
/*!*/;
# at 51548
#101210 16:22:36 server id 1  end_log_pos 51575       Xid = 11333
COMMIT/*!*/;
# at 51575
#101210 16:22:36 server id 1  end_log_pos 51652       Query thread_id=835       exec_time=0     error_code=0
SET TIMESTAMP=1291969356/*!*/;
BEGIN
/*!*/;
# at 51652
#101210 16:22:36 server id 1  end_log_pos 51680       Intvar
SET INSERT_ID=154/*!*/;
# at 51680
#101210 16:22:36 server id 1  end_log_pos 51908       Query thread_id=835       exec_time=0     error_code=0
SET TIMESTAMP=1291969356/*!*/;
INSERT INTO order_rule (assembly_id, per_size, memo, order_id, order_amount_desc_id, company_id, member_id) VALUES ('347', '11', '', '499', 115, '36', '63')
/*!*/;
# at 51908
#101210 16:22:36 server id 1  end_log_pos 51935       Xid = 11334
COMMIT/*!*/;


结果这样:
root@mablevi-desktop:~/shell_test# grep -i -C1 "INSERT INTO" test 
SET TIMESTAMP=1291969356/*!*/;
INSERT INTO order_size_amount (order_id, amount, rule_id, size_id, company_id, member_id) VALUES ('499', '3', 153, '311', '36', '63')
/*!*/;
--
SET TIMESTAMP=1291969356/*!*/;
INSERT INTO order_rule (assembly_id, per_size, memo, order_id, order_amount_desc_id, company_id, member_id) VALUES ('347', '11', '', '499', 115, '36', '63')
/*!*/;

#8


引用 6 楼 acmain_chm 的回复:
 

常见的方法是先找一个空数据库服务器,然后把数据恢复在这台机器上,再把需要的表复制出来就行了。


 我想说的,被斑竹说了

#9


引用楼主 yjdabc 的回复:
我们的Mysql数据库硬盘坏了,现在只能二进制日志文件,数据库只丢失了一个表,这个表记录不全,我现在从二进制文件中生成了.sql文件,此文件接近1G,我现在想找一个程序可以将.sql文件中涉及my_dt表的insert,update,delete提取出来,请问有这样的工具吗?

最快的,最有效就是找一台专用空服务器,将你的数据恢复在空服务器上,然后拿出你my_dt表的所有数据。