mysql集群简介
人多势众
主从复制
异步复制,基于二进制日志,先完全备份同步原始数据,再进行二进制复制,记录点为完全备份时间点
操作请求 --> 主服务器,数据更新 -->写入二进制日志binlog --> 开启dump线程用于实时向从服务器传输同步数据 --> 从服务器开启io线程用于接收dump线程发来的同步数据 --> 写入中继日志relaylog中,也是二进制日志文件,减少内存占用 --> sql线程会将中继日志中的同步数据写入从服务器的数据库
特点
- 异步复制
- 主从数据不一致比较常见,存在延迟差
从服务器的版本可以高于主服务器,可以兼容低版本,主服务器不可高于从服务器
主从复制配置,非新建
主机所安装的mysql版本需相同
以8.0.26为例,如是8.0以下需开启二进制日志功能,sql_log_bin=1
#两台主机主10.0.0.8和从10.0.0.18
#在主10.0.0.8上
#1 创建备份所需文件夹
mkdir /data/logbin /data/backup
chown -R mysql. /data/logbin /data/backup
#2 更改配置文件
vim /etc/my.cnf
[mysqld]
server-id=8 #主从复制全局的唯一编号,不能重复
log-bin=/data/logbin/mysql-bin #二进制日志路径
systemctl restart mysqld
#3 登录mysql创建账号和授权
mysql
create user wei@'10.0.0.%' identified by '123456';
grant replication slave on *.* to wei@'10.0.0.%'; #replication slave允许复制权限
#4 完全备份,注意要先创建账号授权后再备份,保留一份账号数据信息在从服务器
mysqldump -uroot -p123456 -A -F --single-transaction --source-data > /backup/full-`date +%F`.sql
#8.0.26版本之前用--master-data代替--source-data
#在从10.0.0.18上
#1 更改配置文件
vim /etc/my.cnf
[mysqld]
server-id=18
read-only #建议添加只读权限,防止普通用户更改服务器数据,root可用
systemctl restart mysqld
#2 主服务器复制完全备份到从服务器
scp /data/backup/full-2023-05-16.sql 10.0.0.18:/backup
chown -R mysql. /backup
#3 添加二进制日志文件标记设定的值
vim /backup/full-2023-05-16.sql
CHANGE MASTER TO
MASTER_HOST='10.0.0.8', #从服务器的主服务器是谁,或者说访问哪台主机
MASTER_USER='wei', #用哪个账号连接
MASTER_PASSWORD='123456', #密码
MASTER_PORT=3306, #端口
MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=156; #二进制日志文件标记位
#如需更改相关值可直接当成SQL语句执行即可
reset slave all; #可删除全部的CHANGE MASTER同步信息
#4 还原数据
mysql
set sql_log_bin=0; #同步数据过程关闭二进制日志功能
source /backup/full-2023-05-16.sql;
set sql_log_bin=1;
start slave; #开启同步线程
#查看线程
show processlist;
show slave status\G #查看详细状态信息
主主复制
注意项:
- 自动增长id冲突
- 文件名冲突
解决方法:
- 将一台主机自动增长id设为单数,另一台设为双数
- 仅在一台主机上进行写操作
配置自动增长单双数
第一台主机10.0.0.8
vim /etc/my.cnf
auto_increment_offset=1 #开始点
auto_increment_increment=2 #增长幅度
systemctl restart mysqld
另一台主机10.0.0.18
vim /etc/my.cnf
auto_increment_offset=2
auto_increment_increment=2
systemctl restart mysqld
搭建主主复制
#先搭建主从复制,然后在主服务器10.0.0.8上添加从服务器的访问信息将主服务器变成从服务器
mysql> CHANGE MASTER TO
MASTER_HOST='10.0.0.18',
MASTER_USER='wei',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000009', MASTER_LOG_POS=456; #注意该记录信息是从服务器10.0.0.18的二进制日志标记位
#开启同步线程
start slave;
半同步复制
只要有任何一个从服务器同步完成就返回成功结果
以8.0为例,三台主机一主两从,10.0.0.8、10.0.0.18、10.0.0.28,需打开二进制功能,8.0默认开启
#环境准备
yum -y install mysql-server
systemctl start mysqld
#登录mysql安装插件
mysql
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; #需先安装该插件以便后续使用
UNINSTALL PLUGIN rpl_semi_sync_master ; #删除插件
SHOW PLUGINS; #查看插件
#更改配置文件
vim /etc/my.cnf
[mysqld]
server-id=8
rpl_semi_sync_master_enabled=1; #启用插件
rpl_semi_sync_master_timeout = 3000; #等待同步时间,默认为十秒,以毫秒为单位,如该时间内未完成同步会更改为异步同步,返回客户已成功的结果
systemctl restart mysqld
#创建账号
mysql
create user wei@'10.0.0.%' identified by '123456';
grant replication slave on *.* to wei@'10.0.0.%';
#完全备份并拷贝到其他从主机
mysqldump -uroot -p123456 -A -F --single-transaction --source-data > /backup/full-`date +%F`.sql
scp /data/backup/full-2023-05-16.sql 10.0.0.18:/backup
scp /data/backup/full-2023-05-16.sql 10.0.0.28:/backup
#10.0.0.18上
#
vim /etc/my.cnf
[mysqld]
server-id=18
rpl_semi_sync_slave_enabled=1;
systemctl restart mysqld
#安装插件
mysql
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
#更改同步数据信息
vim /backup/full-2023-05-16.sql
CHANGE MASTER TO
MASTER_HOST='10.0.0.8',
MASTER_USER='wei',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS=156;
#还原数据
mysql < /backup/full-2023-05-16.sql
#开启同步线程
mysql
start slave;
#10.0.0.28上,步骤与18相同,同步数据可以直接拷贝的18的full文件来用就可以,都指向的8为主服务器
#可检查半同步是否开启
SHOW GLOBAL VARIABLES LIKE '%semi%';
SHOW GLOBAL STATUS LIKE '%semi%'; #状态变量,可查看从服务器连接数量
show plugins; #查看已安装的插件
增强半同步复制(5.7版本)
可解决幻读和一部分数据丢失的风险,8.0默认开启
#更改变量为,也可写入配置文件
rpl_semi_rsync_master_wait_point=after_sync
#查看变量的值
show variables like 'rpl_semi_rsync_master_wait_point'
复制过滤器
在配置文件中更改
1、服务器选项,主服务器仅在二进制日志文件中记录与特定数据库相关的事件,黑白名单,
基于二进制还原数据库时将无法还原,不建议使用
vim /etc/my.cnf
binlog-do-db = #数据库白名单列表,不支持同时指定多个值,如果想实现多个数据库需多行实现,只记录该值的二进制日志
binlog-ignore-db = #数据库黑名单列表,不记录该值的二进制日志
show master status; #查看黑白名单
2、在所需配置的从服务器上添加过滤,不影响二进制备份还原
replicate_do_db=db1 #指定复制库的白名单,从服务器仅复制指定的二进制日志文件信息,多个写多行
replicate_ignore_db= #指定复制库黑名单
replicate_do_table= #指定复制表的白名单
replicate_ignore_table= #指定复制表的黑名单
replicate_wild_do_table= foo%.bar% #支持通配符
replicate_wild_ignore_table=
GTID复制
5.7版本可用
- 事务发生的编号全局唯一性,可自动判断事务完成与否,备份时可不用再指定二进制日志文件标记位置
- 实现多线程并发复制,减少同步延迟
- 具有幂等性,多次执行结果是一样的
实现GTID
服务器配置文件,8.0为例
vim /etc/my.cnf
server-id=1
gtid_mode=ON #开启GTID功能
enforce_gtid_consistency #使用GTID,保证数据一致性
systemctl restart mysqld
其余备份同步步骤相同,区别在于在从服务器上添加访问主服务器信息不同
mysql>CHANGE MASTER TO MASTER_HOST='10.0.0.8',
MASTER_USER='wei',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_AUTO_POSITION=1; #使用GTID功能自动去找标记位
mysql>start slave;
造成主从不一致的原因
- 主库binlog格式为Statement,同步到从库执行后可能造成主从不一致。
- 主库执行更改前有执行set sql_log_bin=0,会使主库不记录binlog,从库也无法变更这部分数据。
- 从节点未设置只读,误操作写入数据
- 主库或从库意外宕机,宕机可能会造成binlog或者relaylog文件出现损坏,导致主从不一致
- 主从实例版本不一致,特别是高版本是主,低版本为从的情况下,主数据库上面支持的功能,从数据库上面可能不支持该功能
- MySQL自身bug导致
- 主从sql_mode 不一致
如何避免主从不一致
- 主库binlog采用ROW格式
- 主从实例数据库版本保持一致
- 主库做好账号权限把控,不可以执行set sql_log_bin=0
- 从库开启只读,不允许人为写入
- 定期进行主从一致性检验
主从不一致修复方法
-
将从库重新实现
虽然这也是一种解决方法,但是这个方案恢复时间比较慢,而且有时候从库也是承担一部分的查询操作的,不能贸然重建。
-
使用percona-toolkit工具辅助
PT工具包中包含pt-table-checksum和pt-table-sync两个工具,主要用于检测主从是否一致以及修复数据不一致情况。这种方案优点是修复速度快,不需要停止主从辅助,缺点是需要知识积累,需要时间去学习,去测试,特别是在生产环境,还是要小心使用关于使用方法,可以参考下面链接:https://www.cnblogs.com/feiren/p/7777218.html
-
手动重建不一致的表
在从库发现某几张表与主库数据不一致,而这几张表数据量也比较大,手工比对数据不现实,并且重做整个库也比较慢,这个时候可以只重做这几张表来修复主从不一致这种方案缺点是在执行导入期间需要暂时停止从库复制,不过也是可以接受的
范例:A,B,C这三张表主从数据不一致
1、从库停止Slave复制
mysql>stop slave;
2、在主库上dump这三张表,并记录下同步的binlog和POS点
mysqldump -uroot -pmagedu -q --single-transaction --master-data=2 testdb A B C >/backup/A_B_C.sql
3、查看A_B_C.sql文件,找出记录的binlog和POS点
head A_B_C.sql
例如:MASTERLOGFILE='mysql-bin.888888', MASTERLOGPOS=666666;
4、把A_B_C.sql拷贝到Slave机器上,并做指向新位置
mysql>start slave until MASTERLOGFILE='mysql-bin.888888', MASTERLOGPOS=666666;
#以上指令start slave until是为了保障其他表的数据不丢失,一直同步到主服务器所备份的标记点结束,
5、在Slave机器上导入A_B_C.sql
mysql -uroot -pmagedu testdb
mysql>set sql_log_bin=0;
mysql>source /backup/A_B_C.sql
mysql>set sql_log_bin=1;
6、导入完毕后,从库开启同步即可。
mysql>start slave;
拆分
简单来说,就是指通过某种特定的条件,将我们存放在同一个数据库中的数据分散存放到多个数据库(主机) 上面,以达到分散单台设备负载的效果。
-
一种是按照不同的表(或者 Schema)来切分到不同的数据库(主机)之上,这种切可以称之为数据的垂直(纵向)切分;
垂直切分的最大特点就是规则简单,实施也更为方便,尤其适合各业务之间的耦合度非常低,相互影响很小, 业务逻辑非常清晰的系统。垂直切分是按照业务的分类将表分散到不同的库,所以有些业务表会过于庞大,存在单库读写与存储瓶颈
-
另外一种则是根据 表中的数据的逻辑关系,将同一个表中的数据按照某种条件拆分到多台数据库(主机)上面,这种切分称之为数据的水平(横向)切分。
将同一个表中的不同数据拆分到不同的数据库中, 对于应用程序来说,拆分规则本身就比根据表名来拆分更为复杂,后期的数据维护也会更为复杂一些。
相对于垂直拆分,水平拆分不是将表做分类,而是按照某个字段的某种规则来分散到多个库之中,每个表中包含一部分数据。
拆分数据就需要定义分片规则。关系型数据库是行列的二维模型,拆分的第一原则是找到拆分维度。
共同特点缺点有:
- 引入分布式事务的问题
- 跨节点 Join 的问题
- 跨节点合并排序分页问题
- 多数据源管理问题
总结
- 能不切分尽量不要切分
- 如果要切分一定要选择合适的切分规则,提前规划好。
- 数据切分尽量通过数据冗余或表分组(Table Group)来降低跨库 Join 的可能
- 由于数据库中间件对数据 Join 实现的优劣难以把握,而且实现高性能难度极大,业务读取尽量 少使用多表 Join。