Mysql原理、主從複製、半同步複製及基於SSL複製

本篇博文主要講解Mysql主從複製、半同步、基於SSL加密的複製mysql

簡介linux

MySQL是一個開放源碼的小型關聯式數據庫管理系統,開發者爲瑞典MySQL AB公司。MySQL被普遍地應用在Internet上的中小型網站中。因爲其體積小、速度快、整體擁有成本低,尤爲是開放源碼這一特色,許多中小型網站爲了下降網站整體擁有成本而選擇了MySQL做爲網站數據庫sql

Mysql複製
數據庫

Mysql內建的複製功能是構建大型、高性能應用程序的基礎;將Mysql的數據分佈到多個系統上,而這種分佈的機制是經過將一臺Mysql服務器的數據複製到其餘主機(slave)上,由slave主機讀取Master服務器的二進制日誌文件而後從新在本地執行一遍來實現
vim

注意:作Mysql主從複製時,全部更新操做都只能在Master服務器,而Slave服務只負責更新本身的數據並提供查詢操做緩存

作Mysql複製能解決什麼問題?
安全

一、數據的分佈bash

二、負載均衡服務器

三、備份操做網絡

四、高可用和容錯性

Mysql複製原理

總的來講Mysql的複製就三個步驟:

一、在Master服務器將改變的數據記錄到二進制日誌(binary log)中(這些記錄叫作二進制日誌事件)

二、Slave服務器將Master服務器上的二進制日誌拷貝到本身的中繼日誌(relay-log)中

三、Slave服務器讀取中繼日誌中的事件,而後將改變的數據寫入到本身的數據庫中

下面咱們使用一張圖來講明覆制的過程:

203250518.gif

第一步:是在Master服務器上記錄二進制日誌。在每一個更新數據的事務完成以前,Master服務器都會將數據更改記錄到二進制日誌中。即便事務在執行期間是交錯的,Mysql也會串行地將事務寫入到二進制日誌中。在把事件寫入二進制日誌以後,Master服務器告訴存儲引擎能夠提交事務了

第二步:是Slave服務器把主服務器的二進制日誌拷貝到本身的硬盤上,進入所謂的「中繼日誌」中。首先,它啓動一個工做線程,叫I/O線程,這個I/O線程開啓一個普通的客戶端鏈接,而後啓動一個特殊的二進制日誌轉儲進程(它沒有相應的SQL命令)。這個轉儲進程Master服務器的二進制日誌中讀取數據。它不會對事件進行輪詢。若是3跟上了Master服務器,就會進入休眠狀態並等待有新的事件發生時Master服務器發出的信號。I/O線程把數據寫入Slave服務器的中繼日誌中

第三步:SQL線程讀取中繼日誌,而且重放其中的事件,而後更新Slave服務器的數據。因爲這個線程能跟上I/O線程,中繼日誌一般在操做系統的緩存中,因此中繼日誌的開銷很低。SQL線程執行事件也能夠被寫入Slave服務器本身的二進制日誌中,它對於有些場景很實用

上圖中顯示了在Slave服務器有兩個運行的線程,在Master服務器上也有一個運行的線程:和其餘普通鏈接同樣,由Slave服務器發起的鏈接,在Master服務器上一樣擁有一個線程

配置注意事項

1、Master服務器必須開啓二進制日誌

2MasterSlaveServer-id不能相同

3、同一個Master的多個SlaveServer-id也不能相同

4Binlog_format最好相同

5、在Slave服務器上配置log-slave-updates=1時,也須要開啓二進制日誌;若是能夠推薦使用read_only選項,該選項會阻止沒有權限的線程修改數據


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


軟件版本

系統版本:CentOS 6.4_x86_64

Mysql版本:mysql-5.5.33-linux2.6-x86_64

環境介紹

224450798.gif


安裝前準備

一、修改主機名稱

######NOD1節點執行
sed -i 's@\(HOSTNAME=\).*@\1master.allen.com@g' /etc/sysconfig/network
hostname master.allen.com
######NOD2節點執行
sed -i 's@\(HOSTNAME=\).*@\1slave.allen.com@g' /etc/sysconfig/network
hostname slave.allen.com
註釋:修改文件須重啓系統生效,這裏使用"hostname"命令先修改文件而後執行命令修改主機名稱能夠不用重啓

二、配置主機名解析,這裏修改hosts文件來實現

######在兩臺服務器執行以下命令
cat >> /etc/hosts << EOF
172.16.14.1 master.allen.com master
172.16.14.2 slave.allen.com slave
EOF

三、同步兩臺服務器時間,保持時間一致;使用"ntpdate"命令更新時間,使用"date"命令查看時間;這裏不在介紹


Mysql安裝 Mysql下載點此處

一、在Master與Slave服務器上分別安裝Mysql

######在Master服務器上安裝Mysql
====================================================================
######添加Mysqld運行用戶
[root@master ~]# useradd -r -u 300 mysql
######建立數據存放目錄
[root@master ~]# mkdir -p /mydata/data
######解壓並建立軟連接
[root@master ~]# tar xf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local/
[root@master ~]# cd /usr/local/
[root@master local]# ln -s mysql-5.5.33-linux2.6-x86_64 mysql
[root@master local]# cd mysql
######爲Mysqld服務提供Sysv服務腳本並添加到系統服務設置爲開機自啓動
[root@master mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@master mysql]# chmod +x /etc/init.d/mysqld
[root@master mysql]# chkconfig --add mysqld
[root@master mysql]# chkconfig mysqld on
######爲Mysqld服務提供主配置文件
[root@master mysql]# cp support-files/my-large.cnf /etc/my.cnf
######修改主配置文件添加如下選項
[root@master mysql]# vim /etc/my.cnf
datadir = /mydata/data        #數據存放目錄
innodb_file_per_table = 1     #innodb表每表一個表空間
######修改PATH變量
[root@master mysql]# echo "PATH=/usr/local/mysql/bin:$PATH" >> /etc/profile
[root@master mysql]# . /etc/profile
######修改Mysqld服務的頭文件讓系統能夠識別
[root@master mysql]# ln -s /usr/local/mysql/include /usr/include/mysql
######修改Mysqld服務的庫文件讓系統能夠識別
[root@master mysql]# echo "/usr/local/mysql/lib" >> /etc/ld.so.conf
[root@master mysql]# ldconfig
######設置Mysqld服務的安裝程序與數據存放目錄屬主、屬組用戶
[root@master mysql]# chown -R root.mysql ./*
[root@master mysql]# chown -R  mysql.mysql /mydata/data
######初始化數據庫
[root@master mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
######啓動Mysqld服務測試
[root@master ~]# service mysqld start
Starting MySQL....                                         [  OK  ]
######在Slave服務器上安裝Mysql
====================================================================
######添加Mysqld運行用戶
[root@slave ~]# useradd -r -u 300 mysql
######建立數據存放目錄
[root@slave ~]# mkdir -p /mydata/data
######解壓並建立軟連接
[root@slave ~]# tar xf mysql-5.5.33-linux2.6-x86_64.tar.gz -C /usr/local/
[root@slave ~]# cd /usr/local/
[root@slave local]# ln -s mysql-5.5.33-linux2.6-x86_64 mysql
[root@slave local]# cd mysql
######爲Mysqld服務提供Sysv服務腳本並添加到系統服務設置爲開機自啓動
[root@slave mysql]# cp support-files/mysql.server /etc/init.d/mysqld
[root@slave mysql]# chmod +x /etc/init.d/mysqld
[root@slave mysql]# chkconfig --add mysqld
[root@slave mysql]# chkconfig mysqld on
######爲Mysqld服務提供主配置文件
[root@slave mysql]# cp support-files/my-large.cnf /etc/my.cnf
######修改主配置文件添加如下選項
[root@slave mysql]# vim /etc/my.cnf
datadir = /mydata/data        #數據存放目錄
innodb_file_per_table = 1     #innodb表每表一個表空間
######修改PATH變量
[root@slave mysql]# echo "PATH=/usr/local/mysql/bin:$PATH" >> /etc/profile
[root@slave mysql]# . /etc/profile
######修改Mysqld服務的頭文件讓系統能夠識別
[root@slave mysql]# ln -s /usr/local/mysql/include /usr/include/mysql
######修改Mysqld服務的庫文件讓系統能夠識別
[root@slave mysql]# echo "/usr/local/mysql/lib" >> /etc/ld.so.conf
[root@slave mysql]# ldconfig
######設置Mysqld服務的安裝程序與數據存放目錄屬主、屬組用戶
[root@slave mysql]# chown -R root.mysql ./*
[root@slave mysql]# chown -R  mysql.mysql /mydata/data
######初始化數據庫
[root@slave mysql]# ./scripts/mysql_install_db --user=mysql --datadir=/mydata/data/
######啓動Mysqld服務測試
[root@slave ~]# service mysqld start
Starting MySQL....                                         [  OK  ]

主從複製配置

一、在Master服務器上創建用於Slave服務器複製數據的賬戶

[root@master ~]# mysql
mysql> grant replication slave,replication client
on *.* to 'allen'@'172.16.14.2' identified by 'p@ssword';
Query OK, 0 rows affected (0.02 sec);
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> show grants for 'allen'@'172.16.14.2';  #查看用戶受權
+------------------------------------------------------------------------------------------------------------------------------------------------+
| Grants for allen@172.16.14.2                                                                                                                   |
+------------------------------------------------------------------------------------------------------------------------------------------------+
| GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'allen'@'172.16.14.2' IDENTIFIED BY PASSWORD '*4F477FE814A0E3A4A5FD42BBB87C2DE8C36750DE' |
+------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)

二、在Slave服務器上使用受權用戶鏈接測試

[root@slave ~]# mysql -uallen -pp@ssword -h 172.16.14.1
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.33-log MySQL Community Server (GPL)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>

三、修改Master服務器上的Mysqld主配置文件以下:

[root@master ~]# vim /etc/my.cnf
log-bin = mysql-bin              #二進制日誌文件
log_bin_index = mysql_bin.index  #二進制日誌文件索引
binlog_format = mixed            #設置日誌格式爲混合模式
server-id       = 10             #用於識別的ID
[root@master ~]# service mysqld restart #重啓服務使配置文件生效

四、修改Slave服務器上的Mysqld主配置文件以下:

[root@slave ~]# vim /etc/my.cnf
#binlog_format=mixed               #註釋此行
skip_slave_start = 1               #啓動服務時不自動啓動從服務線程
read_only = 1                      #設置Slave服務器爲只讀
relay_log = relay_log              #開啓中繼日誌文件
relay_log_index = relay_log.index  #開啓中繼日誌文件索引
server-id       = 20               #用戶識別的ID號
#log-bin=mysql-bin                 #註釋掉二進制日誌文件,由於Master服務器已經記錄了一份,這裏沒有必要再記錄一份,避免浪費資源
[root@slave ~]# service mysqld restart #重啓服務使配置生效

五、查看Master服務器的二進制日誌及二進制日誌事件位置用於Slave服務器複製

[root@master ~]# mysql -e 'show master status;'
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 |      107 |              |                  |
+------------------+----------+--------------+------------------+
註釋:
    File:表示今後日誌開始複製
    Position:表示從這個事件開始複製

六、在Slave服務器上同步Master服務器上面的數據以下:

mysql> change master to master_host='172.16.14.1',master_user='allen',master_password='p@ssword',
master_port=3306,master_log_file='mysql-bin.000004',master_log_pos=107;
============================================================================
######獵取指令幫助
mysql> help change master to
CHANGE MASTER TO
  MASTER_HOST='master.allen.com',     #主機名稱
  MASTER_USER='allen',                #鏈接Master服務器的受權用戶
  MASTER_PASSWORD='p@ssword',         #受權用戶密碼
  MASTER_PORT=3306,                   #端口
  MASTER_LOG_FILE='mysql-bin.000004', #二進制日誌文件
  MASTER_LOG_POS=107,                 #二進制日誌事件位置

七、啓動Slave服務器的複製線程並查看狀態

mysql> start slave;            #啓動Slave服務器線程
mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.14.1        #Master服務器地址
                  Master_User: allen              #鏈接Master服務器用戶名
                  Master_Port: 3306               #Master服務器監聽端口
                Connect_Retry: 60                 #重試時間間隔
              Master_Log_File: mysql-bin.000004   #I/O線程讀取的二進制日誌文件
          Read_Master_Log_Pos: 107                #I/O線程讀取的二進制日誌文件事件位置
               Relay_Log_File: relay_log.000002   #SQL線程正在讀取的中繼日誌文件
                Relay_Log_Pos: 253                #SQL線程讀取和執行的中繼日誌文件事件位置
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes                #Slave服務器IO線程狀態
            Slave_SQL_Running: Yes                #Slave服務器SQL線程狀態
              Replicate_Do_DB:                    #下面Replicate開頭的表示用來指明哪些庫或者表在複製時不須要同步
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0                 #SQL線程讀取日誌參數的錯誤數量
                   Last_Error:                   #SQL線程讀取日誌參數的錯誤消息
                 Skip_Counter: 0                 #最近被用於SQL_SLAVE_SKIP_COUNTER的值
          Exec_Master_Log_Pos: 107       
              Relay_Log_Space: 403               #全部原有中繼日誌的總大小
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No                #是否容許對Master服務器進行SSL鏈接
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0                 #落後於Master服務器的時間
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: 10

八、在Slave服務器查看啓動的線程

[root@slave ~]# mysql -e 'show processlist;'
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                                       | Info             |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+
|  1 | system user |           | NULL | Connect |  851 | Waiting for master to send event                                            | NULL             |
|  2 | system user |           | NULL | Connect |  851 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL             |
| 20 | root        | localhost | NULL | Query   |    0 | NULL                                                                        | show processlist |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------------+------------------+

九、在Master服務器建立數據庫並在Slave服務器上驗證是否存在

######在Master服務器建立數據庫並查看
[root@master ~]# mysql -e 'create database allen;'
[root@master ~]# mysql -e 'show databases'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| allen              |
| mysql              |
| performance_schema |
| test               |
+--------------------+
===========================================================
######在Slave服務器查看是否有"allen"數據庫
[root@slave ~]# mysql -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| allen              |    #數據庫已成功同步到Slave服務器
| mysql              |
| performance_schema |
| test               |
+--------------------+

十、在Master與Slave服務器查看二進制日誌事件位置已更新

######查看Master服務器
[root@master ~]# mysql -e 'show master status;'
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 |      192 |              |                  |
+------------------+----------+--------------+------------------+
==========================================================================
######查看Slave服務器
[root@slave ~]# mysql -e 'show slave status\G;' | grep "Read_Master_Log_Pos"
          Read_Master_Log_Pos: 192

半同步複製

簡述

半同步意思:表示Master服務器只須要接收到其中一臺Slave的返回信息,就會commit;不然須要等待直到超時時間而後切換成異步再提交;這樣作的目的可使主從數據庫的數據延遲縮小,能夠在損失很小的性能的前提下提升數據安全性

一、半同步的開啓也是比較簡單滴,只須要在Master與Slave服務器上都安裝上半同步的插件並啓用便可;而插件在Mysql的安裝目錄中:"/usr/local/mysql/lib/plugin/"

######查看半同步插件
ls /usr/local/mysql/lib/plugin
semisync_master.so    #用於Master服務器安裝的半同步插件
semisync_slave.so     #用於Slave服務器安裝的半同步插件

二、在Master與Slave服務器分別安裝半同步插件

######在Master服務器安裝半同步插件
[root@master ~]# mysql
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so'; #安裝Master半同步插件
mysql> set global rpl_semi_sync_master_enabled = 1;    #開啓Master半同步功能
mysql> set global rpl_semi_sync_master_timeout = 1000;
=========================================================================
######在Slave服務器安裝半同步插件
[root@slave ~]# mysql
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; #安裝Slave半同步插件
mysql> set global rpl_semi_sync_slave_enabled = 1;      #開啓Slave半同步功能
mysql> stop slave io_thread;start slave io_thread;      #重啓IO線程生效

三、查看半同步開啓狀態

######在Master服務器上查看
mysql> show global status like 'rpl_semi%';
+--------------------------------------------+-------+
| Variable_name                              | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients               | 1     | #已經有一個客戶端鏈接
| Rpl_semi_sync_master_net_avg_wait_time     | 0     |
| Rpl_semi_sync_master_net_wait_time         | 0     |
| Rpl_semi_sync_master_net_waits             | 0     |
| Rpl_semi_sync_master_no_times              | 0     |
| Rpl_semi_sync_master_no_tx                 | 0     |
| Rpl_semi_sync_master_status                | ON    | #已經爲開啓狀態
| Rpl_semi_sync_master_timefunc_failures     | 0     |
| Rpl_semi_sync_master_tx_avg_wait_time      | 0     |
| Rpl_semi_sync_master_tx_wait_time          | 0     |
| Rpl_semi_sync_master_tx_waits              | 0     |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0     |
| Rpl_semi_sync_master_wait_sessions         | 0     |
| Rpl_semi_sync_master_yes_tx                | 0     |
+--------------------------------------------+-------+
mysql> show global variables like '%rpl%';
+------------------------------------+-------+
| Variable_name                      | Value |
+------------------------------------+-------+
| rpl_recovery_rank                  | 0     |
| rpl_semi_sync_master_enabled       | ON    | #Master半同步已經開啓
| rpl_semi_sync_master_timeout       | 1000  | #超時時間
| rpl_semi_sync_master_trace_level   | 32    |
| rpl_semi_sync_master_wait_no_slave | ON    |
+------------------------------------+-------+
=========================================================================
######在Slave服務器上查看
mysql> show global status like 'rpl_semi%';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON    |         #已經爲開啓狀態
+----------------------------+-------+
mysql> show global variables like '%rpl%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_recovery_rank               | 0     |
| rpl_semi_sync_slave_enabled     | ON    |    #Slave半同步已經開啓
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+

四、查看Slave線程是否啓動

[root@slave ~]# mysql -e 'show slave status\G;' | grep Running
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
註釋:這兩項必須爲"Yes",若是是"No"說明啓動失敗

五、在Master服務器上將前面建立的"allen"數據庫刪除,而後驗證Slave服務器

######在Master服務器刪除數據庫
[root@master ~]# mysql -e 'drop database allen;'
[root@master ~]# mysql -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
=======================================================
######在Slave服務器查看
[root@slave ~]# mysql -e 'show databases;'
+--------------------+
| Database           |    註釋:已經成功刪除"allen"數據庫
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+

六、以上配置都不能永久生效,若是想要永久生效,將以上配置加入到配置文件重啓服務便可;這裏就不在演示了


基於SSL的複製

簡述

因爲Mysql的主從複製是明文傳送的,但若是在生產環境中跨網絡咱們使用主從仍是明文傳送的話,就保證不了數據的安全性,爲了解決這一問題,咱們須要加密進行傳送,也就是基於SSL的加密方法進行傳輸數據

一、將Master服務器本身作成CA服務器

[root@master ~]# cd /etc/pki/CA/
[root@master CA]# (umask 077;openssl genrsa -out private/cakey.pem 2048)
[root@master CA]# openssl req -new -x509 -key private/cakey.pem -out cacert.pem -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) []:ShangHai
Locality Name (eg, city) [Default City]:PuDong
Organization Name (eg, company) [Default Company Ltd]:Allen
Organizational Unit Name (eg, section) []:Tech
Common Name (eg, your name or your server's hostname) []:master.allen.com
Email Address []:
[root@master CA]# touch index.txt
[root@master CA]# echo 01 > serial

二、爲Master建立證書申請並由CA服務器簽發證書

[root@master CA]# mkdir /usr/local/mysql/ssl
[root@master CA]# cd /usr/local/mysql/ssl
[root@master ssl]# (umask 077;openssl genrsa -out master.key 2048)
[root@master ssl]# openssl req -new -key master.key -out master.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) []:ShangHai
Locality Name (eg, city) [Default City]:PuDong
Organization Name (eg, company) [Default Company Ltd]:Allen
Organizational Unit Name (eg, section) []:Tech
Common Name (eg, your name or your server's hostname) []:master.allen.com
Email Address []:master@allen.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
[root@master ssl]# openssl ca -in master.csr -out master.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: Sep 20 12:22:19 2013 GMT
            Not After : Sep 20 12:22:19 2014 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = ShangHai
            organizationName          = Allen
            organizationalUnitName    = Tech
            commonName                = master.allen.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
              16:89:07:36:58:C9:AD:7B:97:D6:77:2E:13:FB:66:4F:A9:2B:3E:A3
            X509v3 Authority Key Identifier:             keyid:D8:0B:06:3B:6B:1B:36:88:17:56:EB:2A:41:1A:20:A4:89:7F:97:6A
Certificate is to be certified until Sep 20 12:22:19 2014 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

三、爲Slave服務器建立證書申請

[root@slave ~]# mkdir /usr/local/mysql/ssl
[root@slave ~]# cd /usr/local/mysql/ssl
[root@slave ssl]# (umask 077;openssl genrsa -out slave.key 2048)
[root@slave ssl]# openssl req -new -key slave.key -out slave.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) []:ShangHai
Locality Name (eg, city) [Default City]:PuDong
Organization Name (eg, company) [Default Company Ltd]:Allen
Organizational Unit Name (eg, section) []:Tech
Common Name (eg, your name or your server's hostname) []:slave.allen.com
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

四、爲Slave服務器簽署證書

######將證書申請請求拷貝到CA服務器簽署
[root@slave ssl]# scp slave.csr master.allen.com:/tmp/
[root@master ~]# openssl ca -in /tmp/slave.csr -out /tmp/slave.crt -days 365
Using configuration from /etc/pki/tls/openssl.cnf
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Sep 20 12:32:55 2013 GMT
            Not After : Sep 20 12:32:55 2014 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = ShangHai
            organizationName          = Allen
            organizationalUnitName    = Tech
            commonName                = slave.allen.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:                 4E:19:98:5D:F5:D2:D1:71:8B:93:4F:84:3C:A2:C7:2C:FE:6D:E2:62
            X509v3 Authority Key Identifier:             keyid:D8:0B:06:3B:6B:1B:36:88:17:56:EB:2A:41:1A:20:A4:89:7F:97:6A
Certificate is to be certified until Sep 20 12:32:55 2014 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
######簽署好證書申請拷貝到Slave服務器
[root@master ~]# scp /tmp/slave.crt slave.allen.com:/usr/local/mysql/ssl/

五、將CA證書拷貝到Slave服務器併爲Master拷貝一份

[root@master ~]# scp /etc/pki/CA/cacert.pem slave.allen.com:/usr/local/mysql/ssl/
[root@master ~]# cp /etc/pki/CA/cacert.pem /usr/local/mysql/ssl/

六、修改Master與Slave服務器證書屬主、屬組爲"mysql"用戶

######修改Master服務器
[root@master ~]# chown -R mysql.mysql /usr/local/mysql/ssl
[root@master ~]# ll /usr/local/mysql/ssl/
-rw-r--r-- 1 mysql mysql 1415 Sep 20 20:57 cacert.pem
-rw-r--r-- 1 mysql mysql 4600 Sep 20 20:22 master.crt
-rw-r--r-- 1 mysql mysql 1054 Sep 20 20:20 master.csr
-rw------- 1 mysql mysql 1675 Sep 20 20:17 master.key
===============================================================
######修改Slave服務器
[root@slave ~]# chown -R mysql.mysql /usr/local/mysql/ssl
[root@slave ~]# ll /usr/local/mysql/ssl/
-rw-r--r-- 1 mysql mysql 1415 Sep 15 03:10 cacert.pem
-rw-r--r-- 1 mysql mysql 4598 Sep 15 03:05 slave.crt
-rw-r--r-- 1 mysql mysql 1054 Sep 15 03:00 slave.csr
-rw------- 1 mysql mysql 1675 Sep 15 02:59 slave.key
注意:Master與Slave服務器上的證書屬主、屬組必須爲mysql用戶及組

七、在Master與Slave服務器修改主配置文件開啓SSL加密功能

######修改Master服務器
[root@master ~]# vim /etc/my.cnf                  #添加以下選項
ssl                                               #開啓SSL功能
ssl_ca = /usr/local/mysql/ssl/cacert.pem          #指定CA文件位置
ssl_cert = /usr/local/mysql/ssl/master.crt  #指定證書文件位置
ssl_key = /usr/local/mysql/ssl/master.key   #指定密鑰所在位置
[root@master ~]# service mysqld restart           #重啓服務生效
====================================================================
######修改Slave服務器
[root@slave ~]# vim /etc/my.cnf
ssl
ssl_ca = /usr/local/mysql/ssl/cacert.pem
ssl_cert = /usr/local/mysql/ssl/slave.crt
ssl_key = /usr/local/mysql/ssl/slave.key
[root@slave ~]# service mysqld restart

八、在Master服務器查看SSL加密是否開啓;而後建立受權一個基於密鑰認證的用戶

[root@master ~]# mysql
mysql> show variables like '%ssl%';
+---------------+---------------------------------+
| Variable_name | Value                           |
+---------------+---------------------------------+
| have_openssl  | YES                             |
| have_ssl      | YES                             |
| ssl_ca        | /usr/local/mysql/ssl/cacert.pem |
| ssl_capath    |                                 |
| ssl_cert      | /usr/local/mysql/ssl/master.crt |
| ssl_cipher    |                                 |
| ssl_key       | /usr/local/mysql/ssl/master.key |
+---------------+---------------------------------+
mysql> grant replication client,replication slave on *.* to 'slave'@'172.16.%.%' identified by 'passwd' require ssl;
mysql> flush privileges;

九、查看Master服務器二進制日誌文件和事件位置用於Slave服務器鏈接從這個位置開始複製

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000004 |      350 |              |                  |
+------------------+----------+--------------+------------------+

十、測試使用加密用戶指定密鑰鏈接Master服務器

[root@slave ~]# mysql -uslave -ppasswd -h 172.16.14.1 --ssl-ca=/usr/local/mysql/ssl/cacert.pem --ssl-cert=/usr/local/mysql/ssl/slave.crt --ssl-key=/usr/local/mysql/ssl/slave.key
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 5
Server version: 5.5.33-log MySQL Community Server (GPL)
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>

十一、查看Slave服務器SSL是否開啓並鏈接Master服務器

######查看Slave服務器SSL是否開啓
[root@slave ~]# mysql
mysql> show variables like '%ssl%';
+---------------+---------------------------------+
| Variable_name | Value                           |
+---------------+---------------------------------+
| have_openssl  | YES                             |
| have_ssl      | YES                             |
| ssl_ca        | /usr/local/mysql/ssl/cacert.pem |
| ssl_capath    |                                 |
| ssl_cert      | /usr/local/mysql/ssl/slave.crt  |
| ssl_cipher    |                                 |
| ssl_key       | /usr/local/mysql/ssl/slave.key  |
+---------------+---------------------------------+
######鏈接Master服務器
mysql> change master to master_host='172.16.14.1',master_user='slave',master_password='passwd',
master_log_file='mysql-bin.000004',master_log_pos=350,master_ssl=1,
master_ssl_ca='/usr/local/mysql/ssl/cacert.pem',
master_ssl_cert='/usr/local/mysql/ssl/slave.crt',
master_ssl_key='/usr/local/mysql/ssl/slave.key';
######獲取命令幫助
mysql> help change master to
  | MASTER_SSL = {0|1}                        #是否使用SSL功能
  | MASTER_SSL_CA = 'ca_file_name'            #CA證書位置
  | MASTER_SSL_CERT = 'cert_file_name'        #指定本身的證書文件
  | MASTER_SSL_KEY = 'key_file_name'          #指定本身的密鑰文件

十二、查看Slave服務器狀態

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State:
                  Master_Host: 172.16.14.1
                  Master_User: slave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000004
          Read_Master_Log_Pos: 350
               Relay_Log_File: relay_log.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: mysql-bin.000004
             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: 350
              Relay_Log_Space: 107
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: Yes
           Master_SSL_CA_File: /usr/local/mysql/ssl/cacert.pem
           Master_SSL_CA_Path:
              Master_SSL_Cert: /usr/local/mysql/ssl/slave.crt
            Master_SSL_Cipher:
               Master_SSL_Key: /usr/local/mysql/ssl/slave.key
        Seconds_Behind_Master: NULL
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: 0

基於SSL複製的結果驗證

一、在Master服務器上建立數據庫

[root@master ~]# mysql -e 'create database slave;'
[root@master ~]# mysql -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| slave              |
| test               |
+--------------------+

二、登陸Slave服務器驗證"slave"數據庫是否存在

[root@slave ~]# mysql -e 'show databases;'
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| slave              |
| test               |
+--------------------+

到此Mysql的主從複製、半同步複製、基於SSL加密的複製已所有完成,後續會更新Mysql的主、主複製,敬請關注!!!

相關文章
相關標籤/搜索