mysql 数据库定时备份 增量/全备份
echo 開始:$Begin 結束:$Last $GZDumpFile succ >> $LogFile
cd $BakDir/daily
/bin/rm -f *
?
2)增量備份腳本(腳本中mysql的數據存放路徑是/home/mysql/data,具體根據自己的實際情況進行調整)
[root@test-huanqiu ~]# vim /root/Mysql-DailyBak.sh
#!/bin/bash
# Program
# use cp to backup mysql data everyday!
# History
# Path
BakDir=/home/mysql/backup/daily ? ? ? ? ? ? ? ? ? ? //增量備份時復制mysql-bin.00000*的目標目錄,提前手動創建這個目錄
BinDir=/home/mysql/data ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //mysql的數據目錄
LogFile=/home/mysql/backup/bak.log
BinFile=/home/mysql/data/mysql-bin.index ? ? ? ? ? //mysql的index文件路徑,放在數據目錄下的
/usr/local/mysql/bin/mysqladmin -uroot -p123456 flush-logs
#這個是用于產生新的mysql-bin.00000*文件
Counter=`wc -l $BinFile |awk '{print $1}'`
NextNum=0
#這個for循環用于比對$Counter,$NextNum這兩個值來確定文件是不是存在或最新的
for file in `cat $BinFile`
do
? ? base=`basename $file`
? ? #basename用于截取mysql-bin.00000*文件名,去掉./mysql-bin.000005前面的./
? ? NextNum=`expr $NextNum + 1`
? ? if [ $NextNum -eq $Counter ]
? ? then
? ? ? ? echo $base skip! >> $LogFile
? ? else
? ? ? ? dest=$BakDir/$base
? ? ? ? if(test -e $dest)
? ? ? ? #test -e用于檢測目標文件是否存在,存在就寫exist!到$LogFile去
? ? ? ? then
? ? ? ? ? ? echo $base exist! >> $LogFile
? ? ? ? else
? ? ? ? ? ? cp $BinDir/$base $BakDir
? ? ? ? ? ? echo $base copying >> $LogFile
? ? ? ? ?fi
? ? ?fi
done
echo `date +"%Y年%m月%d日 %H:%M:%S"` $Next Bakup succ! >> $LogFile
3)設置crontab任務,執行備份腳本。先執行的是增量備份腳本,然后執行的是全量備份腳本:
[root@test-huanqiu ~]# crontab -e
#每個星期日凌晨3:00執行完全備份腳本
0 3 * * 0 /bin/bash -x /root/Mysql-FullyBak.sh >/dev/null 2>&1
#周一到周六凌晨3:00做增量備份
0 3 * * 1-6 /bin/bash -x /root/Mysql-DailyBak.sh >/dev/null 2>&1
4)手動執行上面兩個腳本,測試下備份效果
[root@test-huanqiu backup]# pwd
/home/mysql/backup
[root@test-huanqiu backup]# mkdir daily
[root@test-huanqiu backup]# ll
total 4
drwxr-xr-x. 2 root root 4096 Nov 29 11:29 daily
[root@test-huanqiu backup]# ll daily/
total 0
先執行增量備份腳本
[root@test-huanqiu backup]# sh /root/Mysql-DailyBak.sh
[root@test-huanqiu backup]# ll
total 8
-rw-r--r--. 1 root root 121 Nov 29 11:29 bak.log
drwxr-xr-x. 2 root root 4096 Nov 29 11:29 daily
[root@test-huanqiu backup]# ll daily/
total 8
-rw-r-----. 1 root root 152 Nov 29 11:29 mysql-binlog.000030
-rw-r-----. 1 root root 152 Nov 29 11:29 mysql-binlog.000031
[root@test-huanqiu backup]# cat bak.log
mysql-binlog.000030 copying
mysql-binlog.000031 copying
mysql-binlog.000032 skip!
2016年11月29日 11:29:32 Bakup succ!
然后執行全量備份腳本
[root@test-huanqiu backup]# sh /root/Mysql-FullyBak.sh
20161129.sql
[root@test-huanqiu backup]# ll
total 152
-rw-r--r--. 1 root root 145742 Nov 29 11:30 20161129.sql.tgz
-rw-r--r--. 1 root root 211 Nov 29 11:30 bak.log
drwxr-xr-x. 2 root root 4096 Nov 29 11:30 daily
[root@test-huanqiu backup]# ll daily/
total 0
[root@test-huanqiu backup]# cat bak.log
mysql-binlog.000030 copying
mysql-binlog.000031 copying
mysql-binlog.000032 skip!
2016年11月29日 11:29:32 Bakup succ!
開始:2016年11月29日 11:30:38 結束:2016年11月29日 11:30:38 20161129.sql.tgz succ
?
?
?
?
?
實驗樓的 MySQL 數據庫需要設計一個自動備份方案,能夠每周執行一次全備份,每天執行一次增量備份。
數據庫名稱為 shiyanlou,管理的用戶名為 shiyanlou,密碼為 shiyanlou。注意需要先手動啟動 MySQL 服務。
目標
設計并實現備份方案,任務完成后滿足以下要求:
提示語
mysqldump + binary logs
crontab -u shiyanlou -l 再次確認下計劃任務策略是否準確
知識點
來源
實驗樓測試團隊日常數據備份場景
?
?
# GRANT ALL PRIVILEGES? ON? *.*? TO 'monty'@'localhost' ? IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
# GRANT ALL PRIVILEGES ON *.* TO 'monty'@'%'?? IDENTIFIED BY 'some_pass' WITH GRANT OPTION;
#
GRANT命令說明:
ALL PRIVILEGES 是表示所有權限,你也可以使用select、update等權限。
ON 用來指定權限針對哪些庫和表。
*.* 中前面的*號用來指定數據庫名,后面的*號用來指定表名。
TO 表示將權限賦予某個用戶。
'monty'@'localhost' 表示monty用戶,@ 后面接限制的主機,可以是IP、IP段、域名以及%,%表示任何地方。(注意:這里%有的版本不包括本地,以前碰到過給某個用戶設置了%允許任何地方登錄,但是在本地登錄不了,這個和版本有關系,遇到這個問題再加一個localhost的用戶就可以了。)
IDENTIFIED BY指定用戶的登錄密碼。
WITH GRANT OPTION 這個選項表示該用戶可以將自己擁有的權限授權給別人。(注意:經常有人在創建操作用戶的時候不指定WITH GRANT OPTION選項導致后來該用戶不能使用GRANT命令創建用戶或者給其他用戶授權。)
備注:可以使用GRANT重復給用戶添加權限,權限疊加,比如你先給用戶添加了一個SELECT權限,然后又給用戶添加了一個INSERT權限,那么該用戶就同時擁有了SELECT和INSERT權限。
?
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP-> ON bankaccount.*-> TO 'custom'@'localhost'-> IDENTIFIED BY 'obscure';mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP-> ON expenses.*-> TO 'custom'@'whitehouse.gov' -> IDENTIFIED BY 'obscure'; mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP -> ON customer.* -> TO 'custom'@'server.domain' -> IDENTIFIED BY 'obscure';這3個賬戶分別可以用于:
-
第1個賬戶可以訪問bankaccount數據庫,但只能本機訪問。
-
第2個賬戶可以訪問expenses數據庫,但只能從主機訪問whitehouse.gov。
-
第3個賬戶可以訪問customer數據庫,但只能從主機訪問server.domain。
?
???
2.3.1 數據庫備份
由于MySQL表保存為文件方式會很容易備份。要想保持備份的一致性,需要對相關表執行LOCK TABLES操作,然后對表執行FLUSH TABLES。你只需要讀鎖定;這樣當你復制數據庫目錄中的文件時,允許其它客戶繼續查詢表。需要FLUSH TABLES語句來確保開始備份前將所有激活的索引頁寫入硬盤。
如果你想要進行SQL級別的表備份,你可以使用SELECT INTO ...OUTFILE或BACKUP TABLE。對于SELECT INTO ...OUTFILE, 輸出的文件不能先存在。對于BACKUP TABLE也如此,因為覆蓋完整的文件會有安全風險。
對于InnoDB表,可以進行在線備份,不需要對表進行鎖定。
MySQL支持增量備份:需要用--log-bin選項來啟動服務器以便啟用二進制日志。當想要進行增量備份時(包含上一次完全備份或增量備份之后的所有更改),應使用FLUSH LOGS回滾二進制日志。然后,你需要將從最后的完全或增量備份的某個時刻到最后某個點的所有二進制日志復制到備份位置。這些二進制日志為增量備份;恢復時,按照下面的解釋應用。下次進行完全備份時,還應使用FLUSH LOGS或mysqlhotcopy --flushlogs回滾二進制日志。
如果MySQL服務器為復制子服務器時,則無論選擇什么備份方法,當備份子機數據時,還應備份master.info和relay-log.info文件。恢復了子機數據后,需要這些文件來繼續復制。如果子機執行復制LOAD DATA INFILE命令,你應用--slave-load-tmpdir選項備份指定的目錄中的SQL_LOAD-*文件。(如果未指定,該位置默認為tmpdir變量值)。子機需要這些文件來繼續復制中斷的LOAD DATA INFILE操作。
如果必須恢復MyISAM表,先使用REPAIR TABLE或myisamchk -r來恢復,99.9%的情況下該方法可以生效。如果myisamchk恢復失敗,試試下面的方法:
請注意只有添加--log-bin選項啟動MySQL服務器從而啟用二進制日志它才生效。
如果MySQL服務器啟用了二進制日志,你可以使用mysqlbinlog工具來恢復從指定的時間點開始(例如,從你最后一次備份)直到現在或另一個指定的時間點的數據。
恢復原mysqldump備份,或二進制備份。
執行下面的命令重新更新二進制日志:
shell> mysqlbinlog hostname-bin.[0-9]* | mysql在某些情況下,你可能只想要從某個位置重新運行某些二進制日志。(通常你想要根據恢復備份的日期重新運行所有二進制日志)。
還可以對具體文件進行選擇備份:
-
要想復制表,使用SELECT * INTO OUTFILE 'file_name' FROM tbl_name語句。
-
要想重載表,使用LOAD DATA INFILE 'file_name' REPLACE ...載入并恢復表。要避免復制記錄,表必須有PRIMARY KEY或一個UNIQUE索引。當新記錄復制唯一鍵值的舊記錄時,REPLACE關鍵字可以將舊記錄替換為新記錄。
如果備份時遇到服務器性能問題,有用的一個策略是在子服務器而不是主服務器上建立復制并執行備份。
如果使用Veritas文件系統,可以這樣備份:
從客戶端程序執行FLUSH TABLES WITH READ LOCK語句。
從另一個shell執行mount vxfs snapshot命令。
從第一個客戶端執行UNLOCK TABLES。
從快照復制文件。
卸載快照。
2.3.2 備份與恢復策略示例
1) 備份策略
我們都知道必須按計劃定期進行備份??梢杂靡恍┕ぞ?某個時間點的數據快照)完全備份MySQL。例如,InnoDB Hot Backup為InnoDB數據文件提供在線非數據塊物理備份,mysqldump提供在線邏輯備份。
假定我們在星期日下午1點進行了備份,此時負荷較低。下面的命令可以完全備份所有數據庫中的所有InnoDB表:
mysqldump -u root --single-transaction --all-databases > backup_sunday_1_PM.sql以上方法是在線非數據塊備份,不會干擾對表的讀寫。我們假定我們以前的表為InnoDB表,因此--single-transaction一致性地表,并且保證mysqldump所 看見的數據不會更改。(其它客戶端對InnoDB表進行的更改不會被mysqldump進程看見)。如果我們還有其它類型的表,我們必須假定在備份過程中 它們不會更改。例如,對于mysql數據庫中的MyISAM表,我們必須假定在備份過程中沒有對MySQL賬戶進行管理更改。
mysqldump命令產生的.sql文件包含一系列SQL INSERT語句,可以用來重載轉儲的表。
進行完全備份的時候有時不方便,因為會產生大的備份文件并需要花時間來生成。從某個角度來看,完全備份并不理想,因為每個成功的完全備份都包括所有 數據,甚至包括自從上一次完全備份以來沒有被更改的部分。完成了初始完全備份后,進行增量備份會更有效。這樣備份文件要小得多,備份時間也較短。缺點是, 恢復時不能只重載完全備份來恢復數據。還必須要用增量備份來恢復增量更改。
要想進行增量備份,我們需要保存增量更改。應使用--log-bin選項啟動MySQL服務器,以便更新數據時將這些更改保存到文件中。該選項啟用二進制日志,因此服務器會將每個更新數據的SQL語句寫入到MySQL二進制日志。讓我們看看用--log-bin選項啟動的已經運行多日的MySQL服務器的數據目錄。找到以下MySQL二進制日志文件:
每次重啟,MySQL服務器都會使用以上序列中的下一個編號創建一個新的二進制日志文件。當服務器運行時,你還可以通過執行FLUSH LOGS SQL語句或mysqladmin flush-logs命令,告訴服務器關閉當前的二進制日志文件并創建一個新文件。mysqldump也有一個選項來清空日志。數據目錄中的.index文件包含該目錄下所有MySQL二進制日志的清單,該文件用于復制。
恢復時MySQL二進制日志很重要,因為它們是增量備份。如果進行完全備份時確保清空了日志,則后面創建的二進制日志文件包含了備份后的所有數據更改。讓我們稍稍修改前面的mysqldump命令,讓它在完全備份時能夠清空 MySQL二進制日志,以便轉儲文件包含包含新的當前二進制日志:
mysqldump -u root --single-transaction --flush-logs --master-data=2 --all-databases > backup_sunday_1_PM.sql執行該命令后,數據目錄則包含新的二進制日志文件。產生的.sql文件包含下列行:
-- Position to start replication or point-in-time recovery from -- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;因為mysqldump命令可以執行完全備份,以上行代表兩件事情:
.sql文件包含所有寫入gbichot2-bin.000007二進制日志文件或最新的文件之前的更改。
備份后所記錄的所有數據更改不出現在.sql中,但會出現在gbichot2-bin.000007二進制日志文件或最新的文件中。
在星期一下午1點,我們可以清空日志并開始根據新的二進制日志文件來創建增量備份。例如,執行mysqladmin flush-logs命令創建gbichot2-bin.000008。星期日下午1點的完全備份和星期一下午1點之間的所有更改為文件gbichot2-bin.000007。該增量備份很重要,因此最好將它復制到安全的地方。(例如,備份到磁帶或DVD上,或復制到另一臺機器上)。在星期二下午1點,執行另一個mysqladmin flush-logs命令,這樣星期一下午1點和星期二下午1點之間的所有更改為文件gbichot2-bin.000008(也應復制到某個安全的地方)。
MySQL二進制日志占據硬盤空間。要想釋放空間,應隨時清空。操作方法是刪掉不再使用的二進制日志,例如進行完全備份時輸入以下命令:
shell> mysqldump --single-transaction --flush-logs --master-data=2--all-databases --delete-master-logs > backup_sunday_1_PM.sql注釋:如果你的服務器為復制主服務器,用mysqldump方法中的 --delete-master-logs選項刪掉MySQL二進制日志很危險,因為從服務器可能還沒有完全處理該二進制日志的內容。關于這一點,PURGE MASTER LOGS語句的描述中解釋了為什么在刪掉MySQL二進制日志之前應進行確認一下。
2) 為恢復進行備份
現在假設在星期三上午8點出現了災難性崩潰,需要使用備份文件進行恢復?;謴蜁r,我們首先恢復最后的完全備份(從星期日下午1點開始)。完全備份文件是一系列SQL語句,因此恢復它很容易:
shell> mysql < backup_sunday_1_PM.sql接下來使得數據恢復到星期日下午1點的狀態。要想恢復從那時起的更改,我們必須使用增量備份,也就是gbichot2-bin.000007和gbichot2-bin.000008這兩個二進制日志文件。根據需要從備份處取得這些文件,然后按下述方式處理:
shell> mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql我們現在將數據恢復到星期二下午1點的狀態,但是從該時刻到崩潰之間的數據仍然有丟失;要實現恢復,我們需要MySQL服務器將MySQL二進制日志保存到安全的位置(RAID disks, SAN, ...),應為與數據文件的保存位置不同的地方,保證這些日志不在被毀壞的硬盤上。(也就是,我們可以用--log-bin選項啟動服務器,指定一個其它物理設備上的與數據目錄不同的位置。這樣,即使包含該目錄的設備丟失,日志也不會丟失)。如果我們執行了這些操作,我們手頭上會有gbichot2-bin.000009文件,我們可以用它來恢復大部分最新的數據更改,而不會丟失星期二下午1點到崩潰時刻之間的數據。
3) 備份策略摘要
出現操作系統崩潰或電源故障時,InnoDB自己可以完成所有數據恢復工作。但為了確保你可以睡好覺,應遵從下面的指導:
-
一定用--log-bin或甚至--log-bin=log_name選項啟動MySQL服務器,其中日志文件名位于某個安全媒介上,不同于數據目錄所在驅動器。如果你有這樣的安全媒介,最好進行硬盤負載均衡(這樣能夠提高性能)。
-
定期進行完全備份,使用mysqldump命令進行在線非數據塊備份。
-
用FLUSH LOGS或mysqladmin flush-logs清空日志進行定期增量備份。
2.3.3 自動恢復
注意:由于實驗樓環境中默認的mysql配置文件中把log_bin等日志設置選項給注釋了,因此需要更改文件my.cnf:
# 登陸到root賬戶 shell> sudo -s shell> vi /etc/mysql/my.cnf修改后然后保存my.cnf文件,重啟mysql服務器,并查看日志是否啟動:
shell> service mysql restart --log-bin shell> mysql -u root sql> show variables like 'log_%';繼續~
要想確定當前的二進制日志文件的文件名,在命令行中加入下面的MySQL語句:
shell> mysql -u root -e 'SHOW BINLOG EVENTS \G'1) 指定恢復時間
對于MySQL 5,可以在mysqlbinlog語句中通過--start-date和--stop-date選項指定DATETIME格式的起止時間。舉例說明,假設在今天上午10:00(今天是2015年8月6日),執行SQL語句來刪除一個大表。要想恢復表和數據,你可以恢復前一晚上的備份,并從命令行輸入以下命令:
shell> mysqlbinlog --stop-date="2015-8-6 10:01:00" /var/log/mysql/bin.123456 \| mysql -u root -p mypwd該命令將恢復截止到在--stop-date選項中以DATETIME格式給出的日期和時間的所有數據。
在以上行中,從上午10:01登錄的SQL語句將運行。結合執行前夜的轉儲文件和mysqlbinlog的兩行命令可以將所有數據恢復到上午10:00前一秒鐘。你應檢查日志以確保時間確切。下一節介紹如何實現。
2) 指定恢復位置
也可以不指定日期和時間,而使用mysqlbinlog的選項--start-position和--stop-position來指定日志位置。它們的作用與起止日選項相同,不同的是給出了從日志起的位置號。使用日志位置是更準確的恢復方法,特別是當由于破壞性SQL語句同時發生許多事務的時候。要想確定位置號,可以運行mysqlbinlog尋找執行了不期望的事務的時間范圍,但應將結果重新指向文本文件以便進行檢查。操作方法為:
shell> mysqlbinlog --start-date="2014-10-29 9:55:00" --stop-date="2014-10-29 10:05:00" \/var/log/mysql/bin.123456 > /tmp/mysql_restore.sql該命令將在/tmp目錄創建小的文本文件,將顯示執行了錯誤的SQL語句時的SQL語句。你 可以用文本編輯器打開該文件,尋找你不要想重復的語句。如果二進制日志中的位置號用于停止和繼續恢復操作,應進行注釋。用`log_pos加一個數字來標 記位置。使用位置號恢復了以前的備份文件后,你應從命令行輸入下面內容:
shell> mysqlbinlog --stop-position="368312" /var/log/mysql/bin.123456 \| mysql -u root -pmypwd shell> mysqlbinlog --start-position="368315" /var/log/mysql/bin.123456 \| mysql -u root -pmypwd \上面的第1行將恢復到停止位置為止的所有事務。第二行將恢復從給定的起始位置直到二進制日志結束的所有事務。因為mysqlbinlog的輸出包括每個SQL語句記錄之前的SET TIMESTAMP語句,恢復的數據和相關MySQL日志將反映事務執行的原時間。
2.4 日志文件
2.4.1 錯誤日志
錯誤日志文件包含了當mysqld啟動和停止時,以及服務器在運行過程中發生任何嚴重錯誤時的相關信息。
如果mysqld莫名其妙地死掉并且需要mysqld_safe重新啟動它,那么mysqld_safe在錯誤日志中寫入一條restarted mysqld消息。如果mysqld注意到需要自動檢查或著修復一個表,則錯誤日志中將寫入這條消息。
在一些操作系統中,如果mysqld死掉,錯誤日志會包含堆棧跟蹤信息。跟蹤信息可以用來確定mysqld死掉的地方。
可以用--log-error[=file_name]選項來指定mysqld保存錯誤日志文件的位置。如果沒有給定file_name值,mysqld會在數據目錄中使用日志名host_name.err 寫入日志文件,如果你執行FLUSH LOGS,日志會使用-old重新命名后綴并且mysqld創建一個新的空日志文件。(如果未給出--log-error選項,則不會重新命名)。
如果不指定--log-error,或者(在Windows中)如果你使用--console選項,錯誤被寫入標準錯誤輸出stderr。通常標準輸出為你的終端。
在Windows中,如果未給出--console選項,錯誤輸出總是寫入.err文件。
2.4.2 通用查詢日志
如果你想要知道mysqld內部發生了什么,你應該用--log[=file_name]或-l [file_name]選項啟動服務器。如果沒有給定file_name的值, 默認名是host_name.log。所有連接和語句都會被記錄到日志文件。當你懷疑在客戶端發生了錯誤并想確切地知道該客戶端發送給mysqld的語句時,該日志可能非常有用。 mysqld按照它接收的語句順序記錄查詢日志,這可能與執行的順序不同。這與更新日志和二進制日志不同,它們在執行后但是是在任何一個鎖釋放之前記錄日志。(查詢日志還包含所有語句,而二進制日志不包含只查詢數據的語句)。
服務器重新啟動和日志刷新不會產生新的通用查詢日志文件(盡管刷新會關閉并重新打開一般查詢日志文件)。在Unix中,你可以通過下面的命令重新命名文件并創建一個新的日志文件:
shell> mv hostname.log hostname-old.log shell> mysqladmin flush-logs shell> cp hostname-old.log to-backup-directory shell> rm hostname-old.log在Windows中,服務器打開日志文件期間你不能重新命名日志文件,你必須先停止服務器然后重新命名日志文件,然后重啟服務器來創建新的日志文件。
2.4.3 二進制日志
二進制日志以一種更有效的格式,并且是事務安全的方式包含更新日志中可用的所有信息。
二進制日志包含了所有更新了數據或者已經潛在更新了數據(例如,沒有匹配任何行的一個DELETE)的所有語句。語句以“事件”的形式保存,它描述數據更改。
注釋:二進制日志已經代替了老的更新日志,更新日志在MySQL 5.1中不再使用。
二進制日志還包含關于每個更新數據庫的語句的執行時間信息。它不包含沒有修改任何數據的語句。如果你想要記錄所有語句(例如,為了識別有問題的查詢),你應使用一般查詢日志。
二進制日志的主要目的是在恢復使能夠最大可能地更新數據庫,因為二進制日志包含備份后進行的所有更新。
二進制日志還用于在主復制服務器上記錄所有將發送給從服務器的語句。
運行服務器時若啟用二進制日志則性能大約慢1%。但是,二進制日志的好處即用于恢復并允許設置復制超過了這個小小的性能損失。
當用--log-bin[=file_name]選項啟動服務器時,mysqld寫入包含所有更新數據的SQL命令的日志文件。如果未給出file_name值, 默認名為-bin后面所跟的主機名。如果給出了文件名,但沒有包含路徑,則文件被寫入數據目錄。
如果你在日志名中提供了擴展名(例如,--log-bin=file_name.extension),則擴展名被悄悄除掉并忽略。
mysqld在每個二進制日志名后面添加一個數字擴展名。每次你啟動服務器或刷新日志時該數字則增加。如果當前的日志大小達到max_binlog_size時,還會自動創建新的二進制日志。如果你正使用大的事務,二進制日志大小還會超過max_binlog_size。(事務要全寫入一個二進制日志中,絕對不要寫入不同的二進制日志中。)
為了能夠知道還使用了哪個不同的二進制日志文件,mysqld還創建一個二進制日志索引文件,包含所有使用的二進制日志文件的文件名。默認情況下與二進制日志文件的文件名相同,擴展名為'.index'。你可以用--log-bin-index[=file_name]選項更改二進制日志索引文件的文件名。當mysqld在運行時,不應手動編輯該文件;如果這樣做將會使mysqld變得混亂。
可以用RESET MASTER語句刪除所有二進制日志文件,或用PURGE MASTER LOGS只刪除部分二進制文件。
二進制日志格式有一些已知限制,會影響從備份恢復。
可以使用下面的mysqld選項來影響記錄到二進制日志內的內容:
-
--binlog-do-db=db_name
告訴主服務器,如果當前的數據庫(即USE選定的數據庫)是db_name,應將更新記錄到二進制日志中。其它所有沒有明顯指定的數據庫 被忽略。如果使用該選項,你應確保只對當前的數據庫進行更新。
對于CREATE DATABASE、ALTER DATABASE和DROP DATABASE語句,有一個例外,即通過操作的數據庫來決定是否應記錄語句,而不是用當前的數據庫。
一個不能按照期望執行的例子:如果用binlog-do-db=sales啟動服務器,并且執行USE prices; UPDATE sales.january SET amount=amount+1000;,該語句不寫入二進制日志。
-
--binlog-ignore-db=db_name
告訴主服務器,如果當前的數據庫(即USE選定的數據庫)是db_name,不應將更新保存到二進制日志中。如果你使用該選項,你應確保只對當前的數據庫進行更新。
一個不能按照你期望的執行的例子:如果服務器用binlog-ignore-db=sales選項啟動,并且執行USE prices; UPDATE sales.january SET amount=amount+1000;,該語句不被寫入二進制日志。
類似于--binlog-do-db,對于CREATE DATABASE、ALTER DATABASE和DROP DATABASE語句,有一個例外,即通過操作的數據庫來決定是否應記錄語句,而不是用當前的數據庫。
要想記錄或忽視多個數據庫,可以在啟動服務器的時候使用多個選項,為每個數據庫指定相應的選項。
服務器根據下面的規則對選項進行評估,以便將更新記錄到二進制日志中或忽視。請注意對于CREATE/ALTER/DROP DATABASE語句有一個例外。在這些情況下,根據以下列出的不同情況,所創建、修改或刪除的數據庫將代替當前的數據庫。
是否有binlog-do-db或binlog-ignore-db規則?
沒有:將語句寫入二進制日志并退出。
有:執行下一步。
有一些規則(binlog-do-db或binlog-ignore-db或二者都有)。當前有一個數據庫(是否使用USE語句選擇了數據庫?)?
沒有:不要寫入語句,并退出。
有:執行下一步。
有一些binlog-ignore-db規則。當前的數據庫是否匹配binlog-ignore-db規則?
有:不要寫入語句,并退出。
沒有:寫入查詢并退出。
例如,只用binlog-do-db=sales運行的服務器只將當前數據庫為sales的語句寫入二進制日志(換句話說,binlog-do-db有時可以表示“忽視其它數據庫”)。
如果你正進行復制,應確保沒有子服務器在使用舊的二進制日志文件時,方可刪除它們。一種方法是每天一次執行mysqladmin flush-logs并刪除三天前的所有日志??梢允謩觿h除,或最好使用PURGE MASTER LOGS語句刪除日志。
具有SUPER權限的客戶端可以通過SET SQL_LOG_BIN=0語句禁止將自己的語句記入二進制記錄。
你可以用mysqlbinlog實用工具檢查二進制日志文件。如果你想要重新處理日志止的語句,這很有用。例如,可以從二進制日志更新MySQL服務器,方法如下:
shell> mysqlbinlog log-file | mysql -h server_name如果你正使用事務,必須使用MySQL二進制日志進行備份,而不能使用舊的更新日志。
查詢結束后、鎖定被釋放前或提交完成后則立即記入二進制日志。這樣可以確保按執行順序記入日志。
對非事務表的更新執行完畢后立即保存到二進制日志中。對于事務表,例如BDB或InnoDB表,所有更改表的更新(UPDATE、DELETE或INSERT)都會 被緩存起來,直到服務器接收到COMMIT語句。在執行完COMMIT之前,mysqld將整個事務寫入二進制日志。當處理事務的線程啟動時,它為緩沖查詢分配binlog_cache_size大小的內存。如果語句大于該值,線程則打開臨時文件來保存事務。線程結束后臨時文件被刪除。
Binlog_cache_use狀態變量顯示了使用該緩沖區(也可能是臨時文件)保存語句的事務的數量。Binlog_cache_disk_use狀態變量顯示了這些事務中實際上有多少必須使用臨時文件。這兩個變量可以用于將binlog_cache_size調節到足夠大的值,以避免使用臨時文件。
max_binlog_cache_size(默認4GB)可以用來限制用來緩存多語句事務的緩沖區總大小。如果某個事務大于該值,將會失敗并回滾。
如果你正使用更新日志或二進制日志,當使用CREATE ... SELECT or INSERT ... SELECT時,并行插入被轉換為普通插入。這樣通過在備份時使用日志可以確保重新創建表的備份。
默認情況下,并不是每次寫入時都將二進制日志與硬盤同步。因此如果操作系統或機器(不僅僅是MySQL服務器)崩潰,有可能二進制日志中最后的語句丟失了。要想防止這種情況,你可以使用sync_binlog全局變量(設置該變量值為1是最安全的值,但也是最慢的),使二進制日志在每N次二進制日志寫入后與硬盤同步。
該選項可以提供更大程度的安全,還應對MySQL服務器進行配置,使每個事務的二進制日志(sync_binlog =1)和(默認情況為真)InnoDB日志與硬盤同步。該選項的效果是崩潰后重啟時,在滾回事務后,MySQL服務器從二進制日志剪切 回滾的InnoDB事務。這樣可以確保二進制日志反饋InnoDB表的確切數據等,并使從服務器保持與主服務器保持同步(不接收回滾的語句)。
請注意即使MySQL服務器更新其它存儲引擎而不是InnoDB,也可以使用--innodb-safe-binlog選項啟動服務。在InnoDB崩潰恢復時,只能從二進制日志中刪除影響InnoDB表的語句或事務。如果崩潰恢復時MySQL服務器發現二進制日志變短了(即至少缺少一個成功提交的InnoDB事務),如果sync_binlog =1并且硬盤或文件系統的確能根據需要進行同步(有些不需要)則不會發生,則輸出錯誤消息 ("二進制日志<名>比期望的要小")。在這種情況下,二進制日志不準確,復制應從主服務器的數據快照開始。
寫入二進制日志文件和二進制日志索引文件的方法與寫入MyISAM表的相同。
2.4.4 慢速查詢日志
用--log-slow-queries[=file_name]選項啟動服務時,mysqld會寫入一個包含所有執行時間超過long_query_time秒的SQL語句的日志文件。其中,獲得初使表鎖定的時間不算作執行時間。
如果沒有給出file_name值,默認為主機名,后綴為-slow.log。如果給出了文件名,但不是絕對路徑名,文件則寫入數據目錄。
語句執行完并且所有鎖釋放后記入慢查詢日志。記錄順序可以與執行順序不相同。
慢查詢日志可以用來找到執行時間長的查詢,可以用于優化。但是,檢查又長又慢的查詢日志會很困難。要想容易些,你可以使用mysqldumpslow命令獲得日志中顯示的查詢摘要來處理慢查詢日志。
在MySQL 5.1的慢查詢日志中,不使用索引的慢查詢同使用索引的查詢一樣記錄。要想防止不使用索引的慢查詢記入慢查詢日志,使用--log-short-format選項。
在MySQL 5.1中,通過--log-slow-admin-statements服務器選項,你可以請求將慢管理語句,例如將OPTIMIZE TABLE、ANALYZE TABLE和ALTER TABLE語句寫入慢查詢日志。
用查詢緩存處理的查詢不加到慢查詢日志中,因為表有零行或一行而不能從索引中受益的查詢也不寫入慢查詢日志。
2.4.5 日志文件維護
MySQL服務器可以創建各種不同的日志文件,從而可以很容易地看見所進行的操作。
當啟用日志使用MySQL時,你可能想要不時地備份并刪除舊的日志文件,并告訴MySQL開始記入新文件。
在 Linux (Redhat)的安裝上,你可為此使用mysql-log-rotate腳本。如果你在RPM上分發安裝MySQL,腳本應該已經自動被安裝。
在其它系統上,你必須自己安裝短腳本,你可從鏡像網站獲得處理日志文件。
你可以通過mysqladmin flush-logs或SQL語句FLUSH LOGS來強制MySQL開始使用新的日志文件。
日志清空操作主要完成下列事情:
- 如果使用標準日志(--log)或慢查詢日志(--log-slow-queries),關閉并重新打開日志文件。(默認為mysql.log和`hostname-slow.log`)。
- 如果使用更新日志(--log-update)或二進制日志(--log-bin),關閉日志并且打開有更高序列號的新日志文件。
-
如果你只使用更新日志,你只需要重新命名日志文件,然后在備份前清空日志。例如,你可以這樣做:
shell> cd mysql-data-directory shell> mv mysql.log mysql.old shell> mysqladmin flush-logs然后備份并刪除“mysql.old”。
?
轉載于:https://www.cnblogs.com/ggh03/p/6980149.html
總結
以上是生活随笔為你收集整理的mysql 数据库定时备份 增量/全备份的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 女人梦到好几条蛇
- 下一篇: 数据库和数据挖掘领域的会议和期刊