天天看点

mysql 5.5主从复制与基于ssl加密复制

一, 复制的工作机制:由主服务器产生数据,从服务器从主服务器将数据同步过来。靠三个线程来实现:

(1)dump thread:当从服务器来复制时,dump会去读取二进制日志的语句并发送给从服务器

(2)io thread:在从服务器由io thread到主服务上去请求二进制日志中语句的内容。每隔一段时间就会启动,io thread到主服务器上查看二进制日志是否有变化。如果有变化则就请求传输,一条语句复制过来。

(3)SQL thread(单线程):io thread获取到之后将其存储到relay log中。一条语句一条语句执行。

<a target="_blank" href="http://blog.51cto.com/attachment/201208/114408607.jpg"></a>

二,Mysql复制有三个种方式:异步,同步,半同步

1)异步:主服务器的修改操作本地完成就认为完成。至于后面的事,并不理会

2)同步指定是:主服务器涉及的修改操作,要等待从服务器也完成

3)半同步:在一主多从的环境中,只等待一台从服务器同步完成操作。设置一个等待超时时间,如果超过这个时间,则降级为异步。在5.5可以使用半同步,google公司提供一个补丁。半同步如果无法在指定时间完成--&gt;自动 降到异步模式。

三,实验步骤:

四,mysql的数据目录最好存储在lvm的磁盘中,因此下面分别对两台虚拟机创建一个lvm的分区。

#pvcreate /dev/sda5  

#vgcreate myvg /dev/sda5  

#lvcreate -L 5G -n mylv myvg   

# mke2fs -j /dev/myvg/mylv  

# vim /etc/fstab   

/dev/myvg/mylv          /data/mysql             ext3    defaults        0 0 

# mount -a  

# df  

# chown -R mysql:mysql /data/mysql/  

#cd /usr/local/mysql 

# cp support-files/my-large.cnf /etc/my.cnf 

vim /etc/my.cnf 

thread_concurrency = 4 

datadir = /data/mysql 

#cp support-files/mysql.server /etc/rc.d/init.d/mysqld 

#chmod +x /etc/rc.d/init.d/mysqld 

#chkconfig --add mysqld 

#chown -R :mysql * 

#scripts/mysql_install_db --user=mysql --datadir=/data/mysql 

#service mysqld start 

五,在master上,执行下列mysql语句

mysql&gt; grant replication slave,replication client on *.* to repluser@'172.16.150.%' identified by 'redhat';

创建用户,并赋权为replication。能复制所有数据库。

mysql&gt; flush privileges; 

mysql&gt; show master status; 记录当前的二进制日志名,与所处的位置。

+------------------+----------+--------------+------------------+ 

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | 

| mysql-bin.000001 |      356 |              |                  | 

六,在slave上,先修改配置文件:

vim /etc/my.cnf  

[mysqld] 在mysqld段中修改 

thread_concurrency = 4  

datadir = /data/mysql  

#log-bin=mysql-bin  禁止二进制日志,在此实现中并不需要二进制日志 

relay_log      = mysql-relay 启用中继日志,需要自己添加 

server-id = 2修改为2,不要与master的server-id相同就ok

  上面修改完之后启用 service mysqld resstart

七,在slave连接到mysql,并执行下面mysql语句

 mysql&gt; change master to 

&gt; master_host='172.16.150.30', 

&gt;master_user='repluser', 

&gt;master_password='redhat', 

&gt;master_log_file='mysql-bin.000001', 在master执行show master status所看到的。

&gt;master_log_pos=356;数字是整数不能加引号 

mysql &gt; start slave;启动重服务器线程

此时已经完成一个简单的主从复制。在从服务器用户还可以新增数据与表,如果这样会导致主从的数据不能保持一至。此时需要从服务器的配置文件添加一个行

[mysqld] 

read-only = 1 

添加完之后需要重启mysqld服务,这并不能阻止具有super权限修改数据,只能阻止普通用户。如果从服务器重新启用后,slave会自动启动,那么此时想做一些维护工作并不合适,此时在配置文件中添加一项

[mysqld]

skip_slave_start=1 

八,在主服务器的配置文件中,最好在在配置文件添加下列选项:

sync_binlog=1 

在事务提交时,会先写到内存缓存的日志中,=1任何一个事务提交之后就立即写入到磁盘中的二进制文件 

innodb_flush_logs_at_trx_commit=1 

表示任何一个事物提交之后就立即写入到磁盘中的日志文件 

 到此一个比较安全的主从的复制完。

由于Mysq的复制是明文传输,很难保存其数据的安全,因此需要利用ssl加密协议来加强安全。将/data/mysql的数据删除,删除之前先停止mysql服务,并重新初始化。

# vim /etc/pki/tls/openssl.cnf  

dir             = ../../CA 将这行修改 =/etc/pki/CA 

# cd /etc/pki/CA 

# (umaks 077; openssl genrsa 2048 &gt; private/cakey.pem) 

# openssl req -new -x509 -key private/cakey.pem  -out cacert.pem -days 3650 

# mkdir certs crl newcerts 

# touch index.txt 

# echo 01 &gt; serial 

二,给master自己签署证书

# mkdir /etc/mysql_ssl 

#chown mysql:mysql /etc/mysql_ssl 

如果不修改这个证书存放目录,会导致Mysql用户可能没有权限读取证书

# cd /etc/mysql_ssl 

#(umask 077;openssl genrsa 1024 &gt; master.key) 

#openssl req -new -key master.key -out master.csr

#openssl ca -in master.csr -out master.crt

#cp /etc/pki/CA/cacert.pem . 

三,slave上生成私钥与证书

# mkdir /etc/mysql_ssl  

#chown mysql:mysql /etc/mysql_ssl  

# cd /etc/mysql_ssl  

#(umask 077;openssl genrsa 1024 &gt; slave.key)  

#openssl req -new -key slave.key -out slave.csr 

#scp slave.csr 172.16.150.30:/tmp 

四,在master签署slave的证书

#cd /tmp 

#openssl ca -in slave.csr -out slave.crt 

#scp /etc/pki/CA/cacert.pem 172.16.150.30:/etc/mysql_ssl 

#scp slave.crt 172.16.150.30:/etc/mysql_ssl 

五,在master的my.cnf中添加下面内容,并重启服务。

ssl 

ssl-ca=/etc/mysql_ssl/cacert.pem 

ssl-cert=/etc/mysql_ssl/master.crt 

ssl-key=/etc/mysql_ssl/master.key 

查看有没有生效

mysql&gt; show variables like '%ssl%'; 

+---------------+---------------------------+ 

| Variable_name | Value                     | 

| have_openssl  | YES  启用openssl                     | 

| have_ssl      | YES    启用ssl加密                   | 

| ssl_ca        | /etc/mysql_ssl/cacert.pem | 

| ssl_capath    |                           | 

| ssl_cert      | /etc/mysql_ssl/master.crt | 

| ssl_cipher    |                           | 

| ssl_key       | /etc/mysql_ssl/master.key | 

+---------------+--------------------------- 

六,在slave上,也需要添加,重启服务,查看有没有生效

ssl-cert=/etc/mysql_ssl/slave.crt 

ssl-key=/etc/mysql_ssl/slave.key 

七,在master创建用户指定复制时必要在使用ssl加密,也可以修改之前的用户,下面新增一个用户。

mysql&gt; grant replication client,replication slave on *.* to rep@'172.16.150.%' identified by 'redhat' require ssl; 

mysql&gt; flush privileges;

Query OK, 0 rows affected (0.00 sec)

mysql&gt; show master status;

+------------------+----------+--------------+------------------+ | File

| Position | Binlog_Do_DB | Binlog_Ignore_DB

| +------------------+----------+--------------+------------------+ |

mysql-bin.000005 | 544 | |

| +------------------+----------+--------------+------------------+

八,在slave服务器上配置复制的信息:

mysql&gt; change master to 

    -&gt; master_host='172.16.150.30', 

    -&gt; master_user='rep', 

    -&gt; master_password='redhat', 

    -&gt; master_log_file='mysql-bin.000005', 

    -&gt; master_log_pos=544, 

    -&gt; master_ssl=1, 

    -&gt; master_ssl_ca='/etc/mysql_ssl/cacert.pem', 

    -&gt; master_ssl_cert='/etc/mysql_ssl/slave.crt', 

    -&gt; master_ssl_key='/etc/mysql_ssl/slave.key'; 

验证有没有生效:

mysql&gt; start slave; 

mysql&gt; show slave status\G 

*************************** 1. row *************************** 

               Slave_IO_State: Waiting for master to send event 

                  Master_Host: 172.16.150.30 

                  Master_User: rep 

                  Master_Port: 3306 

                Connect_Retry: 60 

              Master_Log_File: mysql-bin.000005 

          Read_Master_Log_Pos: 544 

               Relay_Log_File: mysql-relay.000002 

                Relay_Log_Pos: 253 

        Relay_Master_Log_File: mysql-bin.000005 

             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: 544 

              Relay_Log_Space: 405 

              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/slave.crt 

            Master_SSL_Cipher:  

               Master_SSL_Key: /etc/mysql_ssl/slave.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 row in set (0.00 sec) 

十,在master上创建一个数据库,并查看slave上会不会生效。

本文转自 deng304749970 51CTO博客,原文链接:http://blog.51cto.com/damondeng/956980,如需转载请自行联系原作者