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/29734436/viewspace-2152513/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Mysql之binlog日誌說明及利用binlog日誌恢復資料操作記錄MySql
- mysql 誤刪除表內資料,透過binlog日誌恢復MySql
- Mysql資料庫之Binlog日誌使用總結MySql資料庫
- 利用binlog日誌恢復mysql資料MySql
- MySQL--binlog日誌恢復資料MySql
- MySQL 的日誌:binlogMySql
- mysql清除binlog日誌MySql
- MySQL的binlog日誌MySql
- 清除MySQL Binlog日誌MySql
- mysql binlog日誌刪除MySql
- Mysql-binlog日誌-TMySql
- mysql開啟日誌記錄MySql
- MySQL更新資料時,日誌(redo log、binlog)執行流程MySql
- 資料庫篇:mysql日誌型別之 redo、undo、binlog資料庫MySql型別
- MySQL資料庫中的日誌檔案---(1)錯誤日誌MySql資料庫
- 提取MySQL binlog中指定表的操作記錄MySql
- mysql 日誌之錯誤日誌MySql
- oracle外部表記錄alert日誌&&資料庫執行報告Oracle資料庫
- MySQL 使用tee記錄語句和輸出日誌MySql
- 【mysql】【Sequelize】【錯誤記錄】update修改資料後,不返回資料(其實就是mysql不支援)MySql
- 【資料】MySQL日誌MySql
- 記錄騰訊雲使用日誌
- 一種資料被誤修改後的找回方法
- MySQL 日誌系統 redo log、binlogMySql
- MySQL 正確刪除 binlog 日誌MySql
- mysql檢視binlog日誌詳解MySql
- 實時備份mysql binlog日誌MySql
- [MySQL binlog]徹底解析Mixed日誌格式的binlogMySql
- php日誌,記錄日誌PHP
- 日誌資訊記錄表|全方位認識 mysql 系統庫MySql
- 教你自動恢復MySQL資料庫的日誌檔案(binlog)MySql資料庫
- 欄位修改記錄操作日誌的實現
- MySQL慢日誌全解析MySql
- MySQL使用binlog2sql閃回誤刪除資料MySql
- 使用Redis記錄系統日誌Redis
- 使用Rsyslog記錄Apache日誌Apache
- 使用 .NET Core 的日誌記錄
- LightDB不記錄WAL日誌的表