專職DBA-mysqldump邏輯備份恢復

專職DBA-MySQL數據庫備份與恢復基礎


[root@db01 ~]# ps -aux | grep mysql
mysql     7452  0.2 19.2 1118856 193572 pts/0  Sl   18:55   0:01 mysqld --defaults-file=/data/mysql/3306/my.cnf
root      7547  0.0  0.0 112708   972 pts/0    R+   19:03   0:00 grep --color=auto mysql

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p
Enter password:

mysql> create database app;
Query OK, 1 row affected (0.00 sec)

mysql> use app;
Database changed

mysql> create table t1(id int,name varchar(32));
Query OK, 0 rows affected (0.02 sec)

mysql> show tables;
+---------------+
| Tables_in_app |
+---------------+
| t1            |
+---------------+
1 row in set (0.00 sec)

mysql> desc t1;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(11)     | YES  |     | NULL    |       |
| name  | varchar(32) | YES  |     | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> insert into t1(id,name) values(1,"app01");
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1(id,name) values(2,"app02");
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1(id,name) values(3,"app03");
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1(id,name) values(4,"app04");
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1(id,name) values(5,"app05"); 
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1(id,name) values(6,"app06"); 
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1(id,name) values(7,"app07");
Query OK, 1 row affected (0.00 sec)

mysql> insert into t1(id,name) values(8,"app08");
Query OK, 1 row affected (0.01 sec)

mysql> insert into t1(id,name) values(9,"app09");
Query OK, 1 row affected (0.01 sec)

mysql> select * from t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | app01 |
|    2 | app02 |
|    3 | app03 |
|    4 | app04 |
|    5 | app05 |
|    6 | app06 |
|    7 | app07 |
|    8 | app08 |
|    9 | app09 |
+------+-------+
9 rows in set (0.00 sec)


[root@db01 ~]# mkdir -p /backup/mysql/3306


1.使用mysqldump備份數據庫
mysqldump備份的內容就是曾經執行過的SQL語句。
爲了恢復,mysqldump把數據寫成了一個insert語句,另外多了兩行鎖表和解鎖。
邏輯備份:就是以SQL語句的形式直接輸出或者生成備份文件的過程。
數據量<=30G 用mysqldump
數據量>=30G 用Xtrabackup(物理備份方式)

(1).不帶參數備份單個數據庫
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=off app > /backup/mysql/3306/app.sql

檢查備份結果
[root@db01 ~]# egrep -v "#|\*|--|^$" /backup/mysql/3306/app.sql
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `t1` WRITE;
INSERT INTO `t1` VALUES (1,'app01'),(2,'app02'),(3,'app03'),(4,'app04'),(5,'app05'),(6,'app06'),(7,'app07'),(8,'app08'),(9,'app09');
UNLOCK TABLES;


(2).加-B參數備份
-B 增長建立數據庫語句 和 use鏈接數據庫的語句。後面能夠直接跟多個數據庫名,同時備份多個庫。
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=off -B app > /backup/mysql/3306/app_B.sql
Enter password:


[root@db01 ~]# diff /backup/mysql/3306/app.sql /backup/mysql/3306/app_B.sql
18a19,26
> -- Current Database: `app`
> --
> 
> CREATE DATABASE /*!32312 IF NOT EXISTS*/ `app` /*!40100 DEFAULT CHARACTER SET utf8 */;
> 
> USE `app`;
> 
> --
50c58
< -- Dump completed on 2019-08-01 19:25:51
---
> -- Dump completed on 2019-08-01 19:29:10


(3).使用gzip壓縮備份數據庫(壓縮2/3[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=off -B app|gzip > /backup/mysql/3306/app_B.sql.gz


(4).備份多個庫
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "create database app01;"

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show databases;" 
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| app                |
| app01              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+


[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=off -B app app01|gzip > /backup/mysql/3306/apps_B.sql.gz

MySQL 5.5版本的數據庫,備份mysql庫時須要加一個--events參數不然會有警告信息。


(5).分庫備份
用mysqldump分別備份每個數據庫
# mysqldump -S /data/mysql/3306/mysql.sock -p -B app|gzip > /backup/app.sql.gz
# mysqldump -S /data/mysql/3306/mysql.sock -p -B mysql|gzip > /backup/mysql.sql.gz
# mysqldump -S /data/mysql/3306/mysql.sock -p -B shenzhen|gzip > /backup/shenzhen.sql.gz

特殊技巧
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show databases;"
Enter password: 
+--------------------+
| Database           |
+--------------------+
| information_schema |
| app                |
| app01              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show databases;"|egrep -v "_schema|atabase|sys"
Enter password: 
app
app01
mysql

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p123 -e "show databases;"|egrep -v "_schema|atabase|sys"|sed -r 's#^(.*)#mysqldump -S /data/mysql/3306/mysql.sock -p123 --set-gtid-purged=OFF -B \1|gzip >/tmp/\1.sql.gz#g'
mysql: [Warning] Using a password on the command line interface can be insecure.
mysqldump -S /data/mysql/3306/mysql.sock -p123 --set-gtid-purged=OFF -B app|gzip >/tmp/app.sql.gz
mysqldump -S /data/mysql/3306/mysql.sock -p123 --set-gtid-purged=OFF -B app01|gzip >/tmp/app01.sql.gz
mysqldump -S /data/mysql/3306/mysql.sock -p123 --set-gtid-purged=OFF -B mysql|gzip >/tmp/mysql.sql.gz

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p123 -e "show databases;"|egrep -v "_schema|atabase|sys"|sed -r 's#^(.*)#mysqldump -S /data/mysql/3306/mysql.sock -p123 --set-gtid-purged=OFF -B \1|gzip >/tmp/\1.sql.gz#g'|bash
mysql: [Warning] Using a password on the command line interface can be insecure.
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysqldump: [Warning] Using a password on the command line interface can be insecure.
mysqldump: [Warning] Using a password on the command line interface can be insecure.

[root@db01 ~]# ls -l /tmp/
total 244
-rw-r--r-- 1 root root    517 Aug  1 20:12 app01.sql.gz
-rw-r--r-- 1 root root    771 Aug  1 20:12 app.sql.gz
-rw-r--r-- 1 root root 239951 Aug  1 20:12 mysql.sql.gz


(6).備份單個表
不加-B參數,第一個爲庫,第二個爲表,其餘後面的都爲表。app t1 t2 t3
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF app t1 > /backup/mysql/3306/app_t1.sql


(7).備份多個表
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF mysql user db > /backup/mysql/3306/mysql_user_db.sql


[root@db01 ~]# egrep -v "#|\*|--|^$" /backup/mysql/3306/db_mysql_user_db.sql


(8)分表備份
mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF app t1 > /backup/mysql/3306/app_t1.sql
mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF app t2 > /backup/mysql/3306/app_t2.sql
mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF app t3 > /backup/mysql/3306/app_t3.sql
mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF mysql user > /backup/mysql/3306/app_t3.sql
mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF mysql db > /backup/mysql/3306/app_t3.sql
而後寫個腳本,這樣作很low


(9).備份方案:
作一個完整的全備,再作一個分庫分表備份。
雖然文件多、碎,但能夠利用腳本批量操做多個sql文件。

若是多個庫或多個表備份到了以一個文件裏,那麼這種狀況下,如何恢復單個庫或者單個表?
找個第三方測試庫,將全部備份都導入到這個測試庫裏,而後把須要的單庫或表再備份出來,最後恢復到須要恢復的正式庫裏。
若是是單表恢復,還能夠執行"grep -w 表名 bak.sql > 表名.sql"命令。
固然最好是備份時提早採用分庫分表備份。

(10).-d參數,只備份數據庫表結構,就是建表語句
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF -d app > /backup/mysql/3306/app_desc.sql

[root@db01 ~]# egrep -v "#|\*|--|^$" /backup/mysql/3306/app_desc.sql 
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


(11).-t參數,只備份數據庫表數據,不包括表結構
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF -t app > /backup/mysql/3306/app_t.sql

[root@db01 ~]# egrep -v "#|\*|--|^$" /backup/mysql/3306/app_t.sql
LOCK TABLES `t1` WRITE;
INSERT INTO `t1` VALUES (1,'app01'),(2,'app02'),(3,'app03'),(4,'app04'),(5,'app05'),(6,'app06'),(7,'app07'),(8,'app08'),(9,'app09'),(10,'app10');
UNLOCK TABLES;


(12).-T參數,同時將數據和表結構分離導出備份
數據是純文本.txt
表結構是SQL語句.sql
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF app --compact -T /tmp/

[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF app t1 --compact -T /tmp/

--compact 減小無用的輸出

[root@db01 ~]# ls -l /tmp/
total 8
-rw-r--r-- 1 root  root  287 Aug 28 17:05 t1.sql 表結構
-rw-rw-rw- 1 mysql mysql  81 Aug 28 17:05 t1.txt 表數據

[root@db01 ~]# cat /tmp/t1.sql
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;

[root@db01 ~]# cat /tmp/t1.txt
1       app01
2       app02
3       app03
4       app04
5       app05
6       app06
7       app07
8       app08
9       app09
10      app10

MySQL5.6版本由於安全權限問題不能直接導出了。
那我就是這麼任性怎麼辦?改配置文件
[root@db01 ~]# vim /data/mysql/3306/my.cnf 
[mysqld]
secure_file_priv=''

[root@db01 ~]# mysqladmin -S /data/mysql/3306/mysql.sock -p shutdown

[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &

[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF app --compact -T /tmp/


2.binlog文件
binlog是二進制文件,記錄用戶對數據庫更新的SQL語句信息。
增刪改SQL語句會記錄到binlog裏。
查詢語句不會記錄到binlog裏。
binlog文件裏的數據就是寫入數據庫的數據,使用binlog文件恢復數據,叫二進制增量數據恢復。
Oracle數據庫裏面有切日誌的習慣吧,mysql也有切日誌,就是刷新binlog。

開啓binlog功能
[root@db01 ~]# grep "log_bin" /data/mysql/3306/my.cnf 
log_bin                  = /data/mysql/3306/logs/mysql-bin

[root@db01 ~]# mysqladmin -S /data/mysql/3306/mysql.sock -p shutdown
[root@db01 ~]# mysqld --defaults-file=/data/mysql/3306/my.cnf &

[root@db01 ~]# ls -l /data/mysql/3306/logs/
total 8
-rw-r----- 1 mysql mysql 177 Aug  1 18:52 mysql-bin.000001 日誌文件
-rw-r----- 1 mysql mysql  39 Aug  1 18:52 mysql-bin.index 索引文件


binlog日誌切割就是肯定全備和binlog增量備份的臨界點。
-F參數 切割binlog日誌,將會從備份完成時刻起,使用新的binlog日誌文件從新記錄,未來增量恢復重新的binlog日誌文件開始便可。
當備份多個庫時,每一個庫都會刷新一次binlog,若是隻想刷新一次binlog,可加--lock-all-tables或--master-data參數。
[root@db01 ~]# mysqldump -uroot -p -S /data/mysql/3306/mysql.sock -F -B --set-gtid-purged=OFF app|gzip > /backup/mysql/3306/app_$(date +%F).sql.gz
Enter password:

[root@db01 ~]# ls -l /data/mysql/3306/logs/
total 12
-rw-r----- 1 mysql mysql 177 Aug  1 18:46 mysql-bin.000001
-rw-r----- 1 mysql mysql 154 Aug 28 04:38 mysql-bin.000002
-rw-r----- 1 mysql mysql  39 Aug 28 04:38 mysql-bin.index

[root@db01 ~]# mysqldump -uroot -p -S /data/mysql/3306/mysql.sock -F -B --set-gtid-purged=OFF app|gzip > /backup/mysql/3306/app_$(date +%F).sql.gz
Enter password:

[root@db01 ~]# ls -l /data/mysql/3306/logs/
total 16
-rw-r----- 1 mysql mysql 177 Aug  1 18:46 mysql-bin.000001
-rw-r----- 1 mysql mysql 201 Aug 28 04:40 mysql-bin.000002
-rw-r----- 1 mysql mysql 154 Aug 28 04:40 mysql-bin.000003
-rw-r----- 1 mysql mysql  78 Aug 28 04:40 mysql-bin.index


mysqldump提供一個參數--master-data,不用刷新binlog,也能找到全量和增量的臨界點。
在備份的文件對應的SQL語句裏會添加change master語句及binlog文件及位置點。
[root@db01 ~]# mysqldump -uroot -p -S /data/mysql/3306/mysql.sock --master-data=1 --set-gtid-purged=OFF app --compact|head -1
Enter password: 
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=154;

[root@db01 ~]# mysqldump -uroot -p -S /data/mysql/3306/mysql.sock --master-data=2 --set-gtid-purged=OFF app --compact|head -1 
Enter password: 
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=154;

--master-data=1 備份結果爲可執行的change master to
--master-data=2 備份結果爲註釋的change master to


當全備完成後,全備時刻之前的binlog文件就無用了(默認保留7天),由於全備裏已經有這部分數據了。可是全備之後到下一次全備以前的數據就是十分重要的,這部分數據就存在於binlog裏。
所以在進行全備時須要找到全備以後和binlog增量之間的臨界點,使得恢復時,須要的binlog文件一條很少(不能和全備的內容重合),一條很多(全備後的全部數據都要有)。


3.-x參數,鎖定全部表備份(備份期間沒法寫入數據)
4.innodb表特有的備份參數--single-transaction(備份期間能夠寫入數據,可是新寫入的數據不會被備份到備份文件裏)
[root@db01 ~]# mysqldump -uroot -p -S /data/mysql/3306/mysql.sock -A -B --master-data=2 --set-gtid-purged=OFF --single-transaction |gzip > /backup/mysql/3306/full.sql.gz

--master-data會自動開啓-x鎖表參數功能。


5.mysqldump命令參數總結:
-B, --databases  能夠跟多個庫名,同時備份多個庫,備份文件中有create和use關鍵語句。
-A, --all-databases  備份全部的數據庫
-d, --no-data  只備份庫表結構,不備份行數據。
-t, --no-create-info  只備份表內行數據,不備份表結構。
-T, --tab=  將庫表和數據分離備份到不一樣的文件,行數據.txt,表結構.sql
-F, --flush-logs  刷新binlog日誌,生成新的binlog文件。
--master-data={1|2}  在備份結果中增長binlog日誌文件名及對應的binlog位置點。
-x, --lock-all-tables  備份時對全部數據庫的表執行全局讀鎖。鎖表備份數據,不容許備份期間寫入數據。
-l, --lock-tables  鎖定全部的表爲只讀。
--single-transaction  備份開始時刻的數據是什麼樣,備份出來就是什麼樣子。至關於鎖表備份數據(可是確實不是鎖表),容許備份期間寫入數據。
-R, --routines  備份存儲過程和函數數據。
--triggers  備份觸發器數據。
--compact  只顯示不多的有用輸出,適合學習測試環境調試用。


6.導入導出
(1).導出表
前面剛剛學的mysqldump -T參數導入.txt文本
[root@db01 ~]# mkdir -p /backup/mysql/txt
[root@db01 ~]# chown mysql:mysql /backup/mysql/txt

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p

mysql> use app;
Database changed

mysql> select * from t1 into outfile "/backup/mysql/txt/app_t1.txt";
Query OK, 9 rows affected (0.00 sec)

mysql> system cat /backup/mysql/txt/app_t1.txt;
1       app01
2       app02
3       app03
4       app04
5       app05
6       app06
7       app07
8       app08
9       app09


導出時設置字符集
mysql> select * from t1 into outfile "/backup/mysql/txt/app_t1.txt" charset utf8;
Query OK, 9 rows affected (0.00 sec)

mysql> system cat /backup/mysql/txt/app_t1.txt;
1       app01
2       app02
3       app03
4       app04
5       app05
6       app06
7       app07
8       app08
9       app09


指定分隔符導出
mysql> select * from t1 into outfile "/backup/mysql/txt/app_t2.txt" fields terminated by "_"; 
Query OK, 9 rows affected (0.00 sec)

mysql> system cat /backup/mysql/txt/app_t2.txt;
1_app01
2_app02
3_app03
4_app04
5_app05
6_app06
7_app07
8_app08
9_app09


導出時對字段加引號
mysql> select * from t1 into outfile "/backup/mysql/txt/app_t3.txt" fields enclosed by "'";
Query OK, 9 rows affected (0.00 sec)

mysql> system cat /backup/mysql/txt/app_t3.txt;
'1'     'app01'
'2'     'app02'
'3'     'app03'
'4'     'app04'
'5'     'app05'
'6'     'app06'
'7'     'app07'
'8'     'app08'
'9'     'app09'


(2).導入表
mysql> delete from t1;
Query OK, 9 rows affected (0.01 sec)

mysql> select * from t1;
Empty set (0.00 sec)

mysql> system cat /backup/mysql/txt/app_t1.txt; 
1       app01
2       app02
3       app03
4       app04
5       app05
6       app06
7       app07
8       app08
9       app09

mysql> load data infile "/backup/mysql/txt/app_t1.txt" into table t1;
Query OK, 9 rows affected (0.01 sec)
Records: 9  Deleted: 0  Skipped: 0  Warnings: 0

mysql> select * from t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | app01 |
|    2 | app02 |
|    3 | app03 |
|    4 | app04 |
|    5 | app05 |
|    6 | app06 |
|    7 | app07 |
|    8 | app08 |
|    9 | app09 |
+------+-------+
9 rows in set (0.00 sec)



mysql> delete from t1;
Query OK, 9 rows affected (0.01 sec)

mysql> system cat /backup/mysql/txt/app_t2.txt;
1_app01
2_app02
3_app03
4_app04
5_app05
6_app06
7_app07
8_app08
9_app09

mysql> load data infile "/backup/mysql/txt/app_t2.txt" into table t1 fields terminated by '_';
Query OK, 9 rows affected (0.00 sec)
Records: 9  Deleted: 0  Skipped: 0  Warnings: 0

mysql> select * from t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | app01 |
|    2 | app02 |
|    3 | app03 |
|    4 | app04 |
|    5 | app05 |
|    6 | app06 |
|    7 | app07 |
|    8 | app08 |
|    9 | app09 |
+------+-------+
9 rows in set (0.00 sec)


mysql> delete from t1;
Query OK, 9 rows affected (0.02 sec)

mysql> system cat /backup/mysql/txt/app_t3.txt;
'1'     'app01'
'2'     'app02'
'3'     'app03'
'4'     'app04'
'5'     'app05'
'6'     'app06'
'7'     'app07'
'8'     'app08'
'9'     'app09'

mysql> load data infile "/backup/mysql/txt/app_t3.txt" into table t1 fields enclosed by "'";
Query OK, 9 rows affected (0.02 sec)
Records: 9  Deleted: 0  Skipped: 0  Warnings: 0

mysql> select * from t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | app01 |
|    2 | app02 |
|    3 | app03 |
|    4 | app04 |
|    5 | app05 |
|    6 | app06 |
|    7 | app07 |
|    8 | app08 |
|    9 | app09 |
+------+-------+
9 rows in set (0.00 sec)



7.恢復數據庫
mysql命令、source命令恢復數據庫的原理就是在數據庫裏從新執行文件的SQL語句的過程。

(1).source命令恢復數據庫
[root@db01 ~]# mysqldump -uroot -p -S /data/mysql/3306/mysql.sock --set-gtid-purged=OFF -B app > /backup/mysql/3306/app_t1.sql

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p

mysql> use app;
Database changed

mysql> drop table t1;
Query OK, 0 rows affected (0.02 sec)

mysql> source /backup/mysql/3306/app_t1.sql;

mysql> select count(*) from t1;
+----------+
| count(*) |
+----------+
|        9 |
+----------+
1 row in set (0.00 sec)


[root@db01 ~]# mysqldump -uroot -p -S /data/mysql/3306/mysql.sock -B --master-data=2 --single-transaction --set-gtid-purged=OFF app|gzip > /backup/mysql/3306/app.sql.gz

[root@db01 ~]# ls -l /backup/mysql/3306/app.sql.gz
-rw-r--r-- 1 root root 864 Aug 28 05:29 /backup/mysql/3306/app.sql.gz

[root@db01 ~]# gzip -d /backup/mysql/3306/app.sql.gz
[root@db01 ~]# ls -l /backup/mysql/3306/
total 4
-rw-r--r-- 1 root root 2192 Aug 28 05:29 app.sql

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p

mysql> drop database app;
Query OK, 1 row affected (0.02 sec)

mysql> select * from app.t1;
ERROR 1146 (42S02): Table 'app.t1' doesn't exist

mysql> source /backup/mysql/3306/app.sql;

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| app                |
| app01              |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> select * from app.t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | app01 |
|    2 | app02 |
|    3 | app03 |
|    4 | app04 |
|    5 | app05 |
|    6 | app06 |
|    7 | app07 |
|    8 | app08 |
|    9 | app09 |
+------+-------+
9 rows in set (0.01 sec)


(2).mysql命令恢復數據庫
mysql> drop database app;
Query OK, 1 row affected (0.03 sec)

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p < /backup/mysql/3306/app.sql

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p

mysql> select * from app.t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | app01 |
|    2 | app02 |
|    3 | app03 |
|    4 | app04 |
|    5 | app05 |
|    6 | app06 |
|    7 | app07 |
|    8 | app08 |
|    9 | app09 |
+------+-------+
9 rows in set (0.00 sec)


(3).使用開發人員給的SQL語句恢復文件
開發寫的SQL文件,開頭可能沒有use app;
那你恢復就要指定庫名了呀,至關於use app;
# mysql -S /data/mysql/3306/mysql.sock -p app < /backup/app.sql


(4).開發人員提交插入的SQL語句,DBA執行前最好先指定字符集
咱們本身手寫一個sql文件
[root@db01 ~]# cat /tmp/insert.sql
set names utf8;
insert into t1(id,name) values(10,'app10');

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p app < /tmp/insert.sql

使用-e參數,能夠在命令行執行SQL語句。
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "select * from app.t1;"
Enter password: 
+------+-------+
| id   | name  |
+------+-------+
|    1 | app01 |
|    2 | app02 |
|    3 | app03 |
|    4 | app04 |
|    5 | app05 |
|    6 | app06 |
|    7 | app07 |
|    8 | app08 |
|    9 | app09 |
|   10 | app10 |
+------+-------+


總結:
若是mysqldump命令備份app數據庫時加了-B參數,備份文件中自帶use app和create database app,用mysql命令恢復時就不用指定use app了。
若是mysqldump命令備份app數據庫時沒有加-B參數,備份文件中就不會有use app和create database app,用mysql命令恢復時就要考慮app數據庫仍是否存在,不存在就create新建,存在的話恢復數據庫時就指定use app;


(5).恢復壓縮的備份數據
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF -B --master-data=2 --single-transaction app|gzip > /backup/mysql/3306/app.sql.gz

[root@db01 ~]# ls -l /backup/mysql/3306/
total 4
-rw-r--r-- 1 root root 869 Aug 28 18:50 app.sql.gz

方式一:使用gzip -d 解壓會刪除原備份壓縮文件
[root@db01 ~]# gzip -d /backup/mysql/3306/app.sql.gz
[root@db01 ~]# ls -l /backup/mysql/3306/
total 4
-rw-r--r-- 1 root root 2204 Aug 28 18:50 app.sql
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p < /backup/mysql/3306/app.sql

[root@db01 ~]# rm -rf /backup/mysql/3306/app.sql


方式二:gzip -cd 解壓不會刪除原備份壓縮文件
[root@db01 ~]# mysqldump -S /data/mysql/3306/mysql.sock -p --set-gtid-purged=OFF -B --master-data=2 --single-transaction app|gzip > /backup/mysql/3306/app.sql.gz

[root@db01 ~]# ls -l /backup/mysql/3306/
total 4
-rw-r--r-- 1 root root 874 Aug 28 18:54 app.sql.gz

[root@db01 ~]# gzip -cd /backup/mysql/3306/app.sql.gz > /tmp/app.sql
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p < /tmp/app.sql

[root@db01 ~]# rm -rf /tmp/app.sql


方式三:使用gunzip -cd 解壓不會刪除原備份文件
[root@db01 ~]# ls -l /backup/mysql/3306/
total 4
-rw-r--r-- 1 root root 874 Aug 28 18:54 app.sql.gz

[root@db01 ~]# gunzip -cd /backup/mysql/3306/app.sql.gz > /tmp/app.sql
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p < /tmp/app.sql

或者
[root@db01 ~]# gunzip < /backup/mysql/3306/app.sql.gz |mysql -S /data/mysql/3306/mysql.sock -p

[root@db01 ~]# rm -rf /tmp/app.sql


方式四:使用zcat讀取備份壓縮包數據
[root@db01 ~]# ls -l /backup/mysql/3306/
total 4
-rw-r--r-- 1 root root 874 Aug 28 18:54 app.sql.gz

[root@db01 ~]# zcat /backup/mysql/3306/app.sql.gz > /tmp/app.sql
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p < /tmp/app.sql

或者
[root@db01 ~]# zcat /backup/mysql/3306/app.sql.gz | mysql -S /data/mysql/3306/mysql.sock -p


以上四種方式均可以解壓備份文件,而後再進行恢復。
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p

mysql> drop database app;
Query OK, 1 row affected (0.02 sec)

[root@db01 ~]# zcat /backup/mysql/3306/app.sql.gz |mysql -S /data/mysql/3306/mysql.sock -p


8.mysql -e 參數,其實前面已經講過了
使用mysql -e 參數在Linux命令行執行SQL語句
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "select * from app.t1;"
Enter password: 
+------+-------+
| id   | name  |
+------+-------+
|    1 | app01 |
|    2 | app02 |
|    3 | app03 |
|    4 | app04 |
|    5 | app05 |
|    6 | app06 |
|    7 | app07 |
|    8 | app08 |
|    9 | app09 |
|   10 | app10 |
+------+-------+


使用mysql -e 參數在Linux命令行查看SQL線程執行狀態
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show processlist;"
Enter password: 
+----+------+-----------+------+---------+------+----------+------------------+
| Id | User | Host      | db   | Command | Time | State    | Info             |
+----+------+-----------+------+---------+------+----------+------------------+
| 20 | root | localhost | NULL | Query   |    0 | starting | show processlist |
+----+------+-----------+------+---------+------+----------+------------------+


查看完整的線程狀態
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show full processlist;"
Enter password: 
+----+------+-----------+------+---------+------+----------+-----------------------+
| Id | User | Host      | db   | Command | Time | State    | Info                  |
+----+------+-----------+------+---------+------+----------+-----------------------+
| 21 | root | localhost | NULL | Query   |    0 | starting | show full processlist |
+----+------+-----------+------+---------+------+----------+-----------------------+


MySQL系統的sleep線程過多,有大量的慢查詢語句,致使數據庫沒法接受正常的請求。
固然我這裏的數據庫沒有呀!
show full processlist;
在企業中你要是直接mysql> kill id號; 就直接殺掉了。
kill掉insert,update命令可能會丟失數據。

解決辦法:
先調整mysql的下面的兩個參數配置
mysql> show variables like "%_timeout%";
+-----------------------------+----------+
| Variable_name               | Value    |
+-----------------------------+----------+
| connect_timeout             | 10       |
| delayed_insert_timeout      | 300      |
| have_statement_timeout      | YES      |
| innodb_flush_log_at_timeout | 1        |
| innodb_lock_wait_timeout    | 50       |
| innodb_rollback_on_timeout  | OFF      |
| interactive_timeout         | 28800    |
| lock_wait_timeout           | 31536000 |
| net_read_timeout            | 30       |
| net_write_timeout           | 60       |
| rpl_stop_slave_timeout      | 31536000 |
| slave_net_timeout           | 60       |
| wait_timeout                | 28800    |
+-----------------------------+----------+
13 rows in set (0.00 sec)

mysql> set global wait_timeout = 60;
Query OK, 0 rows affected (0.01 sec)

mysql> set global interactive_timeout = 60;
Query OK, 0 rows affected (0.00 sec)


而後在配置文件my.cnf修改
[root@db01 ~]# vim /data/mysql/3306/my.cnf
[mysqld]
interactive_timeout = 120
wait_timeout = 120

利用mysql -e 參數查看mysql變量及性能狀態
[root@db01 ~]# mysql -uroot -poldboy123 -e "show variables;"

查看my.cnf配置文件是否在數據庫中生效
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p123 -e "show global variables like 'log_bin';"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+


查看mysql數據庫運行狀態
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show global status;"


用mysql -e修改數據庫參數不重啓數據庫直接臨時生效
[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show variables;"|grep key_buffer
Enter password: 
key_buffer_size 8388608

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "set global key_buffer_size = 1024*1024*16;"

[root@db01 ~]# mysql -S /data/mysql/3306/mysql.sock -p -e "show variables;"|grep key_buffer
Enter password: 
key_buffer_size 16777216

這樣你重啓數據庫就會失效滴!
由於你沒有寫到/data/mysql/3306/my.cnf
key_buffer_size = 16M


9.重要命令總結
(1).show顯示系列
show processlist; 查看數據庫里正在執行的SQL語句,可能沒法查看完整的SQL語句。
show full processlist; 查看正在執行的SQL語句,完整顯示。
set global key_buffer_size = 1024*1024*16; 不重啓數據庫調整參數,直接臨時生效,重啓後失效。
show variables; 查看數據庫的配置參數信息,例如my.cnf裏參數的生效狀況。
show variables like 'log_bin';
kill ID; 殺死SQL線程的命令,ID爲線程號。
show session status; 查看當前會話的數據庫狀態信息。
show global status; 查看整個數據庫運行的狀態信息。
show engine innodb status; 顯示innodb引擎的性能狀態


(2).mysqladmin命令經常使用參數
[root@db01 ~]# mysqladmin -S /data/mysql/3306/mysql.sock -p \
password 123 設置密碼
password 123 修改密碼
status 查看狀態,至關於mysql> show status ;
-i 1 status 每秒查看一次狀態
extended-status 等同於show global status;
flush-log 切割日誌
processlist 查看執行的SQL語句信息
processlist -i 1 每秒查看一次執行的SQL語句
shutdown 關閉mysql服務
variables 至關於show variables;


(3).mysql命令經常使用參數
-u 指定數據庫用戶
-p 指定數據庫用戶密碼
-S 指定數據庫socket文件
-h 指定數據庫主機,默認localhost
-P 指定數據庫實例的端口,默認3306
-e 不登陸數據庫在Linux命令行執行數據庫命令
--default-character-set=utf8 指定字符集登陸數據庫或備份
更多的命令信息,請看[root@linux-node1 ~]# mysql --help


10.mysqlbinlog增量恢復工具
(1).mysqlbinlog工具的做用是解析mysql的二進制binlog的日誌內容,把二進制日誌解析成能夠在mysql數據庫裏執行的SQL語句。
(2).mysql的binlog日誌用於記錄mysql內部的增刪改等更新操做,對數據庫的查詢語句不會被記錄。
(3).binlog日誌的主要做用是數據庫的主從複製,以及數據災難後的增量恢復。
(4).必須打開log_bin功能才能生成binlog日誌文件
[root@db01 ~]# grep "log_bin" /data/mysql/3306/my.cnf
log_bin                  = /data/mysql/3306/logs/mysql-bin

[root@testdb ~]# grep log-bin /data/3306/my.cnf
log-bin = /data/3306/mysql-bin
mysql 5.6之後應該是log_bin下劃線形式的呀

[root@db01 ~]# ls -l /data/mysql/3306/logs/
total 40
-rw-r----- 1 mysql mysql   177 Aug  1 18:46 mysql-bin.000001
-rw-r----- 1 mysql mysql   201 Aug 28 04:40 mysql-bin.000002
-rw-r----- 1 mysql mysql  7654 Aug 28 07:05 mysql-bin.000003
-rw-r----- 1 mysql mysql   241 Aug 28 07:05 mysql-bin.000004
-rw-r----- 1 mysql mysql   217 Aug 28 07:05 mysql-bin.000005
-rw-r----- 1 mysql mysql 11388 Aug 28 19:06 mysql-bin.000006
-rw-r----- 1 mysql mysql   195 Aug 28 16:47 mysql-bin.index

[root@db01 ~]# file /data/mysql/3306/logs/mysql-bin.000006
/data/mysql/3306/logs/mysql-bin.000006: MySQL replication log
binlog日誌是二進制格式的,不能使用查看文本工具的命令vim,vi,cat等去查看


(5).用mysqlbinlog -d參數解析指定庫的binlog日誌
-d 指定庫
-r 指定生成的文件
如下是MySQL5.6.40的環境,沒有開啓gtid。
[root@db01 ~]# mysql -uroot -p123
mysql> use app; 流程很重要!!!
mysql> insert into t1(name) values('zhouwanchun'); 流程很重要!!!
Query OK, 1 row affected (0.00 sec)

[root@db01 ~]# mysqlbinlog -d app /data/mysql/3306/logs/mysql-bin.000001 -r /tmp/bin.sql
[root@db01 ~]# ls -l /tmp/bin.sql
-rw-rw---- 1 root root 1832 Apr  2 23:09 /tmp/bin.sql

[root@db01 ~]# grep -i insert /tmp/bin.sql 看到了剛剛insert的語句了吧
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
SET INSERT_ID=11/*!*/;
insert into t1(name) values('zhouwanchun')

MySQL5.7的gtid
[root@db01 ~]# mysqlbinlog --skip-gtids --include-gtids='a3ad97d4-b449-11e9-97c5-000c290c6b6c:1-6' /data/mysql/3306/logs/mysql-bin.000001 > bin.sql


(6).按照位置截取binlog內容(精確)
位置點,就是mysqlbinlog解析文件裏的不一樣行行首的"# at數字"標識的數據。
[root@db01 ~]# ls -l /data/mysql/3306/mysql-bin.000006
-rw-rw---- 1 mysql mysql 794 Mar 29 17:41 /data//msyql/3306/mysql-bin.000006
我要截取mysql-bin.000006文件從位置365到位置456的日誌:
開始位置點必需要在binlog裏,結尾位置點能夠不存在。
mysqlbinlog mysql-bin.000006 --start-position=365 --stop-position=456 -r /tmp/bin.sql

有頭無尾,請問結束位置是???如下命令能夠查看
mysqlbinlog mysql-bin.000006 --start-position=365 -r /tmp/bin.sql

有尾無頭,請問開始位置是???如下命令能夠查看
mysqlbinlog mysql-bin.000006 --stop-position=456 -r /tmp/bin.sql


(7).按照時間截取binlog內容(模糊,不許確)
時間點,就是mysqlbinlog解析文件裏的不一樣行行首的"# 170303 9:44:22"標識的數據。
mysqlbinlog mysql-bin.000006 --start-datetime='2018-10-16 08:20:21' --stop-datetime='2018-10-16 08:21:21' -r /tmp/bin.sql

有頭無尾,請問結束時間是???如下命令能夠查看
mysqlbinlog mysql-bin.000006 --start-datetime='2018-10-16 08:20:21' -r /tmp/bin.sql

有尾無頭,請問開始時間是???如下命令能夠查看
mysqlbinlog mysql-bin.000006 --stop-datetime='2018-10-16 08:21:21' -r /tmp/bin.sql

之後咱們增量恢復的時候就會用到mysqlbinlog命令
(8).mysqlbinlog命令經常使用參數
-d, --database=  指定庫拆分binlog
-r, --result-file=  指定解析binlog生成sql語句文件
-R, --read-from-remote-server  從mysql服務器讀取binlog日誌
-j, --start-position=  讀取binlog的開始位置點
--stop-position=       讀取binlog的結束位置點
--start-datetime=  讀取binlog的開始時間點
--stop-datetime=   讀取binlog的結束時間點
--base64-output=decode-rows  解析row級別binlog日誌的方法
例如:
mysqlbinlog --base64-output=decode-rows -vvv mysql-bin.000006
相關文章
相關標籤/搜索