为了方便大家阅读,快速找到对自己有用的资料,先讲明我做此实验所用的硬件环境,和所使用的软件版本,同时中间也列出了试验中遇到的问题,及个人的解决方法,希望对大家有所帮助,同时也希望留下你的宝贵意见和建议。

   实验环境 :

      linux-2.6.18-308.el5

     mysql-5.5.24-linux2.6-i686.tar.gz 编译安装好的 

  实验拓扑图:

基于ssl的mysql的主从复制及排错 _ssl

实验思路:

         1、主从服务器的基本设置及主从复制,先确保简单的主从复制没有问题

         2、准备证书和私钥

         3、配置基于ssl的主从复制

具体操作步骤:

一、主从服务器的基本设置及简单的主从复制

     1、master的配置:

  1. mysql> grant replication slave,replication client on *.* to
  2.  'slave'@'172.16.2.2' identified by 'redhat'; 授权用户 
  3. mysql> flush privileges; 
  4. mysql> show master status;  
  5. +------------------+----------+--------------+------------------+ 
  6. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | 
  7. +------------------+----------+--------------+------------------+ 
  8. mysql-bin.000008 |      353 |      这两个值需要记着  
  9. +------------------+----------+--------------+------------------+ 
  10. 1 row in set (0.00 sec)  

      2、slave的配置:

  1. # vim /etc/my.cnf  
  2.     server-id       = 12     修改server-id 只要两个服务器不一样  
  3.     relay-log=mysql-relay     开启中继日志  
  4. # service mysqld restart    修改配置文件 需要重启服务  
  5. mysql> change master to master_host='172.16.2.1',连入mysql 修改参数
  6.         -> master_user='slave',                      
  7.         -> master_password='redhat'
  8.         -> master_log_file='mysql-bin.000008',  
  9.         -> master_log_pos=353;      这些参数都要和master上的对应  
  10.     Query OK, 0 rows affected (0.27 sec)  
  11.  
  12.   注意:5.5以后必须使用命令 不可以写入配置文件。 

     注:此时如果出现一下类似错误,很可能就是你的主服务器版本高于从服务器,配置主从服务器,主服务器的版本不能高于从服务器的。

  1. ERROR 1201 (HY000): Could not initialize master info structure;
  2.  more error messages can be found in the MySQL error log 

 

  3、启动slave 前提必须是上面的命令执行成功

  1. mysql> start slave;    启动slave  
  2.     Query OK, 0 rows affected (0.07 sec)     
  3. mysql> show slave status\G 
  4. *************************** 1. row *************************** 
  5.              Slave_IO_State: Waiting for master to send event 
  6.                       Master_Host: 172.16.2.1 
  7.                       Master_User: slave 
  8.                       Master_Port: 3306 
  9.                     Connect_Retry: 60 
  10.                   Master_Log_File: mysql-bin.000008 
  11.               Read_Master_Log_Pos: 353 
  12.                    Relay_Log_File: mysql-relay.000002 
  13.                     Relay_Log_Pos: 253 
  14.             Relay_Master_Log_File: mysql-bin.000008 
  15.                  Slave_IO_Running: Yes 
  16.                 Slave_SQL_Running: Yes 这两项都为yes 才说明启动成功了  
  17.                   Replicate_Do_DB:  
  18.               Replicate_Ignore_DB:  
  19.                Replicate_Do_Table:  
  20.            Replicate_Ignore_Table:  
  21.           Replicate_Wild_Do_Table:  
  22.       Replicate_Wild_Ignore_Table:  
  23.                        Last_Errno: 0 
  24.                        Last_Error:  
  25.                      Skip_Counter: 0 
  26.               Exec_Master_Log_Pos: 353 
  27.                   Relay_Log_Space: 405 
  28.                   Until_Condition: None 
  29.                    Until_Log_File:  
  30.                     Until_Log_Pos: 0 
  31.                Master_SSL_Allowed: No 
  32.                Master_SSL_CA_File:  
  33.                Master_SSL_CA_Path:  
  34.                   Master_SSL_Cert:  
  35.                 Master_SSL_Cipher:  
  36.                    Master_SSL_Key:  
  37.             Seconds_Behind_Master: 0 
  38.     Master_SSL_Verify_Server_Cert: No 
  39.                     Last_IO_Errno: 0 
  40.                     Last_IO_Error: 这里不显示信息表示没有错误  
  41.                    Last_SQL_Errno: 0 
  42.                    Last_SQL_Error:  
  43.       Replicate_Ignore_Server_Ids:  
  44.                  Master_Server_Id: 12 
  45.     1 row in set (0.00 sec) 

    4、此时一个简单的主从复制就做好了,可以测试一下,在主服务器上创建数据库,到从服务器上查看。但是此刻如果你在从服务器上写入数据,也是可以的 ,但主服务器不会到从服务器上复制数据,这样就导致了主从的数据不一样,所以我们要在从服务器上修改一个参数,让从服务器只读不可以写。

    mysql> show global variables like 'read_only';

| read_only     | OFF   | 默认是关闭的 

     mysql>  set global read_only=1; 设置为只读。 也可以写入配置文件中 

  建议:如果在现实环境中,很可能是主服务器运行很长时间了,才创建从服务器,此时开启从服务器就需要同步很长时间,我们可以先把主服务器备份一下,把数据导入到从服务器,在开启从服务器。

 二、准备证书和私钥 

   1、在master上配置CA服务器

  1. #vim /etc/pki/tls/openssl.cnf  
  2. 将  dir             = ../../CA 
  3. 修改为dir             = /etc/pki/CA 
  4. #(umask 077;openssl genrsa 2048 > private/cakey.pem) 
  5. #openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650 
  6. #mkdir certs crl newcerts 
  7. #touch index.txt 
  8. #echo 01 > serial 

    2、为mysql准备私钥和证书

     在主服务器上:

  1. #mkdir /usr/local/mysql/ssl
  2. #cd ssl/ 
  3. #(umask 077;openssl genrsa 1024 > mysql.key) 
  4. #openssl req -new -key mysql.key -out mysql.csr 
  5. #openssl ca -in mysql.csr -out mysql.crt 
  6. #cp /etc/pki/CA/cacert.pem /usr/local/mysql/ssl/ 
  7. #chown -R mysql.mysql ssl/  一定要记得修改属主和属组  

     在从服务器上:

  1. #mkdir /usr/local/mysql/ssl
  2. #chown -R mysql.mysql ssl/
  3. #cd ssl/ 
  4. #(umask 077;openssl genrsa 1024 > mysql.key) 
  5. #openssl req -new -key mysql.key -out mysql.csr 
  6. #scp ./mysql.csr node1:/root  把证书申请传到CA服务器上

     在master为slave签署证书

  1. #openssl ca -in mysql.csr -out mysql.crt 
  2. #scp ./mysql.crt node2:/usr/local/mysql/ssl 
  3. #cd /etc/pki/CA 
  4. #scp ./cacert.pem node2:/usr/local/mysql/ssl 

   注: node1 :172.16.2.1 node2: 172.16.2.2

到此证书和私钥我们都准备好了,为了下面的实验顺利,我们最好每做一步都验证一下,这样也好排错。

 确保主从服务器上都有以下文件,及属主和属组 都正确。

路径可以自己定义,只要和后面的保持一致就可以 

  1. [root@node1 ssl]# ll 
  2. total 16 
  3. -rw-r--r-- 1 mysql mysql 1468 Aug  7 10:23 cacert.pem 
  4. -rw-r--r-- 1 mysql mysql 3682 Aug  7 10:23 mysql.crt 
  5. -rw-r--r-- 1 mysql mysql  643 Aug  7 10:22 mysql.csr 
  6. -rw------- 1 mysql mysql  887 Aug  7 10:21 mysql.key 
  7. [root@node1 ssl]# pwd 
  8. /usr/local/mysql/ssl 

三、配置基于ssl 的主从复制 

   1、在主从服务器上都开启ssl功能:在主从服务器上都操作   

  1. mysql> show variables like '%ssl%'; 
  2. +---------------+----------+ 
  3. | Variable_name | Value    | 
  4. +---------------+----------+ 
  5. have_openssl  | DISABLED |  
  6. | have_ssl      | DISABLED |  默认是disabled 关闭的 
  7. #vim /etc/my.cnf 
  8. 在[mysqld]段,添加 
  9. ssl                    #表示开启mysql的ssl功能 
  10. # service mysqld restart          一定要重启服务 
  11. mysql> show variables like '%ssl%'; 
  12. +---------------+-------+ 
  13. | Variable_name | Value | 
  14. +---------------+-------+ 
  15. | have_openssl  | YES   | 
  16. | have_ssl      | YES   |  验证一下 为yes 表示启动了  
  17. 注: 在两台服务器上做同样的操作,且确保两台都启动了

     2、配置ssl参数 :(在主从服务器上都操作 )

  1. #vim /etc/my.cnf    在之间添加的ssl下面添加以下内容: 
  2. ssl-ca=/usr/local/mysql/ssl/cacert.pem 
  3. ssl-cert=/usr/local/mysql/ssl/mysql.crt 
  4. ssl-key=/usr/local/mysql/ssl/mysql.key 
  5. 注:  这里使用绝对路径和前面你放置证书和私钥的位置保持一致  

      验证配置

  1. # service mysqld restart 每修改一次配置文件都要重启服务  
  2. mysql> show variables like '%ssl%'; 
  3. +---------------+---------------------------------+ 
  4. | Variable_name | Value                           | 
  5. +---------------+---------------------------------+ 
  6. | have_openssl  | YES                             | 
  7. | have_ssl      | YES                             | 
  8. | ssl_ca        | /usr/local/mysql/ssl/cacert.pem | 
  9. | ssl_capath    |                                 | 
  10. | ssl_cert      | /usr/local/mysql/ssl/mysql.crt  | 
  11. | ssl_cipher    |                                 | 
  12. | ssl_key       | /usr/local/mysql/ssl/mysql.key  | 
  13. +---------------+---------------------------------+ 
  14. 7 rows in set (0.09 sec) 

  3、在master上:记录主服务器的二进制文件及时间,授权用户

  1. mysql> show master status; 
  2. +------------------+----------+--------------+------------------+ 
  3. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | 
  4. +------------------+----------+--------------+------------------+ 
  5. | mysql-bin.000007 |      107 |              |                  | 
  6. +------------------+----------+--------------+------------------+ 
  7. 1 row in set (0.00 sec) 
  8. mysql> grant replication slave,replication client on *.* to
  9.  'slave'@'172.16.2.2' identified by 'redhat' require ssl
  10. Query OK, 0 rows affected (0.04 sec) 
  11. require ssl 只能ssl认证才可以复制

    4、 在slave 上修改参数,启动slave 

  1. mysql> change master to  
  2.       master_host='172.16.2.1'
  3.       master_user='slave',  
  4.       master_password='redhat',  
  5.       master_log_file='mysql-bin.000007'
  6.       master_log_pos=107,  和master的对应
  7.       master_ssl=1,              
  8.  master_ssl_ca='/usr/local/mysql/ssl/cacert.pem',
  9.     master_ssl_capath='/usr/local/mysql/ssl',
  10.  master_ssl_cert='/usr/local/mysql/ssl/mysql.crt'
  11. master_ssl_key='/usr/local/mysql/ssl/mysql.key'
  12. mysql> start slave; 
  13.     Query OK, 0 rows affected (0.01 sec) 
  14. mysql> show slave status \G 
  15. *************************** 1. row *************************** 
  16.                    Slave_IO_State: Waiting for master to send event  
  17.                       Master_Host: 172.16.2.1 
  18.                       Master_User: slave 
  19.                       Master_Port: 3306 
  20.                     Connect_Retry: 60 
  21.                   Master_Log_File: mysql-bin.000007 
  22.               Read_Master_Log_Pos: 107 
  23.                    Relay_Log_File: mysql-relay.000002 
  24.                     Relay_Log_Pos: 253 
  25.             Relay_Master_Log_File: mysql-bin.000007 
  26.                  Slave_IO_Running: Yes 
  27.                 Slave_SQL_Running: Yes 
  28.                   Replicate_Do_DB:  
  29.               Replicate_Ignore_DB:  
  30.                Replicate_Do_Table:  
  31.            Replicate_Ignore_Table:  
  32.           Replicate_Wild_Do_Table:  
  33.       Replicate_Wild_Ignore_Table:  
  34.                        Last_Errno: 0 
  35.                        Last_Error:  
  36.                      Skip_Counter: 0 
  37.               Exec_Master_Log_Pos: 107 
  38.                   Relay_Log_Space: 405 
  39.                   Until_Condition: None 
  40.                    Until_Log_File:  
  41.                     Until_Log_Pos: 0 
  42.                Master_SSL_Allowed: Yes 
  43.                Master_SSL_CA_File: /usr/local/mysql/ssl/cacert.pem 
  44.                Master_SSL_CA_Path: /usr/local/mysql/ssl 
  45.                   Master_SSL_Cert: /usr/local/mysql/ssl/mysql.crt 
  46.                 Master_SSL_Cipher:  
  47.                    Master_SSL_Key: /usr/local/mysql/ssl/mysql.key 
  48.             Seconds_Behind_Master: 0 
  49.     Master_SSL_Verify_Server_Cert: No 
  50.                     Last_IO_Errno: 0 
  51.                     Last_IO_Error:  
  52.                    Last_SQL_Errno: 0 
  53.                    Last_SQL_Error:  
  54.       Replicate_Ignore_Server_Ids:  
  55.                  Master_Server_Id: 1 
  56.     1 row in set (0.00 sec) 

  1. Slave_IO_Running: Yes 
  2. Slave_SQL_Running: Yes
  3. Master_SSL_Allowed: Yes  三个都输出为yes 才表明配置成功

注:出现的错误:

  1. Slave_IO_State: Connecting to master    
  2. Slave_IO_Running: Connecting  一直显示 正在连接   
  3. Slave_SQL_Running: Yes 
  4. Last_IO_Error: error connecting to master 'slave@172.16.2.1:3306' - retry-time: 60  retries: 86400 
  5. 问题原因:两个服务器的时间不一致,同步一下时间就OK,排查一个上午原来就是这的原因,让我很是郁闷 

 此时基于ssl的mysql的主从复制配置成功 

四、测试 

   在slave服务器上:

  1. # mysql -uslave -h172.16.2.1 -predhat  
  2. --sslca=/usr/local/mysql/ssl/cacert.pem 
  3.  --ssl-cert=/usr/local/mysql/ssl/mysql.crt 
  4.  --ssl-key=/usr/local/mysql/ssl/mysql.key  这是一行命令 连接master mysql 
  5. mysql> \s  显示信息  
  6.     -------------- 
  7.     mysql  Ver 14.14 Distrib 5.5.24, for linux2.6 (i686) using readline 5.1 
  8.      
  9.     Connection id:      5 
  10.     Current database:    
  11.     Current user:       slave@node2.magedu.com 
  12.     SSL:            Cipher in use is DHE-RSA-AES256-SHA 
  13.     Current pager:      stdout 
  14.     Using outfile:      '' 
  15.     Using delimiter:    ; 
  16.     Server version:     5.5.24-log MySQL Community Server (GPL) 
  17.     Protocol version:   10 
  18.     Connection:     172.16.2.1 via TCP/IP 
  19.     Server characterset:    latin1 
  20.     Db     characterset:    latin1 
  21.     Client characterset:    utf8 
  22.     Conn.  characterset:    utf8 
  23.     TCP port:       3306 
  24.     Uptime:         14 min 6 sec 
  25.      
  26.     Threads: 3  Questions: 13  Slow queries: 0  Opens: 33  Flush tables: 1  Open tables: 26  Queries per second avg: 0.015 
  27.     -------------- 

      SSL:            Cipher in use is DHE-RSA-AES256-SHA 

     说明连接是加密的  

     如果显示 :SSL: Not in use 则连接没有加密。

到此基于ssl的mysql主从复制就配置好了,如果要配置主主复制的只需要在两台服务器上做同样的操作就可以了。

   遗留问题:由于SSL相关的配置写进了配置文件,则默认是加密连接的。那要取消加密连接,怎么办?  --skip-ssl 怎么用?希望大家多提宝贵意见,留作下次分析吧。