一、半同步复制
1.mysql的复制
通过记录主服务器的二进制日志,并在从服务器上进行重放(replay)完成复制,默认都是异步进行的。
2.半同步复制
半同步复制是google贡献给MySQL的一个补丁,在MySQL 5.5之后就支持了,MariaDB都是支持的。
MySQL的插件,一般在MySQL安装目录下;
半同步复制插件默认没有启用,需要自己安装,/usr/local/mysql/lib/plugin可以看到semisync_master.so和semisync_slave.so和其他许多插件;进行半同步时,主启用semisync_master.so,从启用semisync_slave.so,且只要一个从(离主近,带宽足够可用)启用半同步即可。
3.半同步的目的
保证Master服务器的事务必须接收指定slave服务器(一台)的返回消息,才会commit;否则需要等待超时时间(rpl_semi_sync_master_timeout的默认为10s),然后切换成异步再提交;这样做的目的可以使主从数据库的数据延迟缩小,可以在损失很小的性能的前提下提高数据安全性。
解决的问题:如果slve不幸落后,而更不幸的是主库此时又出现Crash,这时备库中的数据就是不完整的,无法使用备库来继续提供数据一致的服务了。Semisynchronous Replication则一定程度上保证提交的事务已经传给了至少一个slave。
二、半同步复制的实现
1.检查插件
# ls /usr/local/mysql/lib/plugin semisync_master.so #用于Master服务器安装的半同步插件 semisync_slave.so #用于Slave服务器安装的半同步插件
2.安装半同步插件
#####主服务器安装插件(Mysql提供插件安装机制:HELP INSTALL): MariaDB[(none)]> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; MariaDB[(none)]> SHOW GLOBAL VARIABLES LIKE '%semi%'; MariaDB[(none)]> SET GLOBAL rpl_semi_sync_master_enabled=ON; #开启半同步 MariaDB[(none)]> SET GLOBAL rpl_semi_sync_master_timeout=1000; #等待超时时间:单位ms; ####从服务器插件: MariaDB[(none)]> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; MariaDB[(none)]> SHOW GLOBAL VARIABLE LIKE '%semi%'; MariaDB[(none)]> SET GLOBAL rpl_semi_sync_slave_enabled=ON; mysql> STOP SLAVE IO_THREAD; mysql> START SLAVE IO_THREAD; #重启IO线程生效3
3.查看半同步开启状态
######在Master服务器上查看 MariaDB[(none)]> show global status like 'rpl_semi%'; Rpl_semi_sync_master_clients 1 #已经有一个客户端连接 Rpl_semi_sync_master_status ON #已经为开启状态 MariaDB[(none)]> show global variables like '%rpl%'; rpl_semi_sync_master_enabled ON #Master半同步已经开启 rpl_semi_sync_master_timeout 1000 #超时时间 ######在Slave服务器上查看 MariaDB[(none)]> show global status like 'rpl_semi%'; Rpl_semi_sync_master_status ON #已经为开启状态 MariaDB[(none)]> show global variables like '%rpl%'; rpl_semi_sync_slave_enabled ON #Master半同步已经开启
4.上面的设置重启服务后会失效的,设置开机生效
不建议把半同步配置写在配置文件中;
####Master: vim /etc/my.cnf [mysqld] rpl_semi_sync_master_enabled=1 rpl_semi_sync_master_timeout=1000 ####Slave: vim /etc/my.cnf [mysqld] rpl_semi_sync_slave_enabled=1
5.通过全局变量来设置半同步
####Master: MariaDB[(none)]> set global rpl_semi_sync_master_enabled=1 取消加载插件 MariaDB[(none)]> uninstall plugin rpl_semi_sync_master; ####Slave: MariaDB[(none)]> set global rpl_semi_sync_slave_enabled = 1; MariaDB[(none)]> uninstall plugin rpl_semi_sync_slave;
三、基于SSL的复制
Mysql的主从复制是明文传送的,为保证数据的安全性,使用SSL的加密进行传输数据。(不过,SSL的Heartblood事件之后,SSL的安全性也被大大怀疑,囧)
1.在master上自建CA服务器
# cd /etc/pki/CA/ # (umask 077;openssl genrsa -out private/cakey.pem 2048) # openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650 # touch index.txt # echo 01 > serial
2.master自签证书
# mkdir /usr/local/mysql/ssl # cd /usr/local/mysql/ssl # (umask 077;openssl genrsa -out master.key 2048) # openssl req -new -key master.key -out master.csr -days 3650 //证书申请 # openssl ca -in master.csr -out master.crt -days 3650 //签署证书
3.为Slave服务器创建证书申请
# mkdir /usr/local/mysql/ssl # cd /usr/local/mysql/ssl # (umask 077;openssl genrsa -out slave.key 2048) # openssl req -new -key slave.key -out slave.csr -days 3650 # scp slave.csr master.hoo.com:/tmp/
4.为Slave签署证书
//master上操作 # openssl ca -in /tmp/slave.csr -out /tmp/slave.crt -days 3650 # scp /tmp/slave.crt slave.allen.com:/usr/local/mysql/ssl/
5.SSL文件的权限
######修改Master服务器 # chown -R mysql.mysql /usr/local/mysql/ssl //保证秘钥在目录下 ######修改Slave服务器 # chown -R mysql.mysql /usr/local/mysql/ssl //保证秘钥在目录下
6.在Master与Slave服务器修改主配置文件开启SSL加密功能
######修改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 #指定密钥所在位置 # service mysqld restart #重启服务生效 ######修改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 # service mysqld restart
7.在master上查看SSL是否生效;
# mysql MariaDB[(none)]> 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 | +---------------+---------------------------------+
8.查看master的状态
MariaDB[(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000004 | 550 | | | +------------------+----------+--------------+------------------+
9.添加一个用户,并使用加密方式连接到master
####master MariaDB[(none)]> grant replication client,replication slave on *.* to 'slave'@'172.16.%.%' identified by 'passwd' require ssl; MariaDB[(none)]> flush privileges; ####slave # mysql -uslave -ppasswd -h 172.16.1.3 --ssl-ca=/usr/local/mysql/ssl/cacert.pem --ssl-cert=/usr/local/mysql/ssl/slave.crt --ssl-key=/usr/local/mysql/ssl/slave.key
10.开始基于SSL的复制
####查看Slave服务器SSL是否开启 # mysql MariaDB[(none)]> show variables like '%ssl%'; ####获取命令帮助 MariaDB[(none)]> 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' #指定自己的密钥文件 ####连接Master服务器 MariaDB[(none)]> change master to master_host='172.16.1.3',master_user='slave',master_password='passwd', master_log_file='mysql-bin.000004',master_log_pos=550,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';
11.查看slave服务器状态
MariaDB[(none)]> show slave status\G; Slave_IO_Running: Yes Slave_SQL_Running: 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
12.测试
在master上创建数据库,在slave上查看是否同步
四、补充,复制过滤器
####复制过滤器 master: binlog_do_db= (白名单列表,表示复制哪些数据库,记录到二进制日志) binlog_ignore_db= (黑名单列表,忽略哪些数据库) 以上两点不建议同时使用 slave: replicate_do_db= (数据库白名单,多个用列表) replicate_ignore_db= (黑名单) 不建议同时使用, 如果同时启用则以白名单为准, 如果同时出现在白黑名单中,则拒绝复制 replicate_do_table= db_name.table_name (表的白名单) replicate_ignore_table=(表的黑名单) replicate_wild_do_table= replicate_wild_ignore_table= 以上两项支持通配符,进行过滤 主服务器只能过滤到库级别,从服务器可以过滤到表级别;