第二十一周作業

1、回顧并詳細總結MySQL的存儲引擎、索引;

常用存儲引擎的對比:

特點 MyISAM InnoDB MEMORY MERGE NDB
存儲限制 64TB 沒有
事務安全 支持
鎖機制 表鎖 行鎖 表鎖 表鎖 行鎖
B樹索引 支持 支持 支持 支持 支持
哈希索引 支持
全文索引 支持
集群索引 支持
數據緩存 支持 支持 支持
索引緩存 支持 支持 支持 支持 支持
數據可壓縮 支持
空間使用 N/A
內存使用 中等
批量插入的速度
支持外鍵 支持

InnoDB:5.5版本之后默認的存儲引擎,具有提交、回滾和崩潰恢復能力的事務安全機制,但是對比MyISAM,InnoDB寫處理效率差一些,并且會占用更多的磁盤空間以保留數據和索引。
處理大量的短期事務;
數據存儲于“表空間(table space)”中;
(1) 所有InnoDB表的數據和索引放置于同一個表空間中;
表空間文件:datadir定義的目錄下
數據文件:ibddata1, ibddata2, …
(2) 每個表單獨使用一個表空間存儲表的數據和索引;
innodb_file_per_table=ON

數據文件(存儲數據和索引):tbl_name.ibd, 
表格式定義:tbl_name.frm

基于MVCC來支持高并發,支持所有的四個隔離級別,默認級別為REPEATABLE READ; 間隙鎖防止幻讀;
使用聚集索引
支持“自適應hash索引”
鎖粒度:行級鎖

MariaDB (XtraDB (percona))

數據存儲:表空間
并發:MVCC, 間隙鎖
索引:聚集索引、輔助索引
性能:預計操作、自適應hash、插入緩存區
備份:支持熱備(xtrabacup)

MyISAM:5.5之前版本的默認存儲引擎,MyISAM不支持事務、外鍵,其優勢是訪問速度快,并且支持全文索引,對事務完整性沒有要求或者以SELECT、INSERT為主的應用基本上都可以使用這個引擎來創建表。
支持全文索引(FULLTEXT index)、壓縮、空間函數(GIS); 但不支持事務,且為表級鎖;
崩潰后無法安全恢復

適用場景:只讀(或者寫較少)、表較?。梢越邮荛L時間進行修復操作)
Aria:crash-safe

文件:
tbl_name.frm: 表格式定義
tbl_name.MYD: 數據文件
tbl_name.MYI: 索引文件

特性:
加鎖和并發:表級鎖
修復:手工或自動修復、但可能丟失數據
索引:非聚集索引
延遲更新索引鍵:
壓縮表

行格式:dynamic, fixed, compressed, compact, redundent

其它的存儲引擎:
CSV:將普通的CSV(字段通過逗號分隔)作為MySQL表使用;
MRG_MYISAM:將多個MyISAM表合并成為一個虛擬表;
BLACKHOLE:類似于/dev/null,不真正存儲任何數據;
MEMORY:所有數據都保存于內存中,內存表;支持hash索引;表級鎖;
臨時表
PERFORMANCE_SCHEMA:偽存儲引擎;
ARCHIVE:只支持SELECT和INSERT操作;支持行級鎖和專用緩存區;
FEDERATED:用于訪問其它遠程MySQL服務器一個代理,它通過創建一個到遠程MySQL服務器的客戶端連接,并將查詢傳輸到遠程服務器執行,而后完成數據存??;
在MariaDB的上實現是FederatedX

MariaDB支持的其它存儲引擎:
OQGraph
SphinxSE
TokuDB
Cassandra
CONNECT
SQUENCE

MySQL中的索引:

基本法則:索引應該構建在被用作查詢條件的字段上;

索引類型:
B+ Tree索引:順序存儲,每一個葉子節點到根結點的距離是相同的;左前綴索引,適合查詢范圍類的數據;

可以使用B-Tree索引的查詢類型:
全值匹配:精確某個值, “Jinjiao King”;
匹配最左前綴:只精確匹配起頭部分,”Jin%”
匹配范圍值:
精確匹配某一列并范圍匹配另一列:
只訪問索引的查詢

不適合使用B-Tree索引的場景:
如果不從最左列開始,索引無效; (Age,Name)
不能跳過索引中的列;(StuID,Name,Age)
如果查詢中某個列是為范圍查詢,那么其右側的列都無法再使用索引優化查詢;(StuID,Name)

Hash索引:基于哈希表實現,特別適用于精確匹配索引中的所有列;
注意:只有Memory存儲引擎支持顯式hash索引;

適用場景:
只支持等值比較查詢,包括=, IN(), <=>; 

不適合使用hash索引的場景:
存儲的非為值的順序,因此,不適用于順序查詢;
不支持模糊匹配;

空間索引(R-Tree)
MyISAM支持空間索引,它可以使用諸如GEOMETRY這樣的地址空間數據類型。和B-Tree索引不同,空間索引不會要求WHERE子句使用索引的最左前綴。它同時全方位的索引了數據。這樣就可以高效的使用任何數據組合進行查找,然而,必須使用MySQL GIS函數,例如MBRCONTAINS(),才能得到這個好處。

全文索引(FULLTEXT)
FULLTEXT是MyISAM表的一種特殊索引,它從文本中找到關鍵字,而不是直接和索引中的值進行比較。

索引優點:
索引可以降低服務需要掃描的數據量,減少了IO次數;
索引可以幫助服務器避免排序和使用臨時表;
索引可以幫助將隨機I/O轉為順序I/O;

高性能索引策略:
獨立使用列,盡量避免其參與運算;
左前綴索引:索引構建于字段的左側的多少個字符,要通過索引選擇性來評估
索引選擇性:不重復的索引值和數據表的記錄總數的比值;
多列索引:
AND操作時更適合使用多列索引;
選擇合適的索引列次序:將選擇性最高放左側;

2、以實戰案例的形式總結MySQL的備份類型以及如何恢復等詳細操作;

MySQL常見的三種備份方式:

1)mysqldump+binlog,完全備份,通過備份二進制日志實現增量備份

2)lvm2快照+binlog:幾乎熱備,物理備份

3)xtrabackup: 
對InnoDB:熱備,支持完全備份和增量備份
對MyISAM引擎:溫備,只支持完全備份

環境:

源庫:192.168.0.23

目標庫:192.168.0.24

方式1:mysqldump+binlog

#+++++++++++++++++++++源庫++++++++++++++++++++++++++#
###開啟數據庫的二機制日志###
~]# vim /etc/my.cnf
[mysqld]
log-bin=mysql_bin
~]# systemctl start mariadb.service
> show global variables like '%log_bin%'; 
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| log_bin                         | ON    |
| log_bin_trust_function_creators | OFF   |
| sql_log_bin                     | ON    |
+---------------------------------+-------+

###使用mysqldump工具對數據庫進行全備###
~]# mysqldump -A --single-transaction --master-data=2 >/tmp/all.sql

###對數據庫做一些操作###
> create database mydb;
> use mydb;
> create table t1 (id int,name char(10));
> insert into t1 values (1,'Tom');
> select * from t1;
+------+------+
| id   | name |
+------+------+
|    1 | Tom  |
+------+------+

###假設此時數據庫發生故障,需要通過最近一次的全備和二進制日志在備庫上將數據庫恢復到故障點前的狀態###
###在備份文件確定起始pos和日志文件名###
~]# vim /tmp/all.sql
...
CHANGE MASTER TO MASTER_LOG_FILE='mysql_bin.000003', MASTER_LOG_POS=245;
...

###在源庫上導出全備后生成的log日志###
~]# mysqlbinlog --start-position=245 /var/lib/mysql/mysql_bin.000003 >/tmp/incre.sql

###將全備和增備數據傳送到目標庫系統上###
~]# scp /tmp/all.sql /tmp/incre.sql root@192.168.0.24:/tmp/

#+++++++++++++++++++++目標庫++++++++++++++++++++++++++#
###在目標庫上分別恢復全備和增備###
> set sql_log_bin=0;            #臨時關閉二進制日志,為了防止導入全備時產生大量二進制日志
> source /tmp/all.sql;       #導入全備
~]# mysql </tmp/incre.sql    #導入增備

###恢復后庫和表數據都存在,恢復成功!###
> select * from mydb.t1;
+------+------+
| id   | name |
+------+------+
|    1 | Tom  |
+------+------+
1 row in set (0.00 sec)

方式2:基于lvm2的快照

#+++++++++++++++++++++源庫++++++++++++++++++++++++++#
###創建一個LV,專門用來存放MySQL的數據文件###
~]# pvcreate /dev/sdb1
~]# vgcreate myvg /dev/sdb1
~]# lvcreate -n mydata -L 2G myvg
~]# mke2fs -t ext4 /dev/myvg/mydata
~]# mount /dev/myvg/mydata /var/lib/mysql

###制作lvm2快照###
mysql> FLUSH TABLES WITH READ LOCK;  #鎖定所有表
mysql> FLUSH LOGS;
mysql> SHOW MASTER STATUS;   #記錄二進制日志文件及事件位置
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000004 |      245 |              |                  |
+------------------+----------+--------------+------------------+
~]# lvcreate -L 1G -s -n mydata_snap /dev/myvg/mydata   #創建快照
mysql> UNLOCK TABLES; 

###對數據庫做一些操作###
mysql> create database mydb;
mysql> use mydb;
mysql> create table t1 (id int,name char(20));
mysql> insert into t1 values (1,'Tom'),(2,'Jerry');
mysql> select * from t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | Tom   |
|    2 | Jerry |
+------+-------+

###假設此時數據庫發生故障,需要使用lvm快照和二進制日志在備庫上將數據庫恢復到故障點前的狀態
###掛載并備份快照備份###
~]# mount /dev/myvg/mydata_snap /mnt/mydata_snap/
~]# cd /mnt/mydata_snap/
~]# tar -zcvf /tmp/mydata.tar.gz ./*

###在源庫上導出全備后生成的log日志###
~]# mysqlbinlog --start-position=245 /var/lib/mysql/mysql_bin.000004 >/tmp/incre.sql  ###將快照備份包和增量日志備份發送到目標庫###
~]# scp /tmp/mydata.tar.gz /tmp/incre.sql root@192.168.0.24:/tmp

#+++++++++++++++++++++目標庫++++++++++++++++++++++++++#
###在目標庫上進行全備和增量日志恢復###
~]# tar xf /tmp/mydata.tar.gz -C /var/lib/mysql
~]# systemctl start mariadb.service
mysql </tmp/incre.sql    #導入增量日志
###恢復后庫和表數據都存在,恢復成功!###
mysql> select * from mydb.t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | Tom   |
|    2 | Jerry |
+------+-------+

方式3:xtrabackup

#+++++++++++++++++++++源庫++++++++++++++++++++++++++#
###安裝xtrabackup包###
~]# rpm -ivh percona-xtrabackup-24-2.4.7-1.el7.x86_64.rpm

###進行全備###
~]# mkdir /backup
~]# innobackupex --user=root /backup
~]# ls /backup/
2017-07-14_21-08-00      #生成的全備文件夾 

###對數據庫做一些操作后進行增量備份###
mysql> create database mydb; mysql> use mydb;
mysql> create table t1 (id int,name char(20));
mysql> insert into t1 values (1,'Tom'),(2,'Jerry');
mysql> select * from t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | Tom   |
|    2 | Jerry |
+------+-------+
~]# innobackupex --incremental /backup/ --incremental-basedir=/backup/2017-07-14_20-23-25           #這里要指明最近一次全備文件夾名稱
~]# ls /backup/
2017-07-14_21-08-00  2017-07-14_21-09-15
~]# scp -r /backup/* root@192.168.0.24:/backup

#+++++++++++++++++++++目標庫++++++++++++++++++++++++++#
###在目標庫上對全量和增量備份集進行準備(prepare),準備的目的是對已提交的事務進行重放,未提交的事務進行回滾。###
~]# innobackupex --apply-log --redo-only /backup/2017-07-14_21-08-00/
~]# innobackupex --apply-log --redo-only /backup/2017-07-14_21-08-00/ --incremental-dir=/backup/2017-07-14_21-09-15/

###使用合并后的全量備份集進行恢復###
~]# innobackupex --copy-back /backup/2017-07-14_21-08-00/

###修改恢復后的數據文件權限,并啟動mysql服務###
~]# chown -R mysql.mysql /var/lib/mysql/*
~]# systemctl start mariadb.service

###恢復后庫和表數據都存在,恢復成功!###
mysql> select * from mydb.t1;
+------+-------+
| id   | name  |
+------+-------+
|    1 | Tom   |
|    2 | Jerry |
+------+-------+

3、MySQL的復制有哪些類型,詳細描述復制原理,并完成實際的操作。

方式1:主從模式

第二十一周作業

主從復制原理:

1) Slave服務器上執行start slave,開啟主從復制開關。
2) 此時,Slave服務器的IO線程會通過在Master上授權的復制用戶權限請求連接Master服務器,并請求從指定binlog日志文件的指定位置(日志文件名和位置就是在配置主從復制服務時執行change master命令時指定的)之后發送binlog日志內容。
3) Master服務器接收到來自Slave服務器的IO線程的請求后,Master服務器上負責復制IO線程根據Slave服務器的IO線程請求的信息讀取指定binlog日志文件指定位置之后的binlog日志信息,然后返回給Slave端的IO線程。返回信息中除了binlog日志內容外,還有本次返回日志內容后在Master服務器的新的Binlog文件名稱以及在binlog中的下一個指定更新位置。
4) 當Slave服務器的IO線程獲取到來自Master服務器上IO線程發送日志內容及日志文件位置點后,將binlog日志內容依次寫入到Slave端自身的relay log(即中繼日志)文件(MySQL-relay-bin.xxxxxx)的最末端,并將新的binlog文件名和位置記錄到master-info文件中,以便下一次讀取Master端新binlog日志時能夠告訴Master服務器需要新binlog日志的哪個文件哪個位置開始請求的binlog日志內容。
5) Slave服務器端的SQL線程會實時的檢測本地RelayLog中新增加的日志內容,然后及時的把Log文件中的內容解析成在Master端曾經執行的SQL語句的內容,并在自身Slave服務器上按語句的順序執行應用這些SQL語句,應用完畢后清理應用過的日志。
6) 經過了上面的過程,就可以確保在Master端和Slave端執行了同樣的SQL語句。當復制狀態正常的情況下,Master端和Slave端的數據是完全一樣的。

配置過程:

環境:

主庫:192.168.0.23

備庫:192.168.0.24

#+++++++++++++++++++++主庫++++++++++++++++++++++++++#
###修改主庫配置文件###
~]# vim /etc/my.cnf
[mysqld]
...
server-id=1     #此處server-id必須唯一
log-bin=master-bin  #開啟binlog日志
~]# systemctl start mariadb.service
###創建復制賬號###
mysql> grant replication slave,replication client on *.* to 'repluser'@'192.168.0.%' identified by 'replpass';
mysql> flush privileges;
mysql> show master status;   #查看主庫當前的日志pos
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000003 |      497 |              |                  |
+------------------+----------+--------------+------------------+
#+++++++++++++++++++++備庫++++++++++++++++++++++++++#
###修改備庫配置文件###
~]# vim /etc/my.cnf
[mysqld]
...
server-id=2     #此處server-id必須唯一
~]# systemctl start mariadb.service
###配置slave參數###
mysql> change master to master_host='192.168.0.23',master_user='repluser',master_password='replpass',master_log_file='mysql_bin.000003',master_log_pos=497;
mysql> start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.23
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000004
          Read_Master_Log_Pos: 421
               Relay_Log_File: mariadb-relay-bin.000004
                Relay_Log_Pos: 616
        Relay_Master_Log_File: mysql_bin.000004
             Slave_IO_Running: Yes      #只要Slave_IO_Running和Slave_SQL_Running都為Yes,主從復制就配置成功了
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 421
              Relay_Log_Space: 1285
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1

注意:如果主節點已經運行了一段時間,且有大量數據時,應當通過備份主服務器并恢復數據至從服務器;復制起始位置為備份時,二進制日志文件及其POS;

方式2:主主模式

主主同步實現原理與主從同步相似,只不過兩個節點互為主從,相對于主從模式,主主模式具有下列特點:

(1) 都啟用binlog和relay log 
(2) 定義自動增長的id字段的增長方式
(3) 都授權有復制權限的用戶賬號
(4) 各自把對方指定為主服務器

配置過程:

環境:

主庫:192.168.0.23

備庫:192.168.0.24

#+++++++++++++++++++++主庫1++++++++++++++++++++++++++#
###修改主庫1配置文件###
~]# vim /etc/my.cnf
[mysqld]
...
server-id=1     #此處server-id必須唯一
log-bin=master-bin  #開啟binlog日志
#下面兩個參數并非必須,但可以避免自增序列發生沖突
auto_increment_offset=1     #序列初始值,此處從奇數最小值開始
auto_increment_increment=2  #每次遞增的步長

~]# systemctl start mariadb.service


###創建復制賬號###
mysql> grant replication slave,replication client on *.* to 'repluser'@'192.168.0.%' identified by 'replpass';
mysql> flush privileges;
mysql> show master status;   #查看主庫當前的日志pos
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000003 |      507 |              |                  |
+------------------+----------+--------------+------------------+

#+++++++++++++++++++++主庫2++++++++++++++++++++++++++#
###修改備庫配置文件###
~]# vim /etc/my.cnf
[mysqld]
...
server-id=1     #此處server-id必須唯一
log-bin=master-bin  #開啟binlog日志
#下面兩個參數并非必須,但可以避免自增序列發生沖突
auto_increment_offset=2     #序列初始值,此處從偶數最小值開始
auto_increment_increment=2  #每次遞增的步長

~]# systemctl start mariadb.service

###創建復制賬號###
mysql> grant replication slave,replication client on *.* to 'repluser'@'192.168.0.%' identified by 'replpass';
mysql> flush privileges;
mysql> show master status;   #查看主庫當前的日志pos
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000003 |      507 |              |                  |
+------------------+----------+--------------+------------------+

###配置slave參數###
mysql> change master to master_host='192.168.0.23',master_user='repluser',master_password='replpass',master_log_file='mysql_bin.000003',master_log_pos=507;
mysql> start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.23
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000003
          Read_Master_Log_Pos: 507
               Relay_Log_File: mariadb-relay-bin.000002
                Relay_Log_Pos: 529
        Relay_Master_Log_File: mysql_bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 507
              Relay_Log_Space: 825
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1

#+++++++++++++++++++++主庫1++++++++++++++++++++++++++#
###配置slave參數###
mysql> change master to master_host='192.168.0.24',master_user='repluser',master_password='replpass',master_log_file='mysql_bin.000003',master_log_pos=507;
mysql> start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.24
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000003
          Read_Master_Log_Pos: 507
               Relay_Log_File: mariadb-relay-bin.000002
                Relay_Log_Pos: 529
        Relay_Master_Log_File: mysql_bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 507
              Relay_Log_Space: 825
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 2

方式3:半同步模式

半同步工作方式:介于異步復制和全同步復制之間,主庫在執行完客戶端提交的事務后不是立刻返回給客戶端,而是等待至少一個從庫接收到并寫到relay log中才返回給客戶端。相對于異步復制,半同步復制提高了數據的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步復制最好在低延時的網絡中使用。

原理圖:

第二十一周作業

存在的問題:

客戶端事務在存儲引擎層提交后,在得到從庫確認的過程中,主庫宕機了,此時,可能的情況有兩種:
1)事務還沒發送到從庫上。此時,客戶端會收到事務提交失敗的信息,客戶端會重新提交該事務到新的主上,當宕機的主庫重新啟動后,以從庫的身份重新加入到該主從結構中,會發現,該事務在從庫中被提交了兩次,一次是之前作為主的時候,一次是被新主同步過來的。
2)事務已經發送到從庫上。此時,從庫已經收到并應用了該事務,但是客戶端仍然會收到事務提交失敗的信息,重新提交該事務到新的主上。

配置方式:

環境:

主節點:192.168.0.23

備節點:192.168.0.24

1)在主備節點上均安裝半同步插件

#+++++++++++++++++++++主庫++++++++++++++++++++++++++#
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME          | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+

#+++++++++++++++++++++備庫++++++++++++++++++++++++++#
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';                 
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME          | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_slave  | ACTIVE        |
+----------------------+---------------+

2)修改主備節點上的配置文件

#+++++++++++++++++++++主庫++++++++++++++++++++++++++#
~]# vim /etc/my.cnf
[mysqld]
log-bin=mysql_bin
server-id=1

#+++++++++++++++++++++備庫++++++++++++++++++++++++++#
~]# vim /etc/my.cnf
[mysqld]
log-bin=mysql_bin
server-id=2

3)在主庫上創建復制用戶

mysql> grant replication slave,replication client on *.* to 'repluser'@'192.168.0.%' identified by 'replpass';
mysql> flush privileges;

4)查看主庫當前的binlog日志位置

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000003 |      507 |              |                  |
+------------------+----------+--------------+------------------+

5)在備庫上配置slave

mysql> change master to master_host='192.168.0.23',master_user='repluser',master_password='replpass',master_log_file='mysql_bin.000003',master_log_pos=507;

6)在主備節點上分別啟動半同步服務

#+++++++++++++++++++++主庫++++++++++++++++++++++++++#
mysql> set global rpl_semi_sync_slave_enabled=1;
mysql> show global variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled       | ON    |
| rpl_semi_sync_master_timeout       | 10000 |
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+

#+++++++++++++++++++++備庫++++++++++++++++++++++++++#
mysql> set global rpl_semi_sync_slave_enabled=1;                     
mysql> show global variables like '%semi%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_semi_sync_slave_enabled        | ON    |
| rpl_semi_sync_slave_trace_level    | 32    |
+------------------------------------+-------+

7)從節點上啟用半同步

mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.23
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000003
          Read_Master_Log_Pos: 507
               Relay_Log_File: mariadb-relay-bin.000002
                Relay_Log_Pos: 529
        Relay_Master_Log_File: mysql_bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 507
              Relay_Log_Space: 825
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1

方式4:基于SSL的主從復制

配置過程:

環境:

主庫:192.168.0.23

備庫:192.168.0.24

1)在主備節點分別搭建CA服務器和客戶端

#+++++++++++++++++++++主庫++++++++++++++++++++++++++#
###生成一個私鑰###
~]# (umask 077;openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096)
Generating RSA private key, 4096 bit long modulus
.........................................................................................................................................................++
.......................++
e is 65537 (0x10001)

###生成自簽證書###
~]# openssl req -new -x509 -key /etc/pki/CA/private/cakey.pem -out /etc/pki/CA/cacert.pem
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SHANXI
Locality Name (eg, city) [Default City]:XIAN
Organization Name (eg, company) [Default Company Ltd]:DCITS
Organizational Unit Name (eg, section) []:Ops
Common Name (eg, your name or your server's hostname) []:ca.dcits.com
Email Address []:fangtao@dcits.com

###為CA提供所需的目錄及文件###
~]# touch /etc/pki/CA/{serial,index.txt}
~]# echo 01>/etc/pki/CA/serial 

#+++++++++++++++++++++備庫++++++++++++++++++++++++++#
###生成簽署請求###
~]# mkdir /etc/mysql/ssl
~]# cd /etc/mysql/ssl
~]# (umask 077;openssl genrsa -out mysql.key 2048)
Generating RSA private key, 2048 bit long modulus
.....................................................................+++
...................+++
e is 65537 (0x10001)
~]# openssl req -new -key mysql.key -out mysql.csr -days 365
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:SHANXI
Locality Name (eg, city) [Default City]:XIAN
Organization Name (eg, company) [Default Company Ltd]:DCITS
Organizational Unit Name (eg, section) []:Ops
Common Name (eg, your name or your server's hostname) []:ca.dcits.com
Email Address []:fangtao@dcits.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

###將請求發送給主庫(CA主機)###
~]# scp mysql.csr mysql.key root@192.168.0.23:/tmp/

###

#+++++++++++++++++++++主庫++++++++++++++++++++++++++#
###在主庫(CA服務器)上簽署證書###
~]# openssl ca -in /tmp/mysql.csr -out /etc/pki/CA/certs/mysql.crt -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
        Validity
            Not Before: Jul 19 10:05:05 2017 GMT
            Not After : Jul 19 10:05:05 2018 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = SHANXI
            organizationName          = DCITS
            organizationalUnitName    = Ops
            commonName                = ca.dcits.com
            emailAddress              = fangtao@dcits.com
        X509v3 extensions:
            X509v3 Basic Constraints: 
                CA:FALSE
            Netscape Comment: 
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier: 
                A4:59:A0:16:FB:D4:C2:27:1A:09:61:FA:C4:39:B7:CE:01:60:2A:28
            X509v3 Authority Key Identifier: 
                keyid:0B:15:FD:99:9B:55:BB:52:B1:F3:37:50:42:BC:59:52:0A:13:CB:D9

Certificate is to be certified until Jul 19 10:05:05 2018 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

###將證書發送給備庫###
~]# scp mysql.crt cacert.pem root@192.168.0.24:/etc/mysql/ssl

###修改主庫上證書相關文件的權限###
~]# chown -R mysql.mysql /etc/pki/CA 

2)分別在主備庫上修改配置文件,啟用ssl

#+++++++++++++++++++++主庫++++++++++++++++++++++++++#
~]# vim /etc/my.cnf
[mysqld]
log-bin=mysql_bin
server-id=1
ssl
ssl_ca=/etc/pki/CA/cacert.pem
ssl_cert=/etc/pki/CA/certs/mysql.crt
ssl_key=/etc/pki/CA/private/mysql.key

~]# systemctl start mariadb.service
mysq> show variables like '%ssl%';
+---------------+-------------------------------+
| Variable_name | Value                         |
+---------------+-------------------------------+
| have_openssl  | YES                           |
| have_ssl      | YES                           |
| ssl_ca        | /etc/pki/CA/cacert.pem        |
| ssl_capath    |                               |
| ssl_cert      | /etc/pki/CA/certs/mysql.crt   |
| ssl_cipher    |                               |
| ssl_key       | /etc/pki/CA/private/mysql.key |
+---------------+-------------------------------+

#+++++++++++++++++++++備庫++++++++++++++++++++++++++#
~]# vim /etc/my.cnf
[mysqld]
server-id=2
log-bin=mysql_bin
ssl
ssl_ca=/etc/mysql/cacert.pem
ssl_cert=/etc/mysql/mysql.crt
ssl_key=/etc/mysql/mysql.key

~]# systemctl start mariadb.service
mysq> show variables like '%ssl%';
+---------------+-----------------------+
| Variable_name | Value                 |
+---------------+-----------------------+
| have_openssl  | DISABLED              |
| have_ssl      | DISABLED              |
| ssl_ca        | /etc/mysql/cacert.pem |
| ssl_capath    |                       |
| ssl_cert      | /etc/mysql/mysql.crt  |
| ssl_cipher    |                       |
| ssl_key       | /etc/mysql/mysql.key  |
+---------------+-----------------------+

3)在主庫上創建復制賬號

mysql> grant replication slave,replication client on *.* to 'repluser'@'192.168.0.%' require ssl;
mysql> set password for repluser=PASSWORD('replpass');
mysql> flush privileges;
mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000004 |      484 |              |                  |
+------------------+----------+--------------+------------------+

4)在從庫上開啟同步

mysql> change master to  
master_host='192.168.0.23', 
master_user='repluser', 
master_password='replpass', 
master_log_file='mysql_bin.000004', 
master_ssl=1, 
master_ssl_ca='/etc/mysql/ssl/cacert.pem', 
master_ssl_cert='/etc/mysql/ssl/mysql.crt', 
master_ssl_key='/etc/mysql/ssl/mysql.key';

5)啟動主從同步并查看狀態

mysql> start slave;
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.0.23
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql_bin.000008
          Read_Master_Log_Pos: 245
               Relay_Log_File: mariadb-relay-bin.000009
                Relay_Log_Pos: 529
        Relay_Master_Log_File: mysql_bin.000008
             Slave_IO_Running: Yes        #同步狀態正常! Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 245
              Relay_Log_Space: 825
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: Yes
           Master_SSL_CA_File: /etc/mysql/ssl/cacert.pem    #證書已被應用
           Master_SSL_CA_Path: 
              Master_SSL_Cert: /etc/mysql/ssl/mysql.crt
            Master_SSL_Cipher: 
               Master_SSL_Key: /etc/mysql/ssl/mysql.key
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1

方式5:過濾器

同步方式說明:讓從節點僅復制指定的數據庫,或指定數據庫的指定表;

有兩種實現方式:
1) 主服務器僅向二進制日志中記錄與特定數據庫(特定表)相關的事件;
問題:時間還原無法實現;不建議使用;
2) 從服務器SQL_THREAD在replay中繼日志中的事件時,僅讀取與特定數據庫(特定表)相關的事件并應用于本地;
問題:會造成網絡及磁盤IO浪費

配置過程:

環境:

主庫:192.168.0.23

備庫:192.168.0.24

1)基于數據庫過濾

#+++++++++++++++++++++主庫++++++++++++++++++++++++++#
###修改主庫配置文件###
~]# vim /etc/my.cnf
[mysqld]
...
server-id=1 
log-bin=master-bin
~]# systemctl start mariadb.service
###創建復制賬號###
mysql> grant replication slave,replication client on *.* to 'repluser'@'192.168.0.%' identified by 'replpass';
mysql> flush privileges;
mysql> show master status;   #查看主庫當前的日志pos
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql_bin.000009 |      497 |              |                  |
+------------------+----------+--------------+------------------+
#+++++++++++++++++++++備庫++++++++++++++++++++++++++#
###修改備庫配置文件###
~]# vim /etc/my.cnf
[mysqld]
...
server-id=2         
replicate-do-db=mydb        #表示和哪個數據庫相關的寫入類、修改類指令會被寫入
replicate-ignore-db=testdb      #表示忽略(黑名單)
~]# systemctl start mariadb.service
###配置slave參數###
mysql> change master to master_host='192.168.0.23',master_user='repluser',master_password='replpass',master_log_file='mysql_bin.000009',master_log_pos=497;
mysql> start slave;
mysql> show slave status\G;
mysql> show global variables like 'replicate%';
+----------------------------------+-----------+
| Variable_name                    | Value     |
+----------------------------------+-----------+
| replicate_annotate_row_events    | OFF       |
| replicate_do_db                  | mydb      |
| replicate_do_table               |           |
| replicate_events_marked_for_skip | replicate |
| replicate_ignore_db              | testdb    |
| replicate_ignore_table           |           |
| replicate_wild_do_table          |           |
| replicate_wild_ignore_table      |           |
+----------------------------------+-----------+

2)基于表過濾

步驟與基于庫一致,只是在修改備庫參數文件時使用:

replication-do-table=TABLE_NAME

replication-ignore-table=TABLE_NAME

3)基于表的通配符

步驟與基于庫一致,只是在修改備庫參數文件時使用:

replicate-wild-do-table=PATTERN
replicate-wild-ignore-table=PATTERN

原創文章,作者:N26-西安-方老喵,如若轉載,請注明出處:http://www.www58058.com/79377

(0)
N26-西安-方老喵N26-西安-方老喵
上一篇 2017-07-19
下一篇 2017-07-19

相關推薦

  • LINUX基礎知識

    計算機的組成及其功能。 現代計算機體系將計算機分為控制器、運算器、存儲器、輸入設備和輸出設備5個部分 *控制器:控制器是整個計算機的中樞神經,其功能是對程序規定的控制信息進行解釋,并根據具體要求進行控制、調度程序、數據、地址,協調計 算機各個部分工作,協調計算機各部分工作及內存、IO設備等的訪問 *運算器:運算器是對數據進行各種算數運算和邏輯運算也就是對數據…

    Linux干貨 2018-02-25
  • Linux基礎命令

    Linux基礎命令 大家都知道Linux是由許許多多的小程序組成的,而這些小程序是怎么啟動的呢?在Linux中這些小程序大多是靠命令來啟動運行的 命令(COMMAND):請求內核將某個二進制程序運行為一個進程的過程就是命令 程序由命令運行之后就會形成一個有生命周期的‘進程’,一個靜態的二進制程序運行為一個動態的進程是由命令發起的. 在Linux中命令可分為兩…

    Linux干貨 2016-11-02
  • gitlib環境部署

         GitLab是利用 Ruby on Rails一個開源的版本管理系統,實現一個自托管的Git項目倉庫,可通過Web界面進行訪問公開的或者私人項目。它擁有與Github類似的功能,能夠瀏覽源代碼,管理缺陷和注釋??梢怨芾韴F隊對倉庫的訪問,它非常易于瀏覽提交過的版本并提供一個文件歷史庫。它還提供一個代碼片段收集功能可以輕松…

    2016-05-19
  • rpm包管理

    一、什么是RPM     RPM全稱為“RedHat Package Manager”,看名字就知道這是RedHat公司搞出來的,后來因為RPM發展的很好,逐漸成為了一種通用的標準,就更名為“RPM is Package Manager"。     RPM最大的特點就是…

    Linux干貨 2015-05-11
  • 第三周作業

    1、列出當前系統上所有已經登錄的用戶的用戶名,注意:同一個用戶登錄多次,則只顯示一次即可。 [root@localhost /]# who | cut -d ‘ ‘ -f 1  | sort -u root user1 或: [root@localhost /]# who | cut -d ‘ ‘ -…

    Linux干貨 2017-02-24
  • IP SAN實驗

    實驗環境 centos7 serverx2 IP:192.168.0.206??? 192.168.0.207 iscsi-server端的配置 準備磁盤設備 安裝程序包 創建target 創建lun 授權   首先添加兩塊硬盤 sdb sdc 然后安裝軟件包 yum -y install epel-release yum -y install s…

    2017-12-16
欧美性久久久久