"個人博客:mysql數據恢復,binlog詳解" binlog日誌恢複數據,是輓救錯誤操作和數據損壞一根救命稻草,所以認識和使用binglog對於技術人員還是很有必要的 binlog一般用於 主從複製 中 master節點開啟binlog把二進位日誌傳遞給slave節點達到主從數據一致 第二點自然 ...
個人博客:mysql數據恢復,binlog詳解
binlog日誌恢複數據,是輓救錯誤操作和數據損壞一根救命稻草,所以認識和使用binglog對於技術人員還是很有必要的
binlog一般用於
- 主從複製 中 master節點開啟binlog把二進位日誌傳遞給slave節點達到主從數據一致
- 第二點自然是用於數據恢復了,使用mysqlbinlog工具來恢複數據
因為我自己的網站遇到過mysql表被我誤刪操作,drop table後當時我還是挺淡定的,雖然我不清楚我能不能把數據拯救回來,對於個人網站而言可能都沒有主從,也沒有把mysql的各項配置設置完美,這種情形下最擔心的當然是binlog是否開啟了,如果沒有開啟binlog並且也沒有做數據備份,我感覺基本上就GG了
因為我mysql是通過docker容器安裝的,所以具體 my.cnf 配置文件的放在哪也忘記了
- 使用 find / -name my.cnf 找到文件在哪
root@0d5861775029:/# find / -name my.cnf
find: '/proc/1/map_files': Operation not permitted
find: '/proc/182/map_files': Operation not permitted
find: '/proc/187/map_files': Operation not permitted
find: '/proc/1601/map_files': Operation not permitted
find: '/proc/1731/map_files': Operation not permitted
find: '/proc/1741/map_files': Operation not permitted
/etc/alternatives/my.cnf
/etc/mysql/my.cnf
/var/lib/dpkg/alternatives/my.cnf
root@0d5861775029:/#
- 查看my.cnf配置找到binlog以及mysql數據存儲的位置
#
# The MySQL Server configuration file.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
secure-file-priv= NULL
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Custom config should go here
!includedir /etc/mysql/conf.d/
- 可以看到mysql數據存儲的目錄是 datadir = /var/lib/mysql 目錄中
root@0d5861775029:/etc/mysql# cd /var/lib/mysql/
root@0d5861775029:/var/lib/mysql# ls
#innodb_temp binlog.index client-key.pem ib_logfile1 mysql.ibd server-cert.pem undo_002
auto.cnf ca-key.pem db_blog ibdata1 performance_schema server-key.pem
binlog.000001 ca.pem ib_buffer_pool ibtmp1 private_key.pem sys
binlog.000002 client-cert.pem ib_logfile0 mysql public_key.pem undo_001
上面的前戲都看完了,這其實並非binlog具體使用,而是我個人發現數據目錄方式 接下來我將詳細介紹binlog的使用
一、開啟binlog日誌
- 查看binlog是否開啟
- ON 表示已經開啟
- 查看更多內容可以這樣
show variables like 'log_%';
mysql> show variables like 'log_bin'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_bin | ON | +---------------+-------+ 1 row in set (0.00 sec)
mysql> show variables like 'log_%';
+----------------------------------------+----------------------------------------+
| Variable_name | Value |
+----------------------------------------+----------------------------------------+
| log_bin | ON |
| log_bin_basename | /var/lib/mysql/binlog |
| log_bin_index | /var/lib/mysql/binlog.index |
| log_bin_trust_function_creators | OFF |
| log_bin_use_v1_row_events | OFF |
| log_error | stderr |
| log_error_services | log_filter_internal; log_sink_internal |
| log_error_suppression_list | |
| log_error_verbosity | 2 |
| log_output | FILE |
| log_queries_not_using_indexes | OFF |
| log_slave_updates | ON |
| log_slow_admin_statements | OFF |
| log_slow_extra | OFF |
| log_slow_slave_statements | OFF |
| log_statements_unsafe_for_binlog | ON |
| log_throttle_queries_not_using_indexes | 0 |
| log_timestamps | UTC |
+----------------------------------------+----------------------------------------+
18 rows in set (0.00 sec)
- 編輯my.cnf開啟binlog
在[mysqld] 區塊
設置/添加 log-bin=mysql-bin 確認是打開狀態(值 mysql-bin 是日誌的基本名或首碼名);
然後重啟mysql
二、查看binlog日誌操作命令
- 查看所有binlog日誌列表
mysql> show logs;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'logs' at line 1
mysql> show master logs;
+---------------+-----------+-----------+
| Log_name | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 | 3091158 | No |
| binlog.000002 | 141156437 | No |
+---------------+-----------+-----------+
2 rows in set (0.17 sec)
- 查看master狀態,也就是最新一個binlog日誌編號名稱和最後一個操作事件pos結束位置
mysql> show master status;
+---------------+-----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+-----------+--------------+------------------+-------------------+
| binlog.000002 | 141156437 | | | |
+---------------+-----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
- 刷新log日誌,將會產生一個新編號的binlog日誌文件
mysql> flush logs;
- 重置(清空)所有binlog日誌
mysql> reset master;
三、查看binlog日誌內容
使用mysqlbinlog命令查看
因為binlog是二進位文件,普通文件查看器都無法打開,必須使用自帶的mysqlbinlog命令查看
- mysqlbinlog binlog.000002 使用mysqlbinlog不好觀察
- 在mysql中查看binlog日誌
mysql> show binlog events [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count];
選項解析:
IN 'log_name' 指定要查詢的binlog文件名(不指定就是第一個binlog文件)
FROM pos 指定從哪個pos起始點開始查起(不指定就是從整個文件首個pos點開始算)
LIMIT [offset,] 偏移量(不指定就是0)
row_count 查詢總條數(不指定就是所有行)
截取部分查詢結果:
*************************** 20. row ***************************
Log_name: mysql-bin.000021 ----------------------------------------------> 查詢的binlog日誌文件名
Pos: 11197 ----------------------------------------------------------> pos起始點:
Event_type: Query ----------------------------------------------------------> 事件類型:Query
Server_id: 1 --------------------------------------------------------------> 標識是由哪台伺服器執行的
End_log_pos: 11308 ----------------------------------------------------------> pos結束點:11308(即:下行的pos起始點)
Info: use `zyyshop`; INSERT INTO `team2` VALUES (0,345,'asdf8er5') ---> 執行的sql語句
*************************** 21. row ***************************
Log_name: mysql-bin.000021
Pos: 11308 ----------------------------------------------------------> pos起始點:11308(即:上行的pos結束點)
Event_type: Query
Server_id: 1
End_log_pos: 11417
Info: use `zyyshop`; /*!40000 ALTER TABLE `team2` ENABLE KEYS */
*************************** 22. row ***************************
Log_name: mysql-bin.000021
Pos: 11417
Event_type: Query
Server_id: 1
End_log_pos: 11510
Info: use `zyyshop`; DROP TABLE IF EXISTS `type`
- 指定查詢 binlog.000002 日誌
mysql> show binlog events in 'binlog.000002' limit 10;
+---------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+---------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| binlog.000002 | 4 | Format_desc | 1 | 124 | Server ver: 8.0.16, Binlog ver: 4 |
| binlog.000002 | 124 | Previous_gtids | 1 | 155 | |
| binlog.000002 | 155 | Anonymous_Gtid | 1 | 234 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 234 | Query | 1 | 482 | CREATE USER 'schwarzeni'@'localhost' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$H{;gmzB@[}K1i\nBcce80ezg8j3o0qDdYocc1OxBkShlQyzmOV/c4rGP69' /* xid=7 */ |
| binlog.000002 | 482 | Anonymous_Gtid | 1 | 561 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 561 | Query | 1 | 801 | CREATE USER 'cuishifeng'@'%' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$f8Zs\ZhY(9]HPTcaN83yCTNmHs/LQsa2DerCX.ZVgd4InrYiCpj75mA' /* xid=8 */ |
| binlog.000002 | 801 | Anonymous_Gtid | 1 | 878 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 878 | Query | 1 | 968 | FLUSH PRIVILEGES |
| binlog.000002 | 968 | Anonymous_Gtid | 1 | 1047 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 1047 | Query | 1 | 1256 | ALTER USER 'cuishifeng'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*10320381F36BE49A18F09B06A4BC005223975101' /* xid=12 */ |
+---------------+------+----------------+-----------+-------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
10 rows in set (0.00 sec)
- 指定查詢 binlog.000002 這個文件,從pos點:968開始查起
mysql> show binlog events in 'binlog.000002' from 968 limit 10;
+---------------+------+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+---------------+------+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------+
| binlog.000002 | 968 | Anonymous_Gtid | 1 | 1047 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 1047 | Query | 1 | 1256 | ALTER USER 'cuishifeng'@'%' IDENTIFIED WITH 'mysql_native_password' AS '*10320381F36BE49A18F09B06A4BC005223975101' /* xid=12 */ |
| binlog.000002 | 1256 | Anonymous_Gtid | 1 | 1333 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 1333 | Query | 1 | 1423 | flush privileges |
| binlog.000002 | 1423 | Anonymous_Gtid | 1 | 1500 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 1500 | Query | 1 | 1646 | GRANT ALL PRIVILEGES ON *.* TO 'cuishifeng'@'%' /* xid=70 */ |
| binlog.000002 | 1646 | Anonymous_Gtid | 1 | 1723 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 1723 | Query | 1 | 1813 | flush privileges |
| binlog.000002 | 1813 | Anonymous_Gtid | 1 | 1890 | SET @@SESSION.GTID_NEXT= 'ANONYMOUS' |
| binlog.000002 | 1890 | Query | 1 | 1968 | FLUSH TABLES |
+---------------+------+----------------+-----------+-------------+---------------------------------------------------------------------------------------------------------------------------------+
10 rows in set (0.00 sec)
從日誌中可以看出執行的mysql命令 並且有起始位置,對於恢複數據非常有用
- 查詢第一個(最早)的binlog日誌
mysql> show binlog events;
四、現在從binlog日誌恢複數據
- 常用命令
恢復語法格式:
# mysqlbinlog mysql-bin.0000xx | mysql -u用戶名 -p密碼 資料庫名
常用選項:
--start-position=953 起始pos點
--stop-position=1437 結束pos點
--start-datetime="2013-11-29 13:18:54" 起始時間點
--stop-datetime="2013-11-29 13:21:53" 結束時間點
--database=zyyshop 指定只恢復zyyshop資料庫(一臺主機上往往有多個資料庫,只限本地log日誌)
不常用選項:
-u --user=name Connect to the remote server as username.連接到遠程主機的用戶名
-p --password[=name] Password to connect to remote server.連接到遠程主機的密碼
-h --host=name Get the binlog from server.從遠程主機上獲取binlog日誌
--read-from-remote-server Read binary logs from a MySQL server.從某個MySQL伺服器上讀取binlog日誌
小結:實際是將讀出的binlog日誌內容,通過管道符傳遞給mysql命令。這些命令、文件儘量寫成絕對路徑;
日誌恢復 相當於執行當時DDL語句,如果日誌恢復的語句例如你庫中存在某個表 日誌又執行創建這個表 肯定是走不通的 所以最好指定具體位置恢復
- 查看binlog日誌 確定從哪恢復
mysql> show binlog events in 'mysql-bin.000023';
以下為末尾片段:
+------------------+------+------------+-----------+-------------+------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+------------------+------+------------+-----------+-------------+------------------------------------------------------------+
| mysql-bin.000023 | 922 | Xid | 1 | 953 | COMMIT /* xid=3820 */ |
| mysql-bin.000023 | 953 | Query | 1 | 1038 | BEGIN |
| mysql-bin.000023 | 1038 | Query | 1 | 1164 | use `zyyshop`; update zyyshop.tt set name='李四' where id=4|
| mysql-bin.000023 | 1164 | Xid | 1 | 1195 | COMMIT /* xid=3822 */ |
| mysql-bin.000023 | 1195 | Query | 1 | 1280 | BEGIN |
| mysql-bin.000023 | 1280 | Query | 1 | 1406 | use `zyyshop`; update zyyshop.tt set name='小二' where id=2|
| mysql-bin.000023 | 1406 | Xid | 1 | 1437 | COMMIT /* xid=3823 */ |
| mysql-bin.000023 | 1437 | Query | 1 | 1538 | drop database zyyshop |
+------------------+------+------------+-----------+-------------+------------------------------------------------------------+
通過分析,造成資料庫破壞的pos點區間是介於 1437--1538 之間,只要恢復到1437前就可。
mysqlbinlog --start-position=953 --stop-position=1538 --database=zyyshop binlog.000002 | mysql -uroot -p123456 -v zyyshop
- 指定時間恢復
- 知道自己在哪個時間段誤操作了
mysql> drop table tt;
@ --start-datetime="2013-11-29 13:18:54" 起始時間點
@ --stop-datetime="2013-11-29 13:21:53" 結束時間點
# mysqlbinlog --start-datetime="2013-11-29 13:18:54" --stop-datetime="2013-11-29 13:21:53" --database=zyyshop binlog.000002 | mysql -uroot -p123456 -v zyyshop
希望這篇文章能夠幫助誤刪操作的朋友順利恢複數據