1. 程式人生 > >mysql5.5-資料備份與恢復

mysql5.5-資料備份與恢復

一、mysqldump的工作原理

  • mysql資料庫自帶了一個很好用的備份命令,就是mysqldump。
  • 它的基本使用如下:
  • 語法:mysqldump -u 使用者名稱 -p 密碼 資料庫名 > 備份的檔名
  • 利用mysqldump命令備份資料的過程,實際上就是把資料從mysql資料庫裡以邏輯sql語句的形式直接輸出或者生成備份檔案的過程。
  • 利用mysqldump命令恢復資料的過程,實際上就是把備份資料,以邏輯sql 語句的形式再資料庫執行的過程。

二、資料庫備份

1.備份單個數據庫

  • 語法:mysqldump -u 使用者名稱 -p 密碼 資料庫名 > 備份的檔名
  • 引數: -A 備份所有資料庫 -B 指定多個庫 -F 重新整理binlog日誌 –compact 去掉註釋,debug除錯使用 –master-data 增加binlog日誌檔名及對應的位置點

1.1查看錶資料

mysql> use liang;
Database changed
mysql> show tables;
+-----------------+
| Tables_in_liang |
+-----------------+
| student         |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from student;
+----+------+
| id | name |
+----+------+
|  1 | aa   |
|  2 | bb   |
|  3 | c    |
|  4 | dd   |
|  5 | ee   |
+----+------+
5 rows in set (0.01 sec)

1.2備份資料庫

[[email protected] ~]# mkdir /backup
[ro[email protected] ~]# mysqldump -uroot -p -S /data/3306/mysql.sock liang > /backup/liang.sql
Enter password: 
[[email protected] ~]# ll /backup/liang.sql 
-rw-r--r--. 1 root root 1950 9月  16 05:52 /backup/liang.sql
備份檔案的主要內容
    22  DROP TABLE IF EXISTS `student`; 
    23  /*!40101 SET @saved_cs_client     = @@character_set_client */;
    24  /*!40101 SET character_set_client = utf8 */;
    25  CREATE TABLE `student` (
    26    `id` int(4) NOT NULL AUTO_INCREMENT,
    27    `name` char(20) NOT NULL,
    28    PRIMARY KEY (`id`),
    29    KEY `index_name` (`name`)
    30  ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
    31  /*!40101 SET character_set_client = @saved_cs_client */;
    32
    33  --
    34  -- Dumping data for table `student`
    35  --
    36
    37  LOCK TABLES `student` WRITE;
    38  /*!40000 ALTER TABLE `student` DISABLE KEYS */;
    39  INSERT INTO `student` VALUES (1,'aa'),(2,'bb'),(3,'c'),(4,'dd'),(5,'ee');
=====》》》
mysqldump備份其實就是將資料以sql語句的形式匯出
22行 ###恢復的時候會先刪掉表,再建立匯入資料。

1.3指定字符集備份

[[email protected] ~]# mysqldump -uroot -p -S /data/3306/mysql.sock --default-character-set=utf8 liang > /backup/liang2.sql      
Enter password: 
[[email protected] ~]# ll /backup/liang2.sql 
-rw-r--r--. 1 root root 1950 9月  16 06:02 /backup/liang2.sql
====》
--default-character-set=utf8 指定utf8字元編碼匯出

1.4指定-B備份

[[email protected] ~]# mysqldump -uroot -p -S /data/3306/mysql.sock -B liang > /backup/B-linag.sql
Enter password: 
[[email protected] ~]# ll /backup/B-linag.sql
-rw-r--r--. 1 root root 2092 9月  16 06:24 /backup/B-linag.sql
內容
    22  CREATE DATABASE /*!32312 IF NOT EXISTS*/ `liang` /*!40100 DEFAULT CHARACTER SET latin1 */;
    23
    24  USE `liang`;
====》
這裡比不加-B多出了兩條sql語句,就是建立資料庫與進入資料庫的語句。

1.4指定壓縮命令備份資料

[[email protected] ~]# mysqldump -uroot -p -S /data/3306/mysql.sock -B liang|gzip> /backup/B-linag.sql.gz
Enter password: 
[[email protected] ~]# ll /backup/B-linag.sql.gz
-rw-r--r--. 1 root root 793 9月  16 06:34 /backup/B-linag.sql.gz
對比壓縮與不壓縮的檔案
[[email protected] ~]# ll   /backup/B-linag.sql  
-rw-r--r--. 1 root root 2092 9月  16 06:24 /backup/B-linag.sql
[[email protected] ~]# ll   /backup/B-linag.sql.gzip 
-rw-r--r--. 1 root root 793 9月  16 06:34 /backup/B-linag.sql.gzip
====》
指定壓縮命令備份比不指定的高出接近三倍的效率

2.分庫備份

2.1結合awk拆分資料庫

[[email protected] ~]# mysql -uroot -p000000 -S /data/3306/mysql.sock -e "show databases;"|egrep -vi "data|info|per"|awk '{print "mysqldump -uroot -p000000 -S /data/3306/mysql.sock -B " $0 "|gzip >/backup/"$0".sql.gz"}'
mysql -uroot -p000000 -S /data/3306/mysql.sock -B liang|gzip >/backup/liang.sql.gz
mysql -uroot -p000000 -S /data/3306/mysql.sock -B liang_gbk|gzip >/backup/liang_gbk.sql.gz
mysql -uroot -p000000 -S /data/3306/mysql.sock -B liang_utf8|gzip >/backup/liang_utf8.sql.gz
mysql -uroot -p000000 -S /data/3306/mysql.sock -B mysql|gzip >/backup/mysql.sql.gz
備份
[[email protected] ~]# mysql -uroot -p000000 -S /data/3306/mysql.sock -e "show databases;"|egrep -vi "data|info|per"|awk '{print "mysqldump -uroot -p000000 -S /data/3306/mysql.sock -B " $0 "|gzip >/backup/"$0".sql.gz"}'|bash
-- Warning: Skipping the data of table mysql.event. Specify the --events option explicitly.
===============
Warning: 這是因為mysqldump預設是不備份事件表(mysql)的,解決辦法 加上引數--events。
===============
檢視
[[email protected] ~]# ll /backup/
總用量 156
-rw-r--r--. 1 root root    514 9月  16 07:56 liang_gbk.sql.gz
-rw-r--r--. 1 root root    513 9月  16 07:56 liang.sql.gz
-rw-r--r--. 1 root root    512 9月  16 07:56 liang_utf8.sql.gz
-rw-r--r--. 1 root root 144243 9月  16 07:56 mysql.sql.gz

2.2指令碼迴圈

[[email protected] ~]# cat sql.backup.sh 
#!/bin/bash
user=root
passwd=000000
sock=/data/3306/mysql.sock
Bin=/application/mysql/bin/
List=`${Bin}mysql -u${user} -p${passwd} -S ${sock} -e "show databases;"|egrep -vi "data|info|per"`
for num in `echo $List`
do
        ${Bin}mysqldump -p${passwd} -S ${sock} --events -B ${num}|gzip >/backup/`date +%F`${num}.sql.gz
done
[[email protected] ~]# bash sql.backup.sh 
[[email protected] ~]# ll /backup/2018*
-rw-r--r--. 1 root root    535 9月  16 08:13 /backup/2018-09-16liang_gbk.sql.gz
-rw-r--r--. 1 root root    533 9月  16 08:13 /backup/2018-09-16liang.sql.gz
-rw-r--r--. 1 root root    533 9月  16 08:13 /backup/2018-09-16liang_utf8.sql.gz
-rw-r--r--. 1 root root 144274 9月  16 08:13 /backup/2018-09-16mysql.sql.gz

2.3備份部分庫

語法:mysqldump -u使用者 -p密碼  -B 庫名 庫名 .. . >備份的檔名
[[email protected] ~]# mysqldump -uroot -p -S /data/3306/mysql.sock -B liang liang_gbk liang_utf8|gzip >/backup/liang.al.gz
[[email protected] ~]# ll /backup/liang.sql.gz                                                         
-rw-r--r--. 1 root root 513 9月  16 07:56 /backup/liang.sql.gz

2.4備份所有庫

[[email protected] ~]# mysqldump -uroot -p -S /data/3306/mysql.sock -A -B |gzip >/backup/all.sql.gz
[[email protected] ~]# ll /backup/all.sql.gz     
-rw-r--r--. 1 root root 144476 9月  20 13:49 /backup/all.sql.gz

3.資料庫單表備份

語法:mysqldump -u使用者名稱 -p密碼 資料庫名 表名 > 備份的檔名
例: mysqldump -uroot -p000000 liang student > /backup/liang_student.sql
引數:
-d 只備份表結構
-t 只備份表資料
-x 鎖表
-l 只讀鎖表
--single-transaction 適合innodb事物資料庫備份,
==========================
不能加-B 引數
=============================

3.1檢視liang資料庫的表

[[email protected] ~]# mysql -uroot -p -S /data/3306/mysql.sock -e"use liang;show tables;"
Enter password: 
+-----------------+
| Tables_in_liang |
+-----------------+
| liang           |
| student         |
| student01       |
| student02       |
+-----------------+
備份
[[email protected] ~]# mysqldump -uroot -p -S /data/3306/mysql.sock liang student|gzip >/backup/liang_student.sql.gz
Enter password: 
[[email protected] ~]# ll /backup/liang_student.sql.gz 
-rw-r--r--. 1 root root 664 9月  20 13:51 /backup/liang_student.sql.gz

3.2資料庫分表備份

awk方式
[[email protected] ~]# mysql -uroot -p000000 -S /data/3306/mysql.sock -e"use liang;show tables;"|grep -v "Tables_in_liang"|awk '{print "mysqldump -uroot -p000000 -S /data/3306/mysql.sock liang "$0"|gzip > /backup/`date +%F`-liang-"$0"sql.gz"}'|bash
[[email protected] ~]# ll /backup/2018-09-20-liang-*
-rw-r--r--. 1 root root 661 9月  20 13:58 /backup/2018-09-20-liang-liangsql.gz
-rw-r--r--. 1 root root 668 9月  20 13:58 /backup/2018-09-20-liang-student01sql.gz
-rw-r--r--. 1 root root 668 9月  20 13:58 /backup/2018-09-20-liang-student02sql.gz
-rw-r--r--. 1 root root 664 9月  20 13:58 /backup/2018-09-20-liang-studentsql.gz

三、資料恢復

1.source恢復資料

mysql> show tables;
+-----------------+
| Tables_in_liang |
+-----------------+
| liang           |
| student         |
| student01       |
| student02       |
+-----------------+
4 rows in set (0.00 sec)

mysql> drop table liang;
Query OK, 0 rows affected (0.01 sec)

mysql> drop table student;
Query OK, 0 rows affected (0.02 sec)
恢復資料
mysql> source /backup/all.sql
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
....
...
..
mysql> show tables;
+-----------------+
| Tables_in_liang |
+-----------------+
| liang           |
| student         |
| student01       |
| student02       |
+-----------------+
4 rows in set (0.00 sec)

2.mysql命令恢復資料

2.1簡單恢復

刪除student表
[[email protected] ~]# mysql -uroot -p -S /data/3306/mysql.sock  -e "use liang;drop table student;"  
恢復資料
[[email protected] ~]# mysql -uroot -p -S /data/3306/mysql.sock liang </backup/liang.sql 
Enter password: 
查看錶資料
[[email protected] ~]# mysql -uroot -p -S /data/3306/mysql.sock -e "use liang;select * from student;"
Enter password: 
+----+------+
| id | name |
+----+------+
|  1 | aa   |
|  2 | bb   |
|  3 | c    |
|  4 | dd   |
|  5 | ee   |
+----+------+

2.2指定-B備份的資料恢復

[[email protected] ~]# mysql -uroot -p -S /data/3306/mysql.sock  -e "use liang;drop table student;" 
Enter password:          
[[email protected] ~]# mysql -uroot -p -S /data/3306/mysql.sock  < /backup/B-linag.sql
Enter password: 
[[email protected] ~]# mysql -uroot -p -S /data/3306/mysql.sock -e "use liang;select * from student;"
Enter password: 
+----+------+
| id | name |
+----+------+
|  1 | aa   |
|  2 | bb   |
|  3 | c    |
|  4 | dd   |
|  5 | ee   |
+----+------+
====》
指定-B備份的資料庫,恢復時不需要指定資料庫,因為它會自動建立並進入該庫。

2.3指定壓縮命令備份的資料恢復

[[email protected] ~]# mysql -uroot -p -S /data/3306/mysql.sock  -e "use liang;drop table student;" 
Enter password:   
[[email protected] ~]# gunzip < /backup/B-linag.sql.gz | mysql -uroot -p -S /data/3306/mysql.sock
Enter password: 
[[email protected] ~]#  mysql -uroot -p -S /data/3306/mysql.sock -e "use liang;select * from student;"
Enter password: 
+----+------+
| id | name |
+----+------+
|  1 | aa   |
|  2 | bb   |
|  3 | c    |
|  4 | dd   |
|  5 | ee   |
+----+------+

3.分庫與分表備份的恢復

庫與表資料恢復的方法一樣,下面以表為例恢復資料
mysql> show tables;
+-----------------+
| Tables_in_liang |
+-----------------+
| liang           |
| student         |
| student01       |
| student02       |
+-----------------+
4 rows in set (0.00 sec)
刪除所有表
mysql> drop table liang;
Query OK, 0 rows affected (0.00 sec)

mysql> drop table student;
Query OK, 0 rows affected (0.01 sec)

mysql> drop table student01;
Query OK, 0 rows affected (0.01 sec)

mysql> drop table student02;
Query OK, 0 rows affected (0.00 sec)
恢復
[[email protected] backup]# ll 2018-09-20*
-rw-r--r--. 1 root root 661 9月  20 13:58 2018-09-20-liang-liangsql.gz
-rw-r--r--. 1 root root 668 9月  20 13:58 2018-09-20-liang-student01sql.gz
-rw-r--r--. 1 root root 668 9月  20 13:58 2018-09-20-liang-student02sql.gz
-rw-r--r--. 1 root root 664 9月  20 13:58 2018-09-20-liang-studentsql.gz

[[email protected] backup]# ls 2018-09-20*|tr "\t" "\n"|awk '{print "gunzip < "$0"|mysql -uroot -p000000 -S /data/3306/mysql.sock liang"}'
gunzip < 2018-09-20-liang-liangsql.gz|mysql -uroot -p -S /data/3306/mysql.sock liang
gunzip < 2018-09-20-liang-student01sql.gz|mysql -uroot -p -S /data/3306/mysql.sock liang
gunzip < 2018-09-20-liang-student02sql.gz|mysql -uroot -p -S /data/3306/mysql.sock liang
gunzip < 2018-09-20-liang-studentsql.gz|mysql -uroot -p -S /data/3306/mysql.sock liang
[[email protected] backup]# ls 2018-09-20*|tr "\t" "\n"|awk '{print "gunzip < "$0"|mysql -uroot -p000000 -S /data/3306/mysql.sock liang"}'|bash

檢視
mysql> show tables;
+-----------------+
| Tables_in_liang |
+-----------------+
| liang           |
| student         |
| student01       |
| student02       |
+-----------------+
4 rows in set (0.00 sec)

四、mysqlbinlog增量恢復

  • mysql的bin-log日誌會記錄mysql內部對mysql資料庫所有增刪改等更新的內容的記錄
  • mysql的binlog日誌需要用mysqlbinlog檢視。

1.配置binlog日誌

[[email protected] ~]# egrep "mysqld|log-bin" /data/3306/my.conf 
[mysqld]  
log-bin = /data/3306/mysql-bin 
刪除資料庫
mysql> drop database liang_gbk;
Query OK, 0 rows affected (0.01 sec)

mysql> drop database liang_utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> drop database liang;
Query OK, 4 rows affected (0.01 sec)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
重啟
[[email protected] ~]# /data/3306/mysqld restart
mysql 3306 stop......                                      [確定]
mysql 3306 start......                                     [確定]
恢復資料,binlog會記錄
mysql> source /backup/all01.sql
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)
...
..
檢視binlog檔案
[[email protected] ~]# ll /data/3306/mysql-bin.*
-rw-rw----. 1 mysql mysql 107 9月  20 19:50 /data/3306/mysql-bin.000001###binlog日誌
-rw-rw----. 1 mysql mysql  28 9月  20 19:50 /data/3306/mysql-bin.index###binlog日誌的索引

2.檢視binlog部分日誌

    26  # at 260
    27  #180920 19:56:53 server id 1  end_log_pos 378   Query   thread_id=1     exec_time=0   error_code=0
    28  use `liang`/*!*/;
    29  SET TIMESTAMP=1537487813/*!*/;
    30  DROP TABLE IF EXISTS `liang` /* generated by server */
    31  /*!*/;
    32  # at 378
    33  #180920 19:56:53 server id 1  end_log_pos 580   Query   thread_id=1     exec_time=1   error_code=0
    34  SET TIMESTAMP=1537487813/*!*/;
    35  CREATE TABLE `liang` (
    36    `id` int(4) NOT NULL,
    37    `name` char(10) DEFAULT NULL,
    38    PRIMARY KEY (`id`)
    39  ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    40  /*!*/;
    41  # at 580
    42  #180920 19:56:54 server id 1  end_log_pos 688   Query   thread_id=1     exec_time=0   error_code=0
    43  SET TIMESTAMP=1537487814/*!*/;
    44  /*!40000 ALTER TABLE `liang` DISABLE KEYS */
    45  /*!*/;
    46  # at 688
    47  #180920 19:56:54 server id 1  end_log_pos 795   Query   thread_id=1     exec_time=0   error_code=0
    48  SET TIMESTAMP=1537487814/*!*/;
    49  /*!40000 ALTER TABLE `liang` ENABLE KEYS */
    50  /*!*/;
    51  # at 795
    52  #180920 19:56:54 server id 1  end_log_pos 915   Query   thread_id=1     exec_time=0   error_code=0
    53  SET TIMESTAMP=1537487814/*!*/;
    54  DROP TABLE IF EXISTS `student` /* generated by server */
    55  /*!*/;
    56  # at 915
    57  #180920 19:56:54 server id 1  end_log_pos 1119  Query   thread_id=1     exec_time=0   error_code=0
    58  SET TIMESTAMP=1537487814/*!*/;
    59  CREATE TABLE `student` (
    60    `id` int(4) NOT NULL,
    61    `name` char(10) DEFAULT NULL,
    62    PRIMARY KEY (`id`)
    63  ) ENGINE=InnoDB DEFAULT CHARSET=latin1
    64  /*!*/;

3.使用binlog日誌恢復資料

3.1拆庫恢復資料

binlog會記錄所有庫的增刪查改記錄,有時我們只想恢復單個數據庫
就需要拆庫恢復資料庫
刪除liang資料庫
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| liang              |
| liang_gbk          |
| liang_utf8         |
| mysql              |
| performance_schema |
+--------------------+
6 rows in set (0.00 sec)

mysql> drop database liang; 
恢復
[[email protected] ~]# mysqlbinlog -d liang /data/3306/mysql-bin.000001 >/backup/liang.sql
[[email protected] ~]# cat -n /backup/liang.sql|grep "drop"
   130  drop database liang
[[email protected] ~]# sed -i '/^drop/d' /backup/liang.sql
================
-d 拆庫
因為刪除的命令也被記錄了,所有需要將刪除的命令刪掉再恢復
================
[[email protected] ~]# mysql -uroot -p000000 -S /data/3306/mysql.sock < /backup/liang.sql
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| liang              |
| liang_gbk          |
| liang_utf8         |
| mysql              |
| performance_schema |
+--------------------+
6 rows in set (0.00 sec)

4.基於位置點的恢復

mysql> use liang;
Database changed
mysql> create table student03(
    -> id int(4) PRIMARY KEY,
    -> name char(4)
    -> );
Query OK, 0 rows affected (0.02 sec)
mysql> insert into student03 (name) values ("aa");
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * from student03;
+----+------+
| id | name |
+----+------+
|  0 | aa   |
+----+------+
1 row in set (0.00 sec)

4.1指定開始和結束位置

mysql> drop table student03;
Query OK, 0 rows affected (0.00 sec)
找到建立student03表的地方
   244  # at 5175
   245  #180920 20:16:13 server id 1  end_log_pos 5300  Query   thread_id=1     exec_time=0   error_code=0
   246  SET TIMESTAMP=1537488973/*!*/;
   247  SET @@session.foreign_key_checks=1, @@session.unique_checks=1/*!*/;
   248  SET @@session.sql_mode=0/*!*/;
   249  create table student03(
   250  id int(4) PRIMARY KEY,
   251  name char(4)
   252  )
   253  /*!*/;
   254  # at 5300
   255  #180920 20:16:50 server id 1  end_log_pos 5369  Query   thread_id=1     exec_time=0   error_code=0
   256  SET TIMESTAMP=1537489010/*!*/;
   257  BEGIN
   258  /*!*/;
   259  # at 5369
   260  #180920 20:16:50 server id 1  end_log_pos 5475  Query   thread_id=1     exec_time=0   error_code=0
   261  SET TIMESTAMP=1537489010/*!*/;
   262  insert into student03 (name) values ("aa")
   263  /*!*/;
   264  # at 5475 
   265  #180920 20:16:50 server id 1  end_log_pos 5502  Xid = 139
   266  COMMIT/*!*/;
   267  # at 5502
恢復資料
[[email protected] ~]# mysqlbinlog /data/3306/mysql-bin.000001 --start-position=5175 --stop-position=5475 -r /backup/bin.sql
[[email protected] ~]#  mysql -uroot -p000000 -S /data/3306/mysql.sock < /backup/bin.sql 
mysql> select * from student03;
+----+------+
| id | name |
+----+------+
|  0 | aa   |
+----+------+
1 row in set (0.00 sec)
===========================
注意:結尾的日誌點比較特殊,不會被包含,5175pos的binlog。
位置點資訊要實際存在,不能亂指定
不指定開始表示從日誌第一行開始恢復
不指定結尾則表示恢復到日誌結尾一行
====================================================

4.2指定時間恢復

[[email protected] ~]# mysqlbinlog /data/3306/mysql-bin.000001 --start-datetime='2018-09-20 20:16:13' --stop-datetime='2018-09-20 20:16:50' -r /backup/date.sql

mysql> drop table student03;   
Query OK, 0 rows affected (0.01 sec)
[[email protected] ~]# mysql -uroot -p000000 -S /data/3306/mysql.sock <  /backup/date.sql
mysql> select * from student03;
+----+------+
| id | name |
+----+------+
|  0 | aa   |
+----+------+
1 row in set (0.00 sec)