2020重新出發(fā),MySql基礎(chǔ),MySql數(shù)據(jù)庫備份與恢復(fù)

@[toc]

MySQL數(shù)據(jù)庫備份與恢復(fù)

盡管采取了一些管理措施來保證數(shù)據(jù)庫的安全,但是在不確定的意外情況下,總是有可能造成數(shù)據(jù)的損失。

  • 例如,意外的停電,不小心的操作失誤等都可能造成數(shù)據(jù)的丟失。

所以為了保證數(shù)據(jù)的安全,我們需要定期對數(shù)據(jù)進行備份。如果數(shù)據(jù)庫中的數(shù)據(jù)出現(xiàn)了錯誤,就需要使用備份好的數(shù)據(jù)進行數(shù)據(jù)還原,這樣可以將損失降至最低。

MySQL 提供了多種方法對數(shù)據(jù)進行備份和恢復(fù)。

數(shù)據(jù)庫為什么需要備份

任何數(shù)據(jù)庫都需要備份,備份數(shù)據(jù)是維護數(shù)據(jù)庫必不可少的操作。

備份就是為了防止原數(shù)據(jù)丟失,保證數(shù)據(jù)的安全。當(dāng)數(shù)據(jù)庫因為某些原因造成部分或者全部數(shù)據(jù)丟失后,備份文件可以幫我們找回丟失的數(shù)據(jù)。

因此,數(shù)據(jù)備份是很重要的工作。

常見數(shù)據(jù)庫備份的應(yīng)用場景如下。

數(shù)據(jù)丟失應(yīng)用場景:

  • 人為操作失誤造成某些數(shù)據(jù)被誤操作
  • 軟件 BUG 造成部分數(shù)據(jù)或全部數(shù)據(jù)丟失
  • 硬件故障造成數(shù)據(jù)庫部分數(shù)據(jù)或全部數(shù)據(jù)丟失
  • 安全漏洞被入侵數(shù)據(jù)惡意破壞

非數(shù)據(jù)丟失應(yīng)用場景:

  • 特殊應(yīng)用場景下基于時間點的數(shù)據(jù)恢復(fù)
  • 開發(fā)測試環(huán)境數(shù)據(jù)庫搭建
  • 相同數(shù)據(jù)庫的新環(huán)境搭建
  • 數(shù)據(jù)庫或者數(shù)據(jù)遷移

以上列出的是一些數(shù)據(jù)庫備份常見的應(yīng)用場景,數(shù)據(jù)庫備份還有其它應(yīng)用場景,這里就不一一列舉了。

比如磁盤故障導(dǎo)致整個數(shù)據(jù)庫所有數(shù)據(jù)丟失,并且無法從已經(jīng)出現(xiàn)故障的硬盤上面恢復(fù)出來時,可以通過最近時間的整個數(shù)據(jù)庫的物理或邏輯備份數(shù)據(jù)文件,盡可能的將數(shù)據(jù)恢復(fù)到故障之前最近的時間點。

操作失誤造成數(shù)據(jù)被誤操作后,我們需要有一個能恢復(fù)到錯誤操作時間點之前的瞬間的備份文件存在,當(dāng)然這個備份可能是整個數(shù)據(jù)庫的備份,也可以僅僅只是被誤操作的表的備份。

MySQL備份類型

備份是以防萬一的一種必要手段,在出現(xiàn)硬件損壞或非人為的因素而導(dǎo)致數(shù)據(jù)丟失時,可以使用備份恢復(fù)數(shù)據(jù),以將損失降低到最小程度,因此備份是必須的。

備份可以分為以下幾個類型。根據(jù)備份的方法(是否需要數(shù)據(jù)庫離線)可以將備份分為:

  • 熱備(Hot Backup)
    • 熱備份可以在數(shù)據(jù)庫運行中直接備份,對正在運行的數(shù)據(jù)庫操作沒有任何的影響,數(shù)據(jù)庫的讀寫操作可以正常執(zhí)行。這種方式在 MySQL 官方手冊中稱為 Online Backup(在線備份)。
    • 按照備份后文件的內(nèi)容,熱備份又可以分為:
      • 邏輯備份:在 MySQL 數(shù)據(jù)庫中,邏輯備份是指備份出的文件內(nèi)容是可讀的,一般是文本內(nèi)容。內(nèi)容一般是由一條條 SQL 語句,或者是表內(nèi)實際數(shù)據(jù)組成。如 mysqldump 和 SELECT * INTO OUTFILE 的方法。這類方法的好處是可以觀察導(dǎo)出文件的內(nèi)容,一般適用于數(shù)據(jù)庫的升級、遷移等工作。但其缺點是恢復(fù)的時間較長。
      • 裸文件備份:裸文件備份是指復(fù)制數(shù)據(jù)庫的物理文件,既可以在數(shù)據(jù)庫運行中進行復(fù)制(如 ibbackup、xtrabackup 這類工具),也可以在數(shù)據(jù)庫停止運行時直接復(fù)制數(shù)據(jù)文件。這類備份的恢復(fù)時間往往比邏輯備份短很多。
    • 按照備份數(shù)據(jù)庫的內(nèi)容來分,備份又可以分為:
      • 完全備份:是指對數(shù)據(jù)庫進行一個完整的備份,即備份整個數(shù)據(jù)庫,如果數(shù)據(jù)較多會占用較大的時間和空間。
      • 部分備份:是指備份部分數(shù)據(jù)庫(例如,只備份一個表)。部分備份又分為:
        • 增量備份需要使用專業(yè)的備份工具。指的是在上次完全備份的基礎(chǔ)上,對更改的數(shù)據(jù)進行備份。也就是說每次備份只會備份自上次備份之后到備份時間之內(nèi)產(chǎn)生的數(shù)據(jù)。因此每次備份都比差異備份節(jié)約空間,但是恢復(fù)數(shù)據(jù)麻煩。
        • 差異備份指的是自上一次完全備份以來變化的數(shù)據(jù)。和增量備份相比,浪費空間,但恢復(fù)數(shù)據(jù)比增量備份簡單。
  • 冷備(Cold Backup)
    • 冷備份必須在數(shù)據(jù)庫停止的情況下進行備份,數(shù)據(jù)庫的讀寫操作不能執(zhí)行。這種備份最為簡單,一般只需要復(fù)制相關(guān)的數(shù)據(jù)庫物理文件即可。這種方式在 MySQL 官方手冊中稱為 Offline Backup(離線備份)。
  • 溫備(Warm Backup)
    • 溫備份同樣是在數(shù)據(jù)庫運行中進行的,但是會對當(dāng)前數(shù)據(jù)庫的操作有所影響,備份時僅支持讀操作,不支持寫操作。

MySQL 中進行不同方式的備份還要考慮存儲引擎是否支持,如 MyISAM 不支持熱備,支持溫備和冷備。而 InnoDB 支持熱備、溫備和冷備。

一般情況下,我們需要備份的數(shù)據(jù)分為以下幾種:

  • 表數(shù)據(jù)
  • 二進制日志、InnoDB 事務(wù)日志
  • 代碼(存儲過程、存儲函數(shù)、觸發(fā)器、事件調(diào)度器)
  • 服務(wù)器配置文件

下面是幾種常用的備份工具:

  • mysqldump:邏輯備份工具,適用于所有的存儲引擎,支持溫備、完全備份、部分備份、對于 InnoDB 存儲引擎支持熱備。
  • cp、tar 等歸檔復(fù)制工具:物理備份工具,適用于所有的存儲引擎、冷備、完全備份、部分備份。
  • lvm2 snapshot:借助文件系統(tǒng)管理工具進行備份。
  • mysqlhotcopy:名不副實的一個工具,僅支持 MyISAM 存儲引擎。
  • xtrabackup:一款由 percona 提供的非常強大的 InnoDB/XtraDB 熱備工具,支持完全備份、增量備份。

MySQL熱備份及恢復(fù)

熱備份是在數(shù)據(jù)庫處于運行狀態(tài)時直接備份,不影響現(xiàn)有業(yè)務(wù)的正常進行。熱備份又細分為邏輯備份和裸文件備份,

邏輯備份

邏輯備份的最大優(yōu)點就是對于各種存儲引擎,都可以用同樣的方法來備份。而冷備份則不同,不同的存儲引擎的備份方法也各不相同。因此,對于不同存儲引擎混合的數(shù)據(jù)庫,用邏輯備份會更簡單一些。

邏輯備份可以說是最簡單,也是目前中小型系統(tǒng)最常用的備份方法。邏輯備份主要有以下幾種方法:

mysqldump

mysqldump 是 MySQL 自帶的邏輯備份工具。它的備份原理是通過協(xié)議連接到 MySQL 數(shù)據(jù)庫,將需要備份的數(shù)據(jù)查詢出來,然后將查詢出的數(shù)據(jù)轉(zhuǎn)換成對應(yīng)的 INSERT 語句。當(dāng)我們需要還原恢復(fù)這些數(shù)據(jù)時,只要執(zhí)行這些 INSERT 語句,就能將對應(yīng)的數(shù)據(jù)還原。所以有的資料也將這種備份方式稱為 INSERT 備份。

恢復(fù)數(shù)據(jù)時可以使用 mysql -uroot -p <backup.sql 直接調(diào)用備份文件執(zhí)行所有命令,將數(shù)據(jù)完全恢復(fù)到備份時候的狀態(tài)。如果已經(jīng)連接上了 MySQL 服務(wù)器,那么可以通過 source /path/backup.sql 來進行恢復(fù)。

SELECT INTO…OUTFILE

SELECT INTO…OUTFILE 語句可以把表數(shù)據(jù)導(dǎo)出到一個文本文件中,且能將數(shù)據(jù)庫中的表數(shù)據(jù)以特定分隔符進行分隔后記錄在文本文件中,以達到邏輯備份的效果。

這種備份方式與 mysqldump 方法相比,使用的存儲空間更小,數(shù)據(jù)格式更加清晰明確,編輯方便。但是這種方法只能導(dǎo)出或?qū)霐?shù)據(jù)的內(nèi)容,不包括表的結(jié)構(gòu),如果表的結(jié)構(gòu)文件損壞,則必須先恢復(fù)原來的表的結(jié)構(gòu)。而且這種方法不能在同一個備份文件中存在多個表的備份數(shù)據(jù),增加了文件維護和恢復(fù)的成本。

這種備份方法恢復(fù)起來會稍微麻煩一點,需要一個表一個表通過相關(guān)命令來進行恢復(fù)。當(dāng)然如果是通過腳本來實現(xiàn)自動多表恢復(fù)也是比較方便的?;謴?fù)方法有 2 個,一個是通過 MySQL 的 LOAD DATA INFILE 命令來恢復(fù)數(shù)據(jù),另一種方法就是通過 MySQL 提供的使用工具 mysqlimport 來進行恢復(fù)。

mydumper

mydumper 是針對 MySQL 數(shù)據(jù)庫備份的一個輕量級第三方的開源工具,備份方式為邏輯備份。它支持多線程,備份速度遠高于原生態(tài)的 mysqldump 以及其它眾多優(yōu)異特性。與其配套的相應(yīng)恢復(fù)數(shù)據(jù)為 myloader 工具。DBA 稱 mydumper 和 myloader 為備份界的“小鋼炮”。

我們可以看出所謂的邏輯備份就是備份 SQL 語句,然后恢復(fù)數(shù)據(jù)時執(zhí)行備份 SQL,從而實現(xiàn)數(shù)據(jù)庫數(shù)據(jù)的重現(xiàn)。邏輯備份完成后所形成的文件都可以直接編輯。

邏輯備份的作用如下:

  • 通過邏輯備份,我們可以僅僅恢復(fù)備份中的部分數(shù)據(jù)而不需要全部恢復(fù)。不會影響不相關(guān)的數(shù)據(jù);
  • 通過全庫的邏輯備份,我們可以在新的 MySQL 環(huán)境下完全重建出一個與備份時完全一樣的數(shù)據(jù)庫,并且不受平臺類型限制;
  • 通過特定條件的邏輯備份,我們可以將某些特定數(shù)據(jù)輕松遷移(或者同步)到其它的 MySQL 或另外的數(shù)據(jù)庫環(huán)境。

裸文件備份

裸文件備份主要在底層復(fù)制數(shù)據(jù)文件,所以備份速度要比邏輯備份更快。

我們利用 Percona 公司發(fā)布的一個 XtraBackup 熱備份工具來完成裸文件備份,它是 Percona 公司的開源項目,據(jù)官方介紹它是世界上唯一 一款開源的能夠?qū)?InnoDB 和 XtraDB 數(shù)據(jù)庫進行熱備的工具。

它的優(yōu)點就是備份與恢復(fù)過程的速度很快,安全可靠,而且在備份過程中不會縮表,不影響現(xiàn)有業(yè)務(wù)。但它目前還是不能對表結(jié)構(gòu)文件和其它非事務(wù)類型的表進行備份。

MySQL冷備份及恢復(fù)

冷備份可以稱為 Offline Backup(離線備份)。這種備份最為簡單,一般只需要復(fù)制相關(guān)的數(shù)據(jù)庫物理文件到另外的位置即可。

由于 MySQL 服務(wù)器中的數(shù)據(jù)文件是基于磁盤的文本文件,所以最簡單、最直接的備份操作,就是將數(shù)據(jù)文件直接復(fù)制出來。但是由于 MySQL 服務(wù)器的數(shù)據(jù)文件在運行時期,總是處于打開和使用狀態(tài),因此備份文件不一定有效。為了解決該問題,在復(fù)制數(shù)據(jù)文件時,需要先停止 MySQL 服務(wù)器。

這樣做的好處是可以保證數(shù)據(jù)庫的完整性,備份過程簡單且恢復(fù)速度相對快一些,但是關(guān)閉數(shù)據(jù)庫會影響現(xiàn)有業(yè)務(wù)的進行。服務(wù)器停止運行期間,用戶不能再繼續(xù)訪問網(wǎng)站。例如,一些電商網(wǎng)站店慶促銷時,如果為了備份要停庫,那么帶來的代價損失將不可估量。所以冷備一般用于不是很重要、非核心的業(yè)務(wù)上面。

冷備份的優(yōu)點如下:

  • 備份簡單、快速,只要復(fù)制相關(guān)文件即可。
  • 備份文件易于在不同操作系統(tǒng),不同 MySQL 版本上進行恢復(fù)。
  • 恢復(fù)相當(dāng)簡單,只需要把文件恢復(fù)到指定位置即可。
  • 恢復(fù)速度快,不需要執(zhí)行任何 SQL 語句,也不需要重建索引。
  • 低度維護,高度安全。

冷備份的缺點如下:

  • 備份過程中,數(shù)據(jù)庫不能做其它的工作,且必須是關(guān)閉狀態(tài)。
  • InnoDB 存儲引擎冷備的文件通常比邏輯文件大很多,因為表空間存放著很多其它的數(shù)據(jù),如 undo 段,插入緩沖等信息。
  • 若磁盤空間有限,只能拷貝到磁帶等其它外部存儲設(shè)備上,速度會很慢。
  • 冷備也不總是可以輕易的跨平臺。操作系統(tǒng)、MySQL 的版本、文件大小寫敏感和浮點數(shù)格式都會成為問題。

數(shù)據(jù)庫的物理文件主要由數(shù)據(jù)庫的數(shù)據(jù)文件、日志文件以及配置文件等組成。MySQL 系統(tǒng)有一些共有的日志文件和系統(tǒng)表的數(shù)據(jù)文件。每種存儲引擎的物理文件也不一樣,

冷備的備份與恢復(fù)過程也很簡單。僅僅需要如下幾步:

  1. 為了保證所備份數(shù)據(jù)的完整性,在停止 MySQL 數(shù)據(jù)庫服務(wù)器之前,需要先執(zhí)行 FLUSH TABLES 語句將所有數(shù)據(jù)寫入到數(shù)據(jù)文件的文本文件里。
  2. 停掉 MySQL 服務(wù),命令(2種方式)如下:
    • mysqladmin -uroot -proot shutdown
    • NET START mysql
  3. 備份過程就是復(fù)制整個數(shù)據(jù)目錄到遠程備份機或者本地磁盤上,Linux 和 Windows 命令如下:
    • Scp -r /data/mysql/ root@遠程備份機ip:/新的目錄
    • Copy -r /data/mysql/ 本地新目錄
      • 備份到本次磁盤也可以手動復(fù)制上述相關(guān)目錄里的數(shù)據(jù)文件。
  4. 恢復(fù)過程就更簡單了,僅僅需要把已備份的數(shù)據(jù)目錄替換原有的目錄就可以了,最后重啟 MySQL 服務(wù)。
    • 恢復(fù)數(shù)據(jù)是數(shù)據(jù)庫維護中最常用的操作,利用備份文件可以將 MySQL 數(shù)據(jù)庫服務(wù)器恢復(fù)到備份時的狀態(tài),這樣就可以將管理員的非常操作和計算機的故障造成的相關(guān)損失降到最小。

需要注意的是,通過復(fù)制數(shù)據(jù)文件這種方式實現(xiàn)數(shù)據(jù)恢復(fù)時,必須保證兩個 MySQL 數(shù)據(jù)庫的主版本號一致。只有兩個 MySQL 數(shù)據(jù)庫主版本號相同時,才能保證它們的數(shù)據(jù)文件類型是相同的。

MySQL冷備份所需物理文件

MyISAM存儲引擎

MyISAM 存儲引擎的所有數(shù)據(jù)默認存放在 C:/ProgramData/MySQL/MySQL Server 5.7/Data 路徑下,即配置文件(my.ini或my.cnf)中 datadir 參數(shù)的值。

實際上不管我們使用的是 MyISAM 存儲引擎還是其他存儲引擎,每一個數(shù)據(jù)庫都會在“datadir”目錄下有一個文件夾(包括系統(tǒng)信息的數(shù)據(jù)庫 mysql 也是一樣)。

在各個數(shù)據(jù)庫中每一個 MyISAM 存儲引擎的表都會有 3 個文件存在,即記錄表結(jié)構(gòu)元數(shù)據(jù)的“.frm”文件,存儲表數(shù)據(jù)的“.MYD”文件,存儲索引數(shù)據(jù)的“.MYI”文件。

MyISAM 屬于非事務(wù)性存儲引擎,它沒有自己的日志文件。所以 MyISAM 存儲引擎的物理備份除了需要備份 MySQL 系統(tǒng)共有的物理文件之外,還需要備份上面的 3 種文件。

Innodb 存儲引擎

Innodb 存儲引擎屬于事務(wù)性存儲引擎,存放數(shù)據(jù)的位置也可能與 MyISAM 存儲引擎有所不同,這主要取決于 Innodb 的相關(guān)配置。

指定 Innodb 存放數(shù)據(jù)和日志文件的位置參數(shù)為 innodb_data_home_dir、innodb_data_file_path 和 innodb_log_group_home_dir。以及決定 Innodb 的表空間存儲方式參數(shù) innodb_file_per_table,它決定 Innodb 是以共享表空間存放數(shù)據(jù)還是以獨享表空間方式存儲數(shù)據(jù)。

如果使用的是共享表空間的存儲方式,那么需要備份 innodb_data_home_dir 和 innodb_data_file_path 參數(shù)設(shè)定的所有數(shù)據(jù)文件,以及 datadir 中相應(yīng)數(shù)據(jù)庫目錄下的所有 Innodb 存儲引擎表的 .frm 文件。

而如果使用的是獨享表空間,那么除了需要備份上面共享表空間方式所需要備份的所有文件之外,我們還需要備份 datadir 中相應(yīng)數(shù)據(jù)庫目錄下的所有 .idb 文件,該文件中存放的才是獨享表空間方式下 Innodb 存儲引擎表的數(shù)據(jù)。

那么既然是使用獨享表空間,為什么還要備份共享表空間“才使用到”的數(shù)據(jù)文件呢?其實這是很多人的一個共性誤區(qū),以為使用獨享表空間的時候 Innodb 的所有信息就都存放在“datadir”所設(shè)定數(shù)據(jù)庫目錄下的“.ibd”文件中。實際上并不是這樣的,“.ibd”文件中所存放的僅僅只是我們的表數(shù)據(jù)而已。

大家都很清楚,Innodb 是事務(wù)性存儲引擎,它需要 undo 和 redo 信息,而不管 Innodb 使用的是共享還是獨享表空間的方式來存儲數(shù)據(jù)。與事務(wù)相關(guān)的 undo 信息以及其他的一些元數(shù)據(jù)信息,都是存放在 innodb_data_home_dir 和 innodb_data_file_path 這兩個參數(shù)所設(shè)定的數(shù)據(jù)文件中的。所以要想 Innodb 的物理備份有效,就必須備份 innodb_data_home_dir 和 innodb_data_file_path 參數(shù)所設(shè)定的數(shù)據(jù)文件。

此外,除了上面所說的數(shù)據(jù)文件之外,Innodb 還有存放自己的 redo 信息和相關(guān)事務(wù)信息的日志文件在 innodb_log_group_home_dir 參數(shù)所設(shè)定的位置。所以要想 Innodb 物理備份能夠有效使用,我們還必須要備份 innodb_log_group_home_dir 參數(shù)所設(shè)定的位置的所有日志文件。

MySQL數(shù)據(jù)庫遷移

數(shù)據(jù)庫遷移就是把數(shù)據(jù)從一個系統(tǒng)移動到另一個系統(tǒng)上,遷移過程其實就是在源數(shù)據(jù)庫備份和目標(biāo)數(shù)據(jù)庫恢復(fù)的過程組合。遷移的原因是多種多樣的,比如:

  • 需要安裝新的數(shù)據(jù)庫服務(wù)器
  • MySQL 版本更新
  • 數(shù)據(jù)庫管理系統(tǒng)的變更(如從 SQL Server 遷移到 MySQL)

根據(jù)實際操作等情況,可以將數(shù)據(jù)庫遷移操作分成以下 3 種形式。

  • 相同版本 MySQL 數(shù)據(jù)庫之間的遷移。
  • 不同版本 MySQL 數(shù)據(jù)庫之間的遷移。
  • 不同數(shù)據(jù)庫間的遷移。

相同版本的遷移

相同版本的 MySQL 數(shù)據(jù)庫是指主版本號一致的數(shù)據(jù)庫。主版本號一致的數(shù)據(jù)庫遷移最容易實現(xiàn)。由于遷移前后 MySQL 數(shù)據(jù)庫的主版本號相同,所以可以通過復(fù)制數(shù)據(jù)庫目錄來實現(xiàn)數(shù)據(jù)庫遷移。

最安全和最常用的方式是通過使用 mysqldump 命令進行數(shù)據(jù)庫備份,然后使用 mysql 命令將備份文件還原到新的 MySQL 數(shù)據(jù)庫。遷移時的備份和還原操作可以同時執(zhí)行。

假設(shè)從一個名為 hostname1 的機器中備份出所有數(shù)據(jù)庫,然后將這些數(shù)據(jù)庫遷移到名為 hostname2 的機器上,具體語法形式如下:

mysqldump -h hostname1 -u root -password=password1 -all-databases
|
mysql -h hostname2 -u root -password=password2

其中:

  • 符號“|”用來實現(xiàn)將命令 mysqldump 備份的文件送給 mysql 命令;
  • password1 為 hostname1 主機上 root 用戶的密碼;
  • password2 為 hostname2 主機上 root 用戶的密碼;
  • -all-databases 表示遷移全部的數(shù)據(jù)庫,可省略。

不用版本的遷移

不同版本的 MySQL 數(shù)據(jù)庫之間的數(shù)據(jù)遷移通常是 MySQL 升級的原因。例如,服務(wù)器使用 4.0 版本的 MySQL 數(shù)據(jù)庫,現(xiàn)在要升級為 5.7 版本的。這樣就需要不同版本的 MySQL 數(shù)據(jù)庫之間進行數(shù)據(jù)遷移。

不同版本下的數(shù)據(jù)庫遷移,分為 2 種方式:

  • 低版本數(shù)據(jù)庫向高版本數(shù)據(jù)庫進行遷移
  • 高版本數(shù)據(jù)庫向低版本數(shù)據(jù)庫進行遷移

低版本數(shù)據(jù)庫向高版本數(shù)據(jù)庫進行遷移時,由于高版本會兼容低版本,所以該種方式也是最容易實現(xiàn)的操作。對于存儲類型為 MyISAM 的表,最安全和最常用的操作是直接復(fù)制數(shù)據(jù)文件。對于存儲類型為 InnoDB 的表,最安全和最常用的操作是執(zhí)行 mysqldump 命令進行備份和執(zhí)行 mysql 命令還原恢復(fù)數(shù)據(jù)。

但是高版本數(shù)據(jù)庫向低版本數(shù)據(jù)庫進行遷移時,因為高版本數(shù)據(jù)庫可能有一些新的特性,這些特性是低版本數(shù)據(jù)庫所不具有的,所以數(shù)據(jù)庫遷移時要特別小心,最好使用 mysqldump 命令來進行備份,避免遷移時造成數(shù)據(jù)丟失。

不同數(shù)據(jù)庫的遷移

不同數(shù)據(jù)庫之間的遷移是指從其它類型的數(shù)據(jù)庫遷移到 MySQL 數(shù)據(jù)庫,或者從 MySQL 數(shù)據(jù)庫遷移到其他類型的數(shù)據(jù)庫。例如,某個網(wǎng)站原來使用 Oracle 數(shù)據(jù)庫,因為運營成本太高等諸多原因,希望改用 MySQL 數(shù)據(jù)庫?;蛘?,某個管理系統(tǒng)原來使用 MySQL 數(shù)據(jù)庫,因為某種特殊性能的要求,希望改用 Oracle 數(shù)據(jù)庫。這樣的不同數(shù)據(jù)庫之間的遷移也經(jīng)常會發(fā)生。但是這種遷移沒有普通適用的解決辦法。

其它數(shù)據(jù)庫也有類似 mysqldump 這樣的備份工具,可以將數(shù)據(jù)庫中的文件備份成 sql 文件或普通文本。但是,不同的數(shù)據(jù)庫廠商并沒有完全按照 SQL 標(biāo)準(zhǔn)來設(shè)計數(shù)據(jù)庫,這就造成了不同數(shù)據(jù)庫使用的 SQL 語句的差異。例如,微軟的 SQL Server 軟件使用的是 T-SQL 語言。T-SQL 中包含了非標(biāo)準(zhǔn)的 SQL 語句。這就造成了 SQL Server 和 MySQL 的 SQL 語句不能兼容。

除了 SQL 語句存在不兼容的情況外,不同的數(shù)據(jù)庫之間的數(shù)據(jù)類型也有差異。例如,MySQL 不支持 SQL Server 中的 ntext、 Image 等數(shù)據(jù)類型。同樣,SQL Server 也不支持 MySQL 中的 ENUM 和 SET 等數(shù)據(jù)類型。數(shù)據(jù)類型的差異也造成了遷移的困難。

從某種意義上說,這種差異是商業(yè)數(shù)據(jù)庫公司故意造成的壁壘,這種行為是阻礙數(shù)據(jù)庫市場健康發(fā)展的。

但是不同數(shù)據(jù)庫服務(wù)器間的遷移并不是完全不可能。在 Windows 操作系統(tǒng)下,如果要實現(xiàn)從 MySQL 數(shù)據(jù)庫服務(wù)器向 SQL SERVER 數(shù)據(jù)庫服務(wù)器遷移,可以通過 MyODBC 來實現(xiàn);如果要實現(xiàn)從 MySQL 數(shù)據(jù)庫服務(wù)器向 ORACLE 數(shù)據(jù)庫服務(wù)器遷移,可以先通過執(zhí)行 mysqldump 命令導(dǎo)出 sql 文件,然后手動修改 sql 文件中的 CREATE 語句。

MySQL mysqldump備份數(shù)據(jù)庫

數(shù)據(jù)庫的主要作用就是對數(shù)據(jù)進行保存和維護,所以備份數(shù)據(jù)是數(shù)據(jù)庫管理中最常用的操作。為了防止數(shù)據(jù)庫意外崩潰或硬件損傷而導(dǎo)致的數(shù)據(jù)丟失,數(shù)據(jù)庫系統(tǒng)提供了備份和恢復(fù)策略。

保證數(shù)據(jù)安全的最重要的一個措施就是定期的對數(shù)據(jù)庫進行備份。這樣即使發(fā)生了意外,也會把損失降到最低。

數(shù)據(jù)庫備份是指通過導(dǎo)出數(shù)據(jù)或者復(fù)制表文件的方式來制作數(shù)據(jù)庫的副本。當(dāng)數(shù)據(jù)庫出現(xiàn)故障或遭到破壞時,將備份的數(shù)據(jù)庫加載到系統(tǒng),從而使數(shù)據(jù)庫從錯誤狀態(tài)恢復(fù)到備份時的正確狀態(tài)。

MySQL 中提供了兩種備份方式,即 mysqldump 命令以及 mysqlhotcopy 腳本。由于 mysqlhotcopy 只能用于 MyISAM 表,所以 MySQL 5.7 移除了 mysqlhotcopy 腳本。

mysqldump 命令執(zhí)行時,可以將數(shù)據(jù)庫中的數(shù)據(jù)備份成一個文本文件。數(shù)據(jù)表的結(jié)構(gòu)和數(shù)據(jù)將存儲在生成的文本文件中。

備份一個數(shù)據(jù)庫

使用 mysqldump 命令備份一個數(shù)據(jù)庫的語法格式如下:

mysqldump -u username -p dbname [tbname ...]> filename.sql

對上述語法參數(shù)說明如下:

  • username:表示用戶名稱;
  • dbname:表示需要備份的數(shù)據(jù)庫名稱;
  • tbname:表示數(shù)據(jù)庫中需要備份的數(shù)據(jù)表,可以指定多個數(shù)據(jù)表。省略該參數(shù)時,會備份整個數(shù)據(jù)庫;
  • 右箭頭“>”:用來告訴 mysqldump 將備份數(shù)據(jù)表的定義和數(shù)據(jù)寫入備份文件;
  • filename.sql:表示備份文件的名稱,文件名前面可以加絕對路徑。通常將數(shù)據(jù)庫備份成一個后綴名為.sql的文件。

注意:mysqldump 命令備份的文件并非一定要求后綴名為.sql,備份成其他格式的文件也是可以的。例如,后綴名為.txt的文件。通常情況下,建議備份成后綴名為.sql 的文件。因為,后綴名為.sql的文件給人第一感覺就是與數(shù)據(jù)庫有關(guān)的文件。

備份多個數(shù)據(jù)庫

如果要使用 mysqldump 命令備份多個數(shù)據(jù)庫,需要使用 --databases 參數(shù)。備份多個數(shù)據(jù)庫的語法格式如下:

mysqldump -u username -P --databases dbname1 dbname2 ... > filename.sql

加上“--databases”參數(shù)后,必須指定至少一個數(shù)據(jù)庫名稱,多個數(shù)據(jù)庫名稱之間用空格隔開。

備份所有數(shù)據(jù)庫

mysqldump 命令備份所有數(shù)據(jù)庫的語法格式如下:

mysqldump -u username -P --all-databases>filename.sql

使用“--all-databases”參數(shù)時,不需要指定數(shù)據(jù)庫名稱。

MySQL恢復(fù)數(shù)據(jù)庫

當(dāng)數(shù)據(jù)丟失或意外損壞時,可以通過恢復(fù)已經(jīng)備份的數(shù)據(jù)來盡量減少數(shù)據(jù)的丟失和破壞造成的損失。

在 MySQL 中,可以使用 mysql 命令來恢復(fù)備份的數(shù)據(jù)。mysql 命令可以執(zhí)行備份文件中的 CREATE 語句和 INSERT 語句,也就是說,mysql 命令可以通過 CREATE 語句來創(chuàng)建數(shù)據(jù)庫和表,通過 INSERT 語句來插入備份的數(shù)據(jù)。

mysql 命令語法格式如下:

mysql -u username -P [dbname] < filename.sql

其中:

  • username 表示用戶名稱;
  • dbname 表示數(shù)據(jù)庫名稱,該參數(shù)是可選參數(shù)。如果 filename.sql 文件為 mysqldump 命令創(chuàng)建的包含創(chuàng)建數(shù)據(jù)庫語句的文件,則執(zhí)行時不需要指定數(shù)據(jù)庫名。如果指定的數(shù)據(jù)庫名不存在將會報錯;
  • filename.sql 表示備份文件的名稱。

注意:mysql 命令和 mysqldump 命令一樣,都直接在命令行(cmd)窗口下執(zhí)行。

注意:如果使用--all-databases參數(shù)備份了所有的數(shù)據(jù)庫,那么恢復(fù)時不需要指定數(shù)據(jù)庫。因為,其對應(yīng)的 sql 文件中含有 CREATE DATABASE 語句,可以通過該語句創(chuàng)建數(shù)據(jù)庫。創(chuàng)建數(shù)據(jù)庫之后,可以執(zhí)行 sql 文件中的 USE 語句選擇數(shù)據(jù)庫,然后在數(shù)據(jù)庫中創(chuàng)建表并且插入記錄。

MySQL導(dǎo)出表數(shù)據(jù)

通過對數(shù)據(jù)表的導(dǎo)入導(dǎo)出,可以實現(xiàn) MySQL 數(shù)據(jù)庫服務(wù)器與其它數(shù)據(jù)庫服務(wù)器間移動數(shù)據(jù)。導(dǎo)出是指將 MySQL 數(shù)據(jù)表的數(shù)據(jù)復(fù)制到文本文件。數(shù)據(jù)導(dǎo)出的方式有多種,本節(jié)主要介紹使用 SELECTI...INTO OUTFILE 語句導(dǎo)出數(shù)據(jù)。

在 MySQL 中,可以使用 SELECTI...INTO OUTFILE 語句將表的內(nèi)容導(dǎo)出成一個文本文件。SELECT...INTO OUTFILE 語句基本格式如下:

SELECT 列名 FROM table [WHERE 語句] INTO OUTFILE '目標(biāo)文件'[OPTIONS]

該語句用 SELECT 來查詢所需要的數(shù)據(jù),用 INTO OUTFILE 來導(dǎo)出數(shù)據(jù)。其中,目標(biāo)文件用來指定將查詢的記錄導(dǎo)出到哪個文件。這里需要注意的是,目標(biāo)文件不能是一個已經(jīng)存在的文件。

[OPTIONS] 為可選參數(shù)選項,OPTIONS 部分的語法包括 FIELDS 和 LINES 子句,其常用的取值有:

  • FIELDS TERMINATED BY '字符串':設(shè)置字符串為字段之間的分隔符,可以為單個或多個字符,默認情況下為制表符‘\t’。
  • FIELDS [OPTIONALLY] ENCLOSED BY '字符':設(shè)置字符來括上 CHAR、VARCHAR 和 TEXT 等字符型字段。如果使用了 OPTIONALLY 則只能用來括上 CHAR 和 VARCHAR 等字符型字段。
  • FIELDS ESCAPED BY '字符':設(shè)置如何寫入或讀取特殊字符,只能為單個字符,即設(shè)置轉(zhuǎn)義字符,默認值為‘\’。
  • LINES STARTING BY '字符串':設(shè)置每行開頭的字符,可以為單個或多個字符,默認情況下不使用任何字符。
  • LINES TERMINATED BY '字符串':設(shè)置每行結(jié)尾的字符,可以為單個或多個字符,默認值為‘\n’ 。

注意:FIELDS 和 LINES 兩個子句都是自選的,但是如果兩個都被指定了,F(xiàn)IELDS 必須位于 LINES的前面。

注意:導(dǎo)出時可能會出現(xiàn)下面的錯誤:

The MySQL server is running with the --secure-file-priv option so it cannot execute this statement

這是因為MySQL 限制了數(shù)據(jù)的導(dǎo)出路徑。MySQL 導(dǎo)入導(dǎo)出文件只能在 secure-file-priv 變量的指定路徑下的文件才可以導(dǎo)入導(dǎo)出。

有以下 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 導(dǎo)入導(dǎo)出文件的路徑。將 SQL 語句中的導(dǎo)出文件路徑修改為該變量的指定路徑,再執(zhí)行導(dǎo)入導(dǎo)出操作即可。也可以在 my.ini 配置文件中修改 secure-file-priv 的值,然后重啟服務(wù)即可。

如果 secure_file_priv 值為 NULL,則為禁止導(dǎo)出,可以在 MySQL 安裝路徑下的 my.ini 文件中添加secure_file_priv=設(shè)置路徑語句,然后重啟服務(wù)即可。

使用 SELECT...INTO OUTFILE 語句將 test 數(shù)據(jù)庫中的 person 表中的記錄導(dǎo)出到文本文件,使用 FIELDS 選項和 LINES 選項,要求字段之間用隔開,字符型數(shù)據(jù)用雙引號括起來。每條記錄以-開頭。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' 表示每行以回車換行符結(jié)尾,保證每一條記錄占一行。

person.txt 文件內(nèi)容如下:

-1、"Java"、12
-2、"MySQL"、13
-3、"C"、15
-4、"C++"、22
-5、"Python"、18

可以看到,每條記錄都以-開頭,每個數(shù)據(jù)之間以都以、隔開,所有的字段值都被雙引號包括。

MySQL數(shù)據(jù)庫恢復(fù)

數(shù)據(jù)庫恢復(fù)是指以備份為基礎(chǔ),與備份相對應(yīng)的系統(tǒng)維護和管理操作。

系統(tǒng)進行恢復(fù)操作時,先執(zhí)行一些系統(tǒng)安全性的檢查,包括檢查所要恢復(fù)的數(shù)據(jù)庫是否存在、數(shù)據(jù)庫是否變化及數(shù)據(jù)庫文件是否兼容等,然后根據(jù)所采用的數(shù)據(jù)庫備份類型采取相應(yīng)的恢復(fù)措施。

數(shù)據(jù)庫恢復(fù)機制設(shè)計的兩個關(guān)鍵問題是:

  • 第一,如何建立冗余數(shù)據(jù);
  • 第二,如何利用這些冗余數(shù)據(jù)實施數(shù)據(jù)庫恢復(fù)。

建立冗余數(shù)據(jù)最常用的技術(shù)是數(shù)據(jù)轉(zhuǎn)儲和登錄日志文件。通常在一個數(shù)據(jù)庫系統(tǒng)中,這兩種方法是一起使用的。

數(shù)據(jù)轉(zhuǎn)儲是 DBA 定期地將整個數(shù)據(jù)庫復(fù)制到磁帶或另一個磁盤上保存起來的過程。這些備用的版本成為后備副本或后援副本。

可使用 LOAD DATA…INFILE 語句來恢復(fù)先前備份的數(shù)據(jù)。

例子:將之前導(dǎo)出的數(shù)據(jù)備份文件 file.txt 導(dǎo)入數(shù)據(jù)庫 test_db 的表 tb_students_copy 中,其中 tb_students_copy 的表結(jié)構(gòu)和 tb_students_info 相同。

首先創(chuàng)建表 tb_students_copy,輸入的 SQL 語句和執(zhí)行結(jié)果如下所示。

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)

導(dǎo)入數(shù)據(jù)與查詢表 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)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容