mysql教程數據庫教程備份恢復之徹底備份與增量備份策略
備份策略一:直接拷貝數據庫文件(不推薦)
備份策略二:使用mysqlhotcopy備份數據庫(徹底備份,適合小型數據庫備份)
備份策略三:使用mysqldump備份數據庫(徹底+增量備份,適合中型數據庫備份)
備份策略四:使用主從複製機制(replication)(實現數據庫實時備份)
備份策略1、直接拷貝數據庫文件
直接拷貝數據文件最爲直接、快速、方便,但缺點是基本上不能實現增量備份。爲了保證數據的一致性,須要在備份文件前,執行如下 sql 語句:
flush tables with read lock;
也就是把內存中的數據都刷新到磁盤中,同時鎖定數據表,以保證拷貝過程當中不會有新的數據寫入。這種方法備份出來的數據恢復也很簡單,直接拷貝回原來的數據庫目錄下便可。
備份策略2、使用mysqlhotcopy備份數據庫
mysqlhotcopy 是一個 perl 程序,最初由tim bunce編寫。它使用 lock tables、flush tables 和 cp 或 scp 來快速備份數據庫。它是備份數據庫或單個表的最快的途徑,但它只能運行在數據庫文件(包括數據表定義文件、數據文件、索引文件)所在的機器上,而且 mysqlhotcopy 只能用於備份 myisam表。
本備份策略適合於小型數據庫的備份,數據量不大,能夠採用mysqlhotcopy程序天天進行一次徹底備份。
備份策略佈置:
(1)、安裝dbd-mysql perl模塊,支持mysqlhotcopy腳本鏈接到mysql數據庫。
shell> tar -xzvf dbd-mysql-4.005.tar.gz
shell> cd dbd-mysql-4.005
shell> unset lang
shell> perl makefile.pl -mysql_config=/usr/local/mysql/bin/mysql_config -testuser=root -testpassword=userpwd
shell> make
shell> make test
shell> make install
(2)、設置crontab任務,天天執行備份腳本
shell> crontab -e
0 3 * * * /root/mysqlbackup/mysqlbackup.sh >/dev/null 2>&1
天天凌晨3:00執行備份腳本。
mysqlbackup.sh註釋:
#!/bin/sh
# name:mysqlbackup.sh
# ps教程:mysql database backup,use mysqlhotcopy script.
# write by:i.stone
# last modify:2007-11-15
#
# 定義變量,請根據具體狀況修改
# 定義腳本所在目錄
scriptsdir=`pwd`
# 數據庫的數據目錄
datadir=/usr/local/mysql/data/
# 數據備份目錄
tmpbackupdir=/tmp/tmpbackup/
backupdir=/tmp/mysqlbackup/
# 用來備份數據庫的用戶名和密碼
mysqluser=root
mysqlpwd=111111
# 定義email地址
email=alter@3ppt.com
# 若是臨時備份目錄存在,清空它,若是不存在則建立它
if [[ -e $tmpbackupdir ]]; then
rm -rf $tmpbackupdir/*
else
mkdir $tmpbackupdir
fi
# 若是備份目錄不存在則建立它
if [[ ! -e $backupdir ]];then
mkdir $backupdir
fi
# 清空mysqlbackup.log
if [[ -s mysqlbackup.log ]]; then
cat /dev/null >mysqlbackup.log
fi
# 獲得數據庫備份列表,在此能夠過濾不想備份的數據庫
for databases in `find $datadir -type d |
sed -e "s//usr/local/mysql/data///" |
sed -e "s/test//"`; do
if [[ $databases == "" ]]; then
continue
else
# 備份數據庫
/usr/local/mysql/bin/mysqlhotcopy --user=$mysqluser --password=$mysqlpwd -q "$databases" $tmpbackupdir
datetime=`date "+%y.%m.%d %h:%m:%s"`
echo "$datetime databasedatabases backup success!" >>mysqlbackup.log
fi
done
# 壓縮備份文件
date=`date -i`
cd $tmpbackupdir
tar czf $backupdir/mysql-$date.tar.gz ./
# 發送郵件通知
if [[ -s mysqlbackup.log ]]; then
cat mysqlbackup.log | mail -s "mysql backup" $email
fi
# 使用smbclientmv.sh腳本上傳數據庫備份到備份服務器
# $scriptsdir/smbclientmv.sh
smbclientmv.sh註釋:
#!/bin/sh
# name:smbclientmv.sh
# ps:move the data to backup server.
# write by:i.stone
# last modify:2007-11-15
#
# 定義變量
# 備份服務器名
backupserver="backupservername"
# 共享文件夾名
backupshare="sharename"
# 備份服務器的訪問用戶名和密碼
backupuser="smbuser"
backuppw="smbpassword"
# 定義備份目錄
backupdir=/tmp/mysqlbackup
date=`date -i`
# move the data to backupserver
smbclient //$backupserver/$backupshare
$backuppw -d0 -w workgroup -u $backupuser
-c "put $backupdir/mysql-$date.tar.gz
mysql-$date.tar.gz"
# delete temp files
rm -f $backupdir/mysql-$date.tar.gz
(3)、恢復數據庫到備份時的狀態
mysqlhotcopy 備份出來的是整個數據庫目錄,使用時能夠直接拷貝到 mysqld 指定的 datadir (在這裏是 /usr/local/mysql/data/)目錄下便可,同時要注意權限的問題,以下例:
shell> cp -rf db_name /usr/local/mysql/data/
shell> chown -r mysql:mysql /usr/local/mysql/data/ (將 db_name 目錄的屬主改爲 mysqld 運行用戶)
本套備份策略只能恢復數據庫到最後一次備份時的狀態,要想在崩潰時丟失的數據儘可能少應該更頻繁的進行備份,要想恢復數據到崩潰時的狀態請使用主從複製機制(replication)。
備份策略3、使用mysqldump備份數據庫
mysqldump 是採用sql級別的備份機制,它將數據表導成 sql 腳本文件,在不一樣的 mysql 版本之間升級時相對比較合適,這也是最經常使用的備份方法。mysqldump 比直接拷貝要慢些。關於mysqldump的更詳細解釋見最後的附錄。
對於中等級別業務量的系統來講,備份策略能夠這麼定:第一次徹底備份,天天一次增量備份,每週再作一次徹底備份,如此一直重複。而對於重要的且繁忙的系統 來講,則可能須要天天一次全量備份,每小時一次增量備份,甚至更頻繁。爲了避免影響線上業務,實如今線備份,而且能增量備份,最好的辦法就是採用主從複製機 制(replication),在 slave 機器上作備份。
備份策略佈置:
(1)、建立備份目錄
shell> mkdir /tmp/mysqlbackup
shell> mkdir /tmp/mysqlbackup/daily
(2)、啓用二進制日誌
採用 binlog 的方法相對來講更靈活,省心省力,並且還能夠支持增量備份。
啓用 binlog 時必需要重啓 mysqld。首先,關閉 mysqld,打開 /etc/my.cnf,加入如下幾行:
[mysqld]
log-bin
而後啓動 mysqld 就能夠了。運行過程當中會產生 hostname-bin.000001 以及 hostname-bin.index,前面的文件是 mysqld 記錄全部對數據的更新操做,後面的文件則是全部 binlog 的索引,都不能輕易刪除。關於 binlog 的更詳細信息請查看手冊。
(3)、配置ssh密鑰登陸,用於將mysql備份傳送到備份服務器(若是備份服務器爲windows,請跳過此部)。
1)、在mysql所在服務器(192.168.0.20)生成ssh密鑰
[root@lab ~]# ssh-keygen -t rsa
generating public/private rsa key pair.
enter file in which to save the key (/root/.ssh/id_rsa):
//直接回車
enter passphrase (empty for no passphrase):
//直接回車,不使用密碼
enter same passphrase again:
//直接回車,不使用密碼
your identification has been saved in /root/.ssh/id_rsa.
your public key has been saved in /root/.ssh/id_rsa.pub.
the key fingerprint is:
c2:96:9f:2d:5a:8e:08:42:43:35:2f:85:5e:72:f8:1c root@lab
2)、在備份服務器(192.168.0.200)上建立目錄,修改權限,並傳送公鑰。
[root@lab ~]# ssh 192.168.0.200 "mkdir .ssh;chmod 0700 .ssh"
the authenticity of host '192.168.0.200 (192.168.0.200)' can't be established.
rsa key fingerprint is 37:57:55:c1:32:f1:dd:bb:1b:8a:13:6f:89:fb:b8:9d.
are you sure you want to continue connecting (yes/no)? yes
warning: permanently added '192.168.0.200' (rsa) to the list of known hosts.
root@192.168.0.200's password:
//輸入備份服務器的root密碼
[root@lab ~]# scp .ssh/id_rsa.pub 192.168.0.200:.ssh/authorized_keys2
root@192.168.0.200's password:
id_rsa.pub 100% 218 0.2kb/s 00:00
3)、測試ssh登陸
[root@lab ~]# ssh 192.168.0.200 //測試ssh登陸
last login: fri nov 16 10:34:02 2007 from 192.168.0.20
[root@lib ~]#
(4)、設置crontab任務,天天執行備份腳本
shell> crontab -e
#每一個星期日凌晨3:00執行徹底備份腳本
0 3 * * 0 /root/mysqlbackup/mysqlfullbackup.sh >/dev/null 2>&1
#週一到週六凌晨3:00作增量備份
0 3 * * 1-6 /root/mysqlbackup/mysqldailybackup.sh >/dev/null 2>&1
mysqlfullbackup.sh註釋:
#!/bin/sh
# name:mysqlfullbackup.sh
# ps:mysql database full backup.
# write by:i.stone
# last modify:2007-11-17
#
# use mysqldump --help get more detail.
#
# 定義變量,請根據具體狀況修改
# 定義腳本目錄
scriptsdir=`pwd`
# 定義數據庫目錄
mysqldir=/usr/local/mysql
# 定義用於備份數據庫的用戶名和密碼
user=root
userpwd=111111
# 定義備份目錄
databackupdir=/tmp/mysqlbackup
# 定義郵件正文文件
emailfile=$databackupdir/email.txt
# 定義郵件地址
email=alter@3ppt.com
# 定義備份日誌文件
logfile=$databackupdir/mysqlbackup.log
date=`date -i`
echo "" > $emailfile
echo $(date +"%y-%m-%d %h:%m:%s" >> $emailfile
cd $databackupdir
# 定義備份文件名
dumpfile=mysql_$date.sql
gzdumpfile=mysql_$date.sql.tar.gz
# 使用mysqldump備份數據庫,請根據具體狀況設置參數
$mysqldir/bin/mysqldump -u$user -p$userpwd
--opt --default-character-set=utf8 --extended-insert=false
--triggers -r --hex-blob --all-databases
--flush-logs --delete-master-logs
--delete-master-logs
-x > $dumpfile
# 壓縮備份文件
if [[ $? == 0 ]]; then
tar czf $gzdumpfile $dumpfile >> $emailfile 2>&1
echo "backupfilenamegzdumpfile" >> $emailfile
echo "database backup success!" >> $emailfile
rm -f $dumpfile
# delete daily backup files.
cd $databackupdir/daily
rm -f *
# delete old backup files(mtime>2).
$scriptsdir/rmbackup.sh
# 若是不須要將備份傳送到備份服務器或備份服務器爲windows,請將標綠的行註釋掉
# move backup files to backup server.
#適合linux(mysql服務器)到linux(備份服務器)
$scriptsdir/rsyncbackup.sh
if (( !$? )); then
echo "move backup files to backup server success!" >> $emailfile
else
echo "move backup files to backup server fail!" >> $emailfile
fi
else
echo "database backup fail!" >> $emailfile
fi
# 寫日誌文件
echo "--------------------------------------------------------" >> $logfile
cat $emailfile >> $logfile
# 發送郵件通知
cat $emailfile | mail -s "mysql backup" $email
(5) 、恢復數據庫到備份時的狀態
用 mysqldump 備份出來的文件是一個能夠直接倒入的 sql 腳本,直接用 mysql 客戶端導入就能夠了。
/usr/local/mysql/bin/mysql -uroot -puserpwd db_name < db_name.sql
對於任何可適用的更新日誌,將它們做爲 mysql 的輸入:
% ls -t -r -1 hostname-bin* | xargs mysqlbinlog | mysql -uuser -puserpwd
ls 命令生成更新日誌文件的一個單列列表,根據服務器產生它們的次序排序(注意:若是你修改任何一個文件,你將改變排序次序,這將致使更新日誌以錯誤的次序被運用。)
本套備份策略只能恢復數據庫到最後一次備份時的狀態,要想在崩潰時丟失的數據儘可能少應該更頻繁的進行備份,要想恢復數據到崩潰時的狀態請使用主從複製機制 (replication)。若是使用本套備份腳本,將日誌文件和數據文件放到不一樣的磁盤上是一個不錯的主義,這樣不只能夠提升數據寫入速度,還能使數據 更安全
mysql支持單向、異步複製,複製過程當中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入二進制日誌文件,並維護日誌 文件的一個索引以跟蹤日誌循環。當一個從服務器鏈接到主服務器時,它通知主服務器從服務器在日誌中讀取的最後一次成功更新的位置。從服務器接收從那時起發 生的任何更新,而後封鎖並等待主服務器通知下一次更新。
爲何使用主從複製?
一、主服務器/從服務器設置增長了健壯性。主服務器出現問題時,你能夠切換到從服務器做爲備份。
二、經過在主服務器和從服務器之間切分處理客戶查詢的負荷,能夠獲得更好的客戶響應時間。可是不要同時在主從服務器上進行更新,這樣可能引發衝突。
三、使用複製的另外一個好處是可使用一個從服務器執行備份,而不會干擾主服務器。在備份過程當中主服務器能夠繼續處理更新。
mysql使用3個線程來執行復制功能(其中1個在主服務器上,另兩個在從服務器上。當發出start slave時,從服務器建立一個i/o線程,以鏈接主服務器並讓主服務器發送二進制日誌。主服務器建立一個線程將二進制日誌中的內容發送到從服務器。從服 務器i/o線程讀取主服務器binlog dump線程發送的內容並將該數據拷貝到從服務器數據目錄中的本地文件中,即中繼日誌。第3個線程是sql線程,從服務器使用此線程讀取中繼日誌並執行日 志中包含的更新。show processlist語句能夠查詢在主服務器上和從服務器上發生的關於複製的信息。
默認中繼日誌使用host_name-relay-bin.nnnnnn形式的文件名,其中host_name是從服務器主機名,nnnnnn是序列號。 用連續序列號來建立連續中繼日誌文件,從000001開始。從服務器跟蹤中繼日誌索引文件來識別目前正使用的中繼日誌。默認中繼日誌索引文件名爲 host_name-relay-bin.index。在默認狀況,這些文件在從服務器的數據目錄中被建立。中繼日誌與二進制日誌的格式相同,而且能夠用 mysqlbinlog讀取。當sql線程執行完中繼日誌中的全部事件後,中繼日誌將會被自動刪除。
從服務器在數據目錄中另外建立兩個狀態文件--master.info和relay-log.info。狀態文件保存在硬盤上,從服務器關閉時不會丟失。下次從服務器啓動時,讀取這些文件以肯定它已經從主服務器讀取了多少二進制日誌,以及處理本身的中繼日誌的程度。
設置主從複製:
一、確保在主服務器和從服務器上安裝的mysql版本相同,而且最好是mysql的最新穩定版本。
二、在主服務器上爲複製設置一個鏈接帳戶。該帳戶必須授予replication slave權限。若是帳戶僅用於複製(推薦這樣作),則不須要再授予任何其它權限。
mysql> grant replication slave on *.*
-> to 'replication'@'%.3ppt.com' identified by 'slavepass';
三、執行flush tables with read lock語句清空全部表和塊寫入語句:
mysql> flush tables with read lock;
保持mysql客戶端程序不要退出。開啓另外一個終端對主服務器數據目錄作快照。
shell> cd /usr/local/mysql/
shell> tar -cvf /tmp/mysql-snapshot.tar ./data
若是從服務器的用戶帳戶與主服務器的不一樣,你可能不想複製mysql數據庫。在這種狀況下,應從歸檔中排除該數據庫。你也不須要在歸檔中包括任何日誌文件或者master.info或relay-log.info文件。
當flush tables with read lock所置讀鎖定有效時(即mysql客戶端程序不退出),讀取主服務器上當前的二進制日誌名和偏移量值:
mysql > show master status;
+---------------+----------+--------------+------------------+
| file | position | binlog_do_db | binlog_ignore_db |
+---------------+----------+--------------+------------------+
| mysql-bin.003 | 73 | test | manual,mysql |
+---------------+----------+--------------+------------------+
file列顯示日誌名,而position顯示偏移量。在該例子中,二進制日誌值爲mysql-bin.003,偏移量爲73。記錄該值。之後設置從服務器時須要使用這些值。它們表示複製座標,從服務器應從該點開始從主服務器上進行新的更新。
若是主服務器運行時沒有啓用--logs-bin,show master status顯示的日誌名和位置值爲空。在這種狀況下,當之後指定從服務器的日誌文件和位置時須要使用的值爲空字符串('')和4.
取得快照並記錄日誌名和偏移量後,回到前一中端從新啓用寫活動:
mysql> unlock tables;
四、確保主服務器主機上my.cnf文件的[mysqld]部分包括一個log-bin選項。該部分還應有一個server-id=master_id選項,其中master_id必須爲1到232–1之間的一個正整數值。例如:
[mysqld]
log-bin
server-id=1
若是沒有提供那些選項,應添加它們並重啓服務器。
五、中止從服務器上的mysqld服務並在其my.cnf文件中添加下面的行:
[mysqld]
server-id=2
slave_id值同master_id值同樣,必須爲1到232–1之間的一個正整數值。而且,從服務器的id必須與主服務器的id不相同。
六、將數據備據目錄中。確保對這些文件和目錄的權限正確。服務器 mysql運行的用戶必須可以讀寫文件,如同在主服務器上同樣。
shell> chown -r mysql:mysql /usr/local/mysql/data
七、啓動從服務器。在從服務器上執行下面的語句,用你的系統的實際值替換選項值:
mysql> change master to
-> master_host='master_host_name',
-> master_user='replication_user_name',
-> master_password='replication_password',
-> master_log_file='recorded_log_file_name',
-> master_log_pos=recorded_log_position;
八、啓動從服務器線程:
mysql> start slave;
執行這些程序後,從服務器應鏈接主服務器,並補充自從快照以來發生的任何更新。
九、若是出現複製錯誤,從服務器的錯誤日誌(hostname.err)中也會出現錯誤消息。
十、從服務器複製時,會在其數據目錄中發現文件master.info和hostname-relay-log.info。從服務器使用這兩個文件跟蹤 已經處理了多少主服務器的二進制日誌。不要移除或編輯這些文件,除非你確切知你正在作什麼並徹底理解其意義。即便這樣,最好是使用change master to語句mysql