mysql不小心删除数据解决方案

参考文章简要的1
https://blog.51cto.com/402753795/1826074
参考文章细节的2
https://blog.csdn.net/weixin_43733154/article/details/104639335
参考文章细节的3
https://blog.csdn.net/weixin_33674976/article/details/92863378
python脚本
b.py

#_*_ coding:utf-8 _*_
import sys
import os
import io

binlogfile = sys.argv[1]
database_name = sys.argv[2]
table_name = sys.argv[3]
print('--database="'+database_name+'"')
def format_binlog():
    os.system('/www/server/mysql/bin/mysqlbinlog --start-datetime="2021-11-25 08:20:45" --stop-datetime="2021-11-25 16:50:00"  -v -v  --base64-output=DECODE-ROWS  /www/server/mysql/bin/'+binlogfile+' > '+binlogfile+'.txt')

def pickupbinlog():
    f = io.open(binlogfile+'.txt','r')
    fw = io.open(database_name+'_'+table_name+'_'+binlogfile+'.txt','a')
    priv_str = ''
    priv_line = ''
    goal_flag = 0
    for row in f:
        # 处理首行
        if row[0:3] == '###' and priv_str != '###':
            if database_name in row and table_name in row:
                goal_flag = 1
                fw.write(priv_line)
                fw.write(row)
        # 处理末行
        if row[0:3] != '###' and priv_str == '###':
            goal_flag = 0
        # 处理目标操作
        if row[0:3] == '###' and priv_str == '###' and goal_flag == 1:
            fw.write(row)
        priv_str = row[0:3]
        priv_line = row
    f.close()
    fw.close()

if __name__ == '__main__':
    # python2.7 pickupbinlog.py mysql-bin.001051 dbname tablename
    # python3 pickupbinlog.py mysql-bin.001051 dbname tablename
    format_binlog()
    pickupbinlog()

执行命令 python b.py binlog文件名 数据库名 数据表名
假设binlog文件名:mysql-bin.000471
假设数据库名:beiyaozhongtai
数据表名:zt_product_base
执行命令如下:

python b.py mysql-bin.000471 beiyaozhongtai zt_product_base

非删除语句系统会生成sql数据如下:格式

# at 1569
#160713 13:52:06 server id 1  end_log_pos 1569   Table_map: `students`.`test` mapped to number 33
#160713 13:52:06 server id 1  end_log_pos 1789   Update_rows: table id 33 flags: STMT_END_F
### UPDATE `students`.`test`
### WHERE
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2='张三' /* STRING(60) meta=65084 nullable=0 is_null=0 */
###   @3='男' /* STRING(12) meta=65036 nullable=0 is_null=0 */
###   @4='86' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
### SET
###   @1=1 /* INT meta=0 nullable=0 is_null=0 */
###   @2='张三' /* STRING(60) meta=65084 nullable=0 is_null=0 */
###   @3='中' /* STRING(12) meta=65036 nullable=0 is_null=0 */
###   @4='86' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
### UPDATE `students`.`test`
### WHERE
###   @1=2 /* INT meta=0 nullable=0 is_null=0 */
###   @2='李四' /* STRING(60) meta=65084 nullable=0 is_null=0 */

删除的语句是这样的

############################## 处理 a.txt 文件,生成 b.txt 文件 #######################
[root@node21 tmp]# sed -n '/^###/'p a.txt  >b.txt
[root@node21 tmp]# cat b.txt 
### DELETE FROM `lili`.`test1`
### WHERE
###   @1=10 /* INT meta=0 nullable=0 is_null=0 */
###   @2='cl10' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
###   @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
###   @4=30 /* TINYINT meta=0 nullable=0 is_null=0 */
###   @5=180                  /* FLOAT meta=4 nullable=0 is_null=0 */
###   @6=65.5                 /* FLOAT meta=4 nullable=0 is_null=0 */
###   @7='四川信息10' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
###   @8='专科' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
###   @9='18382024230' /* STRING(33) meta=65057 nullable=0 is_null=0 */
###   @10='158317100@qq.com' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
###   @11=7000                 /* FLOAT meta=4 nullable=0 is_null=0 */

先吧删除语句转换成insert语句

############################## 处理 b.txt 文件 去井号,生成 c.txt 文件 #######################
[root@node21 tmp]# sed 's/### //g' b.txt >c.txt
[root@node21 tmp]# cat c.txt 
DELETE FROM `lili`.`test1`
WHERE
  @1=10 /* INT meta=0 nullable=0 is_null=0 */
  @2='cl10' /* VARSTRING(60) meta=60 nullable=0 is_null=0 */
  @3=1 /* ENUM(1 byte) meta=63233 nullable=0 is_null=0 */
  @4=30 /* TINYINT meta=0 nullable=0 is_null=0 */
  @5=180                  /* FLOAT meta=4 nullable=0 is_null=0 */
  @6=65.5                 /* FLOAT meta=4 nullable=0 is_null=0 */
  @7='四川信息10' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
  @8='专科' /* VARSTRING(30) meta=30 nullable=0 is_null=0 */
  @9='18382024230' /* STRING(33) meta=65057 nullable=0 is_null=0 */
  @10='158317100@qq.com' /* VARSTRING(90) meta=90 nullable=0 is_null=0 */
  @11=7000                 /* FLOAT meta=4 nullable=0 is_null=0 */

然后去掉井号 并且在参数后边加上逗号

############################## 处理 c.txt 文件,生成 d.txt 文件 #######################
[root@node21 tmp]# sed 's#/\*.*\*/#,#g' c.txt >d.txt
如果有富文本里面含注释语句容易出错可以更精细匹配
 sed 's#/\*.*\*/
###   @#,#g' c.txt >d.txt
[root@node21 tmp]# cat d.txt 
DELETE FROM `lili`.`test1`
WHERE
  @1=10 ,
  @2='cl10' ,
  @3=1 ,
  @4=30 ,
  @5=180                  ,
  @6=65.5                 ,
  @7='四川信息10' ,
  @8='专科' ,
  @9='18382024230' ,
  @10='158317100@qq.com' ,
  @11=7000                 ,

继续处理把delete转成insert

############################## 处理 d.txt 文件,生成 e.txt 文件 #######################
[root@node21 tmp]# sed 's#DELETE FROM#INSERT INTO#g' d.txt >e.txt
[root@node21 tmp]# cat e.txt 
INSERT INTO `lili`.`test1`
WHERE
  @1=10 ,
  @2='cl10' ,
  @3=1 ,
  @4=30 ,
  @5=180                  ,
  @6=65.5                 ,
  @7='四川信息10' ,
  @8='专科' ,
  @9='18382024230' ,
  @10='158317100@qq.com' ,
  @11=7000                 ,


############################## 处理 e.txt 文件,生成 f.txt 文件 #######################
[root@node21 tmp]# sed 's#WHERE#SELECT#g' e.txt >f.txt
[root@node21 tmp]# cat f.txt 
INSERT INTO `lili`.`test1`
SELECT
  @1=10 ,
  @2='cl10' ,
  @3=1 ,
  @4=30 ,
  @5=180                  ,
  @6=65.5                 ,
  @7='四川信息10' ,
  @8='专科' ,
  @9='18382024230' ,
  @10='158317100@qq.com' ,
  @11=7000                 ,


############################## 处理 f.txt 文件,最后一个@结尾的逗号换成:生成 h.txt 文件 #######################
[root@node21 tmp]# sed -r 's#(@11=.*)(,)#\1;#g' f.txt >h.txt
[root@node21 tmp]# cat h.txt 
INSERT INTO `lili`.`test1`
SELECT
  @1=10 ,
  @2='cl10' ,
  @3=1 ,
  @4=30 ,
  @5=180                  ,
  @6=65.5                 ,
  @7='四川信息10' ,
  @8='专科' ,
  @9='18382024230' ,
  @10='158317100@qq.com' ,
  @11=7000                 ;


############################## 处理 h.txt 文件,生成 aa.sql 文件 ######################
[root@node21 tmp]# sed -r 's#(@.*=)(.*)#\2#g' h.txt >>aa.sql
[root@node21 tmp]# cat aa.sql 
INSERT INTO `lili`.`test1`
SELECT
  10 ,
  'cl10' ,
  1 ,
  30 ,
  180                  ,
  65.5                 ,
  '四川信息10' ,
  '专科' ,
  '18382024230' ,
  '158317100@qq.com' ,
  7000                 ;


############################## 在aa.sql文件后面添加commit;命令 ####################
[root@node21 tmp]# sed -i '$a commit;' aa.sql 
[root@node21 tmp]# cat aa.sql 
INSERT INTO `lili`.`test1`
SELECT
  10 ,
  'cl10' ,
  1 ,
  30 ,
  180                  ,
  65.5                 ,
  '四川信息10' ,
  '专科' ,
  '18382024230' ,
  '158317100@qq.com' ,
  7000                 ;
commit;

面对非delete情况可以一步到位

这个sed会一步完成去井号,去@符,结尾加逗号
参数@4 【where最后一个@结尾用;】
这句是调换where 和 set位置

sed '/### WHERE/{:a;N;//### SET/!ba;s/([^\n])\n(.)\n(.*)/\3\n\2\n\1\n/}'

快捷生成以上sed 参数方法 利用mysql 命令获取

数据库名 'beiyao-zt-test'

数据表名 'zt_product_base'

set @irowa =0 ;
set @irowb =51 ;

SELECT GROUP_CONCAT(CONCAT("s/@",@irowa:=@irowa+1,'=/',COLUMN_NAME,'=/g') SEPARATOR ";") as a, GROUP_CONCAT("\n\(.*\)" SEPARATOR "") as b, GROUP_CONCAT(CONCAT("\",@irowb:=@irowb-1,'\n') SEPARATOR "") as b FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'beiyao-zt-test' AND TABLE_NAME = 'zt_product_base'

sed '/### WHERE/{:a;N;/### SET/!ba;s/\([^\n]*\)\n\(.*\)\n\(.*\)/\3\n\2\n\1/}' 源文件.txt | sed -r '/### WHERE/{:a;N;/@50/!ba;s/###   @2.*//g}' | sed 's#/\*.*\*/#,#g'| sed '/### WHERE/{:a;N;/@1/!ba;s/,/;/g};s/### //g;s#/\*.*\*/##g;s/COMMIT,//g' | sed '/^$/d' >test1

yichen修改后 加了50个字段的

sed '/WHERE/{:a;N;/SET/!ba;s/([^\n])\n(.)\n(.)/\3\n\2\n\1/}' beiyaozhongai_zt_product_base_mysql-bin.000471.txt | sed -r '/WHERE/{:a;N;/@50/!ba;s/### @2.//g}' | sed 's/### //g;s#/*.*/#,#g' | sed '/WHERE/{:a;N;/@1/!ba;s/,/;/g};s#/*.*/##g;s/COMMIT,//g' | sed '/^$/d' >d471.txt

结果如下:

UPDATE `students`.`test`
SET
  @1=1 ,
  @2='张三' ,
  @3='男' ,
  @4='86' ,
WHERE
  @1=1 ;
UPDATE `students`.`test`
SET
  @1=2 ,
  @2='李四' ,
  @3='男' ,
  @4='88' ,
WHERE
  @1=2 ;

把数据库名去掉

sed "s/\`beiyaozhongtai\`\.//g"

然后方式1 替换 指定@字段为数据表的字段
获取所有字段
数据库名'beiyao-zt-test'
表名'zt_product_base'
然后在sql 文件头部加上@1=id;@2=name。。。

   SET GLOBAL group_concat_max_len=102400;
       SET SESSION group_concat_max_len=102400; 
set @irow  =0 ;

SELECT GROUP_CONCAT(CONCAT("SET @",@irow:=@irow+1,'="',COLUMN_NAME,'"') SEPARATOR ";") FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA = 'beiyao-zt-test' AND TABLE_NAME = 'zt_product_base'

#如果报错
1> 1227 - Access denied; you need (at least one of) the SYSTEM_VARIABLES_ADMIN privilege(s) for this operation
需要root超级管理员授权
grant SYSTEM_VARIABLES_ADMIN on *.* to '被授权的mysql用户名';

得到如下结果

SET @1="id";
SET @2="upc";
SET @3="goods_no";
SET @4="product_name";
#下步把对应字段替换

执行下语句会生成cat文本批量替换语句

set @irow  =0 ;

SELECT GROUP_CONCAT(CONCAT("s/@",@irow:=@irow+1,'=/',COLUMN_NAME,'=/g') SEPARATOR ";") FROM information_schema.COLUMNS 
WHERE TABLE_SCHEMA = 'beiyao-zt-test' AND TABLE_NAME = 'zt_product_base'

s/@1=/id=/g;s/@2=/upc=/g;s/@3=/goods_no=/g;s/@4=/product_name=/g;s/@5=/common_name=/g;s/@6=/brand_name=/g;s/@7=/spec=/g;s/@8=/manufacture=/g;s/@9=/producing_area=/g;s/@10=/approval_number=/g;s/@11=/drug_type=/g;s/@12=/dosage_form=/g;s/@13=/packing_unit=/g;s/@14=/main_ingredients=/g;s/@15=/properties=/g;s/@16=/indications=/g;s/@17=/dosage=/g;s/@18=/adr=/g;s/@19=/taboo=/g;s/@20=/caution=/g;s/@21=/announcements=/g;s/@22=/drug_interations=/g;s/@23=/gravida_drug=/g;s/@24=/old_drug=/g;s/@25=/child_drug=/g;s/@26=/pharma_toxicology=/g;s/@27=/overdose=/g;s/@28=/pharmacokinetic=/g;s/@29=/license_legal_person=/g;s/@30=/indate=/g;s/@31=/storage_condition=/g;s/@32=/instruction_book=/g;s/@33=/attending_disease=/g;s/@34=/prescription_type=/g;s/@35=/thumbnails=/g;s/@36=/first_image=/g;s/@37=/images=/g;s/@38=/detail=/g;s/@39=/remark=/g;s/@40=/mid_package=/g;s/@41=/big_package=/g;s/@42=/create_time=/g;s/@43=/update_time=/g;s/@44=/side_effect=/g;s/@45=/spec_int=/g;s/@46=/scope_of_application=/g;s/@47=/pinyin_full=/g;s/@48=/pinyin=/g;s/@49=/type_name_one=/g;s/@50=/type_name_two=/g

然后在前面加上sed -i 即可 结尾用文件名

sed -i  上面的语句 xxx.sql
#把最后一个字段结尾逗号去掉
sed -i -r 's/(type_name_two.*),/\1/g' recover.sql
############################## 在recover.sql文件后面添加commit;命令 ####################
[root@node21 tmp]# sed -i '$a commit;' recover.sql

如果字段数量和数据库相对应也可以值替换@1= 改成id=

sed -i  's/@1=/id=/g' recover.sql

现在是这样

WHERE
  id=55344 ;
UPDATE `beiyaozhongtai`.`zt_product_base`
SET
  id=55345 ,
  @2='6970403270604' ,
  @3=NULL ,
  @4='盐酸金刚乙胺糖浆 (津彤)' ,

删除所有@符

sed -r 's#(@.*=)(.*)#\2#g' recover.sql >>aa.sql

现在是这样

WHERE
  id=55344 ;
UPDATE `beiyaozhongtai`.`zt_product_base`
SET
  id=55345 ,
  6970403270604' ,
  NULL ,
  '盐酸金刚乙胺糖浆 (津彤)' ,

在把数据库名去掉 把表名替换beiyaozhongtai. 需要转义符\

sed -i  's/`beiyaozhongtai`\.//g' recover.sql

或者所有@编号字段都指定数据库字段

#替换@为数据库的字段
sed -i 's/@1/id/g;s/@2/name/g;s/@3/sex/g;s/@4/score/g' recover.sql
#匹配最后一个字段结尾的逗号去掉
sed -i -r 's/(score.*),/\1/g' recover.sql

现在的内容就是数据库可以执行的sql了

UPDATE `students`.`test`
SET
  id=1 ,
  name='张三' ,
  sex='男' ,
  score='86'
WHERE
  id=1 ;
UPDATE `students`.`test`
SET
  id=2 ,
  name='李四' ,
  sex='男' ,
  score='88'
WHERE
  id=2 ;
UPDATE `students`.`test`

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容