MySQL复制

MYSQL的复制其实就是其中一台服务器充当主服务器,而有一台或多台从服务器,它们以某种方式同步数据的过程就叫MYSQL的复制。


MYSQL复制的工作机制

轻松配置MYSQL的主-从复制,主-主复制,半同步复制及基于ssl的复制_主-主

由于画图水平有限,描述的可能不够详尽。根据图示讲解一下都表示什么?分别有什么用途?

MySQL复制过程中要启用三个重要的线程:

(1)dump thread:主服务器从本地的二进制日志传送至从服务的中继日志

(2)IO Thread:从服务器向主服务器请求数据

(3)SQL thread:在从服务器上读取中继日志并应用到本地服务器的线程

三个线程的调用关系就完成了数据复制的过程。

红线表示的IO线程会每隔一段时间向主服务器请求获取二进制文件;当主服务器中有新操作时就响应IO线程,再有dump线程读取本地的二进制日志传递给IO线程,IO线程则将读取的语句记录到本地的relay log中;当记录完成后,SQL线程就会启动起来,然后读取relay log并应用至本地。


MYSQL复制的类型

MYSQL的复制类型有:主-从模型,主-主模型,半同步模型

一、主-从模型

在主从模型中,主服务器可以接收用户的读、写操作,但从服务器只能执行读操作。主从模型是如何配置的呢?现在就开始配置。

1、规划

主服务器地址:192.168.0.100  主机名rs1

从服务器地址:192.168.0.101  主机名rs1

2、环境

这里是基于虚拟机环境的,最好能够同步时间。

3、配置步骤

在主服务器rs1上

(1)创建逻辑卷用于存放数据

  1. 创建一个20G的分区本机为/dev/sda5,调整器类型为8e  
  2. #pvcreate /dev/sda5  
  3. #vgcreate myvg /dev/sda5  
  4. #lvcreate -n mylv -L 10G myvg  
  5. #mke2fs -j /dev/myvg/mylv  
  6. #mkdir -p /data/mydata  
  7. 编写/etc/fstab文件让其能够开机自动挂载  
  8. /dev/myvg/mylv  /data/mydata    ext3    defaults    0 0  

(2)安装MYSQL

  1. #useradd -r mysql  
  2. #tar xf mysql-5.5.24-linux2.6-i686.tar.gz -C /usr/local   
  3. #cd /usr/local  
  4. #ln -sv mysql-5.5.24-linux2.6-i686 mysql  
  5. #cd mysql  
  6. #chown -R mysql.mysql .  
  7. #scripts/mysql_install_db --user=mysql --datadir=/data/mydata  
  8. #cp support-files/my-large.cnf /etc/my.cnf  
  9. #cp support-files/mysql.server /etc/rc.d/init.d/mysqld 
  10. 编辑主配置文件/etc/my.cnf
  11. thread_concurrency = 2 datadir = /data/mydata
  12. log-bin=mysql-bin //开启二进制日志
  13. binlog_format=mixed
  14. server-id = 1 //从服务器的Server-id不能与此值相同
  15. #chown -R root .  
  16. #service mysqld start  

(3)配置相关属性

  1. #/usr/local/mysql/bin/mysql 
  2. mysql>grant replication slave,replication client on *.* to
  3.  repluser@'192.168.0.%' identified by 'sql123'; //创建有复制权限的用户
  4. mysql>flush privileges; 
  5. mysql> show master status; 
  6. +------------------+----------+--------------+------------------+ 
  7. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | 
  8. +------------------+----------+--------------+------------------+ 
  9. | mysql-bin.000001 |      355 |              |                  | 
  10. +------------------+----------+--------------+------------------+ 

在从服务器rs2上

(1)前面两个步骤与主服务器相同,但在编辑配置文件时有所不同。

  1. #vim /etc/my.cnf
  2. thread_concurrency = 2 
  3. datadir = /data/mydata 
  4. log-bin=mysql-bin     //二进制日志可以开启也可以关闭 
  5. relay-log=mysql-relay  //一定要开启中继日志 
  6. binlog_format=mixed 
  7. server-id       = 21  //从服务器的Server-id不能与此值相同 
  8. #service mysqld restart //重启让修改生效

(2)配置相关属性

  1. #/usr/local/mysql/bin/mysql 
  2.  mysql> show global variables like '%relay_log%';//配置生效 
  3. +-----------------------+----------------+ 
  4. | Variable_name         | Value          | 
  5. +-----------------------+----------------+ 
  6. | max_relay_log_size    | 0              | 
  7. | relay_log             | mysql-relay    | 
  8. | relay_log_index       |                | 
  9. | relay_log_info_file   | relay-log.info | 
  10. | relay_log_purge       | ON             | 
  11. | relay_log_recovery    | OFF            | 
  12. | relay_log_space_limit | 0              | 
  13. | sync_relay_log        | 0              | 
  14. | sync_relay_log_info   | 0              | 
  15. +-----------------------+----------------+ 
  16. mysql> show global variables like 'server_id'; 
  17. +---------------+-------+ 
  18. | Variable_name | Value | 
  19. +---------------+-------+ 
  20. | server_id     | 11    | 
  21. +---------------+-------+ 
  22. mysql> change master to  
  23. master_host='192.168.0.100' //主服务器的地址
  24. master_user='repluser' ,   
  25. master_password='sql123',
  26. master_log_file='mysql-bin.000001',
  27. master_log_pos=355
  28. mysql> show slave status\G 
  29. *************************** 1. row *************************** 
  30.                Slave_IO_State:  
  31.                   Master_Host: 192.168.0.100 
  32.                   Master_User: repluser 
  33.                   Master_Port: 3306 
  34.                 Connect_Retry: 60 
  35.               Master_Log_File: mysql-bin.000001 
  36.           Read_Master_Log_Pos: 355 
  37.                Relay_Log_File: mysql-relay.000001 
  38.                 Relay_Log_Pos: 4 
  39.         Relay_Master_Log_File: mysql-bin.000001 
  40.              Slave_IO_Running: No 
  41.             Slave_SQL_Running: No 
  42. 此时IO线程和SQL线程没有启动,执行如下命令使其启用 
  43. mysql>start slave; 

4、测试

此时主从基本配置已完成。下面进行一个小小的测试。

在主服务器上创建一个数据库testdb,在从服务器上查看。

  1. mysql> show databases; 
  2. +---------------------+ 
  3. | Database            | 
  4. +---------------------+ 
  5. | information_schema  | 
  6. | #mysql50#lost+found | 
  7. | mysql               | 
  8. | performance_schema  | 
  9. | test                | 
  10. | testdb              | 
  11. +---------------------+ 

testdb已显示出来,配置完成。

二、主-主模型

两台服务器都有二进制日志和中继日志;服务器可读可写。但请注意配置对于有自动增长字段的数据要设置特别的属性。

1、使用与主从模型相同的主机

2、配置

在rs1服务器上

(1)安装软件步骤同上述内容

(2)配置相关属性

  1. #vim /etcmy.cnf  
  2.  log-bin=mysql-bin        //二进制日志必须开启  
  3.  relay-log=mysql-relay   //中继日志必须开启  
  4.  auto-increment-increment = 2  //增长间隔为2  
  5.  auto-increment-offset = 1 //自动增长的字段从1开始 
  6.  server-id       = 10 

  1. 进入mysql命令行  
  2. mysql>grant replication slave,replication client on *.*  
  3. to repluser@'192.168.0.%' identified by 'sql123';  
  4. mysql> show global variables like '%auto_increment%'; 
  5. +--------------------------+-------+ 
  6. | Variable_name            | Value | 
  7. +--------------------------+-------+ 
  8. | auto_increment_increment | 2     | 
  9. | auto_increment_offset    | 1     | 
  10. +--------------------------+-------+ 
  11. mysql> show master status;  
  12. +------------------+----------+--------------+------------------+  
  13. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |  
  14. +------------------+----------+--------------+------------------+  
  15. | mysql-bin.000001 |      355 |              |                  |  
  16. +------------------+----------+--------------+------------------+  

在从服务器rs2上

(1)同样的基本配置同上。在此直接编辑配置文件

  1. log-bin=mysql-bin 
  2. relay-log=mysql-relay 
  3. auto-increment-increment = 2 
  4. auto-increment-offset = 2 
  5. server-id       = 20 

  1. mysql> show global variables like '%auto_increment%'; 
  2. +--------------------------+-------+ 
  3. | Variable_name            | Value | 
  4. +--------------------------+-------+ 
  5. | auto_increment_increment | 2     | 
  6. | auto_increment_offset    | 2     | 
  7. +--------------------------+-------+ 
  8. mysql>change master to   
  9. master_host='192.168.0.100',  
  10. master_user='repluser',  
  11. master_password='sql123',  
  12. master_log_file='mysql-bin.000001',  
  13. master_log_pos=355;  
  14. mysql>start slave;  
  15.  
  16. mysql>grant replicatin slave,replication client on *.* to 
  17. repluser2@'192.168.0.%' identified by 'sql456'; //创建授权用户 
  18.  
  19. mysql> show master status;  
  20. +------------------+----------+--------------+------------------+  
  21. | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |  
  22. +------------------+----------+--------------+------------------+  
  23. | mysql-bin.000002 |      286 |              |                  |  
  24. +------------------+----------+--------------+------------------+  

现在rs1已是rs2的主服务器,接下来配置rs2成为rs1的主。回到rs1服务器上。

  1. 进入mysql命令行 
  2. change master to 
  3. master_host='192.168.0.101'
  4. master_user='repluser2'
  5. master_password='sql456'
  6. master_log_file='mysql-bin.000002'
  7. master_log_pos=286;  //这里定义的值是从从服务器中得到的。
  8. mysql> show slave status\G 
  9. *************************** 1. row *************************** 
  10.                Slave_IO_State:  
  11.                   Master_Host: 192.168.0.101 
  12.                   Master_User: repluser2 
  13.                   Master_Port: 3306 
  14.                 Connect_Retry: 60 
  15.               Master_Log_File: mysql-bin.000002 
  16.           Read_Master_Log_Pos: 286 
  17.                Relay_Log_File: mysql-relay.000001 
  18.                 Relay_Log_Pos: 4 
  19.         Relay_Master_Log_File: mysql-bin.000002 
  20.              Slave_IO_Running: No 
  21.             Slave_SQL_Running: No 
  22. mysql>start slave 

3、测试

现在rs1上创建一个有自动增长类型的字段,查看设置的属性是否生效。

mysql> desc tb1;
+-------+---------------------+------+-----+---------+----------------+
| Field | Type                | Null | Key | Default | Extra          |
+-------+---------------------+------+-----+---------+----------------+
| id    | tinyint(3) unsigned | NO   | PRI | NULL    | auto_increment |
| name  | char(10)            | YES  |     | NULL    |                |
+-------+---------------------+------+-----+---------+----------------+

插入两个字段。查看效果

mysql> select * from tb1;
+----+-------+
| id | name  |
+----+-------+
|  1 | tom   |
|  3 | jerry |
+----+-------+
在rs1上呈奇数增加。

在rs2对此表也插入两个字段,查看效果。
mysql> select * from tb1;
+----+-------+
| id | name  |
+----+-------+
|  1 | tom   |
|  3 | jerry |
|  4 | Lily  |
|  6 | Lucy  |
+----+-------+
在rs2上呈偶数增长,与预期效果一致,配置成功。
 

三、半同步模型

MYSQL复制时的默认方式为异步,但异步方式会产生很多滞后操作,因此引进了半同步式的模式。半同步模式是依靠插件模块来实现的。它可以将在主服务器上写操作转发至从服务器的内存中,大大提高了数据的同步性。

1、配置一个主从模型

2、在主服务器上

  1. mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; 
  2.  //装载插件模块   
  3. mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1; //启动插件  
  4. mysql> SET GLOBAL rpl_semi_sync_master_timeout = 1000; //设置超时参数 
  5. mysql> show global status like 'rpl_semi%'; 
  6. +--------------------------------------------+-------+ 
  7. | Variable_name                              | Value | 
  8. +--------------------------------------------+-------+ 
  9. | Rpl_semi_sync_master_clients               | 1     |  
  10. | Rpl_semi_sync_master_net_avg_wait_time     | 0     | 
  11. | Rpl_semi_sync_master_net_wait_time         | 0     | 
  12. | Rpl_semi_sync_master_net_waits             | 0     | 
  13. | Rpl_semi_sync_master_no_times              | 0     | 
  14. | Rpl_semi_sync_master_no_tx                 | 0     | 
  15. | Rpl_semi_sync_master_status                | ON    | 
  16. | Rpl_semi_sync_master_timefunc_failures     | 0     | 
  17. | Rpl_semi_sync_master_tx_avg_wait_time      | 0     | 
  18. | Rpl_semi_sync_master_tx_wait_time          | 0     | 
  19. | Rpl_semi_sync_master_tx_waits              | 0     | 
  20. | Rpl_semi_sync_master_wait_pos_backtraverse | 0     | 
  21. | Rpl_semi_sync_master_wait_sessions         | 0     | 
  22. | Rpl_semi_sync_master_yes_tx                | 0     | 
  23. +--------------------------------------------+-------+  
  24. clients 变为1 ,证明主从半同步复制连接成功。 

3、在从服务器上

  1. mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';   
  2. mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;   
  3. mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;   
  4. mysql> show global status like 'rpl_semi%'; 
  5. +----------------------------+-------+ 
  6. | Variable_name              | Value | 
  7. +----------------------------+-------+ 
  8. | Rpl_semi_sync_slave_status | ON    | 
  9. +----------------------------+-------+ 

配置完成。

如果想要配置永久生效则只需在各自服务器的/etc/my.cnf的[mysqld]段添加上述操作中set指令后的内容即可。

四、基于ssl的MYSQL复制

MYSQL的复制过程中数据的传输是明文显示的,这对企业来说是非常不安全的。所以我们采取某种机制对数据进行相应的加密,而ssl就是首选机制了。下面就进行ssl配置。

1、首先配置主-从服务。在此不再详述。

2、将rs1设置为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 
  9.  
  10. 为Master上的Mysql准备私钥以及颁发证书 
  11. #mkdir /usr/local/mysql/ssl 
  12. #cd ssl/ 
  13. #(umask 077;openssl genrsa 1024 > mysql.key) 
  14. #openssl req -new -key mysql.key -out mysql.csr 
  15. #openssl ca -in mysql.csr -out mysql.crt 
  16. #chown -R mysql.mysql ssl/ 

3、为rs2颁发证书

  1. #mkdir /usr/local/mysql/ssl 
  2. #cd /usr/local/mysql
  3. #chown -R mysql.mysql ssl/
  4. #cd ssl/
  5. #(umask 077;openssl genrsa 1024 > slave.key) 
  6. #openssl req -new -key slave.key -out slave.csr 
  7. #scp slave.csr 192.168.0.100:/root 
  8.  
  9. 在rs1上为rs2签发证书 
  10. #openssl ca -in slave.csr -out slave.crt 
  11. #scp slave.crt 192.168.0.101:/usr/local/mysql/ssl 
  12. #cd /etc/pki/CA 
  13. #scp cacert.pem 192.168.0.101:/etc/pki/CA 

4、在主服务器rs1上配置开启ssl

  1. #vim /etc/my.cnf 
  2. [mysqld] 
  3. ssl-ca=/etc/pki/CA/cacert.pem 
  4. ssl-cert=/usr/local/mysql/ssl/mysql.crt 
  5. ssl-key=/usr/local/mysql/ssl/mysql.key 
  6. #serivce mysqld restart 

5、在从服务器上

  1. # vim my.cnf 
  2.  [mysqld] 
  3.  ssl-ca=/etc/pki/CA/cacert.pem 
  4.  ssl-cert=/usr/local/mysql/ssl/slave.crt 
  5.  ssl-key=/usr/local/mysql/ssl/slave.key 
  6. 登录从服务器mysql 更改master的相关选项,以实现ssl功能  
  7. mysql> change master to 
  8.     -> master_host='192.168.0.100'
  9.     -> master_user='repluser'
  10.     -> master_password='sql123'
  11.     -> master_ssl=1
  12.     -> master_ssl_ca = '/etc/pki/CA/cacert.pem'
  13.     -> master_ssl_capath = 'ettc/pki/CA'
  14.     -> master_ssl_cert = '/usr/local/mysql/ssl/slave.crt'
  15.     -> master_ssl_key = '/usr/local/mysql/ssl/slave.key'
  16. mysql>start slave; 
  17. mysql>show slave status; 
  18.              Slave_IO_Running: Yes 
  19.             Slave_SQL_Running: Yes 
  20.            Master_SSL_Allowed: Yes 
  21.            Master_SSL_CA_File: /etc/pki/CA/cacert.pem 
  22.            Master_SSL_CA_Path: /etc/pki/CA 
  23.               Master_SSL_Cert: /usr/local/mysql/ssl/slave.crt 
  24.             Master_SSL_Cipher:  
  25.                Master_SSL_Key: /usr/local/mysql/slave.key 

至此,基于ssl的MYSQL复制配置完成。