1. 程式人生 > >mysql 數據庫定時備份 增量/全備份

mysql 數據庫定時備份 增量/全備份

重新 console select 顯示 邏輯 chang 應該 sta 服務

實驗樓的 MySQL 數據庫需要設計一個自動備份方案,能夠每周執行一次全備份,每天執行一次增量備份。

數據庫名稱為 shiyanlou,管理的用戶名為 shiyanlou,密碼為 shiyanlou。註意需要先手動啟動 MySQL 服務。

目標

設計並實現備份方案,任務完成後滿足以下要求:

  1. MySQL 服務處於運行狀態
  2. 需要為服務器中的 shiyanlou 用戶設定計劃任務
  3. 計劃任務中設定每周的周一淩晨3點執行一次全備份
  4. 計劃任務中設定每天淩晨3點執行一次增量備份,周一不執行
  5. 請不要編寫額外的腳本,將備份命令直接寫入 crontab -u shiyanlou

提示語

mysqldump + binary logs

crontab -u shiyanlou -l 再次確認下計劃任務策略是否準確

知識點

  1. MySQL 數據庫備份
  2. MySQL 全備份與增量備份
  3. 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 是表示所有權限,你也可以使用selectupdate等權限。

ON 用來指定權限針對哪些庫和表。

*.* 中前面的*號用來指定數據庫名,後面的*號用來指定表名。

TO 表示將權限賦予某個用戶。

[email protected] 表示monty用戶,@ 後面接限制的主機,可以是IPIP段、域名以及%%表示任何地方。(註意:這裏%有的版本不包括本地,以前碰到過給某個用戶設置了%允許任何地方登錄,但是在本地登錄不了,這個和版本有關系,遇到這個問題再加一個localhost的用戶就可以了。)

IDENTIFIED BY指定用戶的登錄密碼。

WITH GRANT OPTION 這個選項表示該用戶可以將自己擁有的權限授權給別人。(註意:經常有人在創建操作用戶的時候不指定WITH GRANT OPTION選項導致後來該用戶不能使用GRANT命令創建用戶或者給其他用戶授權。)

備註:可以使用GRANT重復給用戶添加權限,權限疊加,比如你先給用戶添加了一個SELECT權限,然後又給用戶添加了一個INSERT權限,那麽該用戶就同時擁有了SELECTINSERT權限。

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 ...OUTFILEBACKUP TABLE。對於SELECT INTO ...OUTFILE, 輸出的文件不能先存在。對於BACKUP TABLE也如此,因為覆蓋完整的文件會有安全風險。

對於InnoDB表,可以進行在線備份,不需要對表進行鎖定。

MySQL支持增量備份:需要用--log-bin選項來啟動服務器以便啟用二進制日誌。當想要進行增量備份時(包含上一次完全備份或增量備份之後的所有更改),應使用FLUSH LOGS回滾二進制日誌。然後,你需要將從最後的完全或增量備份的某個時刻到最後某個點的所有二進制日誌復制到備份位置。這些二進制日誌為增量備份;恢復時,按照下面的解釋應用。下次進行完全備份時,還應使用FLUSH LOGSmysqlhotcopy --flushlogs回滾二進制日誌。

如果MySQL服務器為復制子服務器時,則無論選擇什麽備份方法,當備份子機數據時,還應備份master.inforelay-log.info文件。恢復了子機數據後,需要這些文件來繼續復制。如果子機執行復制LOAD DATA INFILE命令,你應用--slave-load-tmpdir選項備份指定的目錄中的SQL_LOAD-*文件。(如果未指定,該位置默認為tmpdir變量值)。子機需要這些文件來繼續復制中斷的LOAD DATA INFILE操作。

如果必須恢復MyISAM表,先使用REPAIR TABLEmyisamchk -r來恢復,99.9%的情況下該方法可以生效。如果myisamchk恢復失敗,試試下面的方法:

請註意只有添加--log-bin選項啟動MySQL服務器從而啟用二進制日誌它才生效。

如果MySQL服務器啟用了二進制日誌,你可以使用mysqlbinlog工具來恢復從指定的時間點開始(例如,從你最後一次備份)直到現在或另一個指定的時間點的數據。

  1. 恢復原mysqldump備份,或二進制備份。

  2. 執行下面的命令重新更新二進制日誌:

    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文件系統,可以這樣備份:

  1. 從客戶端程序執行FLUSH TABLES WITH READ LOCK語句。

  2. 從另一個shell執行mount vxfs snapshot命令。

  3. 從第一個客戶端執行UNLOCK TABLES

  4. 從快照復制文件。

  5. 卸載快照。

2.3.2 備份與恢復策略示例

1) 備份策略

我們都知道必須按計劃定期進行備份。可以用一些工具(某個時間點的數據快照)完全備份MySQL。例如,InnoDB Hot BackupInnoDB數據文件提供在線非數據塊物理備份,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命令可以執行完全備份,以上行代表兩件事情:

  1. .sql文件包含所有寫入gbichot2-bin.000007二進制日誌文件或最新的文件之前的更改。

  2. 備份後所記錄的所有數據更改不出現在.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.000007gbichot2-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 LOGSmysqladmin 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 DATABASEALTER DATABASEDROP 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語句有一個例外。在這些情況下,根據以下列出的不同情況,所創建、修改或刪除的數據庫將代替當前的數據庫。

  1. 是否有binlog-do-dbbinlog-ignore-db規則?

    沒有:將語句寫入二進制日誌並退出。

    有:執行下一步。

  2. 有一些規則(binlog-do-dbbinlog-ignore-db或二者都有)。當前有一個數據庫(是否使用USE語句選擇了數據庫?)?

    沒有:不要寫入語句,並退出。

    有:執行下一步。

  3. 有一些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二進制日誌進行備份,而不能使用舊的更新日誌。

查詢結束後、鎖定被釋放前或提交完成後則立即記入二進制日誌。這樣可以確保按執行順序記入日誌。

對非事務表的更新執行完畢後立即保存到二進制日誌中。對於事務表,例如BDBInnoDB表,所有更改表的更新(UPDATEDELETEINSERT)都會 被緩存起來,直到服務器接收到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 TABLEANALYZE TABLEALTER 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 數據庫定時備份 增量/全備份