MySQL優化之——備份和恢復

轉載請註明出處:http://blog.csdn.net/l1028386804/article/details/46766919

備份html

邏輯備份方法mysql

使用MYSQLDUMP命令備份sql

MYSQLDUMP是MYSQL提供的一個很實用的數據庫備份工具。mysqldump命令運行時將數據庫備份成一個文本文件,該文件裏實際上包括了多個CREATE 和INSERT語句,使用這些語句可以又一次建立表和插入數據數據庫

MYSQLDUMP的語法和選項express

mysqldump -u user -p pwd -h host dbname[tbname,[tbname...]]>filename.sql

選項/Option 做用/Action Performed
--add-drop-table
這個選項將會在每一個表的前面加上DROP TABLE IF EXISTS語句,這樣可以保證導回MySQL數據庫的時候不會出錯。因爲每次導回的時候。都會首先檢查表是否存在,存在就刪除
--add-locks
這個選項會在INSERT語句中捆上一個LOCK TABLE和UNLOCK TABLE語句。

這就防止在這些記錄被再次導入數據庫時其它用戶對錶進行的操做 -c or - complete_insert 這個選項使得mysqldump命令給每一個產生INSERT語句加上列(field)的名字。當把數據導出導另一個數據庫時這個選項很是實用。 --delayed-insert 在INSERT命令中增長DELAY選項 -F or -flush-logs 使用這個選項,在運行導出以前將會刷新MySQLserver的log. -f or -force 使用這個選項,即便有發生錯誤。仍然繼續導出 --full 這個選項把附加信息也加到CREATE TABLE的語句中 -l or -lock-tables 使用這個選項,導出表的時候server將會給表加鎖。架構

-t or -no-create- info 這個選項使的mysqldump命令不建立CREATE TABLE語句,這個選項在您僅僅需要數據而不需要DDL(數據庫定義語句)時很是方便。 -d or -no-data 這個選項使的mysqldump命令不建立INSERT語句。 在您僅僅需要DDL語句時,可以使用這個選項。 --opt 此選項將打開所有會提升文件導出速度和創造一個可以更快導入的文件的選項。 -q or -quick 這個選項使得MySQL不會把整個導出的內容讀入內存再運行導出。而是在讀到的時候就寫入導文件裏。 -T path or -tab = path 這個選項將會建立兩個文件,一個文件包括DDL語句或者表建立語句。還有一個文件包括數據。DDL文件被命名爲table_name.sql,數據文件被命名爲table_name.txt.路徑名是存放這兩個文件的文件夾。文件夾必須已經存在,並且命令的使用者有對文件的特權。oracle

-w "WHERE Clause" or -where = "Where clause " 如前面所講的,您可以使用這一選項來過篩選將要放到 導出文件的數據。 假定您需要爲一個表單中要用到的賬號創建一個文件。經理要看今年(2004年)所有的訂單(Orders)。它們並不正確DDL感興趣,並且需要文件有逗號分隔,因爲這樣就很是easy導入到Excel中。socket

爲了完畢這個任務,您可以使用如下的句子: bin/mysqldump –p –where "Order_Date >='2000-01-01'" –tab = /home/mark –no-create-info –fields-terminated-by=, Meet_A_Geek Orders 這將會獲得您想要的結果。工具

schema:模式 The set of statements, expressed in data definition language, that completely describe the structure of a data base. 一組以數據定義語言來表達的語句集,該語句集完整地描寫敘述了數據庫的結構。 SELECT INTO OUTFILE :sqlserver

mysqldump提供了很是多選項。包含調試和壓縮的,在這裏僅僅是列舉最實用的。

執行幫助命令mysqldump --help可以得到特定版本號的完整選項列表

user表示username稱。

host表示登陸用戶的主機名稱。

pwd爲登陸password;

dbname爲需要備份的數據庫名稱。

tbname爲dbname數據庫中需要備份的數據表,可以指定多個需要備份的表;

右箭頭「>」告訴mysqldump將備份數據庫表定義和數據寫入備份文件;

filename爲備份文件的名稱


一、使用mysqldump備份單個數據庫中的所有表

數據庫的記錄是這種

打開cmd,而後運行如下的命令

 

可以看到C盤如下已經生成了school_2014-7-10.sql文件

使用editplus來打開這個sql文件

-- MySQL dump 10.13  Distrib 5.5.20, for Win32 (x86)
--
-- Host: 127.0.0.1    Database: school
-- ------------------------------------------------------
-- Server version    5.5.20-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `book`
--

DROP TABLE IF EXISTS `book`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `book` (
  `bookid` int(11) NOT NULL,
  `bookname` varchar(255) NOT NULL,
  `authors` varchar(255) NOT NULL,
  `info` varchar(255) DEFAULT NULL,
  `comment` varchar(255) DEFAULT NULL,
  `year_publication` year(4) NOT NULL,
  KEY `BkNameIdx` (`bookname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `book`
--

LOCK TABLES `book` WRITE;
/*!40000 ALTER TABLE `book` DISABLE KEYS */;
INSERT INTO `book` VALUES (1,'鍓戝湥','灝忔槑','13','hao',2013);
/*!40000 ALTER TABLE `book` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `student`
--

DROP TABLE IF EXISTS `student`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `student` (
  `stuno` int(11) DEFAULT NULL,
  `stuname` varchar(60) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `student`
--

LOCK TABLES `student` WRITE;
/*!40000 ALTER TABLE `student` DISABLE KEYS */;
INSERT INTO `student` VALUES (2,'xiaofang'),(3,'zhanghai'),(6,'haojie');
/*!40000 ALTER TABLE `student` ENABLE KEYS */;
UNLOCK TABLES;

--
-- Table structure for table `stuinfo`
--

DROP TABLE IF EXISTS `stuinfo`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `stuinfo` (
  `stuno` int(11) DEFAULT NULL,
  `class` varchar(60) DEFAULT NULL,
  `city` varchar(60) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `stuinfo`
--

LOCK TABLES `stuinfo` WRITE;
/*!40000 ALTER TABLE `stuinfo` DISABLE KEYS */;
INSERT INTO `stuinfo` VALUES (1,'wuban','henan'),(2,'liuban','hebei'),(3,'qiban','shandong');
/*!40000 ALTER TABLE `stuinfo` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2014-07-23 22:04:16

可以看到。備份文件包括了一些信息。文件開頭首先寫明瞭mysqldump工具的版本。

而後是主機信息。以及備份的數據庫名稱,最後是mysqlserver的版本5.5.20

備份文件接下來的部分是一些SET語句,這些語句將一些系統變量賦值給用戶定義變量,以確保被恢復的數據庫的系統變量和原來

備份時的變量一樣

好比:

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;

該set語句將當前系統變量character_set_client的值賦值給用戶變量@OLD_CHARACTER_SET_CLIENT

備份文件的最後幾行mysql使用set語句恢復server系統變量原來的值。好比:

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

該語句將用戶定義變量@OLD_CHARACTER_SET_CLIENT 中保存的值賦值給實際的系統變量OLD_CHARACTER_SET_CLIENT 

備份文件裏的「--」字符開頭的行爲凝視語句。以「/*!」開頭、以「*/」結尾的語句爲可運行的mysql凝視,這些語句可以被mysql運行

但在其它數據庫管理系統將被做爲凝視忽略,這可以提升數據庫的可移植性

另外注意到,備份文件開始的一些語句以數字開頭,這些數字表明瞭mysql版本號號,該數字告訴咱們這些語句僅僅有在指定的mysql版本號

或者比該版本號高的狀況下才幹運行。

好比:40101,代表這些語句僅僅有在mysql版本號爲4.01.01或者更高版本號的條件下才幹夠運行


二、使用mysqldump備份數據庫中的某個表

備份school數據庫裏面的book表

 

-- MySQL dump 10.13  Distrib 5.5.20, for Win32 (x86)
--
-- Host: 127.0.0.1    Database: school
-- ------------------------------------------------------
-- Server version    5.5.20-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `book`
--

DROP TABLE IF EXISTS `book`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `book` (
  `bookid` int(11) NOT NULL,
  `bookname` varchar(255) NOT NULL,
  `authors` varchar(255) NOT NULL,
  `info` varchar(255) DEFAULT NULL,
  `comment` varchar(255) DEFAULT NULL,
  `year_publication` year(4) NOT NULL,
  KEY `BkNameIdx` (`bookname`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping data for table `book`
--

LOCK TABLES `book` WRITE;
/*!40000 ALTER TABLE `book` DISABLE KEYS */;
INSERT INTO `book` VALUES (1,'劍聖','小明','13','hao',2013);
/*!40000 ALTER TABLE `book` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2014-07-23 22:24:29

備份文件裏的內容跟前面的介紹是同樣的。惟一不一樣的是僅僅包括了book表的CREATE語句和INSERT語句


三、使用mysqldump備份多個數據庫

假設要使用mysqldump備份多個數據庫。需要使用--databases參數。

使用--databases參數以後,必須指定至少一個數據庫的名稱。多個數據庫名稱之間用空格隔開

使用mysqldump備份school庫和test庫

 備份文件中的內容,基本上跟第一個樣例同樣。但是指明瞭裏面的內容那一部分屬於test庫。哪一部分屬於school庫

 

四、使用--all-databases參數備份系統中所有的數據庫

使用--all-databases不需要指定數據庫名稱

運行完成以後會產生all_2014-7-10.sql的備份文件。裏面會包括了所有數據庫的備份信息

提示:假設在server上進行備份。並且表均爲myisam。應考慮使用mysqlhotcopy

因爲可以更快地進行備份和恢復

使用mysqlhotcopy,假設是Windows操做系統,需要先安裝perl腳本組件才幹使用,因爲mysqlhotcopy是使用perl來編寫的

提示

(1)假設你未使用--quick或者--opt選項,那麼 mysqldump將在轉儲結果以前把全部內容加載到 內存中。這在你轉儲大數據量的數據庫時將會有些問題。該選項默認是打開的,但可以使用--skip-opt來關閉它。
(2)使用--skip-comments可以去掉導出文件裏的凝視語句
(3)使用--compact選項可以僅僅輸出最重要的語句,而不輸出凝視及刪除表語句等等
(4)使用--database或-B選項,可以轉儲多個數據庫,在這個選項名後的參數都被認定爲數據庫名

SQLSERVER邏輯備份

我發現SQLSERVER的備份概念並無ORACLE和MYSQL那麼多

咱們一般都會使用如下的兩個SQL語句來備份SQLSERVER數據庫。好比備份test庫

BACKUP DATABASE test TO DISK='c:\test.bak' 
BACKUP LOG test  TO DISK='c:\test_log.bak' 

第一個SQL是完整備份test庫。假設加上WITH DIFFERENTIAL就是差別備份

第二個SQL是備份test庫的日誌

實際上從我眼中的理解,SQLSERVER就是將數據文件和必要的日誌信息放入一個壓縮包裏面,相似於MYSQL的物理備份。直接拷貝文件,僅僅是MYSQL並無進行打包壓縮

SQLSERVER的邏輯備份

邏輯備份就是生成表定義腳本和數據插入腳本。SQLSERVER2008開始支持生成數據腳本。在SQLSERVER2008以前僅僅支持生成表定義腳本

我所用的數據庫是SQLSERVER2012 SP1

選中需要生成腳本的數據庫

比方我要導出test表的數據和表定義

要選擇架構和數據,並且要選擇索引,這樣就會生成表的數據、定義、索引

生成的腳本例如如下

USE [sss]
GO
/****** Object:  Table [dbo].[test]    Script Date: 2014/7/24 11:27:44 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[test](
    [a] [int] NULL
) ON [PRIMARY]

GO
INSERT [dbo].[test] ([a]) VALUES (10)
GO

由於test表是沒有不論什麼索引的。因此腳本里看不到CREATE INDEX語句

實際上各類數據庫的備份恢復方法都是大同小異的

ORACLE冷備份與恢復

邏輯備份和物理備份

一、導出create table 、create index、insert into 表等語句(邏輯備份)

mysql:mysqldump、load data infile、select into outfile

sqlserver:生成腳本、導入導出嚮導

oracle:(exp/imp)

二、直接拷貝文件(物理備份)

sqlserver:backup database語句、backup log語句、停SQLSERVER服務直接拷貝數據文件

mysql:mysqlhotcopy、innobackupex

oracle:rman、直接將關鍵性文件複製到另外的位置、(exp/imp)、(expdp/impdp)

類似點:上面的各類數據庫的各類備份還原方法,每一種基本上都會有一個單獨的工具來作

好比sqlserver導入導出嚮導就是一個單獨的exe來作

oracle的rman也是一個單獨的工具

冷備份和熱備份:無論oracle、sqlserver、mysql都有冷備份和熱備份的概念

冷備份事實上可以簡單理解爲:中止服務進行備份

熱備份事實上可以簡單理解爲:不中止服務進行備份(在線)

上面的中止服務,正確的來說應該是中止數據庫的寫入

爲何mysql的myisam引擎僅僅支持冷備份呢?

你們可以先想一下innodb引擎。innodb引擎是事務性存儲引擎。每一條語句都會寫日誌,並且每一條語句在日誌裏面都有時間點

那麼在備份的時候,mysql可以依據這個日誌來進行redo和undo,將備份的時候沒有提交的事務進行回滾,已經提交了的進行重作

但是myisam不行,myisam是沒有日誌的。爲了保證一致性。僅僅能停機或者鎖表進行備份

在書《MYSQL性能調優和架構設計》裏面說到了事務的做用

 你們可以想想。爲何sqlserver支持從某一個lsn或者時刻進行恢復數據庫,他也是從日誌裏面讀取日誌的lsn號來進行恢復到某一個lsn時刻的數據或者某一個時刻的數據

假如沒有事務日誌。那麼sqlserver是作不到時點還原的

熱備份、冷備份

爲何SQLSERVER需要中止SQLSERVER服務才幹夠拷貝物理數據文件。爲的都是保證數據一致性

 


物理備份方法

一、直接複製整個數據庫文件夾

因爲MYSQL表保存爲文件方式,因此可以直接複製MYSQL數據庫的存儲文件夾以及文件進行備份。

MYSQL的數據庫文件夾位置不必定一樣,在Windows平臺下,MYSQL5.6存放數據庫的文件夾一般默以爲

C:\Documents and Settings\All User\Application Data\MySQL\MYSQL Server 5.6\data

或者其它用戶本身定義的文件夾。

在Linux平臺下,數據庫文件夾位置一般爲/var/lib/mysql/,不一樣Linux版本號下文件夾會有不一樣

這是一種簡單、高速、有效的備份方式。

要想保持備份一致,備份前需要對相關表運行LOCK TABLES操做,而後對錶運行

FLUSH TABLES。這樣當複製數據庫文件夾中的文件時,贊成其它客戶繼續查詢表。需要FLUSH TABLES語句來確保開始

備份前將所有激活的索引頁寫入磁盤。

固然,也可以中止MYSQL服務再進行備份操做

這樣的方法儘管簡單。但並不是最好的方法。

因爲這樣的方法對INNODB存儲引擎的表不適用。使用這樣的方法備份的數據最好還原

到一樣版本號的server中。不一樣的版本號可能不兼容。

注意:在mysql版本號中,第一個數字表示主版本號號。主版本號號一樣的MYSQL數據庫文件格式一樣

二、使用mysqlhotcopy工具高速備份

mysqlhotcopy是一個perl腳本。最初由Tim Bunce編寫並提供。

他使用LOCK TABLES 、FLUSH TABLES和cp或scp

來高速備份數據庫。他是備份數據庫或單個表的最快途徑,但他僅僅能執行在數據庫文件夾所在機器上。並且僅僅能備份myisam類型的表。

語法

mysqlhotcopy db_name_1,...db_name_n /path/to/new_directory

db_name_1...n表明要備份的數據庫的名稱;

path/to/new_directory指定備份文件文件夾

演示樣例

在Linux如下使用mysqlhotcopy備份test庫到/usr/backup

mysqlhotcopy -u root -p test /usr/backup

要想運行mysqlhotcopy,必須能夠訪問備份的表文件,具備那些表的SELECT權限、RELOAD權限(以即可以運行FLUSH TABLES)

和LOCK TABLES權限

提示:mysqlhotcopy僅僅是將表所在文件夾拷貝到還有一個位置,僅僅能用於備份myisam和archive表。

備份innodb表會出現錯誤信息

由於他複製本地格式的文件。故也不能移植到其它硬件或操做系統下


 還原

邏輯還原

一、使用mysql命令進行還原

對於已經備份的包括CREATE、INSERT語句的文本文件,可以使用myslq命令導入數據庫中

備份的sql文件裏包括CREATE、INSERT語句(有時也會有DROP語句)。

mysql命令可以直接運行文件裏的這些語句

其語法例如如下:

mysql -u user -p [dbname]<filename.sql

user是運行backup.sql中語句的username;-p表示輸入用戶password;dbname是數據庫名

假設filename.sql文件爲mysqldump工具建立的包括建立數據庫語句的文件,運行的時候不需要指定數據庫名

用mysql命令將school_2014-7-10.sql文件裏的備份導入到數據庫中

mysql -u root -h 127.0.0.1 -p school<c:\school_2014-7-10.sql

運行語句以前咱們必須建好school數據庫,假設不存在恢復過程將會出錯。

可以看到表數據都已經導入到數據庫了

 

假設已經登陸mysql,那麼可以使用source命令導入備份文件

使用source命令導入備份文件school_2014-7-10.sql

運行source命令前必須使用use 語句選擇好數據庫,否則會出現ERROR 1046(3D000):NO DATABASE SELECTED 的錯誤

另外一點要注意的是僅僅能在cmd界面下運行,不能在mysql工具裏面運行source命令,不然會報錯

因爲cmd是直接調用mysql.exe來運行命令的

而這些mysql 編輯工具僅僅是利用mysql connector鏈接mysql。來管理mysql並不是直接調用mysql.exe。因此運行source會報錯


物理還原

二、直接拷貝到數據庫文件夾

假設數據庫經過複製數據庫文件備份,可以直接複製備份文件到MYSQL數據文件夾下實現還原。

經過這樣的方式還原時,

必須保證備份數據的數據庫和待還原的數據庫server的主版本一樣。

而且這樣的方式僅僅對MYISAM引擎有效,對於innodb引擎的表不可用

運行還原曾經關閉mysql服務。將備份的文件或文件夾覆蓋mysql的data文件夾。啓動mysql服務。

對於Linux操做系統來講。複製完文件需要將文件的用戶和組更改成mysql執行的用戶和組,通常用戶是mysql,組也是mysql


三、mysqlhotcopy高速恢復

mysqlhotcopy備份後的文件也可以用來恢復數據庫,在mysqlserver中止執行時。將備份的數據庫文件拷貝到mysql存放數據的位置

(mysql的data目錄),又一次啓動mysql服務就能夠。

假設根用戶運行該操做,必須指定數據庫文件的所有者,輸入語句例如如下:

chown -R mysql.mysql /var/lib/mysql/dbname

從mysqlhotcopy複製的備份恢復數據庫

cp -R /usr/backup/test  usr/local/mysql/data

運行完該語句,從新啓動server。mysql將恢復到備份狀態

注意:假設需要恢復的數據庫已經存在,則在使用DROP語句刪除已經存在的數據庫以後,恢復才幹成功。

另外mysql不一樣版本號之間必須兼容,恢復以後的數據才幹夠使用!


數據庫遷移

數據庫遷移就是把數據從一個系統移動到還有一個系統上。

遷移的通常緣由:

一、需要安裝新的數據庫server

二、mysql版本號更新

三、數據庫管理系統變動(從SQLSERVER遷移到mysql)

一樣版本號的MYSQL數據庫之間遷移

一樣版本號mysql數據庫間的遷移就是主版本號號一樣的mysql數據庫直接進行數據庫移動。

前面解說備份和還原的時候,知道最簡單的方法就是複製數據庫文件文件夾,但是這樣的方法僅僅適合於myisam表

對於innodb表,不能直接拷貝文件來備份數據庫

最常用的方法是使用mysqldump導出數據,而後在目標數據庫server使用mysql命令導入

將www.abc.com主機上的mysql數據庫全部遷移到www.bcd.com主機上。

在www.abc.com主機上運行下面命令:

mysqldump -h www.abc.com -u root -p dbname |
mysql -h www.bcd.com -u root -p

mysqldump導入的數據直接經過管道符|。傳給mysql命令導入到主機www.bcd.com數據庫中,dbname爲需要遷移的數據庫名稱

假設要遷移全部數據庫。可以使用--all -databases參數


不一樣版本號的mysql數據庫之間的遷移

因爲數據庫升級。需要將舊版本號mysql數據庫中的數據遷移到新版本號數據庫中。

mysqlserver升級,需要先中止服務,而後卸載舊版本號。並安裝新版本號的mysql。這樣的更新方法很是easy。

假設想保留舊版本號中的用戶訪問控制信息。則需要備份mysql的mysql庫。

在新版本號mysql安裝完畢後,又一次讀入mysql備份文件裏的信息

舊版本號和新版本號的mysql可能使用不一樣的默認字符集,好比mysql.4.x中大多數使用latin1做爲默認字符集。

而mysql5.x的默認字符集爲utf8。

假設數據庫中有中文數據,遷移過程當中需要對默認字符集進行改動,否則可能沒法正常顯示結果

新版本號對舊版本號有必定兼容性。

從舊版本號的mysql向新版本號mysql遷移時,對於myisam引擎的表,可以直接複製數據庫文件,

也可以用mysqlhotcopy工具、mysqldump工具。

對於innodb引擎的表通常僅僅能使用mysqldump將數據導出。

而後使用mysql命令導入目標server。

重新版本號向舊版本號mysql遷移數據時要當心,最好使用mysqldump命令導出。而後導入目標數據庫中。


不一樣數據庫之間的遷移

不一樣類型的數據庫之間的遷移,是指把mysql數據庫遷移到其它的數據庫,好比從mysql遷移到oracle,從oracle遷移到mysql

從mysql遷移到SQLSERVER等。

遷移以前。需要了解不一樣數據庫的結構,比較他們的差別。不一樣數據庫定義一樣類型的數據的keyword可能不一樣。

好比:mysql中日期字段分爲DATE 和TIME兩種,而ORACLE的日期字段僅僅有DATE。

數據庫遷移可以使用一些工具,好比,在Windows系統下。可以使用MyODBC實現mysql和SQLSERVER之間的遷移(使用SQLSERVER導入導出嚮導)

mysql官方提供的工具:MYSQL Migration Toolkit也可以在不一樣數據庫間進行數據遷移。


表的導入導出

MYSQL數據庫可以將數據導出成sql文本文件、xml文件、html文件。相同這些導出文件也可以導入到MYSQL數據庫中

通常異構數據庫遷移都是採用文本文件的方式來導數據

導出 

一、用SELECT...INTO OUTFILE導出文本文件

mysql導出數據時,贊成使用包括表定義的select語句進行數據的導出操做

該文件被建立在server主機上,所以必須有文件寫入權限(FILE權限),才幹使用此語法

SELECT INTO…OUTFILE語法:

select columnlist  from Table WHERE condition  into outfile 'filename' [OPTIONS]
fields terminated by 'VALUE'
fields [OPTIONALLY]  ENCLOSED BY 'VALUE'
fields ESCAPED BY 'VALUE'
lines STARTING by 'VALUE'
lines terminated by 'VALUE'

into outfile語句的做用就是把前面select語句查詢出來的結果導出到名稱爲「filename」的外部文件裏

[OPTIONS]部分爲可選參數。[OPTIONS]部分的語法包含FILED和LINES子句,其可能取值爲:

● fields子句:在FIELDS子句中有三個子句:TERMINATED BY、 [OPTIONALLY] ENCLOSED BY和ESCAPED BY。

假設指定了FIELDS子句,則這三個子句中至少要指定一個。
(1)TERMINATED BY用來指定字段值之間的符號,好比,「TERMINATED BY ','」指定了逗號做爲兩個字段值之間的標誌,默以爲「\t」製表符。
(2)ENCLOSED BY子句用來指定包裹文件裏字符值的符號,好比,「ENCLOSED BY ' " '」表示文件裏字符值放在雙引號之間,

若加上keywordOPTIONALLY表示所有的值都放在雙引號之間。則僅僅有CHAR和VARCHAR等字符數據字段被包含。

(3)ESCAPED BY子句用來指定轉義字符,好比,「ESCAPED BY '*'」將「*」指定爲轉義字符,代替「\」,如空格將表示爲「*N」。
● LINES子句:在LINES子句中使用TERMINATED BY指定一行結束的標誌,如「LINES TERMINATED BY '?'」表示一行以「?」做爲結束標誌,默認值爲「\n」。

 TERMINATED BY也是相同的原理

FIELDS子句和LINES子句都是自選的,但是假設兩個都被指定了。FIELDS子句必須位於LINES子句的前面

SELECT INTO…OUTFILE僅僅能在本機運行。假設要在其它server上導出數據。則需要使用如下命令來生成文件

mysql -e "select ...">filename

-e, --execute=name  Execute command and quit. (Disables --force and history

SELECT INTO…OUTFILE是LOAD DATA INFILE的補語。用於語句的OPTIONS部分的語法包含部分FIELDS子句和LINES子句

這些子句與LOAD DATA INFILE語句同一時候使用

使用SELECT INTO…OUTFILE將test數據庫中的person表的記錄導出到文本文件

輸入命令例如如下

SELECT * FROM test.person  INTO  OUTFILE  "C:\person0.txt" ;

由於指定了INTO OUTFILE 子句,SELECT將查詢出來的3個字段的值保存到C:\person0.txt文件,打開文件內容例如如下

1    green    29    lawer
2    suse    26    dancer
3    evans    27    sports man
4    mary    26    singer

可以看到默認狀況下,MYSQL使用製表符「\t」分隔不一樣的字段,字段沒有被其它字符括起來

另外在Windows平臺下。使用記事本打開該文件,顯示的格式與這裏並不一樣樣。這是因爲Windows系統下回車換行爲「\r\n」

默認換行符爲「\n」,所以會在person.txt中可能看到相似黑色方塊的字符,所有的記錄也會在同一行顯示

默認狀況下,NULL值會顯示爲「\N」,轉義字符會顯示爲「\」

使用SELECT ..INTO OUTFILE將test庫中的person表中的記錄導出到文本文件。使用FIELDS選項和LINES選項。要求字段之間

使用逗號「,」間隔。所有字段值用雙引號括起來,定義轉移字符爲單引號「\'」

SELECT * FROM test.person  INTO  OUTFILE  "C:\person1.txt" 
FIELDS
TERMINATED BY ','
ENCLOSED BY '\''
ESCAPED BY '\''
LINES
TERMINATED BY '\r\n';

在C盤下生成的person1文件內容

'1','green','29','lawer'
'2','suse','26','dancer'
'3','evans','27','sports man'
'4','mary','26','singer'

FIELDS  TERMINATED BY ','表示字段之間用逗號分隔

ENCLOSED BY '\''表示每個字段用雙引號括起來

ESCAPED BY '\''表示將系統默認的轉移字符替換爲單引號

LINES TERMINATED BY '\r\n'表示每行以回車換行符結尾。保證每一條記錄佔一行


二、用mysqldump命令導出文本文件

除了使用SELECT...INTO OUTFILE導出文本文件以外。也可以使用mysqldump

mysqldump不只可以將數據導出包括CREATE、INSERT的sql文件,也可以導出爲純文本文件

mysqldump建立一個包括建立表的CREATE TABLE語句的tablename.sql文件,和一個包括其數據

的tablename.txt文件。mysqldump導出文本文件的基本的語法例如如下

mysqldump -T path -u root -p dbname [tables][OPTIONS]
--fields-terminated-by=
--fields-enclosed-by=
--fields-optionally-enclosed-by=
--fields-escaped-by=
--lines-terminated-by=

僅僅有指定了-T參數才幹夠導出純文本文件;path表示導出數據的文件夾

tables爲指定要導出的表名稱。假設不指定,將導出dbname的所有表

基本上每個選項跟SELECT ..INTO OUTFILE語句中的OPTIONS各個參數設置一樣

不一樣的是。等號後面的value值不要用引號括起來

使用mysqldump將test庫的person表的記錄導出到文本文件。運行的命令例如如下

mysqldump -T C:\ -u root -h 127.0.0.1  -p test person

這裏要注意的是,路徑這裏不能先建立好person.txt文件,不然會報錯,跟SELECT ..INTO OUTFILE語句是同樣的

在C盤會生成一個person.txt文件和person.sql文件,內容例如如下

person.sql

-- MySQL dump 10.13  Distrib 5.5.28, for Win32 (x86)
--
-- Host: 127.0.0.1    Database: test
-- ------------------------------------------------------
-- Server version    5.5.28-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `person`
--

DROP TABLE IF EXISTS `person`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `person` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `Name` varchar(20) NOT NULL,
  `Age` int(10) unsigned DEFAULT NULL,
  `job` varchar(90) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2014-07-27 23:56:01

person.sql的內容跟以前解釋的是同樣的

person.txt

1    green    29    lawer
2    suse    26    dancer
3    evans    27    sports man
4    mary    26    singer 


三、使用mysql命令導出文本文件

mysql是一個功能豐富的工具命令,使用mysql還可以在命令行模式下運行SQL指令,將查詢結果導入到文本文件裏。

相比mysqldump,mysql工具導出的結果可讀性更強

假設mysqlserver是單獨的機器,用戶是在一個client上進行操做,用戶要把數據結果導入到client機器上,可以使用mysql -e語句

基本格式例如如下:

mysql -u root -p --execute="SELECT 語句" dbname >filename.txt

該命令使用--execute 選項,表示運行該選項後面的語句並退出。後面的語句必須用雙引號括起來

dbname爲要導出的數據庫名稱,導出的文件裏不一樣列之間使用製表符分隔,第一行包括了字段名稱

使用mysql命令。導出test庫的person表記錄到文本文件,輸入語句例如如下:

mysql -u root -p --execute="SELECT * FROM person;" test>C:\person3.txt

person3.txt的內容例如如下

ID    Name    Age    job
1    green    29    lawer
2    suse    26    dancer
3    evans    27    sports man
4    mary    26    singer

可以看到,person3.txt文件裏包括了每個字段的名稱和各條記錄,假設某行記錄字段很是多,可能一行不能全然顯示,可以使用

--vertical參數。將每條記錄分爲多行顯示

使用mysql命令導出test庫的person表使用--vertical參數顯示

mysql -u root -p  --vertical --execute="SELECT * FROM person;" test>C:\person4.txt

*************************** 1. row ***************************
  ID: 1
Name: green
 Age: 29
 job: lawer
*************************** 2. row ***************************
  ID: 2
Name: suse
 Age: 26
 job: dancer
*************************** 3. row ***************************
  ID: 3
Name: evans
 Age: 27
 job: sports man
*************************** 4. row ***************************
  ID: 4
Name: mary
 Age: 26
 job: singer

假設person表中記錄內容太長,這樣顯示將會更加easy閱讀

使用mysql命令導出test庫的person表記錄到html文件,輸入語句例如如下

mysql -u root -p --html --execute="SELECT * FROM PERSON;"test >C:\person5.html

假設要導出爲xml文件。那麼使用--xml選項

使用mysql命令導出test庫的person表的中記錄到xml文件

mysql -u root -p --xml --execute="SELECT * FROM PERSON;" test >C:\person6.xml

<?xml version="1.0"?

> <resultset statement="SELECT * FROM PERSON" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <row> <field name="ID">1</field> <field name="Name">green</field> <field name="Age">29</field> <field name="job">lawer</field> </row> <row> <field name="ID">2</field> <field name="Name">suse</field> <field name="Age">26</field> <field name="job">dancer</field> </row> <row> <field name="ID">3</field> <field name="Name">evans</field> <field name="Age">27</field> <field name="job">sports man</field> </row> <row> <field name="ID">4</field> <field name="Name">mary</field> <field name="Age">26</field> <field name="job">singer</field> </row> </resultset>


 導入

一、使用LOAD DATA INFILE 方式導入文本文件

mysql贊成將數據導出到外部文件,也可以從外部文件導入數據。

MYSQL提供了一些導入數據的工具,這些工具備:LOAD DATA語句、source命令、mysql命令

LOAD DATA INFILE語句用於快速地從一個文本文件裏讀取行。並裝入一個表中。文件名必須爲文字字符串

語法例如如下:

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name.txt' 
[REPLACE | IGNORE] 
INTO TABLE tbl_name 
[FIELDS 
[TERMINATED BY 'string'] 
[[OPTIONALLY] ENCLOSED BY 'char'] 
[ESCAPED BY 'char' ] 
] 
[LINES 
[STARTING BY 'string'] 
[TERMINATED BY 'string'] 
] 
[IGNORE number LINES] 
[(col_name_or_user_var,...)] 
[SET col_name = expr,...]] 

load data infile語句從一個文本文件裏以很是高的速度讀入一個表中。
使用這個命令以前。mysqld進程(服務) 必須已經在執行。
當讀取的文本文件不在本機,而是位於server上的文本文件時,使用load data infile語句,在server主機上你必須有file的權限。

1 、假設你指定關鍵詞low_priority,那麼MySQL將會等到沒有其它人讀取這個表的時候,
才插入數據。好比例如如下的命令:

load data low_priority infile "/home/mark/data.sql" into table Orders;

2 、假設指定local關鍵詞,則代表讀取的文件在本機,那麼必須指定local參數。

3 、replace和ignore參數控制對現有表的惟一鍵記錄反覆的處理。

假設你指定replace,新行將取代有一樣的惟一鍵值的現有行。

 (1)假設你指定ignore,跳過有惟一鍵的現有行的反覆行的輸入。

 (2)假設你不指定不論什麼一個選項,當找到反覆鍵時,出現一個錯誤。並且文本文件的餘下部分被忽略。

FIELDS  TERMINATED BY ','表示字段之間用逗號分隔

ENCLOSED BY '\''表示每個字段用雙引號括起來

ESCAPED BY '\''表示將系統默認的轉移字符替換爲單引號

LINES STARTING BY ''表示每行數據開頭的字符,可以爲單個或多個。默認不是有不論什麼字符

LINES TERMINATED BY '\r\n'表示每行以回車換行符結尾,保證每一條記錄佔一行

[IGNORE number LINES] 選項表示忽略文件開始處的行數。number表示忽略的行數。

基本上格式上的參數跟SELECT...INTO OUTFILE是同樣的

使用LOAD DATA命令將C:\person0。txt文件裏的數據導入到test庫中的test表

LOAD DATA INFILE 'C:\person0.txt' INTO TABLE test.person

 先刪除person表裏的數據,而後運行LOAD DATA命令

使用mysqlimport命令導入文本文件

二、使用mysqlimport命令導入文本文件

mysqlimport是一個單獨的exe。他提供了不少與LOAD DATA INFILE語句一樣的功能

大多數選項直接相應LOAD DATA INFILE子句

mysqlimport的語法例如如下

mysqlimport -u root -p dbname filename.txt  [OPTIONS]
--[OPTIONS] 選項
FIELDS  TERMINATED BY 'value'
ENCLOSED BY 'value'
ESCAPED BY 'value'
LINES TERMINATED BY 'value'
IGNORE LINES

[OPTIONS] 選項基本上與LOAD DATA INFILE 語句是同樣的,這裏不作介紹了

mysqlimport不能指定導入的表名稱,表名稱由導入文件名稱稱肯定。即文件名稱做爲表名,導入數據以前該表必須存在

使用mysqlimport命令將C:\文件夾下person.txt文件內容導入到test庫

先刪除test庫的person表的數據

DELETE FROM `person`;

person.txt文件內容

1    green    29    lawer
2    suse    26    dancer
3    evans    27    sports man
4    mary    26    singer

命令例如如下

mysqlimport -u root -p  test C:\person.txt

導入成功

mysqlimport的常見選項:

顯示幫助消息並退出。

·         --columns=column_list, -c column_list

該選項採用用逗號分隔的列名做爲其值。

列名的順序指示怎樣匹配數據文件列和表列。 · --compress,-C 壓縮在client和server之間發送的所有信息(假設兩者均支持壓縮)。 · ---debug[=debug_options],-# [debug_options] 寫調試日誌。debug_options字符串通常是'd:t:o,file_name'。 · --delete。-D 導入文本文件前清空表。 · --fields-terminated-by=...,--fields-enclosed-by=...,--fields-optionally-enclosed-by=...。--fields-escaped-by=...,--lines-terminated-by=... 這些選項與LOAD DATA INFILE對應子句的含義一樣。

參見13.2.5節,「LOAD DATA INFILE語法」。 · --force,-f 忽視錯誤。

好比,假設某個文本文件的表不存在。繼續處理其餘文件。不使用--force,假設表不存在則mysqlimport退出。 · --host=host_name,-h host_name 將數據導入給定主機上的MySQLserver。默認主機是localhost。

· --ignore。-i 參見--replace選項的描寫敘述。 · --ignore-lines=n 忽視數據文件的前n行。 · --local,-L 從本地client讀入輸入文件。 · --lock-tables,-l 處理文本文件前鎖定所有表以便寫入。這樣可以確保所有表在server上保持同步。

· --password[=password],-p[password] 當鏈接server時使用的密碼。

假設使用短選項形式(-p)。選項和 密碼之間不能有空格。

假設在命令行中--password或-p選項後面沒有 密碼值,則提示輸入一個密碼。

· --port=port_num,-P port_num 用於鏈接的TCP/IP端口號。

· --protocol={TCP | SOCKET | PIPE | MEMORY} 使用的鏈接協議。 · --replace,-r --replace和--ignore選項控制複製惟一鍵值已有記錄的輸入記錄的處理。假設指定--replace,新行替換有一樣的惟一鍵值的已有行。假設指定--ignore,複製已有的惟一鍵值的輸入行被跳過。假設不指定這兩個選項,當發現一個複製鍵值時會出現一個錯誤,並且忽視文本文件的剩餘部分。 · --silent。-s 沉默模式。僅僅有出現錯誤時才輸出。 · --socket=path,-S path 當鏈接localhost時使用的套接字文件(爲默認主機)。 · --user=user_name,-u user_name 當鏈接server時MySQL使用的username。 · --verbose,-v 冗長模式。打印出程序操做的具體信息。 · --version,-V 顯示版本號信息並退出。

提示:

LOAD DATA INFILE語句中有一個mysqlimport工具中沒有特色: 

LOAD DATA INFILE 可以按指定的字段把文件導入到數據庫中。

當咱們要把數據的一部份內容導入的時候,這個特色就很是重要。

例如說,咱們要從Access數據庫升級到MySQL數據庫的時候,需要增長一些字段(列/字 段/field)到MySQL數據庫中。以適應一些額外的需要。 

這個時候,咱們的Access數據庫中的數據仍然是可用的。但是因爲這些數據的字段(field)與MySQL中的再也不匹配,所以而沒法再使用mysqlimport工具。

雖然如此,咱們仍然可以使用LOAD DATA INFILE,如下的樣例顯示了怎樣向指定的字段(field)中導入數據:

LOAD DATA INFILE "/home/Order.txt" INTO TABLE Orders(Order_Number, Order_Date, Customer_ID); 

如您所見,咱們可以指定需要的字段(fields)。

這些指定的字段依舊是以括號括起。由逗號分隔的,假設您遺漏了當中不論什麼一個。MySQL將會提醒您^_^ 


怎樣選擇備份工具?

直接複製數據文件是最爲直接、高速的備份方法,但缺點是基本上不能實現增量備份。

備份時必須確保沒有使用這些表。假設在複製一個表的物理數據文件的同一時候server正在改動他,則複製無效。

備份文件時,最好關閉server,而後又一次啓動server。爲了保證數據的一致性,需要在備份文件前運行下面SQL

FLUSH TABLES WITH READ LOCK;

也就是把內存中的數據刷新到磁盤中,同一時候鎖定數據表,以保證複製過程當中不會有新的數據寫入。

這樣的方法備份出來的數據恢復很是easy。直接複製回原來的數據庫文件夾下就能夠

mysqlhotcopy是一個PERL程序,他使用LOCK TABLES、FLUSH TABLES和CP或SCP來高速備份數據庫

他是備份數據庫或單個表的最快的途徑,但他僅僅能執行在數據庫文件所在機器上,並且mysqlhotcopy僅僅能用於備份myisam表

mysqlhotcopy適合於小型數據庫的備份。數據量不大,可以使用mysqlhotcopy程序天天進行一次全然備份

mysqldump將數據表導出爲SQL腳本,在不一樣的MYSQL版本號之間升級時相對照較合適,這也是最常用的備份方法。

mysqldump比直接複製要慢些。


使用mysqldump備份整個數據庫成功,把表和數據庫刪除了,但使用備份文件卻不能恢復數據庫?

出現這樣的狀況是因爲備份的時候沒有指定--databases參數。默認狀況下,假設僅僅指定數據庫名稱,mysqldump

備份的是數據庫中的所有表,而不包含數據庫的建立語句,例如如下

mysqldump -u root -p booksdb >c:\booksdb_2014-7-1.sql

該語句僅僅備份了booksdb數據庫下的所有表。讀者打開該文件,可以看到文件裏不包括建立booksdb數據庫

的CREATE DATABASE語句,所以假設把booksdb也刪除了。使用該sql文件不能還原曾經的表。

還原時會出現ERROR 1046(3D000):NO DATABASE SELECTED 的錯誤信息

而如下的語句,數據庫刪除以後,可以正常還原備份時的狀態

mysqldump -u root -p --databases booksdb>C:\booksdb_db_2014-7-1.sql

該語句不只備份了所有數據庫下的表結構,而且包含建立數據庫的語句


總結

這一節介紹了MYSQL中的備份和還原,還有數據庫的遷移,異構數據庫之間的遷移基本上都用導出文件文件的方法

假設是小數據量尚可以,假設數據量比較大,導出文本文件也會很是大,不是太可取

相關文章
相關標籤/搜索