1. 程式人生 > >MySQL之資料備份與和即時點還原

MySQL之資料備份與和即時點還原

www.syncnavigator.cn

SyncNavigator 做資料同步時所支援的資料庫型別:

支援sqlserver 2000-2014所有版本,全相容,和MYsql 4.x 、MYsql 5.x 、MYsql 6.x版本。

來源資料庫和目標資料庫可以版本不同,比如:來源資料庫是sqlserver 2012  目標資料庫是mysql 5.5 ,都是可以的, SyncNavigator 支援跨資料庫版本,無縫傳輸資料。

只需要能連線上資料庫, SyncNavigator 可以安裝在第三方電腦上,來源資料庫和目標資料庫電腦上可以不用安裝程式。

設定好資料庫連線地址,點選測試連線,能臉上來源資料庫和目標資料庫, SyncNavigator 就能進行高效資料傳輸服務

Raid1,Raid10:僅僅是保證硬體損壞時,業務不需要中止;而像(drop table tb_name 和 rm 這種在軟體層面的誤刪除就不能恢復)

cp命令:cp命令需要時間進行復制,在伺服器業務未中止時容易造成複製的資料在時間點上不一致。

備份型別:

  1. 熱備份 讀、寫不受影響,在備份時伺服器可正常提供有業務

  2. 溫備份 在進行資料備份時,只能進行讀操作

  3. 冷備份 在備份時必須中止業務,讀、寫操作都不行

  4. 物理備份 直接複製資料檔案,速度快

  5. 邏輯備份 將資料匯出至文字檔案中,要從表中先將資料讀出來,再匯入到其他地方,其速度比較慢

  6. 完全備份 將整個資料進行備份

  7. 增量備份 僅備份上次完全備份後或者增量備份後變化的資料

  8. 差異備份 僅備份上次完全備份後變化的資料

備份的時候備份什麼?

資料、配置檔案、二進位制日誌、事務日誌(防止有未完成的事務)

MyISam:幾乎不可能熱備份(要藉助邏輯卷LVM使用快照,鎖定MyISam中所有表,且要以共享方式(read)鎖定,這樣資料就更改不了了,再將資料複製一份)

Innodb:可以進行熱備份,有專門的熱備份工具,perconna提供的xtrabackup就能實現熱備,而且屬於物理備份

但是為了資料的安全,能進行離線備份(冷備份)就進行離線備份;可以藉助主從架構中的從伺服器實施離線備份(這樣不會影響主伺服器的業務,且高效安全)

到底選擇物理備份還是邏輯備份?

物理備份的速度快

邏輯備份的速度慢,會丟失浮點數;但是資料的移植性強且可方便使用文字工具對備份資料直接進行處理

備份策略:

完全備份+增量備份;完全備份+差異備份

如一週做一次完全備份,一天做一次增量備份(備份頻率取決於你資料的變化量,及你可以忍受的還原時長)

MySQL的備份工具

mysqldump:邏輯備份工具,對MyISam為溫備份,對Innodb為熱備份

mysqlhotcopy:物理備份工具,溫備份

檔案系統工具:

  1. 直接cp: 冷備份,會導致備份資料在時間點上出現不一致,但藉助lv快照後可以實現幾乎熱備份

  2. LV:邏輯卷快照功能,幾乎熱備

    >flush tables;

    >lock tables;

    >建立快照

    >釋放鎖

    >複製資料

如果是對Innodb建立快照的話,必須等待快取區中的資料寫入到磁碟上,而這個時間可能會持續很長時間

第三方工具:

 ibbackup:商業工具,每臺server的授權費用很高

 xtrabackup:開源的免費工具,比ibbackup效能還好

mysqldump命令及引數:

db_name 備份指定的資料庫

--master-data={0|1|2}

0:不記錄二進位制檔案及時間位置

1:以change master to的方式記錄事件位置,可用於恢復後直接啟動伺服器

2:以change master to的方式記錄事件位置,但預設被註釋

--single-transaction 

如果指定的備份資料庫中的表儲存引擎為Innodb,可以用--single-transaction啟動熱備份,不能與lock-all-tables一起使用(因為是熱備份);此選項開啟後會啟動一個很長的事務,在繁忙的server上可能會消耗很長的時間

備份多個庫

--all-databases 備份所有庫,在進行資料還原時不必提前建立庫或者表,會自動建立

--databases db_name,db_name.....備份多個指定庫,在進行資料還原時不需要先建立庫,會自動建立

--events 備份時間排程器的

--routines 備份儲存過程和儲存函式的

--triggers 備份觸發器的

--lock-all-tables 在進行備份之前自動鎖定所有表;但如果只進行備份一個表的話直接用>lock tables read 便可,否則會將所有表都鎖定

--flush-logs 在備份之前自動進行日誌滾動;在備份之前最好將二進位制日誌滾動一下

例:

mysql> select * from students.test1; 

+-----+---------+-----+

| cid | name    | sid |

+-----+---------+-----+

|   1 | zxl     | A   |

|   2 | jiamian | B   |

|   3 | fade    | C   |

|   4 | faded   | D   |

+-----+---------+-----+

[[email protected] ~]# mysqldump -uroot -p students  > /root/students.sql

Enter password:  對students庫進行資料備份,儲存檔案為/root/students.sql

[[email protected] ~]# vim /root/students.sql 可以檢視一下

-- MySQL dump 10.13  Distrib 5.6.34, for Linux (x86_64)

--

-- Host: localhost    Database: students

-- ------------------------------------------------------

-- Server version       5.6.34-log

/*!40101 SET @[email protected]@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;

/*!40111 SET @[email protected]@SQL_NOTES, SQL_NOTES=0 */;

--

-- Table structure for table `mytest`

--

DROP TABLE IF EXISTS `mytest`;

/*!40101 SET @saved_cs_client     = @@character_set_client */;

/*!40101 SET character_set_client = utf8 */;

CREATE TABLE `mytest` (

  `cid` tinyint(3) unsigned NOT NULL AUTO_INCREMENT,

  `Course` varchar(50) NOT NULL,

  `starttime` date DEFAULT '2017-02-12',

  PRIMARY KEY (`cid`),

  UNIQUE KEY `course` (`Course`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;

.........

[[email protected] ~]# mysql

mysql> drop database students; 登入後刪除students庫

Query OK, 5 rows affected (1.05 sec)

mysql> \q

[[email protected] ~]# mysql mydb < /root/students.sql 依靠儲存的/root/students.sql檔案還原資料庫,且新庫名為mydb

ERROR 1049 (42000): Unknown database 'mydb' 報錯誤,因為備份單個庫|表,還原前要先建立庫

[[email protected] ~]# mysql  < /root/students.sql 

ERROR 1046 (3D000) at line 22: No database selected

[[email protected] ~]# mysql

mysql> create database mydb; 登入建立一個新庫mydb

mysql> \q

[[email protected] ~]# mysql mydb < /root/students.sql 資料還原

[[email protected] ~]# mysql

mysql> show databases ; 還原成功

+--------------------+

| Database       |

+--------------------+

| mydb          |

mysql> select * from mydb.test1; 庫中表也還原回來了

+-----+---------+-----+

| cid | name    | sid |

+-----+---------+-----+

|   1 | zxl     | A   |

|   2 | jiamian | B   |

|   3 | fade    | C   |

|   4 | faded   | D   |

+-----+---------+-----+

4 rows in set (0.00 sec)

例:將日誌和事務所處的位置也儲存下來,方便還原

[[email protected] ~]# mysqldump -uroot -p --master-data=2  mydb > /root/students-'data+%F-%H-%S'.sql 

Enter password: 

[[email protected] ~]# ls /root/

students-data+%F-%H-%S.sql  

[[email protected] ~]# less /root/students-data+%F-%H-%S.sql 

-- CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000023', MASTER_LOG_POS=4270;

可以看到當前使用的日誌檔案為'master-bin.000023',事務位置為 MASTER_LOG_POS=4270;這樣從4270這個位置進行二進位制日誌的備份便可,而4270之前的資料可以用備份直接進行還原;這樣就做到了即時點資料還原

下面將演示完全備份+增量備份+資料即時點還原

[[email protected] data]#  mysqldump -uroot -p --master-data=2 --flush-logs --all-databases  --lock-all-tables  > /root/All.sql 做完全備份

Enter password: 

[[email protected] data]# mysql

mysql> use mydb;

Database changed

mysql> select * from test1;

+-----+-------+-----+

| cid | name  | sid |

+-----+-------+-----+

|   1 | zxl   | A   |

|   3 | fade  | C   |

|   4 | faded | D   |

|   5 | my   | E   |

+-----+-------+-----+

4 rows in set (0.00 sec)

mysql> delete from test1 where name='my'; 第一天進行了資料刪除

Query OK, 1 row affected (0.01 sec)

mysql> flush logs;

Query OK, 0 rows affected (0.04 sec)

mysql> \q

[[email protected]ode1 data]# mysql -e 'show master status' 檢視當前使用的二進位制日誌是哪個

+-------------------+----------+--------------+------------------+-------------------+

| File         | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+-------------------+----------+--------------+------------------+-------------------+

| master-bin.000027 |    120 |          |                         |                |

+-------------------+----------+--------------+------------------+-------------------+

可以看到當前使用的日誌為 master-bin.000027 ,則master-bin.000026為過去一天的增量產生的二進位制日誌

[[email protected] data]# cp master-bin.000026 /root/monday-increment.sql 進行第一次增量備份

或者用mysqlbinlog命令複製

[[email protected] data]# mysqlbinlog master-bin.000026 /root/monday-increment.sql 

[[email protected] ~]# mysql

mysql> use mydb;

Database changed

mysql> insert into test1 (cid,name,sid) values (6,'jiamian','F'); 第二天進行了資料插入

Query OK, 1 row affected (0.06 sec)

mysql> \q

[[email protected] data]# cp master-bin.000027 /root/tuesday-increment.sql 進行第二次增量備份

[[email protected] ~]# cd /mydata/data/

[[email protected] data]# rm -rf ./* 刪除所有資料,模擬資料崩潰

[[email protected] data]# service mysqld stop

 ERROR! MySQL server PID file could not be found!

[[email protected] data]# killall mysqld

[[email protected] data]# cd /usr/local/mysql/

[[email protected] mysql]# scripts/mysql_install_db --usr=mysql --datadir=/mydata/data/ 先初始化

[[email protected] data]# service mysqld start 在啟動mysqld

Starting MySQL SUCCESS! 

進行資料恢復

[[email protected] data]# mysql -uroot -p < /root/All.sql 匯入完全備份

[[email protected] data]# mysql -uroot -p < /root/monday-increment.sql 匯入第一次增量備份

[[email protected] data]# mysql -uroot -p < /root/tuesday-increment.sql 匯入第二次增量備份

也可以將���面過程寫成一個指令碼,讓其在半夜自動執行。