一 mysqldump指令實現數據備份、mysql指令實現數據還原
經常有朋友問我,DBA到底是做什么的,百科上說:數據庫管理員(Database Administrator,簡稱DBA),是從事管理和維護數據庫管理系統(DBMS)的相關工作人員的統稱,屬於運維工程師的一個分支,主要負責業務數據庫從設計、測試到部署交付的全生命周期管理。DBA的核心目標是保證數據庫管理系統的穩定性、安全性、完整性和高性能。
百科出來的內容總是那么的專業,讓人看完之后的感覺是很解釋的很好,但是我沒有看懂或者似懂非懂的模糊感。。哈哈,其實我認為,DBA主要做三件事情:1.保證公司的數據不丟失不損壞 2.提高數據庫管理系統的工作性能
對於現在的公司來講,數據變得尤為重要,可以說最重要,你的網站可以無法訪問,服務器可以宕機,但是數據絕對不能丟,所以我們本節內容就沖着如果保護好數據而來的。本篇博客的內容並不是很深入,畢竟不是專業的DBA,只是作為超哥的講課內容,讓大家學一些數據備份的基本操作,入門級別咱們只講一下mysqldump指令,至於如果做主從復制,雙機熱備,數據庫高可用,數據庫集群,大家可以去看我其他的博客,博客寫完了,目前還在整理,整理好之后我就發出來供大家批評指正,共同學習~~~,因為畢竟咱們學的是開發,本篇內容就當作是拓展自己的知識領域吧,對你來講都是很有好處的~~~大家加油吧
那么我們就來學一下mysqldump指令。
1.首先我們先創建一個名為crm2的庫
mysql> create database crm2;
mysql> show create database crm2;
2.切換到crm2庫下
mysql> use crm2;
3.創建兩張表,student表和class表
mysql> create table tb1(id int primary key,name char(8) not null,age int,class_id int not null);
Query OK, 0 rows affected (0.63 sec)
mysql> create table class(id int primary key,cname char(20) not null);
Query OK, 0 rows affected (0.34 sec)
4.給兩張表插入一些數據
mysql> insert into class values(1,'一班'),(2,'二班');
mysql> insert into student values(1,'Jaden',18,1),(2,'太白',45,1),(3,'彥濤',30,2);
5.查看一下兩個表的數據
mysql> select * from student;
+----+--------+------+----------+
| id | name | age | class_id |
+----+--------+------+----------+
| 1 | Jaden | 18 | 1 |
| 2 | 太白 | 45 | 1 |
| 3 | 彥濤 | 30 | 2 |
+----+--------+------+----------+
3 rows in set (0.00 sec)
mysql> select * from class;
+----+--------+
| id | cname |
+----+--------+
| 1 | 一班 |
| 2 | 二班 |
+----+--------+
2 rows in set (0.00 sec)
好,前期工作准備完畢,下面我們來通過mysqldump指令進行備份,在cmd窗口下執行下面的指令,注意不是進入mysql里面輸入的,是在外面面。
C:\WINDOWS\system32>mysqldump -h 127.0.0.1 -u root -p666 crm2 > f:\數據庫備份練習\crm2.sql
Warning: Using a password on the command line interface can be insecure. (這個提示是因為我把密碼顯示出來了,自己在自己電腦上測試的時候,這個警告可以忽略)
然后我們就會發現在這個'f:\數據庫備份練習\'路徑下面就有了crm2.sql文件
然后我們通過nodepad++(隨便一個文本編輯器都可以),打開看看里面的內容:
-- MySQL dump 10.13 Distrib 5.6.42, for Win64 (x86_64)
--
-- Host: 127.0.0.1 Database: crm2
-- ------------------------------------------------------
-- Server version 5.6.42
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `class`
--
DROP TABLE IF EXISTS `class`; --如果之前存在class表,就將之前的class表刪除
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `class` ( --創建表
`id` int(11) NOT NULL,
`cname` char(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Dumping data for table `class`
--
LOCK TABLES `class` WRITE; --鎖表
/*!40000 ALTER TABLE `class` DISABLE KEYS */;
INSERT INTO `class` VALUES (1,'一班'),(2,'二班'); --插入數據
/*!40000 ALTER TABLE `class` ENABLE KEYS */;
UNLOCK TABLES; --解鎖
......
等等大致內容(如果你插入的數據有中文,這里顯示的確實亂碼的同學,往回看看我的關於修改mysql字符集編碼的博客,將編碼改為統一的,然后重新操作一遍就可以了)
上面的這個指令的意思就是將crm2這個庫,備份到這個'f:\數據庫備份練習\'路徑下,並且命名為crm2.sql文件。
執行備份語句的時候,其中可以加上很多的參數,用來添加一些備份的時候的特殊要求的,其中有一個-B參數,執行備份語句時,如果加上了-B參數,那么將來再執行數據還原的時候,就不需要自己到數據庫里面去先創建一個crm2這個庫了,並且執行數據還原語句的時候就不需要指定crm2這個庫了,如果沒有加-B參數,就需要自行到數據庫中先創建一個crm2這個庫,並且執行語句是要指定將數據恢復到這個crm2庫里面,看對比:
首先上面我們執行的語句中沒有加上-B參數,那么恢復數據的時候,怎么恢復呢,看下面的語句
1.連接到數據庫中,並創建crm2這個庫
mysql -u root -p666
mysql> create database crm2;
2.退出mysql或者重新啟動一個cmd窗口,然后執行
mysql -uroot -p 庫名 < mysqldump出來的那個sql文件的路徑
例如:mysql -uroot -p crm2< f:\數據庫備份練習\crm2.sql
3.這樣就恢復好了,我們連接上數據庫並查看里面的內容:
mysql -u root -p666
use crm2;
mysql> show tables;
+----------------+
| Tables_in_crm2 |
+----------------+
| class |
| student |
+----------------+
2 rows in set (0.00 sec)
mysql> select * from student;
+----+--------+------+----------+
| id | name | age | class_id |
+----+--------+------+----------+
| 1 | Jaden | 18 | 1 |
| 2 | 太白 | 45 | 1 |
| 3 | 彥濤 | 30 | 2 |
+----+--------+------+----------+
3 rows in set (0.00 sec)
mysql> desc student;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(8) | NO | | NULL | |
| age | int(11) | YES | | NULL | |
| class_id | int(11) | NO | | NULL | |
+----------+---------+------+-----+---------+-------+
4 rows in set (0.02 sec)
就這么簡單我們就將數據庫恢復了,表中的數據和表結構都恢復了。
執行mysqldump的時候加上了-B參數,那么恢復數據的時候,就不需要指定是恢復那個庫里面的數據了,也不需要提前到數據庫中創建一個crm2庫了,因為-B參數導出的文件中自帶創建數據庫和連接數據庫的功能:(使用-B參數備份出來的內容自帶create database 庫名和use 庫名的功能)
1.mysqldump -uroot -p -B crm2> f:\數據庫備份練習\crm2.sql
2.在cmd窗口下執行:mysql -uroot -p < f:\數據庫備份練習\crm2.sql
3.查看一下是否恢復了:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| crm2 |
| d1 |
| mysql |
| performance_schema |
| test |
+--------------------+
mysql> use crm2;
Database changed
mysql> show tables;
+----------------+
| Tables_in_crm2 |
+----------------+
| class |
| student |
+----------------+
2 rows in set (0.00 sec)
mysql> select * from class;
+----+--------+
| id | cname |
+----+--------+
| 1 | 一班 |
| 2 | 二班 |
+----+--------+
2 rows in set (0.00 sec)
mysql> desc student;
+----------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+---------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | char(8) | NO | | NULL | |
| age | int(11) | YES | | NULL | |
| class_id | int(11) | NO | | NULL | |
+----------+---------+------+-----+---------+-------+
4 rows in set (0.02 sec)
上面我們就完成了一個簡單數據庫備份和恢復的過程(在linux下面還可以在導出的時候壓縮文件內容,減小空間占用mysqldump -uroot -p -B crm2|gzip> f:\數據庫備份練習\crm2.sql.gz,windows好像是沒有自帶的zip壓縮指令,大家有興趣的可以去查一下,作為了解吧)
原理:其實很簡單,就是把數據從mysql庫里面以邏輯的sql語句的形式直接輸出或者生成備份文件的過程。
上面我們說完了單庫備份,下面來看看多個庫怎么備份呀
C:\WINDOWS\system32>mysqldump -uroot -p -B crm2 mysql> f:\數據庫備份練習\crm2mysql.sql
Enter password: ***
就是多個庫名用空格分開,這樣備份出來的sql文件還是一個,也就是這兩個庫都備份到一個文件里面了。一般作備份的時候的文件名字都是庫名.sql,多個庫一般就是庫名_庫名_庫名.sql。
那如果我們將很多的庫都是一起備份的,但是我們只想恢復其中一個庫怎么辦,這樣搞是不是就不太合適了(因為一個文件算是一個備份,在進行恢復的時候,一下就將文件里面的所有的庫都還原了,效率低不說,還麻煩),那就需要分庫備份了,也就是將每個庫分開來進行備份,自己備份自己的,一個一個來
其實就是執行多個單庫備份的語句
mysqldump -uroot -p -B crm2> f:\數據庫備份練習\crm2.sql
mysqldump -uroot -p -B mysql> f:\數據庫備份練習\crm2.sql
...
但是如果庫比較多(企業的數據庫里一般都會有多個庫),這么寫就比較麻煩了,所以需要獲取所有數據庫的庫名,然后根據庫名來循環執行上面的單庫備份的語句,並將庫名作為變量放到語句里面進行循環。需要寫腳本(就是一堆系統指令組成的程序)來做這件事情了,具體怎么做,咱們就不說啦,目前知道一下就可以了(寫一個.sh文件,然后sh+文件來執行這個文件,文件里面寫個for循環就行了,等你學會寫shell腳本就會了)
備份表:
上面我們說的是如何備份庫,現在我們來看看如果備份其中的某個表:
語法:mysqldump -u 用戶名 -p 庫名 表名> (路徑)備份的文件名
mysqldump -uroot -p crm2 student> f:\數據庫備份練習\crm2_table_student.sql
單純進行表備份的時候,就不用寫-B參數了,因為庫crm2后面就是student表了,也就是說你的crm2庫還在呢
備份多個表:
語法:mysqldump -u 用戶名 -p 庫名 表名1 表名2> (路徑)備份的文件名
和多個庫一起備份有一個同樣的問題,就是如果我只需要恢復某一張表怎么辦,上面的多表備份是不是也不太合適啊,所以又要進行分表備份
又是同樣的套路,獲取所有的表名,寫一個循環腳本,執行單表備份的指令。
分庫分表備份有些缺點:文件多,很碎,數據量非常大的時候,效率低
1.做一個完整的全備,再做一個分庫分表的備份
2.腳本批量恢復多個sql文件。
備份數據庫表結構:
利用mysqldump -d參數只備份表的結果,例如:備份crm2庫的所有表的結構:
C:\WINDOWS\system32>mysqldump -uroot -p -B -d crm2> f:\數據庫備份練習\crm2stru.sql
Enter password: ***
備份出來的文件打開一看,就沒有了插入數據的部分
mysqldump的關鍵參數說明:
1.-B指定多個庫,增加建庫語句和use 語句
2.--compact 去掉注釋,適合調試輸出,生產上不用
3.-A或者--all-databases
例如:C:\WINDOWS\system32>mysqldump -uroot -p -B -A> f:\數據庫備份練習\all.sql
Enter password: ***
4.-F刷新binlog日志(binlog具體是什么,后面咱們再解釋)
5.--master-data 增加binlog日志文件名及對應的為支點。
6.-x,--lock-all-tables 將所有的表鎖住,一般mysql引擎都是鎖表,全部都不能使用了,所有不太友好
7.--add-locks這個選項會在INSERT語句中捆上一個LOCK TABLE和UNLOCK TABLE語句。這就防止在這些記錄被再次導入數據庫時其他用戶對表進行的操作(mysql默認是加上的)
8.-l,--lock-tables Lock all tables for read
9.-d 只備份表結構
10.-t 只備份數據
11. --single-transaction 開啟事務,適合innodb事務數據庫備份
InnoDB表在備份時,通常啟用選項--single-transaction來保證備份的一致性,實際上他的工作原理時設定本次會話的隔離界別為:REPEATABLE READ,以確保本次會話(dump)時,不會看到其他會話已經提交了數據。
MyISAM全庫備份指令推薦:(gzip是壓縮文件為zip類型的)
mysqldump -uroot -p666 -A -B --master-data=2 -x|gzip>f:\數據庫備份練習\all.sql.gz
InnoDB全庫備份指令推薦:
mysqldump -uroot -p666 -A -B --master-data=2 --single-transaction|gzip>f:\數據庫備份練習\all.sql.gz
數據恢復:
一、通過source命令恢復數據庫
進入mysql數據庫控制台,mysql -uroot -p666登陸后
mysql>use 數據庫;
然后使用source命令,后面參數為腳本文件(如這里用到的是.sql文件,如果你備份的是.txt文件,那這里寫.txt文件)
mysql>source crm2.sql #這個文件是系統路徑下的,默認是登陸mysql前的系統路徑,在mysql中查看系統路徑的方法是通過system+系統命令來搞的
mysql>system ls
二、利用mysql命名恢復(標准)
mysql -root -p666 -e "use crm2;drop table student;show tables;" 必須是雙引號
mysql -uroot -p666 crm2<f:\數據庫備份練習\crm2.sql
mysql -uroot -p666 -e "use crm2;show tables;"
注:如果sql文件里面沒有use db這樣的字樣時,在導入時就要指定數據庫名了。
mysql -uroot -p666 crm2<.sql文件
建議備份數據庫時都指定上-B參數,效果好
說明:mysql不光可以恢復mysqldump的備份,只要文件中是sql語句,都可以通過mysql命令執行到數據庫中
mysql 帶-e參數實現非交互式對話,就是不需要到mysql里面去,在外面執行里面的指令的方法,例如:mysql -uroot -p666 -e "use crm2;show tables;",但是語句必須是雙引號包裹。
批量恢復庫:找到所有的數據庫名,然后通過庫名去循環恢復
關於binlog,等我整理好在給大家吧~~~
#下面的這些內容是我之前整理的,大家不要看了,我會改版的,等新版出來之后在發出來給大家,下面的太晦澀難懂了~~~
二 MySQL數據備份
#1. 物理備份: 直接復制數據庫文件,適用於大型數據庫環境。但不能恢復到異構系統中如Windows。 #2. 邏輯備份: 備份的是建表、建庫、插入等操作所執行SQL語句,適用於中小型數據庫,效率相對較低。 #3. 導出表: 將表導入到文本文件中。
一、使用mysqldump實現邏輯備份
#語法:
# mysqldump -h 服務器 -u用戶名 -p密碼 數據庫名 > 備份文件.sql
#示例:
#單庫備份
mysqldump -uroot -p123 db1 > db1.sql
mysqldump -uroot -p123 db1 table1 table2 > db1-table1-table2.sql #多庫備份 mysqldump -uroot -p123 --databases db1 db2 mysql db3 > db1_db2_mysql_db3.sql #備份所有庫 mysqldump -uroot -p123 --all-databases > all.sql
二、恢復邏輯備份
#方法一:
[root@localhost backup]# mysql -uroot -p123 < /backup/all.sql
#方法二:
mysql> use db1;
mysql> SET SQL_LOG_BIN=0; mysql> source /root/db1.sql #注:如果備份/恢復單個庫時,可以修改sql文件 DROP database if exists school; create database school; use school;
三、備份/恢復案例
#數據庫備份/恢復實驗一:數據庫損壞
備份:
1. # mysqldump -uroot -p123 --all-databases > /backup/`date +%F`_all.sql
2. # mysql -uroot -p123 -e 'flush logs' //截斷並產生新的binlog
3. 插入數據 //模擬服務器正常運行 4. mysql> set sql_log_bin=0; //模擬服務器損壞 mysql> drop database db; 恢復: 1. # mysqlbinlog 最后一個binlog > /backup/last_bin.log 2. mysql> set sql_log_bin=0; mysql> source /backup/2014-02-13_all.sql //恢復最近一次完全備份 mysql> source /backup/last_bin.log //恢復最后個binlog文件 #數據庫備份/恢復實驗二:如果有誤刪除 備份: 1. mysqldump -uroot -p123 --all-databases > /backup/`date +%F`_all.sql 2. mysql -uroot -p123 -e 'flush logs' //截斷並產生新的binlog 3. 插入數據 //模擬服務器正常運行 4. drop table db1.t1 //模擬誤刪除 5. 插入數據 //模擬服務器正常運行 恢復: 1. # mysqlbinlog 最后一個binlog --stop-position=260 > /tmp/1.sql # mysqlbinlog 最后一個binlog --start-position=900 > /tmp/2.sql 2. mysql> set sql_log_bin=0; mysql> source /backup/2014-02-13_all.sql //恢復最近一次完全備份 mysql> source /tmp/1.log //恢復最后個binlog文件 mysql> source /tmp/2.log //恢復最后個binlog文件 注意事項: 1. 完全恢復到一個干凈的環境(例如新的數據庫或刪除原有的數據庫) 2. 恢復期間所有SQL語句不應該記錄到binlog中
四、實現自動化備份
備份計划:
1. 什么時間 2:00
2. 對哪些數據庫備份 3. 備份文件放的位置 備份腳本: [root@localhost~]# vim /mysql_back.sql #!/bin/bash back_dir=/backup back_file=`date +%F`_all.sql user=root pass=123 if [ ! -d /backup ];then mkdir -p /backup fi # 備份並截斷日志 mysqldump -u${user} -p${pass} --events --all-databases > ${back_dir}/${back_file} mysql -u${user} -p${pass} -e 'flush logs' # 只保留最近一周的備份 cd $back_dir find . -mtime +7 -exec rm -rf {} \; 手動測試: [root@localhost ~]# chmod a+x /mysql_back.sql [root@localhost ~]# chattr +i /mysql_back.sql [root@localhost ~]# /mysql_back.sql 配置cron: [root@localhost ~]# crontab -l 2 * * * /mysql_back.sql
五、表的導出和導入
SELECT... INTO OUTFILE 導出文本文件
示例:
mysql> SELECT * FROM school.student1 INTO OUTFILE 'student1.txt' FIELDS TERMINATED BY ',' //定義字段分隔符 OPTIONALLY ENCLOSED BY '”' //定義字符串使用什么符號括起來 LINES TERMINATED BY '\n' ; //定義換行符 mysql 命令導出文本文件 示例: # mysql -u root -p123 -e 'select * from student1.school' > /tmp/student1.txt # mysql -u root -p123 --xml -e 'select * from student1.school' > /tmp/student1.xml # mysql -u root -p123 --html -e 'select * from student1.school' > /tmp/student1.html LOAD DATA INFILE 導入文本文件 mysql> DELETE FROM student1; mysql> LOAD DATA INFILE '/tmp/student1.txt' INTO TABLE school.student1 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '”' LINES TERMINATED BY '\n';
#可能會報錯
mysql> select * from db1.emp into outfile 'C:\\db1.emp.txt' fields terminated by ',' lines terminated by '\r\n';
ERROR 1238 (HY000): Variable 'secure_file_priv' is a read only variable #數據庫最關鍵的是數據,一旦數據庫權限泄露,那么通過上述語句就可以輕松將數據導出到文件中然后下載拿走,因而mysql對此作了限制,只能將文件導出到指定目錄 在配置文件中 [mysqld] secure_file_priv='C:\\' #只能將數據導出到C:\\下 重啟mysql 重新執行上述語句
六、數據庫遷移
務必保證在相同版本之間遷移
# mysqldump -h 源IP -uroot -p123 --databases db1 | mysql -h 目標IP -uroot -p456