1. 爲什麼要備份數據庫
對數據庫來說,最重要也最容易被忽視的就是備份。由於不可預測性,偶然的事件可能會導致非常慘重的損失。
數據越是重要,數據的變化越頻繁,備份越發需要經常進行。
備份週期根據不同業務的需要可以調整,但是不能忽視備份。
備份時最好也備份my.cnf或my.ini,這樣可以保存你以前的配置參數。
2. MyISAM 表備份/恢復策略
2.1. 文件熱備份
2.1.1. 拷貝文件
因爲MySQL表保存爲文件方式,很容易備份。要想保持備份的一致性,對相關表執行LOCK TABLES操作,然後對錶執行FLUSH TABLES。
你只需要讀鎖定;這樣當你複製數據庫目錄中的文件時,允許其它客戶繼續查詢表。需要FLUSH TABLES語句來確保開始備份前將所有激活的索引頁寫入硬盤。
標準流程:鎖表-》刷新表到磁盤-》拷貝文件-》解鎖。
2.1.2. 使用sql 語句備份
如果你想要進行SQL級別的表備份,你可以使用SELECT INTO ...OUTFILE或BACKUP TABLE。對於SELECT INTO ...OUTFILE, 輸出的文件不能先存在。
對於BACKUP TABLE也如此,因爲覆蓋完整的文件會有安全風險。
這兩種備份方法,如果輸出文件有重名的話,最好把重名文件移除。
BACKUP TABLE備份時注意輸出目錄的權限,改方法只是備份MYD和frm文件,不備份索引。
2.1.3. 使用mysqlhotcopy 備份
mysqlhotcopy 是一個 Perl腳本,最初由Tim Bunce編寫並提供。它使用LOCK TABLES、FLUSH TABLES和cp或scp來快速備份數據庫。它是備份數據庫或單個表的最快的途徑,但它只能運行在數據庫目錄所在的機器上。mysqlhotcopy 只用於備份MyISAM。它運行在Unix和NetWare中。
shell> mysqlhotcopy db_name [/path/to/new_directory ]
shell> mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory
備份給定數據庫中的匹配正則表達式的表:
shell> mysqlhotcopy db_name./regex/
加上發音符(‘~’)前綴,表名的正則表達式可以被否定:
shell> mysqlhotcopy db_name./~regex/
mysqlhotcopy支持下面的選項:
· ---help,-?
顯示幫助消息並退出。
· --allowold
如果目標存在不放棄(加上一個_old後綴重新命名它)。
· --checkpoint=db_name.tbl_name
在指定的db_name.tbl_name插入檢查點條目。
· ---debug
啓用調試輸出。
· --dryrun,-n
報告動作而不執行它們。
· --flushlog
所有表鎖定後刷新日誌。
· --keepold
完成後不刪除以前(重新命名的)的目標。
· -- method=command
複製方法(cp或scp)。
· --noindices
備份中不包括全部索引文件。這樣使備份更小、更快。可以在以後用myisamchk -rq重新構建索引。
· --password=password,-p password
當連接服務器時使用的密碼。請注意該選項的密碼值是不可選的,不象其它MySQL程序。
· --port=port_num,-P port_num
當連接本地服務器時使用的TCP/IP端口號。
· --quiet,-q
除了出現錯誤時保持沉默。
· --regexp=expr
複製所有數據庫名匹配給出的正則表達式的數據庫。
· --socket=path,-S path
用於連接的Unix套接字文件。
· --suffix=str
所複製的數據庫名的後綴。
· --tmpdir=path
臨時目錄(代替/tmp)。
· --user=user_name,-u user_name
當連接服務器時使用的MySQL用戶名。
mysqlhotcopy從選項文件讀取[client]和[mysqlhotcopy]選項組。
因爲mysqlhotcopy一般是用來做完全備份,所以推薦使用—flushlog選項來產生增量更新日誌。
2.1.4. 使用mysqldump 備份
可以備份表結構和數據,可以同時支持MyISAM和InnoDB引擎數據庫。
mysqldump可以備份單個表、單個庫或所有庫。
Mysqldump 還可以只導出表結構。
mysqldump是邏輯備份,輸出的是sql語句文件,還可以輸出其他數據庫兼容的格式。
有3種方式來調用mysqldump:
shell> mysqldump [options] db_name [tables]
shell> mysqldump [options] ---database DB1 [DB2 DB3...]
shell> mysqldump [options] --all--database
如果沒有指定任何表或使用了---database或--all--database選項,則轉儲整個數據庫。
要想獲得你的版本的mysqldump支持的選項,執行mysqldump ---help。
如果運行mysqldump沒有--quick或--opt選項,mysqldump在轉儲結果前將整個結果集裝入內存。如果轉儲大數據庫可能會出現問題。該選項默認啓用,但可以用--skip-opt禁用。
mysqldump支持下面的選項:
· ---help,-?
顯示幫助消息並退出。
· --add-drop--database
在每個CREATE DATABASE語句前添加DROP DATABASE語句。
· --add-drop-tables
在每個CREATE TABLE語句前添加DROP TABLE語句。
· --add-locking
用LOCK TABLES和UNLOCK TABLES語句引用每個錶轉儲。重載轉儲文件時插入得更快。
· --all--database,-A
轉儲所有數據庫中的所有表。與使用---database選項相同,在命令行中命名所有數據庫。
· --allow-keywords
允許創建關鍵字列名。應在每個列名前面加上表名前綴。
· ---comments[={0|1}]
如果設置爲 0,禁止轉儲文件中的其它信息,例如程序版本、服務器版本和主機。--skip—comments與---comments=0的結果相同。 默認值爲1,即包括額外信息。
· --compact
產生少量輸出。該選項禁用註釋並啓用--skip-add-drop-tables、--no-set-names、--skip-disable-keys和--skip-add-locking選項。
· --compatible=name
產生與其它數據庫系統或舊的MySQL服務器更兼容的輸出。值可以爲ansi、mysql323、mysql40、postgresql、oracle、mssql、db2、maxdb、no_key_options、no_tables_options或者no_field_options。要使用幾個值,用逗號將它們隔開。這些值與設置服務器SQL模式的相應選項有相同的含義。
該選項不能保證同其它服務器之間的兼容性。它只啓用那些目前能夠使轉儲輸出更兼容的SQL模式值。例如,--compatible=oracle 不映射Oracle類型或使用Oracle註釋語法的數據類型。
· --complete-insert,-c
使用包括列名的完整的INSERT語句。
· --compress,-C
壓縮在客戶端和服務器之間發送的所有信息(如果二者均支持壓縮)。
· --create-option
在CREATE TABLE語句中包括所有MySQL表選項。
· ---database,-B
轉儲幾個數據庫。通常情況,mysqldump將命令行中的第1個名字參量看作數據庫名,後面的名看作表名。使用該選項,它將所有名字參量看作數據庫名。CREATE DATABASE IF NOT EXISTS db_name和USE db_name語句包含在每個新數據庫前的輸出中。
· ---debug[=debug_options],-# [debug_options]
寫調試日誌。debug_options字符串通常爲'd:t:o,file_name'。
· --default-character-set=charset
使用charsetas默認字符集。如果沒有指定,mysqldump使用utf8。
· --delayed-insert
使用INSERT DELAYED語句插入行。
· --delete-master-logs
在主複製服務器上,完成轉儲操作後刪除二進制日誌。該選項自動啓用--master-data。
· --disable-keys,-K
對於每個表,用/*!40000 ALTER TABLE tbl_name DISABLE KEYS */;和/*!40000 ALTER TABLE tbl_name ENABLE KEYS */;語句引用INSERT語句。這樣可以更快地裝載轉儲文件,因爲在插入所有行後創建索引。該選項只適合MyISAM表。
· --extended-insert,-e
使用包括幾個VALUES列表的多行INSERT語法。這樣使轉儲文件更小,重載文件時可以加速插入。
· --fields-terminated-by=...,--fields-enclosed-by=...,--fields-optionally-enclosed-by=...,--fields-escaped-by=...,--行-terminated-by=...
這些選項結合-T選項使用,與LOAD DATA INFILE的相應子句有相同的含義。
· --first-slave,-x
不贊成使用,現在重新命名爲--lock-all-tables。
· --flush-logs,-F
開始轉儲前刷新MySQL服務器日誌文件。該選項要求RELOAD權限。請注意如果結合--all--database(或-A)選項使用該選項,根據每個轉儲的數據庫刷新日誌。例外情況是當使用--lock-all-tables或--master-data的時候:在這種情況下,日誌只刷新一次,在所有 表被鎖定後刷新。如果你想要同時轉儲和刷新日誌,應使用--flush-logs連同--lock-all-tables或--master-data。
· --force,-f
在錶轉儲過程中,即使出現SQL錯誤也繼續。
· --host=host_name,-h host_name
從給定主機的MySQL服務器轉儲數據。默認主機是localhost。
· --hex-blob
使用十六進制符號轉儲二進制字符串列(例如,'abc' 變爲0x616263)。影響到的列有BINARY、VARBINARY、BLOB。
· --lock-all-tables,-x
所有數據庫中的所有表加鎖。在整體轉儲過程中通過全局讀鎖定來實現。該選項自動關閉--single-transaction和--lock-tables。
· --lock-tables,-l
開始轉儲前鎖定所有表。用READ LOCAL鎖定表以允許並行插入MyISAM表。對於事務表例如InnoDB和BDB,--single-transaction是一個更好的選項,因爲它不根本需要鎖定表。
請注意當轉儲多個數據庫時,--lock-tables分別爲每個數據庫鎖定表。因此,該選項不能保證轉儲文件中的表在數據庫之間的邏輯一致性。不同數據庫表的轉儲狀態可以完全不同。
· --master-data[=value]
該選項將二進制日誌的位置和文件名寫入到輸出中。該選項要求有RELOAD權限,並且必須啓用二進制日誌。如果該選項值等於1,位置和文件名被寫入CHANGE MASTER語句形式的轉儲輸出,如果你使用該SQL轉儲主服務器以設置從服務器,從服務器從主服務器二進制日誌的正確位置開始。如果選項值等於2,CHANGE MASTER語句被寫成SQL註釋。如果value被省略,這是默認動作。
--master-data選項啓用--lock-all-tables,除非還指定--single-transaction(在這種情況下,只在剛開始轉儲時短時間獲得全局讀鎖定。又見--single-transaction。在任何一種情況下,日誌相關動作發生在轉儲時。該選項自動關閉--lock-tables。
· --no-create-db,-n
該選項禁用CREATE DATABASE /*!32312 IF NOT EXISTS*/ db_name語句,如果給出---database或--all--database選項,則包含到輸出中。
· --no-create-info,-t
不寫重新創建每個轉儲表的CREATE TABLE語句。
· --no-data,-d
不寫表的任何行信息。如果你只想轉儲表的結構這很有用。
· --opt
該選項是速記;等同於指定 --add-drop-tables--add-locking --create-option --disable-keys--extended-insert --lock-tables --quick --set-charset。它可以給出很快的轉儲操作併產生一個可以很快裝入MySQL服務器的轉儲文件。該選項默認開啓,但可以用--skip-opt禁用。要想只禁用確信用-opt啓用的選項,使用--skip形式;例如,--skip-add-drop-tables或--skip-quick。
· --password[=password],-p[password]
連接服務器時使用的密碼。如果你使用短選項形式(-p),不能在選項和密碼之間有一個空格。如果在命令行中,忽略了--password或-p選項後面的 密碼值,將提示你輸入一個。
· --port=port_num,-P port_num
用於連接的TCP/IP端口號。
· --protocol={TCP | SOCKET | PIPE | MEMORY}
使用的連接協議。
· --quick,-q
該選項用於轉儲大的表。它強制mysqldump從服務器一次一行地檢索表中的行而不是檢索所有行並在輸出前將它緩存到內存中。
· --quote-names,-Q
用‘`’字符引用數據庫、表和列名。如果服務器SQL模式包括ANSI_QUOTES選項,用‘"’字符引用名。默認啓用該選項。可以用--skip-quote-names禁用,但該選項應跟在其它選項後面,例如可以啓用--quote-names的--compatible。
· --result-file=file,-r file
將輸出轉向給定的文件。該選項應用在Windows中,因爲它禁止將新行‘/n’字符轉換爲‘/r/n’回車、返回/新行序列。
· --routines,-R
在轉儲的數據庫中轉儲存儲程序(函數和程序)。使用---routines產生的輸出包含CREATE PROCEDURE和CREATE FUNCTION語句以重新創建子程序。但是,這些語句不包括屬性,例如子程序定義者或創建和修改時間戳。這說明當重載子程序時,對它們進行創建時定義者應設置爲重載用戶,時間戳等於重載時間。
如果你需要創建的子程序使用原來的定義者和時間戳屬性,不使用--routines。相反,使用一個具有mysql數據庫相應權限的MySQL賬戶直接轉儲和重載mysql.proc表的內容。
該選項在MySQL 5.1.2中添加進來。在此之前,存儲程序不轉儲。
· --set-charset
將SET NAMES default_character_set加到輸出中。該選項默認啓用。要想禁用SET NAMES語句,使用--skip-set-charset。
· --single-transaction
該選項從服務器轉儲數據之前發出一個BEGIN SQL語句。它只適用於事務表,例如InnoDB和BDB,因爲然後它將在發出BEGIN而沒有阻塞任何應用程序時轉儲一致的數據庫狀態。
當使用該選項時,應記住只有InnoDB表能以一致的狀態被轉儲。例如,使用該選項時任何轉儲的MyISAM或HEAP表仍然可以更改狀態。
--single-transaction選項和--lock-tables選項是互斥的,因爲LOCK TABLES會使任何掛起的事務隱含提交。
要想轉儲大的表,應結合--quick使用該選項。
· --socket=path,-S path
當連接localhost(爲默認主機)時使用的套接字文件。
· --skip--comments
參見---comments選項的描述。
· --tab=path,-T path
產生tab分割的數據文件。對於每個轉儲的表,mysqldump創建一個包含創建表的CREATE TABLE語句的tbl_name.sql文件,和一個包含其數據的tbl_name.txt文件。選項值爲寫入文件的目錄。
默認情況,.txt數據文件的格式是在列值和每行後面的新行之間使用tab字符。可以使用--fields-xxx和--行--xxx選項明顯指定格式。
註釋:該選項只適用於mysqldump與mysqld服務器在同一臺機器上運行時。你必須具有FILE權限,並且服務器必須有在你指定的目錄中有寫文件的許可。
· --tables
覆蓋---database或-B選項。選項後面的所有參量被看作表名。
· --triggers
爲每個轉儲的錶轉儲觸發器。該選項默認啓用;用--skip-triggers禁用它。
· --tz-utc
在轉儲文件中加入SET TIME_ZONE='+00:00'以便TIMESTAMP列可以在具有不同時區的服務器之間轉儲和重載。(不使用該選項,TIMESTAMP列在具有本地時區的源服務器和目的服務器之間轉儲和重載)。--tz-utc也可以保護由於夏令時帶來的更改。--tz-utc默認啓用。要想禁用它,使用--skip-tz-utc。該選項在MySQL 5.1.2中加入。
· --user=user_name,-u user_name
連接服務器時使用的MySQL用戶名。
· --verbose,-v
冗長模式。打印出程序操作的詳細信息。
· --version,-V
顯示版本信息並退出。
· --where='where-condition', -w 'where-condition'
只轉儲給定的WHERE條件選擇的記錄。請注意如果條件包含命令解釋符專用空格或字符,一定要將條件引用起來。
2.2. 文件冷備份
當mysql服務器停止時,通過複製所有表文件(*.frm、*.MYD和*.MYI文件)來備份MyISAM數據庫。
2.3. MyISAM 表恢復
1、 如果是通過mysqldump備份的,就執行:mysql –u root < 備份文件名。
2、 如果通過mysqlhotcopy或文件冷/熱拷貝來備份的,停止mysql服務,使用備份文件來覆蓋現有文件。
3、 如果是採用BACKUP TABLE備份的,使用restore table來恢復。因爲backup table不會備份索引文件,恢復表注意重建索引。
4、 如果是採用SELECT INTO ...OUTFILE備份的,使用load data恢復數據,也可以使用mysqlimport命令來代替。
3. 日誌備份
3.1. 日誌備份的好處及如何啓用
日誌備份可以支持MyISAM和InnoDB,這跟有些備份工具只支持MyISAM不一樣。
另外,日誌可以做增量備份,這是其他方法無法做到的。
啓動日誌備份:用--log-bin[=file_name]選項來啓動mysql服務。
3.2. 增量備份
先執行FLUSH LOGS刷新日誌,同步日誌緩存到磁盤,關閉當前的日誌併產生新的日誌文件。
拷貝上一次完整備份或增量備份後的一個或一些日誌文件到一個安全的地方。
這樣就製作了一個增量備份。
3.3. 日誌恢復
日誌恢復可以選擇恢復某個數據庫、某些操作點或時間範圍,非常靈活。
通過mysqlbinlog工具可以恢復二進制日誌,可以一次恢復多個日誌文件,命令如下:
shell> mysqlbinlog [options] hostname-bin.[0-9]* | mysql
mysqlbinlog命令選項
· ---help,-?
顯示幫助消息並退出。
· ---database=db_name,-d db_name
只列出該數據庫的條目(只用本地日誌)。
· --force-read,-f
使用該選項,如果mysqlbinlog讀它不能識別的二進制日誌事件,它會打印警告,忽略該事件並繼續。沒有該選項,如果mysqlbinlog讀到此類事件則停止。
· --hexdump,-H
在註釋中顯示日誌的十六進制轉儲。該輸出可以幫助複製過程中的調試。在MySQL 5.1.2中添加了該選項。
· --host=host_name,-h host_name
獲取給定主機上的MySQL服務器的二進制日誌。
· --local-load=path,-l pat
爲指定目錄中的LOAD DATA INFILE預處理本地臨時文件。
· --offset=N,-o N
跳過前N個條目。
· --password[=password],-p[password]
當連接服務器時使用的密碼。如果使用短選項形式(-p),選項和 密碼之間不能有空格。如果在命令行中--password或-p選項後面沒有 密碼值,則提示輸入一個密碼。
· --port=port_num,-P port_num
用於連接遠程服務器的TCP/IP端口號。
· --position=N,-j N
不贊成使用,應使用--start-position。
· --protocol={TCP | SOCKET | PIPE | -position
使用的連接協議。
· --read-from-remote-server,-R
從MySQL服務器讀二進制日誌。如果未給出該選項,任何連接參數選項將被忽略。這些選項是--host、--password、--port、--protocol、--socket和--user。
· --result-file=name, -r name
將輸出指向給定的文件。
· --short-form,-s
只顯示日誌中包含的語句,不顯示其它信息。
· --socket=path,-S path
用於連接的套接字文件。
· --start-datetime=datetime
從二進制日誌中第1個日期時間等於或晚於datetime參量的事件開始讀取。datetime值相對於運行mysqlbinlog的機器上的本地時區。該值格式應符合DATETIME或TIMESTAMP數據類型。例如:
shell> mysqlbinlog --start-datetime="2004-12-25 11:25:56" binlog.000003
該選項可以幫助點對點恢復。
· --stop-datetime=datetime
從二進制日誌中第1個日期時間等於或晚於datetime參量的事件起停止讀。關於datetime值的描述參見--start-datetime選項。該選項可以幫助及時恢復。
· --start-position=N
從二進制日誌中第1個位置等於N參量時的事件開始讀。
· --stop-position=N
從二進制日誌中第1個位置等於和大於N參量時的事件起停止讀。
· --to-last-logs,-t
在MySQL服務器中請求的二進制日誌的結尾處不停止,而是繼續打印直到最後一個二進制日誌的結尾。如果將輸出發送給同一臺MySQL服務器,會導致無限循環。該選項要求--read-from-remote-server。
· --disable-logs-bin,-D
禁用二進制日誌。如果使用--to-last-logs選項將輸出發送給同一臺MySQL服務器,可以避免無限循環。該選項在崩潰恢復時也很有用,可以避免複製已經記錄的語句。註釋:該選項要求有SUPER權限。
· --user=user_name,-u user_name
連接遠程服務器時使用的MySQL用戶名。
· --version,-V
顯示版本信息並退出。
還可以使用--var_name=value選項設置下面的變量:
· open_files_limit
指定要保留的打開的文件描述符的數量。
4. InnoDB 表備份/恢復策略
4.1. 使用商業的在線熱備份工具
InnoDB Hotbackup 是一個在線備份工具,你可以用它來在InnoDB數據庫運行之時備份你的InnoDB數據庫。InnoDB 熱備份工具 不要求你關閉數據庫,並且它不設置任何鎖定或干擾你正常的數據庫處理。InnoDB 熱備份工具 是非免費(商業的)附加軟件,它每年的證書費用是每臺MySQL服務器運行的計算機390歐元。
具體使用方法可以參考相關文檔,我也沒有使用過這個工具。
4.2. 使用mysqldump 熱備份
Mysqldump提供對InnoDB非物理的在線邏輯熱備份。
使用方法與備份MyISAM時一樣。
4.3. 使用select into 熱備份單個/多個表
可以使用select into備份一個或多個表,用法與MyISAM表相同。
4.4. 二進制冷備份
如果你可以關閉你的MySQL服務器,你可以生成一個包含InnoDB用來管理它的表的所有文件的二進制備份。使用如下步驟:
1. 關閉MySQL服務器,確信它是無錯誤關閉。
2. 複製你所有數據文件(ibdata文件和.ibd文件)到一個安全的地方。
3. 複製你所有ib_logfile文件到一個安全的地方。
4. 複製my.cnf配置文件或文件到一個安全的地方。
5. 爲你InnoDB表複製.frm文件到一個安全的地方。
4.5. InnoDB 表恢復
1、 先嚐試使用InnoDB的日誌自動恢復功能,方法是重啓mysql服務。
2、 在一些情況下,明顯地數據庫損壞是因爲操作系統損壞它自己的文件緩存,磁盤上的數據可能完好,最好是首先重啓計算機。它可以消除那些顯得是數據庫頁損壞的錯誤。
如果不行,則採用下面的方法進行恢復。
3、 如果是mysqldump做的完全備份,先恢復完全備份,然後再恢復完全備份後的增量日誌備份。
4、 如果是採用select into備份表的話,則採用load data或mysqlimport恢復。
5、 如果是採用二進制冷備份做的完全備份,則先停止mysql服務,覆蓋備份的二進制文件,然後執行上次完全備份後的增量日誌備份。
6、 注意:InnoDB二進制文件沒有MyISAM那麼好,必須在相同的浮點數的cpu機器上移植。
5. MyISAM/InnoDB 備份/恢復策略
因爲在一個數據庫中有可能要同時使用MyISAM和InnoDB兩種引擎,因此統一考慮他們的備份/恢復策略。
1、 完整備份採用mysqldump。
2、 增量備份採用bin-log日誌。
3、 單表備份採用select into。
4、
6. 定期維護表
雖然MySQL提供了多種備份/恢復手段,但是定期維護表大大可以降低表毀壞的可能性,並且可以提高查詢性能。
1、對於InnoDB引擎,你可以使用innodb_tablespace_monitor來檢查表空間文件內文件空間管理的完整性。
2、對於MyISAM引擎,可以通過sql語句或myisamchk 工具來維護表 。
在許多情況下,你會發現使用SQL語句實現MyISAM表的維護比執行myisamchk操作要容易地多:
· 要想檢查或維護MyISAM表,使用CHECK TABLE或REPAIR TABLE。
· 要想優化MyISAM表,使用OPTIMIZE TABLE。
· 要想分析MyISAM表,使用ANALYZE TABLE。
這些語句比myisamchk有利的地方是服務器可以做任何工作。使用myisamchk,你必須確保服務器在同一時間不使用表。否則,myisamchk和服務器之間會出現不期望的相互干涉。
一般建議在停止mysql服務時執行myisamchk,如果是在線執行則最好先flush tables(把所有更新寫入磁盤)。
7. 備份策略摘要
1、一定用--log-bin或甚至--log-bin=log_name選項運行MySQL服務器,其中日誌文件名位於某個安全媒介上,不同於數據目錄所在驅動器。如果你有這樣的安全媒介,最好進行硬盤負載均衡(這樣能夠提高性能)。
2、定期進行完全備份,使用mysqldump命令進行在線非塊備份。
在負載比較低的時候進行,並且建議採用--single-transaction參數來保證事務數據的一致性,同時不影響其他用戶的正常讀寫。
3、完整備份時採用FLUSH LOGS,便於產生增量備份日誌。
4、用FLUSH LOGS或mysqladmin flush-logs 刷新日誌進行定期增量備份。
5、定期維護表,這樣既可以提高性能,並且可以減少數據丟失和出錯的可能性。
6、關鍵表可以另外再做備份,根據需要。