Linux上通過binlog文件恢復(fù)mysql數(shù)據(jù)庫(kù)詳細(xì)步驟
一、binlog 介紹
服務(wù)器的二進(jìn)制日志記錄著該數(shù)據(jù)庫(kù)的所有增刪改的操作日志(前提是要在自己的服務(wù)器上開啟binlog),還包括了這些操作的執(zhí)行時(shí)間。為了顯示這些二進(jìn)制內(nèi)容,我們可以使用mysqlbinlog命令來查看。
用途1:主從同步
用途2:恢復(fù)數(shù)據(jù)庫(kù)(也是線上出現(xiàn)一次數(shù)據(jù)庫(kù)文件丟失后,才對(duì)這個(gè)有所了解并學(xué)習(xí)的)
mysqlbinlog命令用法:shell> mysqlbinlog [options] log_file ...
<!--[if !supportLists]-->1) mysqlbinlog 選項(xiàng)示例
常見的選項(xiàng)有以下幾個(gè):
--start-datetime
從二進(jìn)制日志中讀取指定等于時(shí)間戳或者晚于本地計(jì)算機(jī)的時(shí)間。取值如:="1470733768" 或者="2016-08-09 5:09:28"
示例:
[root@hcloud ~]# mysqlbinlog --start-datetime="2016-08-09 5:05:27" /var/lib/mysql/mysql-bin.000001 --stop-datetime
從二進(jìn)制日志中讀取指定小于時(shí)間戳或者等于本地計(jì)算機(jī)的時(shí)間 取值和上述一樣
--start-position
從二進(jìn)制日志中讀取指定position 事件位置作為開始。取值:="2698"
示例:
[root@hcloud ~]# mysqlbinlog --start-position="2698" /var/lib/mysql/mysql-bin.000001 --stop-position
從二進(jìn)制日志中讀取指定position 事件位置作為事件截至。取值:="2698"
二、環(huán)境準(zhǔn)備以及備份恢復(fù)
1) 安裝好mysql后,檢查開啟binlog
mysql> SHOW BINARY LOGS;
ERROR 1381 (HY000): You are not using binary logging :上面提示說明沒有服務(wù)器開啟binlog
修改/etc/my.cnf
在mysqld選項(xiàng)中添加 一行內(nèi)容如下:
log-bin=mysql-bin
默認(rèn)如果不給值的話,log-bin 的會(huì)以mysqld-bin 為索引,創(chuàng)建mysqld-bin.00001等
重啟mysqld即可。
2) 檢查下binlog
mysql> show binary logs; +------------------+-----------+ | Log_name | File_size | +------------------+-----------+ | mysql-bin.000001 | 106 | +------------------+-----------+ 1 row in set (0.00 sec)
3) 先創(chuàng)建一些原始數(shù)據(jù)。
mysql> create database Test_DB; Query OK, 1 row affected (0.00 sec) mysql> use Test_DB; Database changed mysql> CREATE TABLE OneTb(id INT(10) NOT NULL,name varchar(20),age INT(10)); Query OK, 0 rows affected (0.00 sec) mysql> insert into OneTb values (1,'user1',18); mysql> insert into OneTb values (2,'user2',19); insert into OneTb values (3,'user3',20);
檢查下數(shù)據(jù):
mysql> select * from OneTb; +----+-------+------+ | id | name | age | +----+-------+------+ | 1 | user1 | 18 | | 2 | user2 | 19 | | 3 | user3 | 20 | +----+-------+------+ 3 rows in set (0.00 sec)
4) 備份還原 (完整備份以及還原)
這里我們模擬一下做下每天的完整備份數(shù)據(jù)庫(kù)任務(wù)。
[root@hcloud ~]# mysqldump -uroot -p Test_DB > /data/mysqlbackup/Test_DB_0809-16:50.sql Enter password:
模擬下操作失誤,將數(shù)據(jù)修改錯(cuò)誤了。
mysql> update OneTb set age = 15; Query OK, 3 rows affected (0.00 sec) Rows matched: 3 Changed: 3 Warnings: 0 mysql> select * from OneTb; +----+-------+------+ | id | name | age | +----+-------+------+ | 1 | user1 | 15 | | 2 | user2 | 15 | | 3 | user3 | 15 | +----+-------+------+ 3 rows in set (0.00 sec)
現(xiàn)在我們使用傳統(tǒng)的方式來進(jìn)行恢復(fù)還原。
[root@hcloud ~]# mysql -uroot -p Test_DB < /data/mysqlbackup/Test_DB_0809-16\:50.sql
再次查詢一下:
mysql> select * from Test_DB.OneTb; +----+-------+------+ | id | name | age | +----+-------+------+ | 1 | user1 | 18 | | 2 | user2 | 19 | | 3 | user3 | 20 | +----+-------+------+ 3 rows in set (0.00 sec)
可以看到數(shù)據(jù)都已經(jīng)還原回來。
5) 利用binlog模擬還原
在原表的基礎(chǔ)上在創(chuàng)建幾條數(shù)據(jù)。
mysql> insert into Test_DB.OneTb values(4,'user4',21),(5,'user5',22),(6,'user6',23); Query OK, 3 rows affected (0.00 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from Test_DB.OneTb; +----+-------+------+ | id | name | age | +----+-------+------+ | 1 | user1 | 18 | | 2 | user2 | 19 | | 3 | user3 | 20 | | 4 | user4 | 21 | | 5 | user5 | 22 | | 6 | user6 | 23 | +----+-------+------+ 6 rows in set (0.00 sec)
如果這個(gè)時(shí)候我們把數(shù)據(jù)不小心修改了或者把庫(kù)刪除掉了,導(dǎo)致數(shù)據(jù)全部丟失,這個(gè)時(shí)候如果再用之前最新的備份文件 Test_DB_0809-16:50.sql,去恢復(fù)數(shù)據(jù)的話,那么將會(huì)丟掉備份之后新插入的數(shù)據(jù)。
注意:如果真的使用最近的一次備份文件去做的話,一定是在萬不得已的情況(比如binlog 被刪除,整個(gè)硬盤掛掉、、、 想想都可怕。。。)。
模擬誤操作,批量更改下用戶的名字。
mysql> update Test_DB.OneTb set name='user10'; Query OK, 6 rows affected (0.00 sec) Rows matched: 6 Changed: 6 Warnings: 0
不行,上一步不夠狠,這里再狠一點(diǎn),把表都給刪除
mysql> drop table Test_DB.OneTb; ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 3 Current database: *** NONE *** Query OK, 0 rows affected (0.00 sec)
由于之前我們一開始開啟了binlog 日志選項(xiàng),用binlog恢復(fù)數(shù)據(jù)庫(kù)。下面從binlog入手,先檢查一下binlog 文件,目前我的mysql 服務(wù)自開啟binlog 后重啟了兩次,所以有2個(gè)binlog文件(每重啟一次,便會(huì)重新生成一個(gè)binlog文件,還有一種情況就是運(yùn)行了FLUSH LOGS命令也會(huì)重建一個(gè));
mysql-bin.index 文件中記錄的是:自log-bin選項(xiàng)開啟后,記錄的所有的二進(jìn)制日志清單列表。
注意:在實(shí)際生產(chǎn)環(huán)境中,如果遇到需要恢復(fù)數(shù)據(jù)庫(kù)的情況,不要讓用戶能訪問到數(shù)據(jù)庫(kù),以避免新的數(shù)據(jù)插入進(jìn)來,以及在主從的環(huán)境下,關(guān)閉主從。
使用mysqlbinlog 命令可以查看binlog文件.我們看下最新的文件mysql-bin.00002
從最后可以看出有刪除的操作。但是我們不能完全的恢復(fù),因?yàn)樽詈筮€有刪除的操作。
現(xiàn)在我的思路就是,先將第一個(gè)binlog 和第二個(gè)binlog 文件導(dǎo)出來à利用指定的position位置的方式(過濾掉刪除表操作和update Test_DB.OneTb set name='user10';這條語句 ),導(dǎo)出2個(gè)sql 語句,最后我們將2個(gè)sql 合成一個(gè)sql,導(dǎo)入到數(shù)據(jù)庫(kù)中即可。
我們先用mysqlbinlog命令找到update 那條語句的位置,然后指定position 將mysql-bin.00001 導(dǎo)出來。
[root@hcloud ~]# mysqlbinlog /var/lib/mysql/mysql-bin.000001 …. #160809 5:09:28 server id 1 end_log_pos 2698 Query thread_id=17 exec_time=0 error_code=0 SET TIMESTAMP=1470733768/*!*/; SET @@session.foreign_key_checks=1, @@session.unique_checks=1/*!*/; SET @@session.sql_mode=0/*!*/; /*!\C latin1 *//*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; insert into Test_DB.OneTb values(4,'user4',21),(5,'user5',22),(6,'user6',23) /*!*/; # at 2698 #160809 5:19:49 server id 1 end_log_pos 2795 Query thread_id=17 exec_time=0 error_code=0 SET TIMESTAMP=1470734389/*!*/; update Test_DB.OneTb set name='user10' /*!*/; # at 2795 #160809 5:30:38 server id 1 end_log_pos 2814 Stop DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
從上面可以看到我們?cè)谧霾迦胝?shù)據(jù)后的position 是2698,那么使用下面的命令導(dǎo)出sql
[root@hcloud ~]# mysqlbinlog --stop-position="2698" /var/lib/mysql/mysql-bin.000001 > Backup_1.sql
然后導(dǎo)出mysql-bin.00002的sql 語句(注:由于演示操作,該文件只有一個(gè)drop 表操作,所以不做處理,但是在實(shí)際環(huán)境中,由于中途可能會(huì)有重啟數(shù)據(jù)庫(kù)操作,那時(shí)就需要檢測(cè)最新的binlog有沒有業(yè)務(wù)需要的語句。)
sql 語句已經(jīng)導(dǎo)出來了。我們可以利用該語句直接恢復(fù)所有正常的數(shù)據(jù)。
注:本次恢復(fù)沒有利用到之前的完整備份,因?yàn)槲沂情_啟binlog后,然后才做的所有建庫(kù)建表操作,第一個(gè)binlog文件里已經(jīng)記錄了所有的數(shù)據(jù)庫(kù)操作,所以不需要使用之前的完整備份(另外:實(shí)際的生產(chǎn)環(huán)境,還是需要利用到完整備份的,因?yàn)榫€上環(huán)境可能會(huì)有N多個(gè)binlog文件,所以需要利用到完整備份和最新的binlog文件來結(jié)合恢復(fù))
開始恢復(fù)前,我們將原有的Test_DB數(shù)據(jù)庫(kù)也給干掉吧。畢竟我們的binlog中有創(chuàng)建操作
mysql> DROP DATABASE Test_DB; Query OK, 0 rows affected (0.03 sec)
恢復(fù)數(shù)據(jù)庫(kù)時(shí)還可以利用在登陸mysql 后,用source 命令導(dǎo)入sql語句,這里暫不介紹
[root@hcloud ~]# mysql -uroot -p < Backup_1.sql
Enter password:
恢復(fù)完成后,我們檢查下表的數(shù)據(jù)是否完整
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | Test_DB | | mysql | +--------------------+ 3 rows in set (0.00 sec) mysql> select * from Test_DB.OneTb; +----+-------+------+ | id | name | age | +----+-------+------+ | 1 | user1 | 18 | | 2 | user2 | 19 | | 3 | user3 | 20 | | 4 | user4 | 21 | | 5 | user5 | 22 | | 6 | user6 | 23 | +----+-------+------+ 6 rows in set (0.00 sec)
Ok完整的都恢復(fù)過來了。
三、總結(jié)
1) 恢復(fù)方式
a) 利用最新一次的完整備份加binlog 指定事件起始時(shí)間和終止時(shí)間或者position恢復(fù)數(shù)據(jù)庫(kù)
b) 利用所有binlog指定事件起始位置和終止時(shí)間來合并sql文件恢復(fù)數(shù)據(jù)庫(kù)(此方法要確保binlog文件的完整)
c) 利用mysqldump 使用完整恢復(fù)。(在確保最新一次的完整備份后的數(shù)據(jù)不重要,允許丟掉的情況下,直接恢復(fù)。該方法最簡(jiǎn)單、效率最高)
2) 附:官方建議的備份原則(為了能睡個(gè)好覺….嗯,是的)
a) 在mysql安裝好并運(yùn)行時(shí),就始終開啟 log-bin選項(xiàng),該日志文件位于datadir目錄下,也要確保該目錄所在存儲(chǔ)介質(zhì)是安全的。
b) 定期做完整的mysql 備份。
c) 定期使用 FlUSH LOGS 或者 mysqladmin flush-logs ,該操作會(huì)關(guān)閉當(dāng)前的二進(jìn)制日志文件,并新建一個(gè)binlog日志文件。(和重啟mysql后新建的binlog操作一樣)。以備份binlog日志,利用binlog日志也可以做增量備份。
以上所述是小編給大家介紹的Linux上通過binlog文件恢復(fù)mysql數(shù)據(jù)庫(kù)詳細(xì)步驟,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
利用mysql的inet_aton()和inet_ntoa()函數(shù)存儲(chǔ)IP地址的方法分享
當(dāng)前很多應(yīng)用都適用字符串char(15)來存儲(chǔ)IP地址(占用16個(gè)字節(jié)),利用inet_aton()和inet_ntoa()函數(shù),來存儲(chǔ)IP地址效率很高,適用unsigned int 就可以滿足需求,不需要使用bigint,只需要4個(gè)字節(jié),節(jié)省存儲(chǔ)空間,同時(shí)效率也高很多2012-03-03詳解數(shù)據(jù)庫(kù)連接的URL的寫法及總結(jié)
這篇文章主要介紹了詳解數(shù)據(jù)庫(kù)連接的URL的寫法及總結(jié)的相關(guān)資料這里提供了四種方法1、oracle.2、MySQL.3、SQL Server.4、DB2,需要的朋友可以參考下2017-07-07MySQL分庫(kù)分表后路由策略設(shè)計(jì)詳情
這篇文章主要介紹了MySQL分庫(kù)分表后路由策略設(shè)計(jì)詳情,分庫(kù)分表后設(shè)計(jì)到的第一個(gè)問題就是,如何選擇路由key,應(yīng)該如何對(duì)key進(jìn)行路由2022-08-08MySQL并發(fā)更新數(shù)據(jù)時(shí)的處理方法
在后端開發(fā)中我們不可避免的會(huì)遇見MySQL數(shù)據(jù)并發(fā)更新的情況,作為一名后端研發(fā),如何解決這類問題也是必須要知道的,同時(shí)這也是面試中經(jīng)常考察的知識(shí)點(diǎn)。2019-05-05Myeclipse 自動(dòng)生成可持久化類的映射文件的方法
這篇文章主要介紹了Myeclipse 自動(dòng)生成可持久化類的映射文件的方法的相關(guān)資料,這里提供了詳細(xì)的實(shí)現(xiàn)步驟,需要的朋友可以參考下2016-11-11MySql?explain命令返回結(jié)果詳細(xì)介紹
explain?是MySql提供的SQL語句查詢性能的工具,是我們優(yōu)化SQL的重要指標(biāo)手段,要看懂explain返回的結(jié)果集就尤為重要,這篇文章主要介紹了MySql?explain命令返回結(jié)果解讀,需要的朋友可以參考下2023-09-09解析MySQL創(chuàng)建外鍵關(guān)聯(lián)錯(cuò)誤 - errno:150
本篇文章是對(duì)MySQL創(chuàng)建外鍵關(guān)聯(lián)錯(cuò)誤-errno:150進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06