原址 http://www.bubuko.com/infodetail-273374.html
如果要備份,請確保 mysql 打開 log-bin,有了 binarylog,mysql 纔可以在必要的時候做完整恢復,或基於時間點的恢復,或基於位置的恢復。
我的數據存放目錄爲:
mysql> SHOW VARIABLES LIKE ‘%datadir%‘; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | datadir | /var/lib/mysql/ | +---------------+-----------------+
1、建立目錄用於存放二進制日誌
[root@localhost ~]# mkdir /mybinlog [root@localhost ~]# chown mysql:mysql /mybinlog
2、編輯配置文件,啓用二進制日誌
[root@localhost ~]# vi /etc/my.cnf ### 二進制日誌目錄及文件名前綴 log-bin = /mybinlog/mysql-bin ## 然後重啓mysqld服務 [root@localhost ~]# service mysqld restart
3、查看生成的binlog日誌
[root@localhost ~]# ls /mybinlog/ mysql-bin.000001 mysql-bin.index
4、準備測試數據
mysql> CREATE DATABASE mydb; mysql> USE mydb; ### 創建 myisam 引擎的表 mysql> CREATE TABLE myisam_tbl( -> id INT NOT NULL AUTO_INCREMENT, -> name VARCHAR(50), -> PRIMARY KEY(id) -> ) ENGINE=myisam DEFAULT charset=utf8; mysql> INSERT INTO myisam_tbl(name) -> VALUES(‘one‘),(‘joy‘),(‘li‘),(‘tom‘),(‘jerry‘),(‘hello‘); ### 造數據的好辦法 mysql> INSERT INTO myisam_tbl(name) -> SELECT name FROM myisam_tbl; ### 創建innodb引擎的表 mysql> CREATE TABLE innodb_tbl( -> id INT NOT NULL AUTO_INCREMENT, -> name VARCHAR(50), -> PRIMARY KEY(id) -> ) engine = innodb DEFAULT charset=utf8; # 把myisam_tbl的數據弄到innodb_tbl表 mysql> INSERT INTO innodb_tbl(name) -> SELECT name FROM myisam_tbl;
一、直接拷貝數據庫文件(文件系統備份工具 cp),物理備份(適合小型數據庫)
標準流程:鎖表->刷新表到磁盤->停止服務->拷貝文件->解鎖
冷備份步驟:
備份:
1.停掉 mysql 服務,在操作系統級別備份 mysql 的數據文件。
2.重啓 mysql 服務,備份重啓以後生成的 binlog。
恢復:
1.停掉 mysql 服務,在操作系統級別恢復 mysql 的數據文件。
2.重啓 mysql 服務,使用 mysqlbinlog 恢復自備份以來的 binlog。
1、在終端1
# 刷新,打開讀鎖 mysql> FLUSH TABLES WITH READ LOCK; Query OK, 0 rows affected (0.00 sec)
2、在終端2
# 創建備份目錄 [root@localhost ~]# mkdir /mnt/mysql-$(date +%F) # 以歸檔模式拷貝所有的數據文件 [root@localhost ~]# cp -a /var/lib/mysql/* /mnt/mysql-2014-07-21/
3、回到第一個終端
# 解鎖 mysql> UNLOCK TABLES; Query OK, 0 rows affected (0.10 sec)
4、模擬數據庫損壞, 刪除原來的所有數據文件
[root@localhost ~]# rm -rf /var/lib/mysql/* # 然後關閉Mysql服務 [root@localhost ~]# service mysqld stop ### 我是通過yum安裝的mysql,是可以順利停掉服務的。 # 如果不能停掉 ERROR! MySQL server PID file could not be found! , 那麼 [root@localhost ~]# ps -ef | grep mysql [root@localhost ~]# killall mysqld ###進行數據庫初始化 #1 編譯安裝的 ,請根據實際情況指定參數 [root@localhost ~]# /usr/local/mysql/scripts/mysql_install_db --basedir=/usr/local/mysql/ --datadir=/mydata/data/ --user=mysql #2 yum安裝的 [root@localhost ~]# /usr/bin/mysql_install_db # 初始化後,我們的數據已經丟失 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | test | +--------------------+ 3 rows in set (0.00 sec)
5、恢復過程,複製完全備份的數據文件到數據目錄中
# \cp 轉義別名,不然複製時老是提醒是否覆蓋 [root@localhost ~]# \cp -a /mnt/mysql-2014-07-21/* /var/lib/mysql/ # 啓動Mysql [root@localhost ~]# service mysqld start mysql> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | mysql | | test | +--------------------+ mysql> USE mydb; Database changed mysql> show tables; +-----------------+ | Tables_in_mydb | +-----------------+ | innodb_tbl | | myisam_tbl | | test_myisam_tbl | +-----------------+ 3 rows in set (0.00 sec)
OK, 我們看到數據已經恢復。cp命令,對其進行的備份,速度快,還原速度幾乎最快,但是靈活度很低,可以跨系統,但是跨平臺能力很差,適合小型數據庫備份!
二、mysqldump邏輯備份數據庫(完全備份+增加備份,速度相對較慢,適合中小型數據庫)(MyISAM是溫備份,InnoDB是熱備份)
邏輯備份步驟:
備份:
1.選擇在系統空閒時,比如在夜間,使用 mysqldump –F(flush-logs)備份數據
庫。
# mysqldump –u root –p*** pointcard –F > pointcard.sql
2.並備份 mysqldump 開始以後生成的 binlog。
恢復:
1. 停掉應用,執行 mysql 導入備份文件.
mysql –u root –p*** pointcard < pointcard.sql
2. 使用 mysqlbinlog 恢復自 mysqldump 備份以來的 binlog。
mysqlbinlog $HOME/data/mysql-bin.123456 | mysql -u root –p***
mysqldump -u -h -p --all-databases --databases <dbname> --events #備份事件 --flush-logs #在數據庫導出之前先執行FLUSH LOGS --lock-all-tables #鎖定所有表 --lock-tables #鎖定某些表 --master-data=n #(指定備份點:log fiel name and position) --opt #(PITR 精確恢復,時間點恢復) --routines #(備份存儲過程、存儲函數) --triggers #(備份觸發器) --single-transaction #(爲事務性數據庫提供備份) --flush-logs # 滾動日誌 --where #(指定過濾條件,只備份符合條件數據)
由於mysqldump針對不同的引擎有所差異,所以務必清楚引擎類型
溫備:
在使用MyISAM引擎中,只能使用溫備份,這時候要防止數據的寫入,所以先加上讀鎖。這時候可以進入數據庫手動加讀鎖。這樣比較麻煩,在mysqldump工具中直接有一個加鎖的選項
# mysqldump --databases mydb --lock-all-tables --flush-logs> /tmp/backup-`date +%F-%H-%M`.sql ### 備份所有庫(完全備份) # mysqldump --all-databases --lock-all-tables --routines --triggers --events --master-data=2 --flush-logs > /root/mybackup/`date +%F-%H-%M`.full.sql
如果是針對某張表備份,只要在數據庫名稱後面加上表名稱就行了
# mysqldump -uroot -p mydb course > /root/mydb.sql 備份表course # mysqldump -uroot -p --databases mydb dnsdata > /root/mydb.sql 同時備份兩個數據庫
這裏注意,要實現時間點的恢復,加上--flush-logs選項,在使用備份文件恢復後,然後再基於二進制日誌進行時間點的恢復
熱備:
如果使用的是InnoDB引擎,就不必進行對數據庫加鎖的操作,加一個選項既可以進行熱備份:--single-transaction
# mysqldump --databases mydb --single-transaction --flush-logs --master-data=2 > /tmp/backup-`date +%F-%H-%M`.sql
實驗:
1、備份前的binlog日誌
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000005 | 106 | | | +------------------+----------+--------------+------------------+
2、備份所有庫(完全備份)
[root@localhost ~]# mysqldump -uroot -p --all-databases --lock-all-tables --routines --triggers --events --master-data=2 --flush-logs > /root/mybackup/$(date +%F-%H-%M).full.sql [root@localhost ~]# ls mybackup/ 2014-07-21-16-53.full.sql
3、查看備份後的binlog, 主要是--flush-logs選項
mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000006 | 106 | | | +------------------+----------+--------------+------------------+
4、我們向myisam_tbl表插入幾條新數據
mysql> INSERT INTO myisam_tbl(name) -> VALUES(‘new-1‘), (‘new-2‘), (‘new-3‘); # 查看binlog mysql> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000006 | 263 | | | +------------------+----------+--------------+------------------+
5、備份binlog(增量備份)
[root@localhost ~]# cp /mybinlog/mysql-bin.000006 /root/mybackup/$(date +%F-%H-%M).binlog.000006
6、模擬誤操作(刪除myisam_tbl表)
mysql> drop table myisam_tbl; Query OK, 0 rows affected (0.01 sec)
7、恢復
恢復前先關閉對恢復過程的二進制日誌記錄,因爲記錄恢復語句是毫無意義的
mysql> set sql_log_bin=0; -- 關閉binlog Query OK, 0 rows affected (0.00 sec) mysql> \. /root/mybackup/2014-07-21-16-53.full.sql mysql> use mydb; mysql> show tables; +-----------------+ | Tables_in_mydb | +-----------------+ | innodb_tbl | | myisam_tbl | | test_myisam_tbl | +-----------------+ mysql> SELECT * FROM myisam_tbl ORDER BY id DESC LIMIT 5; +----+-------+ | id | name | +----+-------+ | 12 | hello | | 11 | jerry | | 10 | tom | | 9 | li | | 8 | joy | +----+-------+
ok,現在已經恢復到完全備份時的狀態,但我們最後插入的三條數據沒有恢復。
[root@localhost ~]# mysqlbinlog /root/mybackup/2014-07-21-17-02.binlog.000006 | mysql -uroot -p mydb Enter password: mysqlbinlog: unknown variable ‘default-character-set=utf8‘
mysqlbinlog報錯: unknown variable ‘default-character-set=utf8‘
it‘s because inside the my.cnf got
default-character-set=utf8
the default-character-set is deprecated in 5.5. we should use instead:
character-set-server = utf8
or add --no-defaults
mysqlbinlog --no-defaults -v logbin-log.000003 > logbin003.sql
==============END=================
[root@localhost ~]# mysqlbinlog --no-defaults /root/mybackup/2014-07-21-17-02.binlog.000006 | mysql -uroot -p mydb mysql> set sql_log_bin=1; -- 打開binlog Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM myisam_tbl ORDER BY id DESC LIMIT 5; +----+-------+ | id | name | +----+-------+ | 15 | new-3 | | 14 | new-2 | | 13 | new-1 | | 12 | hello | | 11 | jerry | +----+-------+
OK, 恢復成功。
時間點的恢復:
1.如果今天上午 10 點發生了誤操作,可以用以下語句用備份和 binglog 將數據恢復到故
障前:
mysqlbinlog --no-defaults --stop-date="2014-07-24 9:59:59" /var/log/mysql/bin.123456 | mysql -u root –pmypwd
2.跳過故障時的時間點,繼續執行後面的 binlog,完成恢復
mysqlbinlog --no-defaults --start-date="2014-07-24 10:01:00" /var/log/mysql/bin.123456 | mysql -u root -pmypwd
位置恢復:
和時間點恢復類似,但是更精確,步驟如下:
mysqlbinlog --no-defaults --start-date="2014-07-24 9:55:00" --stop-date="2014-07-24 10:05:00" /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
該命令將在/tmp 目錄創建小的文本文件,編輯此文件,找到出錯語句前後的位置號 ,
例如前後位置號分別是 368312 和 368315。恢復了以前的備份文件後,你應從命令
行輸入下面內容:
mysqlbinlog --no-defaults --stop-position="368312" /var/log/mysql/bin.123456 | mysql -u root -pmypwd mysqlbinlog --no-defaults --start-position="368315" /var/log/mysql/bin.123456 | mysql -u root -pmypwd
上面的第 1 行將恢復到停止位置爲止的所有事務。下一行將恢復從給定的起始位置
直到二進制日誌結束的所有事務。因爲 mysqlbinlog 的輸出包括每個 SQL 語句記錄
之前的 SET TIMESTAMP 語句,恢復的數據和相關 MySQL 日誌將反應事務執行的原時
間。
注意點
恢復的時刻關閉二進制日誌
mysql>set sql_log_bin=0;
因爲這是基於邏輯備份方式,在恢復日誌時會執行sql語句插入數據,而恢復時候插入數據的日誌沒有意義。
本文出自 “Share your knowledge” 博客,請務必保留此出處http://skypegnu1.blog.51cto.com/8991766/1529586
MySQL備份和還原系列二:cp冷備份 和 mysqldump,布布扣,bubuko.com