專職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