下面会向大家演示最常用的mysql主从配置方案,技术上没有太多复杂的地方,不过也可以满足大多数网站的性能对需求了
-
知识点 (首先我们先了解一些必要的知识点, 这样大家可以之后的工作学习中可以从容的选择架构方案)
①:日志格式
mysql提供了日志格式分别是 'Row' 'Statement' 'Mixed' 'GTID' , 下面我分别 为大家介绍他们之间的区别 'Row' 基于数据行的数据复制格式 优点: - 使用随机函数和高精度时间函数可保证主从数据完全一致 - 数据同步过程中从服务器产生的锁会比 'Statement' 格式更少 缺点: - 主从复制时要求从服务器中的表结构必须完全一致(包括列顺序) 'Statement' 基于SQL语句的复制格式 优点: - 产生的日志IO非常小, 通常是字节级别所以在传输时速度很快 - 不强制要求主从数据库表完全相同 - 相比于 'Row' 格式来说更加灵活 缺点: - 调用随机函数时可能导致数据不一致 '(比如UUID函数,时间函数等其他随机或精度函数)' - 相对于 'Row' 格式从服务器在操作会比前者产生出更多的行数 '(也就是说在主服务器中锁了多少数据在从服务器还要在锁一次)' 'Mixed' 混合复制格式(自动区分) 'GTID' (mysql5.6以上版本新增) - 与日志复制相比不会出现因为日志偏移量而产生的重复执行操作②:主从复制原理
'主库写入二进制日志->从服务器读取主库的二进制变更并写入relay_log->在从库重放relay_log中的日志'③:主从复制方式
'全同步复制 (Fully synchronous replication)' - 当主库执行完写入操作时将日志推送给所有从服务器,只有等所有从库都执行完成后才会将结果反馈给客户端 (牺牲性能换取数据的一致性) '半同步复制 (Semisynchronous replication)' - 当主库执行完一次写入操作将日志推送给所有从服务器,只需等待一台服务器完成写入操作就会将结果反馈给客户端 (介于全同步复制和异步复制之间的中间选择,适用于大多数应用场景) '异步复制 (Asynchronous replication)' - 如未进行配置时mysql默认采用异步复制,当产生新数据时主库会将binlog推送到从库,但是不保证一定能推送成功 (简单来说就是,这事我已经告诉你了,你听没听到是你的事了!) -
准备工作
① 确认需要操作的服务器Mysql配置文件中都开启了 'log-bin=mysql-bin' ② 确认需要操作的服务器Mysql配置文件中 'server-id' 没有出现重复 ③ 在从服务器Mysql配置文件中添加 'read_only' (选配项->只读模式, 如后续考虑配置MHA此项可不设置) ④ 在从服务器Mysql配置文件中添加 'replicate-do-db' (选配项->从服务器指定库名) ⑤ 停止业务运行等待配置完成后在开启服务以此保证数据的真实性(个人习惯) ⑥ 选择适合自己项目的日志格式 '(如使用gtid复制则集群中所有服务器需开启如下参数,且gtid不支持mysql5.6以下版本)' gtid_mode = on enforce_gtid_consistency = on -
操作步骤
① 在主 (写) 服务器添加从 (读) 服务器用户
# Mysql8以下添加用户 mysql> grant replication slave on 库名(*=全部).表名(*=全部) to '账号'@'服务器ip' identified by '连接密码'; # Mysql8t添加用户 mysql> create user '账号'@'服务器IP' identified by '密码'; mysql> grant replication slave on 库名(*=全部).表名(*=全部) to '账号'@'服务器IP'; # 刷新权限 mysql> flush privileges;② 查询主服务器当前日志偏移量
mysql> show master status; # 如使用日志方式复制关注File及Position,如使用gtid复制关注Executed_Gtid_Set③ 配置从 (读) 服务器
# 基于日志点复制 (二选一) mysql> change master to master_host='主服务器ip' (string), master_port=主服务器数据库端口 (int), master_user='从账号' (string), master_password='从密码' (string), master_log_file='主服务器当前的file值' (string), master_log_pos=主服务器当前的position (int); # 基于GTID复制 (二选一) mysql> change master to master_host='主服务id' (string), master_port=主服务器数据库端口 (int), master_user='从账号' (string), master_password='从密码' (string), master_auto_position=日志点 (int) # 配的时候注意字段类型, 我第一次配的时候一直报错, 搞半天才发现是字段类型不对 mysql> start slave # 开始复制数据 mysql> show slave status\G # 检查运行状态 # Slave_IO_Running和Slave_SQL_Running都为Yse时表示连接成功 # 也可以在主库上使用 show processlist 查看从库是否连接正常 -
主从复制时可能产生的问题及解决方案分享
① 如何解决主从单点故障问题
'单点故障在生产过程中无法避免,服务器重启,假死,断电,宕机都可能会造成单点
故障, 解决方案可考虑使用双主多从架构,MMM架构,MHA架构, Mycat高可用配置'
② 如何解决主从复制时产生的单点数据延迟
'使用主从复制时还会遇到这种情况,主服务器成功写入数据并将状态值反馈给客户端,
此时客户端在读取刚才写入的数据时可能会出现找不到数据的情况(虽然说这种事情
出现的概率很低),解决方案如下:'
# 避免使用大事务,如在主库中一次性操作5万条以上的数据(如果真有需要可以拆开执行)
# 开启多线程复制模式操作方法大家可以参考另外一篇分享
# 如主从服务器都在同一个机房内则最好使用内网IP进行复制
# 数据库服务器使用固态SSD硬盘以此提高读写效率
# 主从服务器修改如下参数提高写入参数
innodb_buffer_pool_size = 128M (值为当前服务器内存的80%)
innodb_log_file_size = 128M (加到128M即可)
innodb_log_buffer_size = 8M (加到64M即可)
innodb_flush_log_at_trx_commit = 0
# 如数据对一致性要求严苛建议采用全同步复制
至此,最简单的mysql主从复制就已经配置好了, 但是有一个问题,我是不是读操作要请求这台服务器,写操作要请求另外一台服务器呢? 就不能只请求一台服务器完成所有的操作吗?当然可以,篇幅有限,大家可以参考另外一篇博文