专职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

猜你喜欢

转载自www.cnblogs.com/zhouwanchun/p/11427092.html