MySQL的主从复制应用场景非常多,默认的MySQL复制是基于异步且明文传输的,也就是说,速度快,但是从服务器的数据会有着一定的滞后性,明文也就意味着数据传输的不安全。因此笔者这里构建一个简单的基于加密并半同步的主从MySQL,当然由于其半同步的特性,主服务器的写操作速度必会有所降低。究竟如何选择,这取决于场景需要了。
 

实验环境:RHEL5.8  MySQL5.5.28

  1. 192.168.88.21       master.mos.com  master  
  2. 192.168.88.22       slave.mos.com   slave 

注意:笔者做了双机互信,但在此并未写出,且笔者的两个MySQL默认的root用户的密码皆为空,笔者实验环境的/etc/hosts的文件,皆如上。

 

    一、 创建CA私有认证及所需密钥文件,在主服务器(master)上操作

1、 使用脚本创建CA内部机构,笔者将脚本放到网盘,链接如下:
http://pan.baidu.com/share/link?shareid=139821&uk=1678158691

  1. ./ casetup.sh   #输入ca的主机名和email或者两次回车即可 


2、 创建Master和salve所需的密钥文件,(内部CA需要国家,省,城市,公司,部门这些信息一致)
 

  1. # mkdir -pv /data/{mysql,ssl}  
  2. # cd /data/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 -days 365  
  6. # cp /etc/pki/CA/cacert.pem .  
  7. # cd /data  
  8. # cp /etc/pki/CA/cacert.pem .  
  9. # (umask 077; openssl genrsa 1024 > slave.key)  
  10. # openssl req -new -key slave.key -out slave.csr  
  11. # openssl ca -in slave.csr -out slave.crt -days 365  
  12. # ssh slave 'mkdir -pv /data/mysql' 
  13. # scp slave.* cacert.pem slave:/data/ssl/  
  14. # rm –rf slave.* cacert.pem 

二、 载入半同步支持并提供从复制用户(位于主服务器操作)

1、 安装MySQL过程参考笔者之前的文章即可:
http://mos1989.blog.51cto.com/4226977/1039653

2、 插入谷歌提供的半同步补丁模块semisync的主模块支持,并创建复制所需用户
 

  1. mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';  
  2. mysql> GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO sroot@192.168.88.22 IDENTIFIED BY '123' REQUIRE SSL;  
  3. mysql> FLUSH PRIVILEGES ;  
  4. mysql> \q 

Ps: 若需要卸载半同步模块,在mysql中执行如下语句:
mysql> UNINSTALL PLUGIN rpl_semi_sync_master;

 

三、 配置主服务端配置文件/etc/my.cnf

  1. [mysqld]  
  2. ssl   #开启ssl  
  3. server-id       = 1 #主ID和从不一致即可  
  4. rpl_semi_sync_master_enabled=1 #使半同步默认开启  
  5. rpl_semi_sync_master_timeout=1000 #超过1秒则回到异步模式  
  6. sync_binlog=1 #将sql语句即时写入二进制日志  
  7. ssl_ca=/data/ssl/cacert.pem  
  8. ssl_cert=/data/ssl/mysql.crt  
  9. ssl_key=/data/ssl/mysql.key 


四、重启mysql,清除之前二进制文件,检查相关配置,并记录从服务器复制位置
 

  1. # service mysqld restart  
  2. # mysql –e ‘reset master;’  
  3. mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';  
  4. +------------------------------------+-------+  
  5. | Variable_name                      | Value |  
  6. +------------------------------------+-------+  
  7. | rpl_semi_sync_master_enabled       | ON    |  
  8. | rpl_semi_sync_master_timeout       | 1000  |  
  9. | rpl_semi_sync_master_trace_level   | 32    |  
  10. | rpl_semi_sync_master_wait_no_slave | ON    |  
  11. +------------------------------------+-------+  
  12.  
  13. mysql> SHOW GLOBAL VARIABLES LIKE '%ssl%';  
  14. +---------------+----------------------+  
  15. | Variable_name | Value                |  
  16. +---------------+----------------------+  
  17. | have_openssl  | YES                  |  
  18. | have_ssl      | YES                  |  
  19. | ssl_ca        | /data/ssl/cacert.pem |  
  20. | ssl_capath    |                      |  
  21. | ssl_cert      | /data/ssl/mysql.crt  |  
  22. | ssl_cipher    |                      |  
  23. | ssl_key       | /data/ssl/mysql.key  |  
  24. +---------------+----------------------+  
  25.  
  26. mysql> show master status;  
  27. +------------------+----------+--------------+------------------+  
  28. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |  
  29. +------------------+----------+--------------+------------------+  
  30. | mysql-bin.000001 |     107 |              |                  |  
  31. +------------------+----------+--------------+------------------+  
  32.  

五、 配置从MySql

1、 安装MySQL同上,需要注意的是,笔者的此处的同步,是在两个MySQL都是新安装的基础上实现的,如果已有数据,则需要先在主服务器做完整备份并记录备份时的二进制文件和其位置,然后在从服务器上恢复,以保证两个服务器的数据一致性。

2、 检查是否可以通过密钥和密码登陆主服务器

  1. # mysql -usroot -p123 -h 192.168.88.21 --ssl-ca=/data/ssl/cacert.pem --ssl-cert=/data/ssl/slave.crt --ssl-key=/data/ssl/slave.key 

3、 插入半同步模块支持并配置从服务器/etc/my.cnf
 

  1. # mysql  
  2. mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';  
  3. mysql>\q  
  4.  [mysqld]  
  5. # skip_slave_start=1 #若开启,则从服务器每次需要手动打开  
  6. # log-bin=mysql-bin #关闭从服务二进制,不需要开启  
  7. rpl_semi_sync_slave_enabled=1 #修改半同步模块自动打开  
  8. relay-log=mysql-relay #开启中继日志以接收主服务器二进制日志  
  9. relay-log-index=mysql-relay.index  # 中继日志索引名字  
  10. read_only=1 # 非超级用户则只读  
  11. ssl_ca=/data/ssl/cacert.pem  
  12. ssl_cert=/data/ssl/slave.crt  
  13. ssl_key=/data/ssl/slave.key 

4、 重启服务,并配置从MySQL
 

  1. # service mysqld restart  
  2. # mysql  
  3. mysql>CHANGE MASTER TO MASTER_HOST='192.168.88.21', \
  4. MASTER_USER='sroot', \
  5. MASTER_PASSWORD='123', \
  6. MASTER_LOG_FILE='mysql-bin.000001', \
  7. MASTER_LOG_POS=107, \
  8. MASTER_SSL=1, \
  9. MASTER_SSL_CA='/data/ssl/cacert.pem', \
  10. MASTER_SSL_CERT='/data/ssl/slave.crt', \
  11. MASTER_SSL_KEY='/data/ssl/slave.key';  
  12. mysql>start slave;  
  13. mysql>\q 

Ps: 若需要卸载半同步模块,在mysql中执行如下语句:
mysql> UNINSTALL PLUGIN rpl_semi_sync_slave.so;

5、 检查相关配置信息
 

  1. mysql> SHOW GLOBAL VARIABLES LIKE '%semi%';  
  2. +---------------------------------+-------+  
  3. | Variable_name                   | Value |  
  4. +---------------------------------+-------+  
  5. | rpl_semi_sync_slave_enabled     | ON    |  
  6. | rpl_semi_sync_slave_trace_level | 32    |  
  7. +---------------------------------+-------+  
  8.  
  9. mysql> SHOW GLOBAL VARIABLES LIKE '%ssl%';  
  10. +---------------+----------------------+  
  11. | Variable_name | Value                |  
  12. +---------------+----------------------+  
  13. | have_openssl  | YES                  |  
  14. | have_ssl      | YES                  |  
  15. | ssl_ca        | /data/ssl/cacert.pem |  
  16. | ssl_capath    |                      |  
  17. | ssl_cert      | /data/ssl/slave.crt  |  
  18. | ssl_cipher    |                      |  
  19. | ssl_key       | /data/ssl/slave.key  |  
  20. +---------------+----------------------+  
  21.  
  22. mysql> show slave status\G  
  23. *************************** 1. row ***************************  
  24.                Slave_IO_State: Waiting for master to send event  
  25.                   Master_Host: 192.168.88.21  
  26.                   Master_User: sroot  
  27.                   Master_Port: 3306  
  28.                 Connect_Retry: 60  
  29.               Master_Log_File: mysql-bin.000002  
  30.           Read_Master_Log_Pos: 3144  
  31.                Relay_Log_File: mysql-relay.000008  
  32.                 Relay_Log_Pos: 3290  
  33.         Relay_Master_Log_File: mysql-bin.000002  
  34.              Slave_IO_Running: Yes  
  35.             Slave_SQL_Running: Yes  
  36.               Replicate_Do_DB:   
  37.           Replicate_Ignore_DB:   
  38.            Replicate_Do_Table:   
  39.        Replicate_Ignore_Table:   
  40.       Replicate_Wild_Do_Table:   
  41.   Replicate_Wild_Ignore_Table:   
  42.                    Last_Errno: 0  
  43.                    Last_Error:   
  44.                  Skip_Counter: 0  
  45.           Exec_Master_Log_Pos: 3144  
  46.               Relay_Log_Space: 3588  
  47.               Until_Condition: None  
  48.                Until_Log_File:   
  49.                 Until_Log_Pos: 0  
  50.            Master_SSL_Allowed: Yes  
  51.            Master_SSL_CA_File: /data/ssl/cacert.pem  
  52.            Master_SSL_CA_Path:   
  53.               Master_SSL_Cert: /data/ssl/slave.crt  
  54.             Master_SSL_Cipher:   
  55.                Master_SSL_Key: /data/ssl/slave.key 
  56.         Seconds_Behind_Master: 0  
  57. Master_SSL_Verify_Server_Cert: No 
  58.                 Last_IO_Errno: 0  
  59.                 Last_IO_Error:   
  60.                Last_SQL_Errno: 0  
  61.                Last_SQL_Error:   
  62.   Replicate_Ignore_Server_Ids:   
  63.              Master_Server_Id: 1