mysql 數據庫定時備份 增量/全備份
實驗樓的 MySQL 數據庫需要設計一個自動備份方案,能夠每周執行一次全備份,每天執行一次增量備份。
數據庫名稱為 shiyanlou,管理的用戶名為 shiyanlou,密碼為 shiyanlou。註意需要先手動啟動 MySQL 服務。
目標
設計並實現備份方案,任務完成後滿足以下要求:
- MySQL 服務處於運行狀態
- 需要為服務器中的 shiyanlou 用戶設定計劃任務
- 計劃任務中設定每周的周一淩晨3點執行一次全備份
- 計劃任務中設定每天淩晨3點執行一次增量備份,周一不執行
- 請不要編寫額外的腳本,將備份命令直接寫入
crontab -u shiyanlou
中
提示語
mysqldump + binary logs
crontab -u shiyanlou -l 再次確認下計劃任務策略是否準確
知識點
- MySQL 數據庫備份
- MySQL 全備份與增量備份
- crontab 計劃任務的設定
來源
實驗樓測試團隊日常數據備份場景
# 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
表示將權限賦予某個用戶。
[email protected] 表示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點出現了災難性崩潰,需要使用備份文件進行恢復。恢復時,我們首先恢復最後的完全備份(從星期日下午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
並刪除三天前的所有日誌。可以手動刪除,或最好使用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”
。
mysql 數據庫定時備份 增量/全備份