06.19 MySQL數據庫備份(進階)

第一章 SQL語句分類

1. DDL
數據庫定義語言 管理庫和表 create、drop、alter等
2. DCL
數據控制語言 用戶管理授權 grant、revoke、commit;rollback
3. DML
數據操作語言 針對表裏的數據 insert、delete、update、select

第二章 DDL語句之數據庫管理語言

1. 創建數據庫

mysql> create database oldboy;   #<==字符集和編譯指定相同.

2. 查詢數據庫

show databases;
show databases like '%old%';

3. 查看建庫的語句

mysql> show create database oldboy\G

4. 查看字符集

指定字符集建庫
CREATE DATABASE db_name CHARACTER SET  charset_name COLLATE collation_name
CREATE DATABASE oldgirl CHARACTER SET gbk COLLATE gbk_chinese_ci;
show character set;    #<==找字符集.
mysql> show variables like '%char%';  #查看默認字符集

5. 改庫的字符集

ALTER DATABASE [db_name] CHARACTER SET  charset_name COLLATE collation_name
ALTER DATABASE oldgirl CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

6. 字符集排序規則

mysql> show  collation;

7. 刪除庫

mysql> drop database oldboy;    

8. 切換庫

mysql> use oldboy
Database changed
mysql> select database();
+------------+
| database() |
+------------+
| oldboy     |
+------------+
1 row in set (0.00 sec)

9. 創建表

create table student(
id int(4) not null,
name char(20) not null,
age tinyint(2)  NOT NULL default '0',
dept varchar(16)  default NULL
);

10. 查看錶內容

mysql> select * from test;

11. 查看錶結構

desc student;

12. 查看建表的語句

mysql> show create table student\G
*************************** 1. row ***************************
       Table: student
Create Table: CREATE TABLE `student` (
  `id` int(4) NOT NULL,
  `name` char(20) NOT NULL,
  `age` tinyint(2) NOT NULL DEFAULT '0',
  `dept` varchar(16) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

13. 開發人員建表語句

CREATE TABLE `subject_comment_manager` (
  `subject_comment_manager_id` bigint(12) NOT NULL auto_increment COMMENT '主鍵',
  `subject_type` tinyint(2) NOT NULL COMMENT '素材類型',
  `subject_primary_key` varchar(255) NOT NULL COMMENT '素材的主鍵',
  `subject_title` varchar(255) NOT NULL COMMENT '素材的名稱',
  `edit_user_nick` varchar(64) default NULL COMMENT '修改人',
  `edit_user_time` timestamp NULL default NULL COMMENT '修改時間',
  `edit_comment` varchar(255) default NULL COMMENT '修改的理由',
  `state` tinyint(1) NOT NULL default '1' COMMENT '0代表關閉,1代表正常',
  PRIMARY KEY  (`subject_comment_manager_id`),
  KEY `IDX_PRIMARYKEY` (`subject_primary_key`(32)),   #<==括號內的32表示對前32個字符做前綴索引。
  KEY `IDX_SUBJECT_TITLE` (`subject_title`(32))
  KEY `index_nick_type` (`edit_user_nick`(32),`subject_type`)#<==聯合索引,此行爲新加的,用於給大家講解的。實際表語句內沒有此行。
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

14. char和varchear區別
這裏寫圖片描述
15. 更改表名

rename table student to test;
alter table test rename to student;

16. 添加行默認至行尾

mysql> alter table test add sex char(4);
Query OK, 0 rows affected (0.09 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc test;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| id    | int(4)   | NO   | PRI | NULL    | auto_increment |
| name  | char(20) | NO   |     | NULL    |                |
| sex   | char(4)  | YES  |     | NULL    |                |
+-------+----------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

17. 添加至name行後

#下面指定添加年齡列到name列後面的位置,示例如下:
alter table test add age int(4) after name;

18. 在第一列添加字段

#現在通過下面的命令在第一列添加qq字段。
alter table test add qq varchar(15) first;

19. 刪除字段

alter table test drop qq;

20. 同時添加兩個字段

#若要同時添加兩個字段,可採用如下命令。
mysql> alter table test add age tinyint(2) first,add qq varchar(15);

21. 改變字段

改變字段的命令如下:
alter table ett_ambiguity change ambiguity_state  ambiguity_state tinyint  comment '狀態,默認1=正常,0=失效';
ALTER TABLE `ett_photo`
MODIFY COLUMN `PHOTO_DESCRIPTION` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '描述' AFTER PHOTO_TITLE`;

修改字段類型的命令如下:
mysql> alter table test modify age char(4) after name;         
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

修改字段名稱的命令如下:
mysql> alter table test change age oldboyage char(4) after name;       

第三章 DCL語句之數據庫控制語言

1. 創建用戶
這裏寫圖片描述

CREATE USER '用戶'@'主機' IDENTIFIED BY '密碼';
mysql> create user oldboy@localhost identified by 'oldboy123';

2. 查看用戶權限

mysql> show grants for oldboy@localhost\G

3. 刪除用戶

mysql> select user,host from mysql.user;
mysql> drop user 'root'@'::1';
mysql> drop user 'root'@'mysql\_52';

4. 給用戶授權

mysql> grant all on *.* to chao@localhost;

5. 創建用戶同時授權

mysql> grant all on *.* to oldgirl@localhost identified by 'oldboy123';
mysql> flush privileges;

6. 收回權限

mysql> revoke insert on *.* from 'oldboy'@'localhost';
mysql> show grants for 'oldboy'@'localhost'\G
*************************** 1. row ***************************
Grants for oldboy@localhost: GRANT SELECT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, REPLICATION CLIENT, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE ON *.* TO 'oldboy'@'localhost' IDENTIFIED BY PASSWORD '*FE28814B4A8B3309DAC6ED7D3237ADED6DA1E515'
1 row in set (0.00 sec)
###刪除掉一個  然後就會顯示所有

7. 博客授權

grant select,insert,update,delete,create,drop on blog.* to  'blog'@'172.16.1.%' identified by 'oldboy123';
revoke create,drop on blog.* from 'blog'@'172.16.1.%';

mysql> create user blog@localhost identified by 'oldboy123';
mysql> select user,host from mysql.user;

8. 授權不規範導致的生產血案
運維人員授權用戶all權限了,導致開發通過該用戶自行改了表結構(字段),最後造成服務出問題,最後黑鍋甩在了運維人員身上。
運維人員排查了半天沒結果,最後對比表結構(把生產數據和備份的數據),發現了問題,最後告訴開發,把字段改回去,服務就好了。
啓發:生產場景儘量不要給開發select意外的權限,對於網站的連接賬號,不要授予select、insert、delete、update以外的權限。對別人的仁慈,就是對自己的崗位和公司最大的背叛。

第四章 DML語句之數據庫操作語言

1. 插入數據

use oldboy
drop table test;
CREATE TABLE test (
   id int(4) NOT NULL AUTO_INCREMENT,
  name char(20) NOT NULL,
  PRIMARY KEY (id)
) ;
desc test;


insert into test(id,name) values(1,'oldboy');
insert into test(name) values('oldgirl');

2. 插入兩行數據

mysql> insert into test values(3,'inca');
Query OK, 1 row affected (0.01 sec)

3. 插入多行數據

delete from test;
INSERT INTO `test` VALUES (1,'oldboy'),(2,'oldgirl'),(3,'inca'),(4,'zuma'),(5,'kaka');

4. 備份數據庫

[root@mysql_52 ~]# mysqldump -B --compact oldboy>/opt/bak.sql

5. 更改表中的內容

mysql> update test set id=6 where name='kaka';
mysql> update test set name='bingbing' where id='2';

6. 刪除防止不加條件

mysql> mysql -U

7. 查看用戶主機密碼

mysql> select user,host,password from mysql.user;
+---------+------------+-------------------------------------------+
| user    | host       | password                                  |
+---------+------------+-------------------------------------------+
| root    | localhost  | *FE28814B4A8B3309DAC6ED7D3237ADED6DA1E515 |
| root    | 127.0.0.1  |                                           |
| oldboy  | localhost  | *FE28814B4A8B3309DAC6ED7D3237ADED6DA1E515 |
| oldgirl | 172.16.1.% | *2CADADD54086D5EB4C9F10E0430084D7F179885C |
+---------+------------+-------------------------------------------+
4 rows in set (0.00 sec)

8. 條件where、and、or

mysql> select user,host from mysql.user where user='root' and host='127.0.0.1';
+------+-----------+
| user | host      |
+------+-----------+
| root | 127.0.0.1 |
+------+-----------+
1 row in set (0.00 sec)

9. select查看錶升降序

mysql> select id,name from test where id>2 order by id asc;
+----+------+
| id | name |
+----+------+
|  3 | inca |
|  4 | zuma |
|  5 | kaka |
+----+------+
3 rows in set (0.00 sec)

mysql> select id,name from test where id>2 order by id desc;
+----+------+
| id | name |
+----+------+
|  5 | kaka |
|  4 | zuma |
|  3 | inca |
+----+------+
3 rows in set (0.00 sec)

10. select查看錶limit

mysql> select id,name from test limit 1,3;
+----+---------+
| id | name    |
+----+---------+
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
+----+---------+
3 rows in set (0.00 sec)

mysql> select id,name from test limit 2,3;
+----+------+
| id | name |
+----+------+
|  3 | inca |
|  4 | zuma |
|  5 | kaka |
+----+------+
3 rows in set (0.00 sec)

mysql> select id,name from test limit 2,1;
+----+------+
| id | name |
+----+------+
|  3 | inca |
+----+------+
1 row in set (0.00 sec)

11. 模糊搜索內容%匹配

mysql> select id,name from test where name like 'old%';
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
+----+---------+
2 rows in set (0.00 sec)

mysql> select id,name from test where name like '%o%';

12. 刪除表中的數據

mysql> delete from test where id=2;
Query OK, 1 row affected (0.01 sec)

mysql> select id,name from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | oldboy |
|  3 | inca   |
|  4 | zuma   |
|  5 | kaka   |
+----+--------+
4 rows in set (0.00 sec)

mysql> delete from test where name='zuma';
Query OK, 1 row affected (0.03 sec)

mysql> select id,name from test;
+----+--------+
| id | name   |
+----+--------+
|  1 | oldboy |
|  3 | inca   |
|  5 | kaka   |
+----+--------+
3 rows in set (0.00 sec)

13. 僞刪除可恢復

mysql> alter table test add  state tinyint(2) not null default 1;
Query OK, 0 rows affected (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> 
mysql> desc test;
+-------+------------+------+-----+---------+----------------+
| Field | Type       | Null | Key | Default | Extra          |
+-------+------------+------+-----+---------+----------------+
| id    | int(4)     | NO   | PRI | NULL    | auto_increment |
| name  | char(20)   | NO   |     | NULL    |                |
| state | tinyint(2) | NO   |     | 1       |                |
+-------+------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

mysql> select id,name from test;
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
|  5 | kaka    |
+----+---------+
5 rows in set (0.00 sec)

mysql> update test set state=1;
Query OK, 0 rows affected (0.01 sec)
Rows matched: 5  Changed: 0  Warnings: 0

mysql> select id,name from test;
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
|  5 | kaka    |
+----+---------+
5 rows in set (0.00 sec)

mysql> select * from test;
+----+---------+-------+
| id | name    | state |
+----+---------+-------+
|  1 | oldboy  |     1 |
|  2 | oldgirl |     1 |
|  3 | inca    |     1 |
|  4 | zuma    |     1 |
|  5 | kaka    |     1 |
+----+---------+-------+
5 rows in set (0.00 sec)

mysql> select * from test where id=1;
+----+--------+-------+
| id | name   | state |
+----+--------+-------+
|  1 | oldboy |     1 |
+----+--------+-------+
1 row in set (0.01 sec)

mysql> select * from test where state=1;
+----+---------+-------+
| id | name    | state |
+----+---------+-------+
|  1 | oldboy  |     1 |
|  2 | oldgirl |     1 |
|  3 | inca    |     1 |
|  4 | zuma    |     1 |
|  5 | kaka    |     1 |
+----+---------+-------+
5 rows in set (0.00 sec)

mysql> 
mysql> 
mysql> 
mysql> 
mysql> select * from test where state=1;
+----+---------+-------+
| id | name    | state |
+----+---------+-------+
|  1 | oldboy  |     1 |
|  2 | oldgirl |     1 |
|  3 | inca    |     1 |
|  4 | zuma    |     1 |
|  5 | kaka    |     1 |
+----+---------+-------+
5 rows in set (0.00 sec)

mysql> 
mysql> 
mysql> 
mysql> 
mysql> select * from test where state=1;
+----+---------+-------+
| id | name    | state |
+----+---------+-------+
|  1 | oldboy  |     1 |
|  2 | oldgirl |     1 |
|  3 | inca    |     1 |
|  4 | zuma    |     1 |
|  5 | kaka    |     1 |
+----+---------+-------+
5 rows in set (0.00 sec)

mysql> 
mysql> update test set state=0 where name='oldboy';
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from test where state=1;
+----+---------+-------+
| id | name    | state |
+----+---------+-------+
|  2 | oldgirl |     1 |
|  3 | inca    |     1 |
|  4 | zuma    |     1 |
|  5 | kaka    |     1 |
+----+---------+-------+
4 rows in set (0.00 sec)

mysql> select * from test;
+----+---------+-------+
| id | name    | state |
+----+---------+-------+
|  1 | oldboy  |     0 |
|  2 | oldgirl |     1 |
|  3 | inca    |     1 |
|  4 | zuma    |     1 |
|  5 | kaka    |     1 |
+----+---------+-------+
5 rows in set (0.00 sec)

14. 物理刪除(慎用)

mysql> truncate table test;
Query OK, 0 rows affected (0.05 sec)

第五章 索引的管理

1. 各索引創建

mysql> desc test;
mysql> alter table test add index index_name(name);
mysql> desc test;
mysql> alter table test drop index index_name
mysql> desc test;
mysql> create index index_name on test(name);
mysql> alter table test add primary key(id);

##<==創建逐漸索引:
alter table student change id id

##<==刪除主鍵索引(主鍵列不能自增):
alter table student drop primary key;

##<==創建普通索引:
alter table student add index index_dept(dept);

##<==根據列的前n個字符創建索引
create index index_dept on student(dept(8));

##<==根據多個列創建聯合索引
create index ind_name_dept on student(name.dept);

##<==根據多個列的前n個字符創建聯合索引
create index ind_name_dept on student(name(8),dept(10));

##<==創建唯一索引
create unique index uni_ind_name on student(name);

##<==刪除普通索引與唯一索引
alter table student drop index index_dept

2. 創建索引小結

1、 索引類似數據的目錄,會加快查詢數據的速度。
2、 要在表的列(字段)上創建索引。
3、 索引會加快查詢速度,但是也會音響更新的數據,因爲更新要維護索引數據。
4、 索引列並不是越多越好,要在頻繁查詢的表語句where後的條件列上創建索引。
5、 小表或重複值很多的列上可以不建索引,要在大表以及重複值少的條件列上創建索引。
6、 多個列聯合索引有前綴生效特性。
7、 當字段內容前N個字符已經接近唯一時,可以對字段的前N個字符創建索引。
8、 索引從工作方式區分,有主鍵,唯一,普通索引。
9、 索引類型會有BTREE(默認)和hash(適合做緩存內存數據庫)等。

第六章 數據庫備份與恢復

1. 備份數據的意義
運維工作的核心簡單概括就兩件事:第一個是保護公司的數據,第二個是讓網站能7*24小時提供服務。
雖然這兩件事情很重要,相比較而言,丟失一部分數據和讓7*24小時提供服務,哪個更重要呢?
這就要看公司和具體的業務了。
例如:對於類似百度搜索、騰訊這樣的公司、丟失幾萬條記錄(比如QQ聊天記錄)。
對於絕大多數企業來講,丟失數據就失去商機,失去產品,失去客戶,甚至會造成公司倒閉,那麼,在所有的數據中,哪些數據又是最核心的呢?這恐怕要屬數據庫中的數據了,當然,並不是其他數據不重要,只是這一部分更具代表性。既然數據庫中的數據地位那麼高,那數據庫備份與恢復的重要性就不言而喻了。

2. mysqldump備份命令

##-A  --all-databases
mysqldump  -A >/opt/a.sql

##-B增加建庫(create)及(use)庫的語句,可以直接接多個庫名,同時備份多個庫
##-B 庫1 庫2
-d僅表結構
-t僅數據
--compact減少無用數據輸出
-F, --flush-logs 刷新binlog日誌

邏輯備份:
利用mysqldump命令備份數據的過程,實際上就是把數據(包括庫表)從MySQL庫裏以SQL語句的形式直接輸出或者生成備份文件的過程,這種備份成SQL語句的方式稱爲邏輯備份。

備份多個表:
mysqldump 庫1 表1 表2 表3 >庫1.sql
mysqldump 庫2 表1 表2 表3 >庫2.sql

2. mysqldump重要參數
這裏寫圖片描述
這裏寫圖片描述

3. 分庫備份:for循環

mysqldump -uroot -p'oldboy123' -B oldboy ...
mysqldump -uroot -p'oldboy123' -B oldboy_utf8 ...
mysqldump -uroot -p'oldboy123' -B mysql ...
......
分庫備份
for name in `mysql -e "show databases;"|sed 1d`
do
 mysqldump -uroot -p'oldboy123' -B $name
done

第七章 binlog備份恢復

1. binlog是什麼
binlog是一個二進制格式的文件,用於記錄用戶多數據庫更新的SQL語句信息,例如更改數據庫庫表和更改表內容的SQL語句都會記錄到binlog裏,但是對庫表等內容的查詢則不會記錄到日誌中。

2. binlog對於備份的作用
當有數據寫入到數據庫時,還會同時把更新的SQL語句寫入到對應的binlog文件裏,這個文件就是上文說的binlog文件。
使用mysqldump備份時,一般是對某一時刻的數據進行全備,例如0點進行數據庫備份。

3. 如何配置

[root@db02 ~]# mkdir /application/mysql/logs
[root@db02 ~]# chown -R mysql.mysql /application/mysql/logs
開啓binlog
編輯/etc/my.cnf
[mysqld]
log_bin = /application/mysql/logs/oldboy-bin
重啓:/etc/init.d/mysqld restart
[root@db02 ~]# ll /application/mysql/logs/
total 8
-rw-rw---- 1 mysql mysql 120 Jun 21 12:04 oldboy-bin.000001
-rw-rw---- 1 mysql mysql  42 Jun 21 12:04 oldboy-bin.index

4. -F刷新binlog

mysqldump -A -B -F >/opt/$(date +%F).sql
[root@db02 ~]# ll /application/mysql/logs/
-rw-rw---- 1 mysql mysql 168 Jun 21 12:06 oldboy-bin.000001
-rw-rw---- 1 mysql mysql 168 Jun 21 12:06 oldboy-bin.000002
-rw-rw---- 1 mysql mysql 210 Jun 21 12:07 oldboy-bin.index
提示:每個庫刷新一次.

第八章 innodb事務性引擎備份

1. innodb表特有的備份參數
當使用mysqldump的-single-transaction對innodb表進行備份時,會開啓一個事物,並將整個備份過程放到一個事物裏,以確保執行本次dump會話時,不會看到其他連接會話已經提交了的數據,即備份開始時刻的數據是什麼樣,備份出來就是什麼樣子,也相當於鎖表後備份的數據,但整個參數是允許備份期間寫入數據的,而不是在使用-x參數鎖表後, 備份期間無法寫入任何數據。

mysqldump -B --master-data=2 --single-transaction oldboy|gzip>/opt/all.sql.gz
--master-data={1|2} 告訴你備份後時刻的binlog位置
2 註釋
1 非註釋,要執行(主從複製)
[root@db02 logs]# mysqldump  -B --master-data=2 oldboy >/opt/t.sql


鎖表:適合所有引擎(myisam,innodb)
-x, --lock-all-tables 
-l, --lock-tables
mysqldump  -B -x oldboy >/opt/t.sql

m--->s(從庫備份)

基於事務引擎:不用鎖表就可以獲得一致性的備份.
99% 使用innodb事務引擎.ACID四大特性中的隔離性
--single-transaction

壓縮備份:
mysqldump  -B --master-data=2 oldboy|gzip >/opt/t.sql.gz

解壓:
zcat t.sql.gz >t1.sql
gzip -d t.sql.gz  #刪壓縮包

innodb引擎的備份命令如下:
mysqldump -A -B -R --triggers --master-data=2 --single-transaction |gzip >/opt/all.sql.gz

適合多引擎混合(例如:myisam與innodb混合)的備份命令如下:
mysqldump -A -B -R --triggers --master-data=2 |gzip >/opt/alL_$(date +%F).sql.gz

第九章 企業級數據備份案例

生產場景下,不同引擎的mysqldump備份命令
innodb引擎的備份命令如下:

mysqldump -A -B --master-data=2 --single-transaction|gzip >/opt/all.sql.gz
mysqldump  -B --master-data=2 --single-transaction oldboy |gzip >/opt/all.sql.gz
--single-transaction是innodb引擎轉悠備份參數,優勢就是備份期間數據依然可以執行寫操作。
#--master-data作用 適合多引擎混合(例如myisam與innodb混合)的備份命令如下: 2爲註釋 1爲可用
#這個備份的特點是會鎖表,在備份期間會影響數據寫入,使用--master-data會自動開啓-x鎖表參數功能。
mysqldump -A -B --master-data=2|gzip >/opt/all_$(date +%F).sql.gz

第十章 數據庫sleep線程過多案例

set global wait_timeout = 60;
set global interactive_timeout = 60;
然後在配置文件裏修改:
[mysqld]
interactive_timeout = 120 #<==此參數設置後wait_timeout自動生效。
wait_timeout = 120

其他補充方法:
在PHP程序中,不適用持久鏈接,即使用mysql_connect而不是pconnect
PHP程序執行完畢,應該顯示調用mysql_close
Java程序調整連接池(C3P0)或者調整Java服務(Tomcat有關連接池參數)。
逐步分析MySQL的SQL查詢及慢查詢日誌,找到查詢過慢的SQL,優化之。

第十一章 MySQL重點參數

mysql -e "show variables like '%log_bin%';"
mysql -e "show variables like '%timeout%';"
mysql -e "show global status;"
show processlist                             ##<==查看數據庫正在執行的SQL語句,可能無法看全完整SQL語句
show full processlise                        ##<==查看正在執行的完整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引擎的性能狀態(早期版本show innnodb status
MySQL常用參數 說明
-u 指定數據庫用戶
-p 指定數據庫密碼
-S 指定數據庫socket文件
-h 指定數據庫主機,默認爲localhost
-P 指定數據庫端口,默認爲3306
-e 不登錄數據庫執行數據庫命令
–default-character-set=name 指定字符集登錄數據庫或備份

第十二章 mysqladmin重點參數

mysqladmin的相關命令:
mysqladmin password oldboy123                  #<==設置密碼,前文用過的。
mysqladmin -uroot -poldboy123 password oldboy  #<==修改密碼,前文用過的。
mysqladmin -uroot -poldboy123 status           #<==查看狀態,相當於show status。
mysqladmin -uroot -poldboy123 -i 1 status      #<==每秒查看一次狀態。
mysqladmin -uroot -poldboy123 extended-status   #<==等同show global status;。
mysqladmin -uroot -poldboy123 flush-logs        #<==切割日誌。
mysqladmin -uroot -poldboy123 processlist       #<==查看執行的SQL語句信息。
mysqladmin -uroot -poldboy123 processlist -i 1  #<==每秒查看一次執行的SQL語句。
mysqladmin -uroot -p'oldboy' shutdown           #<==關閉mysql服務,前文用過的。
mysqladmin -uroot -p'oldboy' variables          #<==相當於show variables。

第十三章 MySQL的binlog日誌

1. binlog作用
MySQL的binlog日誌用來記錄MySQL內部增刪改等操作,也就是對MySQL數據庫更新內容的記錄(對數據庫的改動),對數據庫進行查詢的語句(如以show、select開頭的語句),不會被binlog日誌記錄。binlog日誌的主要作用是數據庫的主從複製以及數據災難後的增量恢復。

[root@db02 logs]# mysqlbinlog -d oldboy oldboy-bin.000005 oldboy-bin.000006 -r bin.sql
[root@db02 logs]# cat bin.sql

這裏寫圖片描述

2. 截取部分binlog根據pos位置

mysqlbinlog oldboy-bin.000009 --start-position=365 --stop-position=456 -r pos.sql   
mysqlbinlog oldboy-bin.000009 --start-position=365 --stop-position=456 -r pos.sql
mysqlbinlog oldboy-bin.000009 --start-position=365 -r pos.sql
mysqlbinlog oldboy-bin.000009 --stop-position=456 -r pos.sql

3. 截取部分binlog根據時間

mysqlbinlog oldboy-bin.000009 --start-datetime='2014-10-16 17:14:15' --stop-datetime='2014-10-16 17:15:15' -r time.sql
mysqlbinlog oldboy-bin.000009 --start-datetime='2014-10-16 17:14:15'  -r time.sql
mysqlbinlog oldboy-bin.000009  --stop-datetime='2014-10-16 17:15:15' -r time.sql

第十四章 MySQL企業級數據庫備份實踐

1. 數據庫管理員工作2大核心
能夠讓數據安全得到保護,所謂的數據安全,最容易被誤以爲只有備份和恢復,其實還包含數據被脫庫、泄密等的方面,本章主要講解備份和恢復。
能7*24小時提供服務,數據庫具備7*24小時的服務能力,數數據庫管理員的重要職責,在後文會爲大家講解MySQL的主從複製集羣、MySQL Mha+Keepalived集羣、讀寫分離等綜合保障數據庫具備7*24的服務能力的措施。

1. 全量備份
全量數據就是數據庫中的所有數據(或某一庫的全部數據);全量備份就是把數據庫中所有的數據進行備份。
以InnoDB引擎數據庫爲例:

#備份數據庫中所有庫的所有數據命令爲:
mysqldump -B --master-data=2 --single-transaction -A |gzip >/opt/all.sql.gz

#備份oldboy一個庫中所有數據的命令爲:
mysqldump -B --master-data=2 --single-transaction oldboy|gzip >/opt/oldboy.sql.gz

2. 增量備份
增量數據就是指上一次全量備份數據之後到下一次全備之前數據庫所更新的數據。在使用mysqldump命令做全備時,增量數據就是MySQL的binlog日誌,因此,對binlog日誌的備份在此處就可以稱爲增量備份,當然,有些工具本身就可以實現全量以及增量數據的備份,例xtrabackup工具。

3. 邏輯備份
邏輯備份的有點爲操作簡單、方便、可靠,並且備份的數據可以跨平臺、跨版本、甚至跨軟件、跨操作系統, 還可以實現分庫分表備份;邏輯備份也有一定的缺點,例如:備份速度比物理備份慢、恢復的效率也不是特別高。

邏輯備份常用工具
mysqldump是MySQL官方自帶的最常用邏輯備份工具,還能實現分表分庫備份,也是本章重點講解的備份工具。除此之外,還有一個mydumper工具,它是一個在GPL許可下發布的高性能MySQL備份和恢復工具集。

適用於數據量不是特別大的場景,例如,打包前不大於30GB的數據庫數據,30GB的值主要是考慮備份效率的問題,以及管理員使用複雜度的平衡。
不過,在跨版本、跨軟件升級或遷移數據的時候,此時物理備份一般就不能使用了。

第十五章 物理備份方式

1. 冷備
MySQL的物理備份方法之一是使用cp、rsync、tar、scp等複製工具把MySQL數據文件複製成多份,由於在備份期間數據仍然有寫入操作,所以直接複製的方式備份會引起數據丟失。另外在恢復數據庫時,對新數據庫的路徑、配置也有要求,一般要和原庫的配置保持一致(版本、路徑、配置儘可能一樣)。

爲了確保備份期間的數據一致性,可以選擇人工停庫或者鎖庫後在進行物理複製,而這在生產環境中一般是不允許的,除非是可以申請停機或鎖表時間,所以使用傳統Linux命令拷貝工具還是比較粗的冷備份方式,應避免使用,在後文還會提及根據MySQL主從複製利用從庫進行冷備的策略。

一般在進行大規模數據庫遷移時,先停庫,然後物理遷移,是很有效率的方案。

2. 溫備
只可讀不可寫

3. 熱備
除了在Linux命令行通過命令直接複製MySQL數據文件外,還有一些其它第三方的開源或商業物理熱備份工具。如xtrabackup。使用這個工具可以實現全量即增量備份。

4. 物理備份的特點
物理備份的優缺點正好和邏輯備份相反,因此在企業裏應根據需求,互補使用。
優點:速度快,效率高。
缺點:不容易跨平臺、跨版本、跨軟件、跨操作系統,可以實現分庫分表備份、但恢復麻煩很多,軟件的使用也比較複雜一些。

5. 物理備份常用工具和方法
Linux下冷備份工具爲cp、tar,備份時需要鎖表或者停庫確保數據一致性;開源的熱備份(基於innodb)工具則是xtrabackup。

6. 物理備份企業應用場景
數據庫總數據量超過30GB的,可使用xtrabackup熱備工具進行備份,以提升效率。
可以選擇在數據庫的從庫上進行備份,備份時停止SQL線程應用數據到數據庫,然後通過cp或tar打包備份,這也是不錯的冷備方案,不影響數據庫的服務。

7. 邏輯備份和物理備份區別

區別區別區別區別區別 邏輯備份 物理備份
備份原理 以SQL語句形式存儲 直接複製磁盤物理文件或其他非SQL語句方式的備份
相關命令 mysqldump、mysql、mysqlbinlog cp、rsync、tar、scp、xtrabackupp(熱備)
備份要求 需要鎖表但不需要停庫。鎖表會影響數據庫更新,innodb引擎可以不鎖表,而是採用事物備份方案。 冷備需要鎖表或停機,熱備不需要鎖表(僅事物引擎,例如innodb)或停機
配置特點 恢復時與系統版本,庫的配置甚至版本無關。 物理複製需要系統、配置、版本儘可能的一致。
性能特點 速度慢 速度快
方便性考慮 安全、易掌握、容易控制,一般不會丟失數據 冷備簡單,但應用場景少,熱備工具操作複雜一些,較難掌握

8. 全備的數據什麼時候可以派上用場

  1. 遷移或者升級數據庫時。
  2. 增加從庫的時候。
  3. 人爲執行DDL、DML語句破壞數據庫數據時(此時主從庫沒辦法了,所有庫都會執行)。
  4. 跨機房災備時,此時需要將全備份拷到異地。
  5. 若是因爲硬件或刪除物理文件導致數據庫故障,就不需要用備份數據恢復了,可以直接把主庫關閉,在從庫上配置好VIP等配置後,啓動從庫提供服務即可。

9. 企業裏MySQL備份策略選擇
大多數中小企業的數據庫環境都爲一主多從,因此,可採取在一個從庫服務器上專門做全量以及增量備份(需要開啓從庫記錄binlog日誌功能),至於備份方法,用mysqldump、xtrabackup均可。

第十六章 binlog邏輯備份恢復企業案例實操

具備全量備份(mysqldump)
除全量備份以外,還有全量備份之後產生的所有binlog增量日誌。

1. 準備環境

mysql> drop database oldboy;
mysql> create database oldboy;
mysql> use oldboy;

2. 創建表

mysql> CREATE TABLE `test` (   `id` int(4) NOT NULL AUTO_INCREMENT,   `name` char(20) NOT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

3. 表中插入內容

mysql> insert into `test` values (1,'oldboy'),(2,'olgirl'),(3,'inca'),(4,'zuma'),(5,'kaka');
mysql> select * from test;
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
|  5 | kaka    |
+----+---------+

4. 創建備份目錄

[root@mysql_52 logs]# mkdir /data/backup -p
[root@mysql_52 logs]# date -s "2017/06/22"

5. 全備份

[root@mysql_52 backup]# mysqldump -B --master-data=2 --single-transaction oldboy|gzip>/data/backup/oldboy_`date +%F`.sql.gz

6. 模擬增量

[root@mysql_52 backup]# mysql -e "use oldboy;insert into test values(6,'bingbing');"
[root@mysql_52 backup]# mysql -e "use oldboy;insert into test values(7,'xiaoting');"
[root@mysql_52 backup]# mysql -e "use oldboy;select * from test;"
+----+----------+
| id | name     |
+----+----------+
|  1 | oldboy   |
|  2 | olgirl   |
|  3 | inca     |
|  4 | zuma     |
|  5 | kaka     |
|  6 | bingbing |
|  7 | xiaoting |
+----+----------+


[root@mysql_52 backup]# date -s '2017/06/22 11:40'
[root@mysql_52 backup]# mysql -e "drop database oldboy;"

7. 開始恢復準備 採用iptable防火牆屏蔽所有應用程序的寫入

 ##<==非172.16.1.51禁止訪問數據庫3306端口
[root@mysql_52 backup]# iptables -I INPUT -p tcp --dport 3306 ! -s 172.16.1.51 -j DROP
##<==非172.16.1.51禁止訪問數據庫3306端口
[root@mysql_52 backup]# iptables -I INPUT -p tcp --dport 3306 ! -s 172.16.1.51 -j DROP

cp -a /application/mysql/logs/oldboy-bin.* /data/backup/
[root@mysql_52 backup]# zcat oldboy_2017-06-22.sql.gz >oldboy_2017-06-22.sql
[root@mysql_52 backup]# sed -n '22p' oldboy_2017-06-22.sql
[root@mysql_52 backup]# mysqlbinlog  -d oldboy --start-position=1459 oldboy-bin.000001 -r bin.sql

[root@mysql_52 backup]# grep -i drop bin.sql 
drop database oldboy
[root@mysql_52 backup]# sed -i '/drop/d' bin.sql
[root@mysql_52 backup]# mysql <oldboy_2017-06-22.sql
[root@mysql_52 backup]# mysql -e "show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| chaochao           |
| mysql              |
| oldboy             |
| performance_schema |
| qqqq               |
| test               |
+--------------------+

[root@mysql_52 backup]# mysql -e "use oldboy;select * from test;"
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
|  5 | kaka    |
+----+---------+

[root@mysql_52 backup]# mysql oldboy <bin.sql

[root@mysql_52 backup]# mysql -e "use oldboy;select * from test;"
+----+----------+
| id | name     |
+----+----------+
|  1 | oldboy   |
|  2 | oldgirl  |
|  3 | inca     |
|  4 | zuma     |
|  5 | kaka     |
|  6 | bingbing |
|  7 | xiaoting |
+----+----------+

##恢復完畢
##調整iptables允許用戶訪問.

[root@mysql_52 backup]# iptables -D INPUT 1
[root@mysql_52 backup]# iptables -nL

##多個binlog問題
==========================================================================
mysqlbinlog -d oldboy --start-position=339 oldboy-bin.000009 oldboy-bin.0000010 -r bin1.sql
mysql oldboy <bin1.sql
==========================================================================

第十七章 Xtrabackup物理備份實操

1. Xtrabackup介紹
Xtrabackup是Percona公司專門針對MySQL數據庫開發的一款開源免費的物理備份(熱備)工具。可以對InnoDB和XtraDB等事物引擎的數據庫實現非阻塞(即不鎖表)方式的備份,也可以針對MyISAM等非事物引擎實現鎖表方式備份。

2. Xtrabackup的主要特點

  1. 直接拷貝物理文件,備份和恢復數據的速度非常快、安全可靠。
  2. 在備份期間執行的事務不會間斷,備份InnoDB數據不影響業務。
  3. 備份期間不增加太多數據庫的性能壓力。
  4. 支持對備份的數據自動校驗。
  5. 支持全量、增量、壓縮備份及流備份。
  6. 支持在線遷移表以及快速創建新的從庫。
  7. 支持幾乎所有版本的MySQL和MariaDB。

3. MySQL數據文件擴展名說明

文件擴展名 文件作用說明
.idb 以獨立表空間存儲的InnoDB引擎類型的數據文件擴展名
.ibdata文件 以共享表空間存儲的InnoDB引擎類型的數據文件擴展名
.frm文件 存放與表相關的元數據(meta)信息及表結構的定義信息
.MYD文件 存放MyISAM引擎表的數據文件擴展名
.MYI文件 存放MyISAM引擎表的索引信息文件擴展名

4. 事務性引擎的ACID特性
在MySQL中,InnoDB和MariaDB中的XtraDB都是事務性引擎,事務性引擎的共同特徵是具備事物的4個特性,這4個特性分別是:原子性、一致性、隔離性、持久性,又稱ACID特性。

ACID特性
原子性(Atomicity) 事務的所有SQL語句操作,要麼全部成功,要麼全部失敗。
一致性(Consistency) 事務開始之前和結束之後,數據庫保證數據的完整性不被破壞
隔離性(Isolation) 當多個事務併發訪問同一個數據源時,數據庫能夠保持每個訪問的事務之間是隔離的,互不影響的。
持久性(Durability) 事務處理完成之後,事務所做的更改都是持久化存儲,不會丟失數據

5. Xtrabackup恢復工作原理過程
Percona Xtrabanckup軟件是基於innoDB等事務引擎自帶的redo日誌和undo日誌功能來保持備份和恢復前後數據一致性的,從而確保數據庫的數據安全可靠。在innoDB引擎中存在一個redo日誌(事務日誌)功能。redo日誌文件會存儲每一個innoDB表中數據被修改的記錄。當innoDB數據庫啓動時,會檢查數據文件和redo日誌文件,將已經提交到事務日誌(redo日誌文件)中的信息應用(提交)到數據文件並保存,然後根據undo日誌信息將修改過但沒有提交的數據記錄進行回滾(不提交到數據文件)。

6. Xtrabackup備份原理過程說明
當執行Xtrabackup程序開始備份時,Xtrabackup首先會記錄當前redo日誌的位置(即對應的LSN號),同時會在後臺啓動一個進程持續監視redo日誌文件的變化,並將變化的信息都記錄到Xtrabackup_logfile中,之後會針對所有的innodb數據文件進行備份(複製),待備份innodb數據文件完成後,則執行“flush tables with read lock”命令對整個數據庫鎖表,然後備份(複製)MyISAM等非事務引擎的數據文件。待全部(包括InnoDB、MyISAM數據文件和Redo日誌數據記錄)都備份完畢後,獲取Binlog二進制日誌位置點信息,最後執行unlock tables解鎖命令,恢復整個數據庫可讀寫狀態。
這裏寫圖片描述

6. 安裝Xtrabackup

yum -y install perl perl-devel libaio libaio-devel perl-Time-HiRes perl-DBD-MySQL

wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.4/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm
yum -y install percona-xtrabackup-24-2.4.4-1.el6.x86_64.rpm

mkdir -p /application/mysql/logs/
chown -R mysql.mysql /application/mysql/logs/

7. 配置my.cnf

[client]          
user=root         
password=oldboy123
[mysqld]
basedir = /application/mysql/   
datadir = /application/mysql/data/
###########binlog############
log_bin = /application/mysql/logs/oldboy-bin
expire_logs_days = 7             
[mysqld_safe]
log-error = /application/mysql/logs/oldboy.err
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
[root@mysql_52 ~]# /etc/init.d/mysqld restart

8. Xtrabackup命令
Xtrabackup命令是專門用於對innoDB和XtraDB等事務引擎的數據庫熱備份工具,不能用於備份MyISAM等其他類型的引擎數據,主要特點是備份數據時完全不用鎖表。

9. innobackupex命令
innobackupex命令時將上述Xtrabackup命令使用perl腳本進行二次封裝的工具,除了可以用於innoDB和XtraDB等引擎外,還可以備份MyISAM及多種引擎混合使用的場景,主要特點是備份事務引擎數據不用鎖表,可以備份非事務引擎數據,但要鎖表。

鑑於國內運維和DBA人員在企業裏常使用功能更多的innobackupex命令,來進行備份和恢復,因此本章頁也以此命令爲例講解Xtrabackup軟件的原理及備份恢復應用實踐。

10. 全備備份操作

mkdir /server/backup -p
innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.34/tmp/mysql.sock --no-timestamp /server/backup/full

11. 恢復數據操作

恢復數據
innobackupex --apply-log --use-memory=32M /server/backup/full/

停庫:
/etc/init.d/mysqld stop
lsof -i :3306

破壞數據:
cd /application/mysql/
mv data /opt/

恢復
cp -a /server/backup/full/ /application/mysql/data
chown -R mysql.mysql /application/mysql/data

啓動:
/etc/init.d/mysqld start
mysql -e "select * from oldboy.test"
成功。

12. innobackupex命令參數
這裏寫圖片描述
這裏寫圖片描述

13. 增量備份操作
中小企業MySQL Xtrabackup物理增量恢復案例實戰
條件:
 1.具備全量備份(xtrabackup備份的全備)。
 2.具備全量之後的所有增量備份(xtrabckup備份的增量)。
 3.具備最後一次增量備份以後的所有MySQL的Binlog增量日誌。

1】創建環境
use oldboy
delete from test;
insert into test values(1,'full01');
insert into test values(2,'full02');
insert into test values(3,'full03');
insert into test values(4,'full04');
insert into test values(5,'full05');
檢查:
select * from test;

【2】週一0點全量備份
date -s "2017/06/26"
innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.34/tmp/mysql.sock --no-timestamp /server/backup/new_base_full

【3】數據庫繼續更新
mysql -e "use oldboy;insert into test values(6,'new_inc_one_1');"
mysql -e "use oldboy;insert into test values(7,'new_inc_one_2');"
mysql -e "select * from oldboy.test;"4】週二0點增量備份
第一次增量備份
date -s "2017/06/27"
innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.34/tmp/mysql.sock --no-timestamp --incremental-basedir=/server/backup/new_base_full --incremental /server/backup/new_one_inc

【5】數據庫繼續更新
mysql -e "use oldboy;insert into test values(8,'binlog_data_1');"
mysql -e "use oldboy;insert into test values(9,'binlog_data_2');"
mysql -e "select * from oldboy.test;"6】週三0點增量備份
第二次增量備份
date -s "2017/06/28"
innobackupex --defaults-file=/etc/my.cnf --user=root --password=oldboy123 --socket=/application/mysql-5.6.34/tmp/mysql.sock --no-timestamp --incremental-basedir=/server/backup/new_one_inc --incremental /server/backup/new_two_inc

【7】數據庫繼續更新
mysql -e "use oldboy;insert into test values(10,'realbinlog_data_3');"
mysql -e "use oldboy;insert into test values(11,'realbinlog_data_4');"
mysql -e "select * from oldboy.test;"8】週三上午10點故障
##<==例如執行誤刪除命令

【9】開始恢復
##<==建議停庫:最好用iptables

【10】關閉訪問3306
iptables -I INPUT -p tcp --dport 3306 -j DROP
/etc/init.d/mysqld stop

【11】合併數據文件
innobackupex --apply-log --use-memory=32M --redo-only /server/backup/new_base_full/
innobackupex --apply-log --use-memory=32M --redo-only --incremental-dir=/server/backup/new_one_inc /server/backup/new_base_full/
innobackupex --apply-log --use-memory=32M --incremental-dir=/server/backup/new_two_inc /server/backup/new_base_full/
##<==數據文件準備完畢.

【12】開始正式恢復
cd /application/mysql
mv data data.ori
\cp -a /server/backup/new_base_full data
chown -R mysql.mysql data
================偷偷的看一下======================
[root@db02 mysql]# /etc/init.d/mysqld start
Starting MySQL.... SUCCESS! 
[root@db02 mysql]# mysql -e "select * from oldboy.test;"
+----+---------------+
| id | name          |
+----+---------------+
|  1 | full01        |
|  2 | full02        |
|  3 | full03        |
|  4 | full04        |
|  5 | full05        |
|  6 | new_inc_one_1 |
|  7 | new_inc_one_2 |
|  8 | binlog_data_1 |
|  9 | binlog_data_2 |
+----+---------------+
[root@db02 mysql]# /etc/init.d/mysqld stop
Shutting down MySQL.. SUCCESS! 
==================================================

【13】查看binlog位置點
[root@db02 mysql]# cat /server/backup/new_two_inc/xtrabackup_binlog_info
oldboy-bin.000011   239914】解析binlog
cd /application/mysql/logs/
mysqlbinlog -d oldboy --start-position=2399 oldboy-bin.000011 -r bin1.sql
mysqlbinlog -d oldboy oldboy-bin.000012 >>bin1.sql
(根據你的情況調整)

本次不用操作,但工作中可能有會有很多個binlog文件.
#mysqlbinlog -d oldboy  oldboy-bin.000012 oldboy-bin.000013 oldboy-bin.000014 >>bin2.sql

【15】刪除錯誤的update一行
grep update bin1.sql 
sed -i "/update test set name='oldboy'/d" bin1.sql 
grep update bin1.sql 

開始恢復
iptables -I INPUT -p tcp --dport 3306 -j DROP
/etc/init.d/mysqld start

【16】導入binlog.sql語句
mysql oldboy <bin1.sql 
檢查:
[root@db02 logs]# mysql -e "select * from oldboy.test;"
+----+-------------------+
| id | name              |
+----+-------------------+
|  1 | full01            |
|  2 | full02            |
|  3 | full03            |
|  4 | full04            |
|  5 | full05            |
|  6 | new_inc_one_1     |
|  7 | new_inc_one_2     |
|  8 | binlog_data_1     |
|  9 | binlog_data_2     |
| 10 | realbinlog_data_3 |
| 11 | realbinlog_data_4 |
+----+-------------------+

【17】調整防火牆規則
iptables -D INPUT -p tcp --dport 3306 -j DROP

10.和開發/運營交流,檢查數據恢復情況.
   專業故障恢復報告\發郵件\當面分享.
over.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章