本篇博文主要講解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服務器讀取中繼日誌中的事件,而後將改變的數據寫入到本身的數據庫中
下面咱們使用一張圖來講明覆制的過程:
第一步:是在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服務器必須開啓二進制日誌
2、Master和Slave的Server-id不能相同
3、同一個Master的多個Slave,Server-id也不能相同
4、Binlog_format最好相同
5、在Slave服務器上配置log-slave-updates=1時,也須要開啓二進制日誌;若是能夠推薦使用read_only選項,該選項會阻止沒有權限的線程修改數據
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
軟件版本
系統版本:CentOS 6.4_x86_64
Mysql版本:mysql-5.5.33-linux2.6-x86_64
環境介紹
安裝前準備
一、修改主機名稱
######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的主、主複製,敬請關注!!!