MySQL主从复制
MySQL主从复制是依赖于二进制日志的(必须启用二进制日志功能),然后通过额外的proxy来实现MySQL的读写分离,达到主从复制的效果。
工作原理:主服务器数据的更新 -----> 写入二进制日志 -----> 主服务器的dump线程读取 -----> 传达给从服务器的io线程 -----> 存放在中继日志 -----> SQL线程读取中继日志中的内容 -----> 实现从服务器的数据更新
(数据需要经过中继日志存放然后再由SQL线程读取,这是因为数据从主服务器传递到从服务器的过程中,网络可能会存在不稳定性导致数据的丢失,放入中继日志后一段时间再进行复制可保证其稳定性)
(主从数据的更新不可避免的会存在延迟,这是因为主服务会根据多个io线程来开启对应的dump线程,所以通常也会采取异步复制)
(一般情况下:主服务器写,从服务器读(配置文件中加入read_only=on))
当MySQL使用主从复制后仍是不能解决压力过大的情况时,可采用分库、分表或分表中字段的方法将数据存放在不同的MySQL服务器中,称为垂直分区;也可根据自定义的某个值对数据较大的表进行分布式存放,称为水平分片
本文以下内容介绍了不同的MySQL主从复制架构实现方式(主服务器:Master ;从服务器:Slave)
第一种:一主一从复制的搭建:
1.二进制日志
Master必须启用,Slave建议启用(以防主服务器发生故障时,从服务器临时充当主服务器)
vim /etc/my.cnf
[mysqld] (此配置段下)
log_bin (根据需要,可另指存放路径)
log-basename=master (设置二进制日志的文件名前缀“master-bin.xxxxxx”,可以不用设置)
2.Master和Slave服务器的服务号server_id必须保证各自的唯一性
vim /etc/my.cnf
[mysqld] (此配置段下)
server_id = NUMBER
3.在Master服务器上指定拥有复制权限“replication slave”的用户:
GRANT REPLICATION SLAVE ON *.* TO '用户'@'IP' IDENTIFIED BY '密码';
4.在Slave服务器上使用3步骤创建的用户连接Master服务器
CHANGE MASTER TO MASTER_HOST='IP',MASTER_USER='用户',MASTER_PASSWORD='密码',MASTER_PORT=3306,MASTER_LOG_FILE='master-bin.xxxxx',MASTER_LOG_POS=#; (以逗号隔开)
其中一些含义解释如下:
MASTER_LOG_FILE='master-bin.xxxxx' 指定Slave复制的Master的二进制日志文件名
MASTER_LOG_POS=NUMBER 指定Slave复制开始的位置在什么地方
(此两项内容具体信息可在Master服务器上使用“SHOW MASTER LOGS;”查看)
5.Slave服务器启动复制线程:start slave
(注意:搭建成功后,并已经start slave,若slave服务器重新启动服务,此时会自动启动io、SQL两个线程,继续实现主从复制功能)
其中Slave服务器上会有记录复制相关的功能文件:
master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等
relay-log.info:保存在当前slave节点上已经复制的当前二进制日志和本地replay log日志的对应关系
第二种:当Master服务器已经运行一段时间后,需要增加新的Slave服务器,实现方法:(基于上述一主一从架构搭建好的情况下)
1.利用mysqldump命令,对Master服务器数据进行备份,此时“--master-data”选项可指定为1,这样可保证备份的数据内容“CHANGE MASTER TO……”语句没被注释
mysqldump -A -F --single-transaction --master-data=1 > FILE.sql
2.将备份文件拷贝至新增加的Slave服务器中
3.新增加的Slave服务器修改配置文件,指定唯一的“server_id”编号,启动服务
4.新增加的Slave服务器需要修改 FILE.sql 备份数据文件的相关内容,在“CHANGE MASTER TO……”一行中加入如下内容:
MASTER_HOST='IP',MASTER_USER='用户',MASTER_PASSWORD='密码',MASTER_PORT=3306
5.新增加的Slave服务器导入FILE.sql备份文件,重新启动服务,执行start slave,实现复制
在一主多从情况下,若Master服务器突然宕机,此时需要临时启用某个Slave服务器为主,可以手动在Slave服务器上执行“stop slave”,并且执行“reset slave all”清除原主从关系属性,另外重新建立主从关系即可
为缓解Master服务器的工作压力,可以建立级联复制,也就是M对S,S对SS。
1.需要开启S的二进制日志功能
2.因为数据复制传输的原理是通过二进制日志,但是S自身只会主动将M传递过来的数据记录到中继日志中,这样SS就不能够通过 S来进行数据的更新,所有需要在S的配置文件中加入“log_slave_updates”选项,来实现中继日志的内容更新到二进制日志中
第三种:半同步复制
默认情况下,MySQL的复制功能是异步的,异步复制可以提供最佳的性能,Master把binlog日志发送给Slave即结束,并不验证Slave是否接收完毕。这意味着当Master服务器或Slave服务器端发生故障时,有可能Slave服务器没有接收到主服务器发送过来的binlog日志,这就会造成Master服务器和Slave服务器的数据不一致,甚至在恢复时造成数据的丢失,所以就需要执行半同步复制
半同步复制:在M对多S的情况下,先保证一个S同步成功后,然后立即回应用户的请求,保证数据的安全,以及用户的体验速度
实现方法如下:
分别在M和S上安装插件,并启用相关的变量
M上执行:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL VARIABLES rpl_semi_sync_master_enabled=1; (若需持久有效,需将此变量写入配置文件中)
S上执行:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL VARIABLES rpl_semi_sync_slave_enabled=1; (若需持久有效,需将此变量写入配置文件中)
若S是在已有主从的情况下增加插件,需要重新启动io和SQL线程
若是需要卸载此插件的话,只需执行:
UNINSTALL rpl_semi_sync_master|slave
在主从复制过程中,还可以针对指定的数据库设定复制权限,方法如下:
第一种:基于Master服务器二进制日志的限定,在/etc/my.cnf中加入如下选项:
binlog_do_db= 数据库白名单列表
binlog_ignore_db= 数据库黑名单列表
但是二进制日志是主从复制的必要条件,所以这种方法不建议使用
第二种:基于Slave服务器的SQL THREAD从中继日志读取信息,在/etc/my.cnf中加入如下选项:
replicate_do_db|table= 指定复制库的白名单
replicate_ignore_db|table= 指定复制库的黑名单
若是白名单指定的数据库或表,则SQL THREAD只会从中继日志中读取记录该数据库或表操作信息
若是黑名单指定的数据库或表,则SQL THREAD不会从中继日志中读取记录该数据库或表操作信息
若是同一数据库在两者里都有,则只有白名单生效
主从复制加密(基于SSL/TLS加密)
实现的步骤:
1.在另外的独立的服务器上生成私钥来创建自签名CA证书,
openssl genrsa > cakey.pem
openssl req –new –x509 -key cakey.pem -out cacert.crt -days 3650
另外生成给Master服务使用的私钥和证书申请文件
openssl req -newkey rsa:2048 -nodes -keyout master.key > master.csr
给Slave服务器生成私钥和证书申请文件
openssl req -newkey rsa:2048 -nodes -keyout slave.key > slave.csr
给Master服务器和Slave服务器颁发证书文件
openssl x509 -req -in master.csr -CA cacert.crt -CAkey cakey.pem -set_serial 01 -days 100 > master.crt
openssl x509 -req -in slave.csr -CA cacert.crt -CAkey cakey.pem -set_serial 02 -days 100 > slave.crt
2.然后将Master和Slave服务器需要的文件分别拷贝给它们,存放在指定的文件夹中,假设存放在/app/ssl/下
3.注意要保证拷贝后的文件的读权限
4.在Master服务器的/etc/my.cnf中加入如下选项:
ssl(可省略)
ssl-ca=/app/ssl/cacert.crt
ssl-cert=/app/ssl/master.crt
ssl-key=/app/ssl/master.key
然后启动服务,创建复制使用账户,并强制其加密
grant replication slave on *.* to 'rui'@'172.18.122.%' identified by 'centos' require ssl;
5.Slave服务器在配置文件中加入如下选项:
ssl(可省略)
ssl-ca=/app/ssl/cacert.crt
ssl-cert=/app/ssl/slave.crt
ssl-key=/app/ssl/slave.key
然后启动服务,并使用“CHANGE MASTER TO……”语句执行相关信息,注意需要加上“MASTER_SSL=1”
6.Slave服务器启动线程 start slave,则开始实现同步