mysql误修改全表记录,使用binlog日志找回数据

#添加数据
insert into testdb1.student(id,name,class,score) value(a,'a',1,45),(2,'b',1,46),(3,'c',2,89),(4,'d',2,90),(5,'e',3,67),(6,'f',3,87),(7,'g',4,77),(8,'h',4,91);
mysql> select * from testdb1.student;
+------+------+-------+-------+
| id   | name | class | score |
+------+------+-------+-------+
|    1 | a    | 1     |    45 |
|    2 | b    | 1     |    46 |
|    3 | c    | 2     |    89 |
|    4 | d    | 2     |    90 |
|    5 | e    | 3     |    67 |
|    6 | f    | 3     |    87 |
|    7 | g    | 4     |    77 |
|    8 | h    | 4     |    91 |
+------+------+-------+-------+
8 rows in set (0.00 sec)
#修改数据
update student set score=100;
commit;

mysql> select * from testdb1.student;
+------+------+-------+-------+
| id   | name | class | score |
+------+------+-------+-------+
|    1 | a    | 1     |   100 |
|    2 | b    | 1     |   100 |
|    3 | c    | 2     |   100 |
|    4 | d    | 2     |   100 |
|    5 | e    | 3     |   100 |
|    6 | f    | 3     |   100 |
|    7 | g    | 4     |   100 |
|    8 | h    | 4     |   100 |
+------+------+-------+-------+
8 rows in set (0.00 sec)

mysql> set global read_only=1

mysql> show master status\G
*************************** 1. row ***************************
             File: ray-bin.000004
         Position: 1992
     Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set:
1 row in set (0.00 sec)

# at 2192是在binlog日志中查到的 
[root@localhost ~]# mysqlbinlog /data/3306/logs/ray-bin.000004 -v -v -S /data/3306/soket/mysql.sock --base64-output=decode-rows | grep -A 15 student | sed -n '/# at 2192/,/COMMIT/p'| sed -n 's\### \\p' | sed "s/\/\*.*\*\///g" | sed 's/`//g'> /tmp/1.txt
[root@localhost ~]# cat /tmp/1.txt
UPDATE testdb1.student
WHERE
  @1=1
  @2='a'
  @3='1'
  @4=45
SET
  @1=1
  @2='a'
  @3='1'
  @4=100
UPDATE testdb1.student
WHERE
  @1=2
  @2='b'
  @3='1'
  @4=46
SET
  @1=2
  @2='b'
  @3='1'
  @4=100
UPDATE testdb1.student
WHERE
  @1=3
  @2='c'
  @3='2'
  @4=89
SET
  @1=3
  @2='c'
  @3='2'
  @4=100
UPDATE testdb1.student
WHERE
  @1=4
  @2='d'
  @3='2'
  @4=90
SET
  @1=4
  @2='d'
  @3='2'
  @4=100
UPDATE testdb1.student
WHERE
  @1=5
  @2='e'
  @3='3'
  @4=67
SET
  @1=5
  @2='e'
  @3='3'
  @4=100
UPDATE testdb1.student
WHERE
  @1=6
  @2='f'
  @3='3'
  @4=87
SET
  @1=6
  @2='f'
  @3='3'
  @4=100
UPDATE testdb1.student
WHERE
  @1=7
  @2='g'
  @3='4'
  @4=77
SET
  @1=7
  @2='g'
  @3='4'
  @4=100
UPDATE testdb1.student
WHERE
  @1=8
  @2='h'
  @3='4'
  @4=91
SET
  @1=8
  @2='h'
  @3='4'
  @4=100
[root@localhost ~]# cat column.txt
id
name
class
score
[root@localhost ~]# cat getSQL.sh
#!/bin/bash
# by ray

iswhere=1   #判断循环的行的位置,1表示在where后,0表示不再where后
colNum=0    #计算列数,一般在binlog日志内第一列为@1,第二列为@2一次类推
whereNum=0  #判断where后面字段出现的次数,便于拼接字符串,第一次出现不适用都会,第二次以后使用逗号拼接
setNum=0 #判断set后面字段出现的次数,便于拼接字符串,第一次出现不适用都会,第二次以后使用逗号拼接

replaceColumn(){   #把@开头的列替换为列配置文件内的列,安配置文件的顺序执行
     cat $1 | while read line
     do
          colNum=$[${colNum}+1]
          sed -i "s/@${colNum}/${line}/g" ./execSQL.sql  #替换列
     done
}

getSQL(){   #获取sql
     sql1=''
     sql_result=''
     sql_condition=''
     while read line #读取处理过的binlog日志
     do
          if [[ ${line} =~ 'UPDATE' ]];then     #匹配是否update
               if [ "${sql1}" != "" ];then
                    echo ${sql1}' '${sql_result}' '${sql_condition}';' >> ./execSQL.sql  #打印sql
                    sql1=''
                    sql_result=''
                    sql_condition=''
                    whereNum=0
                    setNum=0
               fi
             sql1=${line}        #拼接sql字符串,获取update
        elif [[ ${line} =~ 'WHERE' ]];then
             sql_condition=${line}   #拼接字符串,把binlog日志内where后面内容
             iswhere=1               #判断是否为where,因为要把where和set后面的内容互换
        elif [[ ${line} =~ 'SET' ]];then
             sql_result=' SET '${sql_result} #拼接字符串
             iswhere=0
        elif [[ ${iswhere} -eq 1 ]];then            #1为where后面,把binlog日志where后面的内容拼接到sql的set后
             if [[ ${whereNum} -eq 0 ]];then              #判断where字符串后的字符串是否一次出现
                  sql_result=${sql_result}' '${line}
                  whereNum=1                    #设置为1,表示不是第一次出现
             elif [[ ${whereNum} -eq 1 ]];then
                  sql_result=${sql_result}', '${line}
             fi
        elif [[ ${iswhere} -eq 0 ]];then           #判断是否为set后面的字符串
             if [[ ${setNum} -eq 0 ]];then               #判断set字符串后的字符串是否一次出现
                  sql_condition=${sql_condition}' '${line}
                  setNum=1                     #设置为1,表示不是第一次出现
             elif [[ ${setNum} -eq 1 ]];then
                  sql_condition=${sql_condition}' and '${line}
             fi
        fi
     done < $1   #把文件用while循环读取每一行
     echo ${sql1}' '${sql_result}' '${sql_condition}';' >> ./execSQL.sql    #最后一行退出循环,所以要打印最后一行
     echo "commit;" >> ./execSQL.sql
     replaceColumn $2
}


#脚本的入口,调用函数获取内容
if [ -e $1 ];then  #判断第一个参数是否为文件
     getSQL $1 $2
else
    echo $1' is not a file!!'
fi

[root@localhost ~]# bash getSQL.sh '/tmp/1.txt' "./column.txt"

mysql> select * from testdb1.student;
+------+------+-------+-------+
| id   | name | class | score |
+------+------+-------+-------+
|    1 | a    | 1     |   100 |
|    2 | b    | 1     |   100 |
|    3 | c    | 2     |   100 |
|    4 | d    | 2     |   100 |
|    5 | e    | 3     |   100 |
|    6 | f    | 3     |   100 |
|    7 | g    | 4     |   100 |
|    8 | h    | 4     |   100 |
+------+------+-------+-------+
8 rows in set (0.00 sec)

[root@localhost ~]# mysql -uroot -p123456 -S /data/3306/soket/mysql.sock < /root/execSQL.sql
mysql: [Warning] Using a password on the command line interface can be insecure.

mysql> select * from testdb1.student;
+------+------+-------+-------+
| id   | name | class | score |
+------+------+-------+-------+
|    1 | a    | 1     |    45 |
|    2 | b    | 1     |    46 |
|    3 | c    | 2     |    89 |
|    4 | d    | 2     |    90 |
|    5 | e    | 3     |    67 |
|    6 | f    | 3     |    87 |
|    7 | g    | 4     |    77 |
|    8 | h    | 4     |    91 |
+------+------+-------+-------+
8 rows in set (0.00 sec)

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/28572479/viewspace-2137179/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/28572479/viewspace-2137179/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值