MySQL數據庫的備份與恢復

一、備份單個數據庫練習多種參數使用

mysql數據庫自帶了一個很好用的備份命令,就是 mysqldump ,它的基本使用如下:
語法: mysqldump -u 用戶名 -p密碼 數據庫名 > 備份的文件名
mysqldump備份原理:mysql 數據庫備份實質就是將 mysql 裏的數據以SQL語句的形式導出。
範例1:備份名字爲 oldboy 的庫

[root@mysql-server ~]# mysqldump -uroot -p123456 oldboy > /opt/oldboy_bak.sql 
[root@mysql-server ~]# egrep -v "#|\*|--|^$" /opt/oldboy_bak.sql 
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(4) NOT NULL,
  `name` char(20) NOT NULL,
  `age` tinyint(2) NOT NULL DEFAULT '0',
  `dept` varchar(16) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
LOCK TABLES `student` WRITE;
INSERT INTO `student` VALUES (1,'oldboy',0,NULL);
UNLOCK TABLES;
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
LOCK TABLES `test` WRITE;
INSERT INTO `test` VALUES (1,'oldboy'),(2,'oldgirl'),(3,'老男孩'),(4,'老女孩');
UNLOCK TABLES;

恢復數據:
[root@mysql-server ~]# mysql -uroot -p123456 oldboy < /opt/oldboy_bak.sql # 必須指定庫名 oldboy ,如果不想指定就在備份時加上 -B
範例二:備份時加 -B 參數

[root@mysql-server ~]# mysqldump -uroot -p123456 -B oldboy >/opt/oldboy_B_bak.sql 
和前面的備份文件對比,看看-B參數的作用
[root@mysql-server ~]# cd /opt/
[root@mysql-server opt]# diff oldboy_bak.sql oldboy_B_bak.sql 
18a19,26
> -- Current Database: `oldboy`
> --
> 
> CREATE DATABASE /*!32312 IF NOT EXISTS*/ `oldboy` /*!40100 DEFAULT CHARACTER SET utf8 */;
> 
> USE `oldboy`;
> 
> --
76c84
< -- Dump completed on 2018-04-22  4:46:07
---
> -- Dump completed on 2018-04-22  5:14:09
提示:直觀看,加 -B 參數的作用是增加創建數據庫和連接數據庫的命令了,即如下兩條語句:
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `oldboy` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `oldboy`;

利用上述加 -B 的備份進行恢復測試:
[root@mysql-server opt]# mysql -uroot -p123456 &lt; /opt/oldboy_B_bak.sql
範例三:指定壓縮命令壓縮備份的 mysql 數據

[root@mysql-server opt]# mysqldump -uroot -p123456 -B oldboy|gzip > /opt/oldboy_bak.sql.gz
[root@mysql-server opt]# ls -l /opt/oldboy_*
-rw-r--r-- 1 root root 2579 Apr 22 04:46 /opt/oldboy_bak.sql
-rw-r--r-- 1 root root  894 Apr 22 05:22 /opt/oldboy_bak.sql.gz
-rw-r--r-- 1 root root 2722 Apr 22 05:14 /opt/oldboy_B_bak.sql

通過以上例子可以得出什麼結論?
1、導出數據用 -B 參數
2、用 gzip 對備份的數據壓縮,提高效率。

二、備份多個庫及多個參數練習

1、操作結果
[root@mysql-server opt]# mysqldump -uroot -p123456 -B oldboy oldboy_gbk|gzip &gt; /opt/all_bak.sql.gz
備份所有庫:

[root@mysql-server ~]# /application/mysql/bin/mysqldump -uroot -p123456 --all-databases --events --ignore-table=mysql.events > 2.sql
# 備份多個庫,庫與庫用空格隔開     
[root@mysql-server opt]# ll /opt/all_bak.sql.gz 
-rw-r--r-- 1 root root 916 Apr 22 05:35 /opt/all_bak.sql.gz

2、-B 參數說明

 -B, --databases     Dump several databases. Note the difference in usage; in
                      this case no tables are given. All name arguments are
                      regarded as database names. 'USE db_name;' will be
                      included in the output.
 -B 該參數用於導出若干個數據庫,在備份結果中會加入 create database ‘db_name’;和 use db_name
提示:-B 參數是關鍵,表示接多個庫,並且增加 use db,和 create database db 的信息。

三、分庫備份

分庫備份實際上就是執行一個備份語句備份一個庫,如果數據庫裏有多個庫,就執行多條相同的備份單個庫的備份語句就可以備份多個庫了,注意每個庫都可以用對應備份的庫作爲庫名,結尾加.sql。命令如下:
法1:命令拼接

[root@mysql-server opt]# mysql -uroot -p123456 -e "show databases;"|egrep -vi "database|infor|perfor"|sed -r 's#^([a-z].*$)#mysqldump -uroot -p123456 --events -B \1|gzip > /opt/bak/\1.sql.gz#g'|bash
[root@mysql-server opt]# ll bak 
total 164
-rw-r--r-- 1 root root 144463 Apr 22 06:14 mysql.sql.gz
-rw-r--r-- 1 root root    535 Apr 22 06:14 oldboy_gbk.sql.gz
-rw-r--r-- 1 root root    911 Apr 22 06:14 oldboy.sql.gz
-rw-r--r-- 1 root root    801 Apr 22 06:14 oldboy_utf8.sql.gz
-rw-r--r-- 1 root root    532 Apr 22 06:14 test.sql.gz
-rw-r--r-- 1 root root    538 Apr 22 06:14 wordpress.sql.gz

法二:shell 腳本(for 循環)

[root@mysql scripts]# cat mysqldump1.sh
#!/bin/sh
USER=root
PASSWORD=oldboy123
SOCKET=/data/3306/mysql.sock
LOGIN="mysql -u$USER -p$PASSWORD -S $SOCKET"
DUMP="mysqldump  -u$USER -p$PASSWORD -S $SOCKET"
DATABASE=$($LOGIN -e "show databases;"|egrep -v "*chema|mysql"|sed '1d')
for database in $DATABASE
do
 $DUMP -B $database |gzip >/server/backup/${database}_B_$(date +%F).sql.gz
done

分庫備份的意義何在?
有時一個企業的數據庫裏會有多個庫,例如(www,bbs,blog),但是出問題時可能是某一個庫,如果在備份時把所有的庫都備份成了一個數據文件的話,恢復某一個庫的數據時就比較麻煩了。

四、備份表

1、備份單個表
語法:mysqldump -uroot -p123456 數據庫名 表名 > 備份的文件名
執行結果:

[root@mysql-server opt]# mysqldump -uroot -p123456 oldboy test > /opt/test_table.sql
提示:不能加 -B 參數了,因爲庫 oldboy 後面就是 test 表了。
[root@mysql-server opt]# egrep -v "#|\*|--|^$" /opt/test_table.sql  
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
LOCK TABLES `test` WRITE;
INSERT INTO `test` VALUES (1,'oldboy'),(2,'oldgirl'),(3,'老男孩'),(4,'老女孩');
UNLOCK TABLES;

2、備份多個表
語法:mysqldump -uroot -p123456 數據庫名 表名1 表名2 ... > 備份的文件名
以下命令是備份 test 表和 student 表兩個表:
[root@mysql-server opt]# mysqldump -uroot -p123456 oldboy test student &gt; /opt/all_table.sql
3、分表備份
企業需求:一個庫裏有大表有小表,有時可能需要只恢復某一個小表,上述的多表備份很難拆開,就會像沒有分庫那樣導致恢復某一個小表很麻煩。
那麼分表備份和分庫的思想一樣,每執行一條語句備份一個表,生成不同的數據文件即可。利用shell 腳本實現(兩個 for 循環):

[root@mysql backup]# cat /server/scripts/mysqldump1.sh 
#!/bin/sh
USER=root
PASSWORD=oldboy123
SOCKET=/data/3306/mysql.sock
LOGIN="mysql -u$USER -p$PASSWORD -S $SOCKET"
DUMP="mysqldump  -u$USER -p$PASSWORD -S $SOCKET"
DATABASE=$($LOGIN -e "show databases;"|egrep -v "*chema|mysql"|sed '1d')
for database in $DATABASE
do
    TABLE=$($LOGIN -e "use $database;show tables;"|sed '1d')
    for table in $TABLE
    do
      #[ ! -d /server/backup/$database/ ] && mkdir /server/backup/$database/ -p
      [ -d /server/backup/$database/ ] || mkdir /server/backup/$database/ -p
      $DUMP $database |gzip >/server/backup/$database/${database}_${table}_$(date +%F).sql.gz
    done 
done

分表備份缺點:文件多,很碎。
a、備一個完整全備,再做一個分庫分表備份。
b、腳本批量恢復多個SQL 文件。
4、備份數據表結構(不包含數據)
利用 mysqldump -d 參數只備份表的結構,例:備份 oldboy 庫的所有表的結構。

[root@mysql-server opt]# mysqldump -uroot -p123456 -B -d oldboy > /opt/biao_jiegou.sql
[root@mysql-server opt]# egrep -v "#|\*|--|^$" /opt/biao_jiegou.sql 
USE `oldboy`;
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(4) NOT NULL,
  `name` char(20) NOT NULL,
  `age` tinyint(2) NOT NULL DEFAULT '0',
  `dept` varchar(16) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `test`;
CREATE TABLE `test` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `name` char(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
    如果只備份數據,用 -t
[root@mysql-server opt]# mysqldump -uroot -p123456 -B -t oldboy > /opt/biao_shuju.sql

5、mysqldump 的關鍵參數說明
關鍵參數:mysqldump --help

    1)、-B 指定多個庫,增加建庫語句和 use 語句
    2)、--compact 去掉註釋,適合調試輸出,生產不用
    3)、-A 備份所有庫
    4)、-F 刷新 binlog 日誌
    5)、--master-data 增加 binlog 日誌文件名及對應的位置點
    6)、-x,--lock-all-tables 鎖表
    7)、-l,--lock-tables 只讀鎖表
    8)、-d 只備份表結構
    9)、-t 只備份數據
    10)、--single-transaction 適合 innodb 事務數據庫備份

innodb 表在備份時,通常啓用選項 --single-transaction 來保證備份的一致性,實際上它的工作原理是設定本次會話的隔離級別爲:repeatable read,以確保本次會話(dump)時,不會看到其他會話已經提交了的數據。
myisam 引擎備份命令:
mysqldump -uroot -p123456 -A -B --master-data=2 -x --events|gzip &gt; /opt/all.sql.gz
innodb 引擎備份命令:推薦使用的

mysqldump -uroot -p123456 -A -B --master-data=2 --single-transaction --events|gzip > /opt/all.sql.gz
  # --master-data=2 作用就是找到開始增量的 binlog 文件名和位置點,-- 在SQL語句中是註釋的意思。
[root@mysql-server ~]# mysqldump -uroot -p123456 --master-data=2 --events oldboy student
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000052', MASTER_LOG_POS=107;

分庫分表備份腳本:

[root@mysql oldboy]# cat /server/scripts/mysqldump1.sh 
#!/bin/sh
USER=root
PASSWORD=oldboy123
SOCKET=/data/3306/mysql.sock
LOGIN="mysql -u$USER -p$PASSWORD -S $SOCKET"
DUMP="mysqldump  -u$USER -p$PASSWORD -S $SOCKET"
DATABASE=$($LOGIN -e "show databases;"|egrep -v "*chema|mysql"|sed '1d')
   for database in $DATABASE
   do
     TABLE=$($LOGIN -e "use $database;show tables;"|sed '1d')
       for table in $TABLE
       do
         #[ ! -d /server/backup/$database/ ] && mkdir /server/backup/$database/ -p
         [ -d /server/backup/$database/ ] || mkdir /server/backup/$database/ -p
         $DUMP $database |gzip >/server/backup/$database/${database}_${table}_$(date +%F).sql.gz
       done 
     $DUMP -B $database |gzip >/server/backup/${database}_B_$(date +%F).sql.gz
   done

五、恢復數據庫實踐

1、利用 source 命令恢復數據庫

mysql> system ls /opt/
all_bak.sql.gz  biao_jiegou.sql    oldboy_B_bak.sql
all_table.sql   oldboy_bak.sql     rh
bak             oldboy_bak.sql.gz  test_table.sql
mysql> source /opt/oldboy_B_bak.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)

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)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 1 row affected (0.00 sec)

Database changed
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.05 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)

Query OK, 1 row 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)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.06 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)

Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

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)

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)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

2、利用 mysql 命令恢復(標準)

[root@mysql-server ~]# mysql -uroot -p123456 oldboy < /opt/oldboy_bak.sql 
    對於備份的壓縮文件,先解壓再恢復數據
[root@mysql-server opt]# gzip -d oldboy_bak.sql.gz             # -d 是刪除源文件
[root@mysql-server ~]# mysql -uroot -p123456 oldboy < /opt/oldboy_bak.sql 

3、恢復分庫分表的備份數據

[root@mysql-server bak]# ls
mysql.sql       oldboy.sql       test.sql
oldboy_gbk.sql  oldboy_utf8.sql  wordpress.sql
[root@mysql-server bak]# for dbname in `ls *\.sql|sed 's#\.sql##g'`;do mysql -uroot -p123456 < ${dbname}.sql;done
[root@mysql-server bak]# mysql -uroot -p123456 -e "show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| oldboy             |
| oldboy_gbk         |
| oldboy_utf8        |
| performance_schema |
| test               |
| wordpress          |
+--------------------+

六、mysql數據庫生產常用命令

1、show status; 《== 查看當前會話的數據庫狀態信息
2、show global status; 《== 查看整個數據庫運行狀態信息,很重要,要分析並要做好監控

mysql> show global status like 'select%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| Select_full_join       | 0     |
| Select_full_range_join | 0     |
| Select_range           | 0     |
| Select_range_check     | 0     |
| Select_scan            | 3     |
+------------------------+-------+
5 rows in set (0.00 sec)

3、show processlist; 《== 查看正在執行的 SQL 語句,看不全
4、show full processlist; 《== 查看正在執行的完整SQL語句,完整顯示
5、set global key_buffer_size = 32777218; 《== 不重啓數據庫調整數據庫參數,直接生效,重啓後失效。(如果想永久生效,修改配置文件 my.cnf )

mysql> set global key_buffer_size = 1024*32;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    1
Current database: *** NONE ***

Query OK, 0 rows affected (0.00 sec)

6、show variables; 《== 查看數據庫的參數信息,例如:my.cnf 裏參數的生效情況

mysql> show variables like 'key_buffer_size'; 
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| key_buffer_size | 32768 |
+-----------------+-------+
1 row in set (0.00 sec)

七、mysqlbinlog 命令介紹及實戰講解

1、 如何開啓 mysqlbinlog 功能
在配置文件 my.cnf 裏取消註釋:
[root@mysql-server bak]# sed -i 's%#log-bin=mysql-bin%log-bin=mysql-bin%g' /etc/my.cnf
2、mysqlbinlog 是解析 mysql 的 binlog 日誌的,那麼 mysql 的 binlog 日誌是什麼?
數據目錄下的如下文件就是 mysql 的 binlog 日誌:

[root@mysql-server bak]# cat /application/mysql/data/mysql-bin.index
./mysql-bin.000001
./mysql-bin.000002
./mysql-bin.000003
./mysql-bin.000004

3、mysql 的 binlog 日誌作用是什麼?
用來記錄 mysql 內部增刪改查等對 mysql 數據庫有更新的內容的記錄。(主要就是對更新、修改的內容記錄)
查看 mysql 的 binlog 日誌:

[root@mysql-server data]# mysqlbinlog mysql-bin.000025
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

4、mysqlbinlog 重要參數命令
1)、-d 截取指定庫的 binlog
[root@mysql-server data]# mysqlbinlog -d oldboy_gbk mysql-bin.000024 &gt;oldboy.gbk.sql # 截取指定 oldboy_gbk 庫的 binlog
2)、按照位置截取:
[root@mysql-server data]# mysqlbinlog mysql-bin.000024 --start-position=592 --stop-position=695 -r pos.sql # 從592開始到695結束,截取之間的內容重定向到文件裏,-r 相當於 &gt;,重定向的意思
3)、按照時間截取:
[root@mysql-server data]# mysqlbinlog mysql-bin.000024 --start-datetime='2018-04-23 17:57:07' --stop-datetime='2018-04-23 17:57:08' -r time.sql # 從這個時間段裏截取內容重定向到文件裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章