主从复制的作用:
数据分布
负载均衡读
备份
高可用和故障切换
MySQL升级测试
主从复制线程:
主节点:
dump Thread:为每个Slave的I/O Thread启动一个dump线程,用于向其发送binary log events
从节点:
I/O Thread:向Master请求二进制日志事件,并保存于中继日志中
SQL Thread:从中继日志中读取日志事件,在本地完成重放
跟复制功能相关的文件:
master.info:用于保存slave连接至master时的相关信息,例如账号、密码、服务器地址等
relay-log.info:保存在当前slave节点上已经复制的当前二进制日志和本地
replay log日志的对应关系
主从复制特点:
异步复制
主从数据不一致比较常见
复制架构:
Master/Slave, Master/Master, 环状复制
一主多从
从服务器还可以再有从服务器
一从多主:适用于多个不同数据库
复制需要考虑二进制日志事件记录格式
STATEMENT(5.0之前)
ROW(5.1之后,推荐)
MIXED
MYSQL垂直分区:
把不相干的数据分开服务器存放,例如数据A和B还有C,分别存放在服务器A B C中,但要求ABC之间互相没关联,不需要用join联表查询。
MYSQL水平分区:
也是分开服务器存放的一种,按照用户ID,奇数和偶数ID分别放在不同的服务器中。
主节点配置:
1.启用二进制日志
[mysqld]
log_bin
2.为当前节点设置一个全局惟一的ID号
[mysqld]
server_id=#
log-basename=master 可选项,设置datadir中日志名称,确保不依赖主机名
3.创建有复制权限的用户账号
GRANT REPLICATION SLAVE ON *.* TO 'repluser'@'HOST' IDENTIFIED BY 'replpass';
4.查看二进制日志位置并记录
show master logs;
从节点配置:
1.启动中继日志
[mysqld]
server_id=# 为当前节点设置一个全局惟的ID号
read_only=ON 设置数据库只读
relay_log=relay-log relay log的文件路径,默认值hostname-relay-bin
relay_log_index=relay-log.index 默认值 hostname -relay-bin.index
2.使用有复制权限的用户账号连接至主服务器,并启动复制线程
CHANGE MASTER TO MASTER_HOST='host',
MASTER_USER='repluser', MASTER_PASSWORD='replpass',
MASTER_LOG_FILE=' mysql-bin.xxxxxx', MASTER_LOG_POS=#;
START SLAVE [IO_THREAD|SQL_THREAD];
设置完了需要在从服务器上执行start slave;启动
查看从服务器状态
show slave status\G
查看MYSQL中启动的线程
show processlist;
主从复制需要注意的问题:
1、限制从服务器为只读
在从服务器上设置read_only=ON
注意:此限制对拥有SUPER权限的用户均无效
阻止所有用户, 包括主服务器复制的更新
FLUSH TABLES WITH READ LOCK;
2、RESET SLAVE
在从服务器清除master.info ,relay-log.info, relay log ,开始新的relay
log ,注意:需要先STOP SLAVE
RESET SLAVE ALL 清除所有从服务器上设置的主服务器同步信息如:
PORT, HOST, USER和 PASSWORD 等
3、sql_slave_skip_counter = N 从服务器忽略几个主服务器的复制事件,global变量
如何保证主从复制的事务安全
在master节点启用参数:
sync_binlog=1 每次写后立即同步二进制日志到磁盘,性能差
如果用到的为InnoDB存储引擎:
innodb_flush_log_at_trx_commit=1 每次事务提交立即同步日志写磁盘
innodb_support_xa=ON 默认值,分布式事务MariaDB10.3.0废除
sync_master_info=# #次事件后master.info同步到磁盘
在slave节点启用服务器选项:
skip_slave_start=ON 不自动启动slave
在slave节点启用参数:
sync_relay_log=# #次写后同步relay log到磁盘
sync_relay_log_info=# #次事务后同步relay-log.info到磁盘
级联复制示意
主从复制是需要在主服务器的二进制日志纪录复制给从服务器,而从服务同步过来的日志是纪录在中继日志,在上面的图里,级联服务器B需要把中继日志里的纪录写入二进制日志,但二进制日志只纪录本机上更新数据库,不记录中继日志做的更新。
所以搭建时除了开启二进制日志,还需要在级联服务器B上面添加配置log_slave_updates,如下:
[mysqld]
log_bin
log_slave_updates
主主复制就是互为主从,容易产生的问题:数据不一致;因此慎用
表中设置自动增长id,否则会产生冲突
配置一个节点使用奇数id
auto_increment_offset=1 开始点
auto_increment_increment=2 增长幅度
另一个节点使用偶数id
auto_increment_offset=2
auto_increment_increment=2
除此之外还要都设置服务器ID和开启二进制日志,剩下的设置跟主从复制一样。
MySQL的复制功能是异步的,异步复制可以提供最佳的性能,主库把binlog日志发送给从库即结束,并不验证从库是否接收完毕。这意味着当主服务器或从服务器端发生故障时,有可能从服务器没有接收到主服务器发送过来的binlog日志,这就会造成主服务器和从服务器的数据不一致,甚至在恢复时造成数据的丢失。
同步复制需要复制到所有从服务器上才算完成,而数据同步会有延迟,如果全同步可能会出现等待时间过长,半同步只需要同步一个从服务器成功就算成功了。
1.配置好主从设置,但先不要启动
2.主服务器安装半同步插件
INSTALL PLUGIN rpl_semi_sync_master SONAME ‘semisync_master.so’;
3.设置插件启用
SET GLOBAL rpl_semi_sync_master_enabled=1;
4.可以设置超时时长,默认10秒
SET GLOBAL rpl_semi_sync_master_timeout = 1000;单位毫秒
5.从服务器安装插件,并设置启用
INSTALL PLUGIN rpl_semi_sync_slave SONAME ‘semisync_slave.so’;
SET GLOBAL rpl_semi_sync_slave_enabled=1;
6.启动从服务器线程即可
查看插件变量
SHOW GLOBAL VARIABLES LIKE ‘%semi%’;
查看半同步状态
SHOW GLOBAL STATUS LIKE '%semi%‘;
复制过滤器可以让从节点仅复制指定的数据库,或指定数据库的指定表
有两种实现方式:
1.主服务器仅向二进制日志中记录与特定数据库相关的事件
binlog_do_db = 数据库白名单列表,多个数据库需多行实现
binlog_ignore_db = 数据库黑名单列表
这样基于二进制还原将无法实现;不建议使用
2.从服务器SQL_THREAD在replay中继日志中的事件时,仅读取与特定数据库(特定表)相关的事件并应用于本地
replicate_do_db= 指定复制库的白名单
replicate_ignore_db= 指定复制库黑名单
replicate_do_table= 指定复制表的白名单
replicate_ignore_table= 指定复制表的黑名单
replicate_wild_do_table= foo%.bar% 支持通配符
replicate_wild_ignore_table=
这个会造成网络及磁盘IO浪费
在默认的主从复制过程或远程连接到MySQL/MariaDB所有的链接通信中的数据都是明文的,外网里访问数据或则复制,存在安全隐患。通过SSL/TLS加密的方式进行复制的方法,来进一步提高数据的安全性
开始配置之前,先准备好CA的证书,主服务器的证书和私钥,从服务器的证书和私钥。
如果没有,参考以下步骤生成
1.生成CA私钥
openssl genrsa 2048 > cakey.pem
2.生成自签名证书
openssl req -new -x509 -key cakey.pem -out cacert.pem -day 3650
3.生成主服务器的私钥和证书申请文件
openssl req -newkey rsa:1024 -nodes -keyout master.key > master.csr
4.给主服务器颁发证书
openssl x509 -req -in master.csr -CA cacert.pem -CAkey cakey.pem -set_serial 01 > master.crt
5.生成从服务器的私钥和证书申请文件
openssl req -newkey rsa:1024 -nodes -keyout slave.key > slave.csr
6.给从服务器颁发证书
openssl x509 -req -in slave.csr -CA cacert.pem -CAkey cakey.pem -set_serial 02 > slave.crt
加密复制配置步骤
1.主服务器配置SSL相关设置
[mysqld]
ssl-ca=/etc/my.cnf.d/ssl/cacert.pem
ssl-cert=/etc/my.cnf.d/ssl/master.crt
ssl-key=/etc/my.cnf.d/ssl/master.key
2.在主服务器上创建复制用的账号要求SSL连接
grant replication slave on *.* to repluser@'192.168.1.%' identified by 'test1123' require ssl;
3.在从服务器上测试用户是否能连接
mysql -h 192.168.1.10 -urepluser -ptest1123 --ssl-ca=cacert.pem --ssl-cert=slave.crt --ssl-key=slave.key
4.从服务器配置
[mysqld]
ssl-ca=/etc/my.cnf.d/ssl/cacert.pem
ssl-cert=/etc/my.cnf.d/ssl/slave.crt
ssl-key=/etc/my.cnf.d/ssl/slave.key
如果不能重启服务,也可以直接在mysql里停止slave线程后重新配置再启动
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_USER='repluser',
MASTER_PASSWORD='test1123',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=245,
MASTER_SSL=1,
MASTER_SSL_CA = '/etc/my.cnf.d/ssl/cacert.pem',
MASTER_SSL_CERT = '/etc/my.cnf.d/ssl/slave.crt',
MASTER_SSL_KEY = '/etc/my.cnf.d/ssl/slave.key';
至此配置结束
GTID复制:global transaction id 全局事物标识符,mysql5.6版本开始支持,GTID复制不像传统的复制方式例如半同步复制、异步复制那样需要找到binlog和pos,只需要知道master的IP、端口、账号、密码即可。开启GTID后,执行change master to master_auto_postion=1即可。
在主从复制的基础上启用GTID,在配置中增加开启参数
[mysqd]
gtid_mode=on
enforce_gtid_consistency
从服务器指定主服务器时不需要添加二进制日志位置
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_USER='repluser',
MASTER_PASSWORD='test1123',
MASTER_AUTO_PASITION=1;
清理日志
PURGE { BINARY | MASTER } LOGS { TO ‘log_name’ | BEFORE datetime_expr }
RESET MASTER
RESET SLAVE
状态监控
SHOW MASTER STATUS
SHOW BINLOG EVENTS
SHOW BINARY LOGS
SHOW SLAVE STATUS
SHOW PROCESSLIST
从服务器与主服务器的复制延迟
Seconds_Behind_Master: 0
如何确定主从节点数据是否一致
使用工具percona-tools
数据不一致如何修复
删除从数据库,重新复制