MySQL 備份和恢復策略
在數據庫表丟失或損壞的情況下,備份你的數據庫是很重要的。如果發生系統崩潰,你肯定想能夠將你的表盡可能丟失最少的數據恢復到崩潰發生時的狀態。本文主要對MyISAM表做備份恢復。</span></span>
備份策略一:直接拷貝數據庫文件(不推薦)
備份策略二:使用mysqlhotcopy備份數據庫(完全備份,適合小型數據庫備份)
備份策略三:使用mysqldump備份數據庫(完全+增量備份,適合中型數據庫備份)
備份策略四:使用主從復制機制(replication)(實現數據庫實時備份)
備份策略一、直接拷貝數據庫文件
直接拷貝數據文件最為直接、快速、方便,但缺點是基本上不能實現增量備份。為了保證數據的一致性,需要在備份文件前,執行以下
FLUSH
也就是把內存中的數據都刷新到磁盤中,同時鎖定數據表,以保證拷貝過程中不會有新的數據寫入。這種方法備份出來的數據恢復也很簡單,直接拷貝回原來的數據庫目錄下即可。
備份策略二、使用mysqlhotcopy備份數據庫
mysqlhotcopy
本備份策略適合于小型數據庫的備份,數據量不大,可以采用mysqlhotcopy程序每天進行一次完全備份。
備份策略布置:
(1)、安裝DBD-mysql
shell>
shell>
shell>
shell>
shell>
shell>
shell>
(2)、設置crontab任務,每天執行備份腳本
shell>
0
每天凌晨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@somode.com
如果臨時備份目錄存在,清空它,如果不存在則創建它</span></p>
if [[ -e $tmpBackupDir ]]; then
else
fi
# 如果備份目錄不存在則創建它
if [[ ! -e $backupDir ]];then
fi
清空MySQLBackup.log</span></p>
if [[ -s MySQLBackup.log ]]; then
fi
得到數據庫備份列表,在此可以過濾不想備份的數據庫</span></p>
for databases in `find $dataDir -type d | \
# 備份數據庫
done
壓縮備份文件</span></p>
date=`date -I`
cd $tmpBackupDir
tar czf $backupDir/mysql-$date.tar.gz ./
發送郵件通知</span></p>
if [[ -s MySQLBackup.log ]]; then
fi
使用smbclientmv.sh腳本上傳數據庫備份到備份服務器</span></p>
# $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</span></p>
smbclient //$BackupServer/$BackupShare \
$BackupPW -d0 -W WORKGROUP -U $BackupUser \
-c "put $BackupDir/mysql-$date.tar.gz \
mysql-$date.tar.gz"
Delete temp files</span></p>
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)。
備份策略三、使用mysqldump備份數據庫
mysqldump
對于中等級別業務量的系統來說,備份策略可以這么定:第一次完全備份,每天一次增量備份,每周再做一次完全備份,如此一直重復。而對于重要的且繁忙的系統來說,則可能需要每天一次全量備份,每小時一次增量備份,甚至更頻繁。為了不影響線上業務,實現在線備份,并且能增量備份,最好的辦法就是采用主從復制機制(replication),在
備份策略布置:
(1)、創建備份目錄
Shell>
Shell>
(2)、啟用二進制日志
采用
啟用
[mysqld]
log-bin
然后啟動
(3)、配置SSH密鑰登錄,用于將MySQL備份傳送到備份服務器(如果備份服務器為Windows,請跳過此部)。
1)、在MySQL所在服務器(192.168.0.20)生成SSH密鑰
[root@lab
Generating
Enter
Enter
Enter
Your
Your
The
c2:96:9f:2d:5a:8e:08:42:43:35:2f:85:5e:72:f8:1c
2)、在備份服務器(192.168.0.200)上創建目錄,修改權限,并傳送公鑰。
[root@lab
The
RSA
Are
Warning:
root@192.168.0.200's
[root@lab
root@192.168.0.200's
id_rsa.pub
3)、測試SSH登錄
[root@lab
Last
[root@lib
(4)、設置crontab任務,每天執行備份腳本
shell>
#每個星期日凌晨3:00執行完全備份腳本
0
#周一到周六凌晨3:00做增量備份
0
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@somode.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備份數據庫,請根據具體情況設置參數</span></p>
$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
壓縮備份文件</span></p>
if [[ $? == 0 ]]; then
Delete daily backup files.</span></p>
Delete old backup files(mtime>2).</span></p>
# 如果不需要將備份傳送到備份服務器或備份服務器為Windows,請將標綠的行注釋掉
# Move Backup Files To Backup Server.
#適合Linux(MySQL服務器)到Linux(備份服務器)
else
fi
# 寫日志文件
echo "--------------------------------------------------------" >> $logFile
cat $eMailFile >> $logFile
# 發送郵件通知
cat $eMailFile | mail -s "MySQL Backup" $eMail
#!/bin/sh
Name:mysqlDailyBackup.sh
PS:MySQL DataBase Daily Backup.
Write by:i.Stone
Last Modify:2007-11-17
定義變量,請根據具體情況修改
定義數據庫目錄和數據目錄
scriptsDir=pwd
mysqlDir=/usr/local/mysql
dataDir=$mysqlDir/data
# 定義用于備份數據庫的用戶名和密碼
user=root
userPWD=111111
# 定義備份目錄,每日備份文件備份到$dataBackupDir/daily
dataBackupDir=/tmp/mysqlbackup
dailyBackupDir=$dataBackupDir/daily
定義郵件正文文件
eMailFile=$dataBackupDir/email.txt
定義郵件地址
eMail=alter@somode.com
定義日志文件
logFile=$dataBackupDir/mysqlbackup.log
得到數據庫所在主機的主機名
HOSTNAME=uname -n
echo "" > $eMailFile
echo $(date +"%y-%m-%d %H:%M:%S") >> $eMailFile
刷新日志,使數據庫使用新的二進制日志文件
$mysqlDir/bin/mysqladmin -u$user -p$userPWD flush-logs
cd $dataDir
得到二進制日志列表
fileList=cat $HOSTNAME-bin.index
iCounter=0
for file in $fileList
do
expr $iCounter + 1
done
nextNum=0
iFile=0
for file in $fileList
do
basename $file
expr $nextNum + 1
跳過最后一個二進制日志(數據庫當前使用的二進制日志文件)
跳過已經備份的二進制日志文件
備份日志文件到備份目錄
expr $iFile + 1
done
if [[ $iFile == 0 ]];then
else
# 如果不需要將備份傳送到備份服務器或備份服務器為Windows,請將標綠的行注釋掉
Move Backup Files To Backup Server.
適合Linux(MySQL服務器)到Linux(備份服務器)</span></p>
發送郵件通知
cat $eMailFile | mail -s "MySQL Backup" $eMail
寫日志文件
echo "--------------------------------------------------------" >> $logFile
cat $eMailFile >> $logFile</span></p>
rsyncBackup.sh注釋:
#!/bin/sh
Name:rsyncBackup.sh
PS:Move Backup Files To Backup Server.
Write by:i.Stone
Last Modify:2007-11-17
請根據具體情況修改,注意最后有“/”
定義數據庫備份目錄
dataBackupDir=/tmp/mysqlbackup/
定義備份服務器上存放備份數據的目錄
backupServerDir=/root/mysqlbackup/
# 定義備份服務器
backupServer=192.168.0.200
#
同步備份文件到備份服務器
rsync -a --delete $dataBackupDir -e ssh $backupServer:$backupServerDir > /dev/null 2>&1
</span></p>
rmBackup.sh注釋:
#!/bin/sh
Name:rmBackup.sh
PS:Delete old Backup.
Write by:i.Stone
Last Modify:2007-11-15
定義備份目錄
dataBackupDir=/tmp/mysqlbackup
# 刪除mtime>2的日志備份文件
find $dataBackupDir -name "mysql_*.gz" -type f -mtime +2 -exec rm {} \; > /dev/null 2>&1
</span></p>
(5)
用
/usr/local/mysql/bin/mysql
對于任何可適用的更新日志,將它們作為
%
ls
本套備份策略只能恢復數據庫到最后一次備份時的狀態,要想在崩潰時丟失的數據盡量少應該更頻繁的進行備份,要想恢復數據到崩潰時的狀態請使用主從復制機制(replication)。如果使用本套備份腳本,將日志文件和數據文件放到不同的磁盤上是一個不錯的主義,這樣不僅可以提高數據寫入速度,還能使數據更安全。
備份策略四、使用主從復制機制(replication)
配置MySQL主從復制(Replication)
MySQL支持單向、異步復制,復制過程中一個服務器充當主服務器,而一個或多個其它服務器充當從服務器。主服務器將更新寫入二進制日志文件,并維護日志文件的一個索引以跟蹤日志循環。當一個從服務器連接到主服務器時,它通知主服務器從服務器在日志中讀取的最后一次成功更新的位置。從服務器接收從那時起發生的任何更新,然后封鎖并等待主服務器通知下一次更新。
為什么使用主從復制?
1、主服務器/從服務器設置增加了健壯性。主服務器出現問題時,你可以切換到從服務器作為備份。
2、通過在主服務器和從服務器之間切分處理客戶查詢的負荷,可以得到更好的客戶響應時間。但是不要同時在主從服務器上進行更新,這樣可能引起沖突。
3、使用復制的另一個好處是可以使用一個從服務器執行備份,而不會干擾主服務器。在備份過程中主服務器可以繼續處理更新。
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。狀態文件保存在硬盤上,從服務器關閉時不會丟失。下次從服務器啟動時,讀取這些文件以確定它已經從主服務器讀取了多少二進制日志,以及處理自己的中繼日志的程度。
設置主從復制:
1、確保在主服務器和從服務器上安裝的MySQL版本相同,并且最好是MySQL的最新穩定版本。
2、在主服務器上為復制設置一個連接賬戶。該賬戶必須授予REPLICATION SLAVE權限。如果賬戶僅用于復制(推薦這樣做),則不需要再授予任何其它權限。
mysql> GRANT REPLICATION SLAVE ON *.*
3、執行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
+---------------+----------+--------------+------------------+
| mysql-bin.003
+---------------+----------+--------------+------------------+
File列顯示日志名,而Position顯示偏移量。在該例子中,二進制日志值為mysql-bin.003,偏移量為73。記錄該值。以后設置從服務器時需要使用這些值。它們表示復制坐標,從服務器應從該點開始從主服務器上進行新的更新。
如果主服務器運行時沒有啟用--logs-bin,SHOW MASTER STATUS顯示的日志名和位置值為空。在這種情況下,當以后指定從服務器的日志文件和位置時需要使用的值為空字符串('')和4.
取得快照并記錄日志名和偏移量后,回到前一中端重新啟用寫活動:
mysql> UNLOCK TABLES;
4、確保主服務器主機上my.cnf文件的[mysqld]部分包括一個log-bin選項。該部分還應有一個server-id=Master_id選項,其中master_id必須為1到232–1之間的一個正整數值。例如:
[mysqld]
log-bin
server-id=1
如果沒有提供那些選項,應添加它們并重啟服務器。
5、停止從服務器上的mysqld服務并在其my.cnf文件中添加下面的行:
[mysqld]
server-id=2
slave_id值同Master_id值一樣,必須為1到232–1之間的一個正整數值。并且,從服務器的ID必須與主服務器的ID不相同。
6、將數據備據目錄中。確保對這些文件和目錄的權限正確。服務器 MySQL運行的用戶必須能夠讀寫文件,如同在主服務器上一樣。
Shell> chown -R mysql:mysql /usr/local/mysql/data
7、啟動從服務器。在從服務器上執行下面的語句,用你的系統的實際值替換選項值:
8、啟動從服務器線程:
執行這些程序后,從服務器應連接主服務器,并補充自從快照以來發生的任何更新。
9、如果出現復制錯誤,從服務器的錯誤日志(HOSTNAME.err)中也會出現錯誤消息。
10、從服務器復制時,會在其數據目錄中發現文件master.info和HOSTNAME-relay-log.info。從服務器使用這兩個文件跟蹤已經處理了多少主服務器的二進制日志。不要移除或編輯這些文件,除非你確切知你正在做什么并完全理解其意義。即使這樣,最好是使用CHANGE MASTER TO語句。
------整理匯總自網上
轉自:http://blog.csdn.net/xujinyang/article/details/7378198