@
MySQL資料庫備份與恢復
儘管採取了一些管理措施來保證資料庫的安全,但是在不確定的意外情況下,總是有可能造成資料的損失。
- 例如,意外的停電,不小心的操作失誤等都可能造成資料的丟失。
所以為了保證資料的安全,我們需要定期對資料進行備份。如果資料庫中的資料出現了錯誤,就需要使用備份好的資料進行資料還原,這樣可以將損失降至最低。
MySQL 提供了多種方法對資料進行備份和恢復。
資料庫為什麼需要備份
任何資料庫都需要備份,備份資料是維護資料庫必不可少的操作。
備份就是為了防止原資料丟失,保證資料的安全。當資料庫因為某些原因造成部分或者全部資料丟失後,備份檔案可以幫我們找回丟失的資料。
因此,資料備份是很重要的工作。
常見資料庫備份的應用場景如下。
資料丟失應用場景:
- 人為操作失誤造成某些資料被誤操作
- 軟體 BUG 造成部分資料或全部資料丟失
- 硬體故障造成資料庫部分資料或全部資料丟失
- 安全漏洞被入侵資料惡意破壞
非資料丟失應用場景:
- 特殊應用場景下基於時間點的資料恢復
- 開發測試環境資料庫搭建
- 相同資料庫的新環境搭建
- 資料庫或者資料遷移
以上列出的是一些資料庫備份常見的應用場景,資料庫備份還有其它應用場景,這裡就不一一列舉了。
比如磁碟故障導致整個資料庫所有資料丟失,並且無法從已經出現故障的硬碟上面恢復出來時,可以通過最近時間的整個資料庫的物理或邏輯備份資料檔案,儘可能的將資料恢復到故障之前最近的時間點。
操作失誤造成資料被誤操作後,我們需要有一個能恢復到錯誤操作時間點之前的瞬間的備份檔案存在,當然這個備份可能是整個資料庫的備份,也可以僅僅只是被誤操作的表的備份。
MySQL備份型別
備份是以防萬一的一種必要手段,在出現硬體損壞或非人為的因素而導致資料丟失時,可以使用備份恢復資料,以將損失降低到最小程度,因此備份是必須的。
備份可以分為以下幾個型別。根據備份的方法(是否需要資料庫離線)可以將備份分為:
- 熱備(Hot Backup)
- 熱備份可以在資料庫執行中直接備份,對正在執行的資料庫操作沒有任何的影響,資料庫的讀寫操作可以正常執行。這種方式在 MySQL 官方手冊中稱為 Online Backup(線上備份)。
- 按照備份後檔案的內容,熱備份又可以分為:
- 邏輯備份:在 MySQL 資料庫中,邏輯備份是指備份出的檔案內容是可讀的,一般是文字內容。內容一般是由一條條 SQL 語句,或者是表內實際資料組成。如 mysqldump 和 SELECT * INTO OUTFILE 的方法。這類方法的好處是可以觀察匯出檔案的內容,一般適用於資料庫的升級、遷移等工作。但其缺點是恢復的時間較長。
- 裸檔案備份:裸檔案備份是指複製資料庫的物理檔案,既可以在資料庫執行中進行復制(如 ibbackup、xtrabackup 這類工具),也可以在資料庫停止執行時直接複製資料檔案。這類備份的恢復時間往往比邏輯備份短很多。
- 按照備份資料庫的內容來分,備份又可以分為:
- 完全備份:是指對資料庫進行一個完整的備份,即備份整個資料庫,如果資料較多會佔用較大的時間和空間。
- 部分備份:是指備份部分資料庫(例如,只備份一個表)。部分備份又分為:
- 增量備份需要使用專業的備份工具。指的是在上次完全備份的基礎上,對更改的資料進行備份。也就是說每次備份只會備份自上次備份之後到備份時間之內產生的資料。因此每次備份都比差異備份節約空間,但是恢復資料麻煩。
- 差異備份指的是自上一次完全備份以來變化的資料。和增量備份相比,浪費空間,但恢復資料比增量備份簡單。
- 冷備(Cold Backup)
- 冷備份必須在資料庫停止的情況下進行備份,資料庫的讀寫操作不能執行。這種備份最為簡單,一般只需要複製相關的資料庫物理檔案即可。這種方式在 MySQL 官方手冊中稱為 Offline Backup(離線備份)。
- 溫備(Warm Backup)
- 溫備份同樣是在資料庫執行中進行的,但是會對當前資料庫的操作有所影響,備份時僅支援讀操作,不支援寫操作。
MySQL 中進行不同方式的備份還要考慮儲存引擎是否支援,如 MyISAM 不支援熱備,支援溫備和冷備。而 InnoDB 支援熱備、溫備和冷備。
一般情況下,我們需要備份的資料分為以下幾種:
- 表資料
- 二進位制日誌、InnoDB 事務日誌
- 程式碼(儲存過程、儲存函式、觸發器、事件排程器)
- 伺服器配置檔案
下面是幾種常用的備份工具:
- mysqldump:邏輯備份工具,適用於所有的儲存引擎,支援溫備、完全備份、部分備份、對於 InnoDB 儲存引擎支援熱備。
- cp、tar 等歸檔複製工具:物理備份工具,適用於所有的儲存引擎、冷備、完全備份、部分備份。
- lvm2 snapshot:藉助檔案系統管理工具進行備份。
- mysqlhotcopy:名不副實的一個工具,僅支援 MyISAM 儲存引擎。
- xtrabackup:一款由 percona 提供的非常強大的 InnoDB/XtraDB 熱備工具,支援完全備份、增量備份。
MySQL熱備份及恢復
熱備份是在資料庫處於執行狀態時直接備份,不影響現有業務的正常進行。熱備份又細分為邏輯備份和裸檔案備份,
邏輯備份
邏輯備份的最大優點就是對於各種儲存引擎,都可以用同樣的方法來備份。而冷備份則不同,不同的儲存引擎的備份方法也各不相同。因此,對於不同儲存引擎混合的資料庫,用邏輯備份會更簡單一些。
邏輯備份可以說是最簡單,也是目前中小型系統最常用的備份方法。邏輯備份主要有以下幾種方法:
mysqldump
mysqldump 是 MySQL 自帶的邏輯備份工具。它的備份原理是通過協議連線到 MySQL 資料庫,將需要備份的資料查詢出來,然後將查詢出的資料轉換成對應的 INSERT 語句。當我們需要還原恢復這些資料時,只要執行這些 INSERT 語句,就能將對應的資料還原。所以有的資料也將這種備份方式稱為 INSERT 備份。
恢復資料時可以使用 mysql -uroot -p <backup.sql
直接呼叫備份檔案執行所有命令,將資料完全恢復到備份時候的狀態。如果已經連線上了 MySQL 伺服器,那麼可以通過 source /path/backup.sql
來進行恢復。
SELECT INTO…OUTFILE
SELECT INTO…OUTFILE 語句可以把表資料匯出到一個文字檔案中,且能將資料庫中的表資料以特定分隔符進行分隔後記錄在文字檔案中,以達到邏輯備份的效果。
這種備份方式與 mysqldump 方法相比,使用的儲存空間更小,資料格式更加清晰明確,編輯方便。但是這種方法只能匯出或匯入資料的內容,不包括表的結構,如果表的結構檔案損壞,則必須先恢復原來的表的結構。而且這種方法不能在同一個備份檔案中存在多個表的備份資料,增加了檔案維護和恢復的成本。
這種備份方法恢復起來會稍微麻煩一點,需要一個表一個表通過相關命令來進行恢復。當然如果是通過指令碼來實現自動多表恢復也是比較方便的。恢復方法有 2 個,一個是通過 MySQL 的 LOAD DATA INFILE 命令來恢復資料,另一種方法就是通過 MySQL 提供的使用工具 mysqlimport 來進行恢復。
mydumper
mydumper 是針對 MySQL 資料庫備份的一個輕量級第三方的開源工具,備份方式為邏輯備份。它支援多執行緒,備份速度遠高於原生態的 mysqldump 以及其它眾多優異特性。與其配套的相應恢復資料為 myloader 工具。DBA 稱 mydumper 和 myloader 為備份界的“小鋼炮”。
我們可以看出所謂的邏輯備份就是備份 SQL 語句,然後恢復資料時執行備份 SQL,從而實現資料庫資料的重現。邏輯備份完成後所形成的檔案都可以直接編輯。
邏輯備份的作用如下:
- 通過邏輯備份,我們可以僅僅恢復備份中的部分資料而不需要全部恢復。不會影響不相關的資料;
- 通過全庫的邏輯備份,我們可以在新的 MySQL 環境下完全重建出一個與備份時完全一樣的資料庫,並且不受平臺型別限制;
- 通過特定條件的邏輯備份,我們可以將某些特定資料輕鬆遷移(或者同步)到其它的 MySQL 或另外的資料庫環境。
裸檔案備份
裸檔案備份主要在底層複製資料檔案,所以備份速度要比邏輯備份更快。
我們利用 Percona 公司釋出的一個 XtraBackup 熱備份工具來完成裸檔案備份,它是 Percona 公司的開源專案,據官方介紹它是世界上唯一 一款開源的能夠對 InnoDB 和 XtraDB 資料庫進行熱備的工具。
它的優點就是備份與恢復過程的速度很快,安全可靠,而且在備份過程中不會縮表,不影響現有業務。但它目前還是不能對錶結構檔案和其它非事務型別的表進行備份。
MySQL冷備份及恢復
冷備份可以稱為 Offline Backup(離線備份)。這種備份最為簡單,一般只需要複製相關的資料庫物理檔案到另外的位置即可。
由於 MySQL 伺服器中的資料檔案是基於磁碟的文字檔案,所以最簡單、最直接的備份操作,就是將資料檔案直接複製出來。但是由於 MySQL 伺服器的資料檔案在執行時期,總是處於開啟和使用狀態,因此備份檔案不一定有效。為了解決該問題,在複製資料檔案時,需要先停止 MySQL 伺服器。
這樣做的好處是可以保證資料庫的完整性,備份過程簡單且恢復速度相對快一些,但是關閉資料庫會影響現有業務的進行。伺服器停止執行期間,使用者不能再繼續訪問網站。例如,一些電商網站店慶促銷時,如果為了備份要停庫,那麼帶來的代價損失將不可估量。所以冷備一般用於不是很重要、非核心的業務上面。
冷備份的優點如下:
- 備份簡單、快速,只要複製相關檔案即可。
- 備份檔案易於在不同作業系統,不同 MySQL 版本上進行恢復。
- 恢復相當簡單,只需要把檔案恢復到指定位置即可。
- 恢復速度快,不需要執行任何 SQL 語句,也不需要重建索引。
- 低度維護,高度安全。
冷備份的缺點如下:
- 備份過程中,資料庫不能做其它的工作,且必須是關閉狀態。
- InnoDB 儲存引擎冷備的檔案通常比邏輯檔案大很多,因為表空間存放著很多其它的資料,如 undo 段,插入緩衝等資訊。
- 若磁碟空間有限,只能拷貝到磁帶等其它外部儲存裝置上,速度會很慢。
- 冷備也不總是可以輕易的跨平臺。作業系統、MySQL 的版本、檔案大小寫敏感和浮點數格式都會成為問題。
資料庫的物理檔案主要由資料庫的資料檔案、日誌檔案以及配置檔案等組成。MySQL 系統有一些共有的日誌檔案和系統表的資料檔案。每種儲存引擎的物理檔案也不一樣,
冷備的備份與恢復過程也很簡單。僅僅需要如下幾步:
- 為了保證所備份資料的完整性,在停止 MySQL 資料庫伺服器之前,需要先執行 FLUSH TABLES 語句將所有資料寫入到資料檔案的文字檔案裡。
- 停掉 MySQL 服務,命令(2種方式)如下:
- mysqladmin -uroot -proot shutdown
- NET START mysql
- 備份過程就是複製整個資料目錄到遠端備份機或者本地磁碟上,Linux 和 Windows 命令如下:
- Scp -r /data/mysql/ root@遠端備份機ip:/新的目錄
- Copy -r /data/mysql/ 本地新目錄
- 備份到本次磁碟也可以手動複製上述相關目錄裡的資料檔案。
- 恢復過程就更簡單了,僅僅需要把已備份的資料目錄替換原有的目錄就可以了,最後重啟 MySQL 服務。
- 恢復資料是資料庫維護中最常用的操作,利用備份檔案可以將 MySQL 資料庫伺服器恢復到備份時的狀態,這樣就可以將管理員的非常操作和計算機的故障造成的相關損失降到最小。
需要注意的是,通過複製資料檔案這種方式實現資料恢復時,必須保證兩個 MySQL 資料庫的主版本號一致。只有兩個 MySQL 資料庫主版本號相同時,才能保證它們的資料檔案型別是相同的。
MySQL冷備份所需物理檔案
MyISAM儲存引擎
MyISAM 儲存引擎的所有資料預設存放在 C:/ProgramData/MySQL/MySQL Server 5.7/Data 路徑下,即配置檔案(my.ini或my.cnf)中 datadir 引數的值。
實際上不管我們使用的是 MyISAM 儲存引擎還是其他儲存引擎,每一個資料庫都會在“datadir”目錄下有一個資料夾(包括系統資訊的資料庫 mysql 也是一樣)。
在各個資料庫中每一個 MyISAM 儲存引擎的表都會有 3 個檔案存在,即記錄表結構後設資料的“.frm”檔案,儲存表資料的“.MYD”檔案,儲存索引資料的“.MYI”檔案。
MyISAM 屬於非事務性儲存引擎,它沒有自己的日誌檔案。所以 MyISAM 儲存引擎的物理備份除了需要備份 MySQL 系統共有的物理檔案之外,還需要備份上面的 3 種檔案。
Innodb 儲存引擎
Innodb 儲存引擎屬於事務性儲存引擎,存放資料的位置也可能與 MyISAM 儲存引擎有所不同,這主要取決於 Innodb 的相關配置。
指定 Innodb 存放資料和日誌檔案的位置引數為 innodb_data_home_dir、innodb_data_file_path 和 innodb_log_group_home_dir。以及決定 Innodb 的表空間儲存方式引數 innodb_file_per_table,它決定 Innodb 是以共享表空間存放資料還是以獨享表空間方式儲存資料。
如果使用的是共享表空間的儲存方式,那麼需要備份 innodb_data_home_dir 和 innodb_data_file_path 引數設定的所有資料檔案,以及 datadir 中相應資料庫目錄下的所有 Innodb 儲存引擎表的 .frm 檔案。
而如果使用的是獨享表空間,那麼除了需要備份上面共享表空間方式所需要備份的所有檔案之外,我們還需要備份 datadir 中相應資料庫目錄下的所有 .idb 檔案,該檔案中存放的才是獨享表空間方式下 Innodb 儲存引擎表的資料。
那麼既然是使用獨享表空間,為什麼還要備份共享表空間“才使用到”的資料檔案呢?其實這是很多人的一個共性誤區,以為使用獨享表空間的時候 Innodb 的所有資訊就都存放在“datadir”所設定資料庫目錄下的“.ibd”檔案中。實際上並不是這樣的,“.ibd”檔案中所存放的僅僅只是我們的表資料而已。
大家都很清楚,Innodb 是事務性儲存引擎,它需要 undo 和 redo 資訊,而不管 Innodb 使用的是共享還是獨享表空間的方式來儲存資料。與事務相關的 undo 資訊以及其他的一些後設資料資訊,都是存放在 innodb_data_home_dir 和 innodb_data_file_path 這兩個引數所設定的資料檔案中的。所以要想 Innodb 的物理備份有效,就必須備份 innodb_data_home_dir 和 innodb_data_file_path 引數所設定的資料檔案。
此外,除了上面所說的資料檔案之外,Innodb 還有存放自己的 redo 資訊和相關事務資訊的日誌檔案在 innodb_log_group_home_dir 引數所設定的位置。所以要想 Innodb 物理備份能夠有效使用,我們還必須要備份 innodb_log_group_home_dir 引數所設定的位置的所有日誌檔案。
MySQL資料庫遷移
資料庫遷移就是把資料從一個系統移動到另一個系統上,遷移過程其實就是在源資料庫備份和目標資料庫恢復的過程組合。遷移的原因是多種多樣的,比如:
- 需要安裝新的資料庫伺服器
- MySQL 版本更新
- 資料庫管理系統的變更(如從 SQL Server 遷移到 MySQL)
根據實際操作等情況,可以將資料庫遷移操作分成以下 3 種形式。
- 相同版本 MySQL 資料庫之間的遷移。
- 不同版本 MySQL 資料庫之間的遷移。
- 不同資料庫間的遷移。
相同版本的遷移
相同版本的 MySQL 資料庫是指主版本號一致的資料庫。主版本號一致的資料庫遷移最容易實現。由於遷移前後 MySQL 資料庫的主版本號相同,所以可以通過複製資料庫目錄來實現資料庫遷移。
最安全和最常用的方式是通過使用 mysqldump 命令進行資料庫備份,然後使用 mysql 命令將備份檔案還原到新的 MySQL 資料庫。遷移時的備份和還原操作可以同時執行。
假設從一個名為 hostname1 的機器中備份出所有資料庫,然後將這些資料庫遷移到名為 hostname2 的機器上,具體語法形式如下:
mysqldump -h hostname1 -u root -password=password1 -all-databases
|
mysql -h hostname2 -u root -password=password2
其中:
- 符號“|”用來實現將命令 mysqldump 備份的檔案送給 mysql 命令;
- password1 為 hostname1 主機上 root 使用者的密碼;
- password2 為 hostname2 主機上 root 使用者的密碼;
- -all-databases 表示遷移全部的資料庫,可省略。
不用版本的遷移
不同版本的 MySQL 資料庫之間的資料遷移通常是 MySQL 升級的原因。例如,伺服器使用 4.0 版本的 MySQL 資料庫,現在要升級為 5.7 版本的。這樣就需要不同版本的 MySQL 資料庫之間進行資料遷移。
不同版本下的資料庫遷移,分為 2 種方式:
- 低版本資料庫向高版本資料庫進行遷移
- 高版本資料庫向低版本資料庫進行遷移
低版本資料庫向高版本資料庫進行遷移時,由於高版本會相容低版本,所以該種方式也是最容易實現的操作。對於儲存型別為 MyISAM 的表,最安全和最常用的操作是直接複製資料檔案。對於儲存型別為 InnoDB 的表,最安全和最常用的操作是執行 mysqldump 命令進行備份和執行 mysql 命令還原恢復資料。
但是高版本資料庫向低版本資料庫進行遷移時,因為高版本資料庫可能有一些新的特性,這些特性是低版本資料庫所不具有的,所以資料庫遷移時要特別小心,最好使用 mysqldump 命令來進行備份,避免遷移時造成資料丟失。
不同資料庫的遷移
不同資料庫之間的遷移是指從其它型別的資料庫遷移到 MySQL 資料庫,或者從 MySQL 資料庫遷移到其他型別的資料庫。例如,某個網站原來使用 Oracle 資料庫,因為運營成本太高等諸多原因,希望改用 MySQL 資料庫。或者,某個管理系統原來使用 MySQL 資料庫,因為某種特殊效能的要求,希望改用 Oracle 資料庫。這樣的不同資料庫之間的遷移也經常會發生。但是這種遷移沒有普通適用的解決辦法。
其它資料庫也有類似 mysqldump 這樣的備份工具,可以將資料庫中的檔案備份成 sql 檔案或普通文字。但是,不同的資料庫廠商並沒有完全按照 SQL 標準來設計資料庫,這就造成了不同資料庫使用的 SQL 語句的差異。例如,微軟的 SQL Server 軟體使用的是 T-SQL 語言。T-SQL 中包含了非標準的 SQL 語句。這就造成了 SQL Server 和 MySQL 的 SQL 語句不能相容。
除了 SQL 語句存在不相容的情況外,不同的資料庫之間的資料型別也有差異。例如,MySQL 不支援 SQL Server 中的 ntext、 Image 等資料型別。同樣,SQL Server 也不支援 MySQL 中的 ENUM 和 SET 等資料型別。資料型別的差異也造成了遷移的困難。
從某種意義上說,這種差異是商業資料庫公司故意造成的壁壘,這種行為是阻礙資料庫市場健康發展的。
但是不同資料庫伺服器間的遷移並不是完全不可能。在 Windows 作業系統下,如果要實現從 MySQL 資料庫伺服器向 SQL SERVER 資料庫伺服器遷移,可以通過 MyODBC 來實現;如果要實現從 MySQL 資料庫伺服器向 ORACLE 資料庫伺服器遷移,可以先通過執行 mysqldump 命令匯出 sql 檔案,然後手動修改 sql 檔案中的 CREATE 語句。
MySQL mysqldump備份資料庫
資料庫的主要作用就是對資料進行儲存和維護,所以備份資料是資料庫管理中最常用的操作。為了防止資料庫意外崩潰或硬體損傷而導致的資料丟失,資料庫系統提供了備份和恢復策略。
保證資料安全的最重要的一個措施就是定期的對資料庫進行備份。這樣即使發生了意外,也會把損失降到最低。
資料庫備份是指通過匯出資料或者複製表檔案的方式來製作資料庫的副本。當資料庫出現故障或遭到破壞時,將備份的資料庫載入到系統,從而使資料庫從錯誤狀態恢復到備份時的正確狀態。
MySQL 中提供了兩種備份方式,即 mysqldump 命令以及 mysqlhotcopy 指令碼。由於 mysqlhotcopy 只能用於 MyISAM 表,所以 MySQL 5.7 移除了 mysqlhotcopy 指令碼。
mysqldump 命令執行時,可以將資料庫中的資料備份成一個文字檔案。資料表的結構和資料將儲存在生成的文字檔案中。
備份一個資料庫
使用 mysqldump 命令備份一個資料庫的語法格式如下:
mysqldump -u username -p dbname [tbname ...]> filename.sql
對上述語法引數說明如下:
- username:表示使用者名稱稱;
- dbname:表示需要備份的資料庫名稱;
- tbname:表示資料庫中需要備份的資料表,可以指定多個資料表。省略該引數時,會備份整個資料庫;
- 右箭頭“>”:用來告訴 mysqldump 將備份資料表的定義和資料寫入備份檔案;
- filename.sql:表示備份檔案的名稱,檔名前面可以加絕對路徑。通常將資料庫備份成一個字尾名為
.sql
的檔案。
注意:mysqldump 命令備份的檔案並非一定要求字尾名為.sql
,備份成其他格式的檔案也是可以的。例如,字尾名為.txt
的檔案。通常情況下,建議備份成字尾名為.sql
的檔案。因為,字尾名為.sql
的檔案給人第一感覺就是與資料庫有關的檔案。
備份多個資料庫
如果要使用 mysqldump 命令備份多個資料庫,需要使用 --databases 引數。備份多個資料庫的語法格式如下:
mysqldump -u username -P --databases dbname1 dbname2 ... > filename.sql
加上“--databases”引數後,必須指定至少一個資料庫名稱,多個資料庫名稱之間用空格隔開。
備份所有資料庫
mysqldump 命令備份所有資料庫的語法格式如下:
mysqldump -u username -P --all-databases>filename.sql
使用“--all-databases”引數時,不需要指定資料庫名稱。
MySQL恢復資料庫
當資料丟失或意外損壞時,可以通過恢復已經備份的資料來儘量減少資料的丟失和破壞造成的損失。
在 MySQL 中,可以使用 mysql 命令來恢復備份的資料。mysql 命令可以執行備份檔案中的 CREATE 語句和 INSERT 語句,也就是說,mysql 命令可以通過 CREATE 語句來建立資料庫和表,通過 INSERT 語句來插入備份的資料。
mysql 命令語法格式如下:
mysql -u username -P [dbname] < filename.sql
其中:
- username 表示使用者名稱稱;
- dbname 表示資料庫名稱,該引數是可選引數。如果 filename.sql 檔案為 mysqldump 命令建立的包含建立資料庫語句的檔案,則執行時不需要指定資料庫名。如果指定的資料庫名不存在將會報錯;
- filename.sql 表示備份檔案的名稱。
注意:mysql 命令和 mysqldump 命令一樣,都直接在命令列(cmd)視窗下執行。
注意:如果使用--all-databases
引數備份了所有的資料庫,那麼恢復時不需要指定資料庫。因為,其對應的 sql 檔案中含有 CREATE DATABASE 語句,可以通過該語句建立資料庫。建立資料庫之後,可以執行 sql 檔案中的 USE 語句選擇資料庫,然後在資料庫中建立表並且插入記錄。
MySQL匯出表資料
通過對資料表的匯入匯出,可以實現 MySQL 資料庫伺服器與其它資料庫伺服器間移動資料。匯出是指將 MySQL 資料表的資料複製到文字檔案。資料匯出的方式有多種,本節主要介紹使用 SELECTI...INTO OUTFILE 語句匯出資料。
在 MySQL 中,可以使用 SELECTI...INTO OUTFILE 語句將表的內容匯出成一個文字檔案。SELECT...INTO OUTFILE 語句基本格式如下:
SELECT 列名 FROM table [WHERE 語句] INTO OUTFILE '目標檔案'[OPTIONS]
該語句用 SELECT 來查詢所需要的資料,用 INTO OUTFILE 來匯出資料。其中,目標檔案
用來指定將查詢的記錄匯出到哪個檔案。這裡需要注意的是,目標檔案不能是一個已經存在的檔案。
[OPTIONS] 為可選引數選項,OPTIONS 部分的語法包括 FIELDS 和 LINES 子句,其常用的取值有:
- FIELDS TERMINATED BY '字串':設定字串為欄位之間的分隔符,可以為單個或多個字元,預設情況下為製表符‘\t’。
- FIELDS [OPTIONALLY] ENCLOSED BY '字元':設定字元來括上 CHAR、VARCHAR 和 TEXT 等字元型欄位。如果使用了 OPTIONALLY 則只能用來括上 CHAR 和 VARCHAR 等字元型欄位。
- FIELDS ESCAPED BY '字元':設定如何寫入或讀取特殊字元,只能為單個字元,即設定轉義字元,預設值為‘\’。
- LINES STARTING BY '字串':設定每行開頭的字元,可以為單個或多個字元,預設情況下不使用任何字元。
- LINES TERMINATED BY '字串':設定每行結尾的字元,可以為單個或多個字元,預設值為‘\n’ 。
注意:FIELDS 和 LINES 兩個子句都是自選的,但是如果兩個都被指定了,FIELDS 必須位於 LINES的前面。
注意:匯出時可能會出現下面的錯誤:
The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
這是因為MySQL 限制了資料的匯出路徑。MySQL 匯入匯出檔案只能在 secure-file-priv 變數的指定路徑下的檔案才可以匯入匯出。
有以下 2 種解決辦法:
首先使用show variables like '%secure%';
語句檢視 secure-file-priv 變數配置。
mysql> show variables like '%secure%' \G
*************************** 1. row ***************************
Variable_name: require_secure_transport
Value: OFF
*************************** 2. row ***************************
Variable_name: secure_auth
Value: ON
*************************** 3. row ***************************
Variable_name: secure_file_priv
Value: C:\ProgramData\MySQL\MySQL Server 5.7\Uploads\
3 rows in set, 1 warning (0.04 sec)
secure_file_priv 的值指定的是 MySQL 匯入匯出檔案的路徑。將 SQL 語句中的匯出檔案路徑修改為該變數的指定路徑,再執行匯入匯出操作即可。也可以在 my.ini 配置檔案中修改 secure-file-priv 的值,然後重啟服務即可。
如果 secure_file_priv 值為 NULL,則為禁止匯出,可以在 MySQL 安裝路徑下的 my.ini 檔案中新增secure_file_priv=設定路徑
語句,然後重啟服務即可。
使用 SELECT...INTO OUTFILE 語句將 test 資料庫中的 person 表中的記錄匯出到文字檔案,使用 FIELDS 選項和 LINES 選項,要求欄位之間用、
隔開,字元型資料用雙引號括起來。每條記錄以-
開頭。SQL 語句如下:
SELECT * FROM test.person INTO OUTFILE 'C:/person.txt'
FIELDS TERMINATED BY '\、' OPTIONALLY ENCLOSED BY '\"' LINES STARTING BY '\-'
TERMINATED BY '\r\n';
其中:
- FIELDS TERMINATED BY '、’:表示欄位之間用
、
分隔; - ENCLOSED BY '"':表示每個欄位都用雙引號括起來;
- LINES STARTING BY '-':表示每行以
-
開頭; - TERMINATED BY '\r\n' 表示每行以回車換行符結尾,保證每一條記錄佔一行。
person.txt 檔案內容如下:
-1、"Java"、12
-2、"MySQL"、13
-3、"C"、15
-4、"C++"、22
-5、"Python"、18
可以看到,每條記錄都以-
開頭,每個資料之間以都以、
隔開,所有的欄位值都被雙引號包括。
MySQL資料庫恢復
資料庫恢復是指以備份為基礎,與備份相對應的系統維護和管理操作。
系統進行恢復操作時,先執行一些系統安全性的檢查,包括檢查所要恢復的資料庫是否存在、資料庫是否變化及資料庫檔案是否相容等,然後根據所採用的資料庫備份型別採取相應的恢復措施。
資料庫恢復機制設計的兩個關鍵問題是:
- 第一,如何建立冗餘資料;
- 第二,如何利用這些冗餘資料實施資料庫恢復。
建立冗餘資料最常用的技術是資料轉儲和登入日誌檔案。通常在一個資料庫系統中,這兩種方法是一起使用的。
資料轉儲是 DBA 定期地將整個資料庫複製到磁帶或另一個磁碟上儲存起來的過程。這些備用的版本成為後備副本或後援副本。
可使用 LOAD DATA…INFILE 語句來恢復先前備份的資料。
例子:將之前匯出的資料備份檔案 file.txt 匯入資料庫 test_db 的表 tb_students_copy 中,其中 tb_students_copy 的表結構和 tb_students_info 相同。
首先建立表 tb_students_copy,輸入的 SQL 語句和執行結果如下所示。
mysql> CREATE TABLE tb_students_copy
-> LIKE tb_students_info;
Query OK, 0 rows affected (0.52 sec)
mysql> SELECT * FROM tb_students_copy;
Empty set (0.00 sec)
匯入資料與查詢表 tb_students_copy 的過程如下所示。
mysql> LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 5.7/
Uploads/file.txt'
-> INTO TABLE test_db.tb_students_copy
-> FIELDS TERMINATED BY ','
-> OPTIONALLY ENCLOSED BY '"'
-> LINES TERMINATED BY '?';
Query OK, 10 rows affected (0.14 sec)
Records: 10 Deleted: 0 Skipped: 0 Warnings: 0
mysql> SELECT * FROM test_db.tb_students_copy;
+----+--------+---------+------+------+--------+------------+
| id | name | dept_id | age | sex | height | login_date |
+----+--------+---------+------+------+--------+------------+
| 1 | Dany | 1 | 25 | F | 160 | 2015-09-10 |
| 2 | Green | 3 | 23 | F | 158 | 2016-10-22 |
| 3 | Henry | 2 | 23 | M | 185 | 2015-05-31 |
| 4 | Jane | 1 | 22 | F | 162 | 2016-12-20 |
| 5 | Jim | 1 | 24 | M | 175 | 2016-01-15 |
| 6 | John | 2 | 21 | M | 172 | 2015-11-11 |
| 7 | Lily | 6 | 22 | F | 165 | 2016-02-26 |
| 8 | Susan | 4 | 23 | F | 170 | 2015-10-01 |
| 9 | Thomas | 3 | 22 | M | 178 | 2016-06-07 |
| 10 | Tom | 4 | 23 | M | 165 | 2016-08-05 |
+----+--------+---------+------+------+--------+------------+
10 rows in set (0.00 sec)