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