MySQL高可用之多源复制

一、MySQL高可用之多源复制

摘要:在 MySQL 8.0 版本中,提供了多源复制,多源复制的出现对于分库分表的业务提供了极大的便利,本文做了详细的说明

️ 1.多源复制简介

  1. 在 MySQL 8.0 版本中,提供了多源复制,多源复制的出现对于分库分表的业务提供了极大的便利,
  2. 目前我们已经部署了多套多源复制供统计使用。
  3. MySQL 5.7 之前只能实现一主一从、一主多从或者多主多从的复制。
  4. 如果想实现多主一从的复制,只能使用 MariaDB,但是 MariaDB 又与官方的MySQL 版本不兼容。
  5. MySQL 5.7 开始支持了多主一从的复制方式,也就是多源复制。
  6. MySQL 8.0 版本相比之前的版本,无论在功能还是性能、安全等方面都已经有不少的提升。
  7. 拓展:MySQL之父Widenius先生离开了Sun之后,觉得依靠Sun/Oracle来发展MySQL,
  8. 实在很不靠谱,于是决定另开分支,这个分支的名字叫做MariaDB。

多源复制的好处

  1. 可以集中备份,在从库上备份,不会影响线上的数据正常运行
  2. 节约购买从库服务器的成本,只需要一个从库服务器即可
  3. 数据汇总在一起,方便后期做数据统计
  4. 减轻DBA维护工作量。

️ 2.多源复制使用场景

Backing up multiple servers to a single server.
Merging table shards.
Consolidating data from multiple servers to a single server.

https://img-blog.csdnimg.cn/img_convert/1a34feb937a8e990ee57b56bdbd1e1f6.png

  1. 如上图,多源复制采用多通道的模式,和普通的复制相比,就是使用 FOR CHANNEL进行了分离。
  2. CHANGE MASTERTO....FORCHANNEL'm1';
  3. CHANGE MASTERTO....FORCHANNEL'm2';
  4. 要开启多源复制功能必须需要在从库上设置 master-info-repository 和 relay-log-info-repository 这两个参数。
  5. 这两个参数是用来存储同步信息的,可以设置的值为 FILE 和 TABLE,5.7默认值是 FILE。
  6. 比如 master-info 就保存在 master.info 文件中,
  7. relay-log-info 保存在 relay-log.info 文件中,
  8. 如果服务器意外关闭,正确的 relay-log-info 没有来得及更新到 relay-log.info 文件,这样会造成数据丢失。
  9. 为了数据更加安全,通常设为 TABLE。这些表都是 innodb 类型的,支持事务。
  10. 相对文件存储安全得多。在 MySQL 库下可以看见这两个表信息,分别是 mysql.slave_master_info 和 mysql.slave_relay_log_info。
  11. 这两个参数也是可以动态调整的。
  12. SET GLOBAL master_info_repository='TABLE';
  13. SET GLOBAL relay_log_info_repository='TABLE';

️ 3.多源复制部署

搭建过程支持GTID复制模式和binlog+position方式复制。

https://img-blog.csdnimg.cn/img_convert/6f29b45f8d484bb7916da264aec68694.png

3.1 下载镜像

docker pull mysql:8.0.27

--docker network create --subnet=172.72.0.0/24 mysql-network docker rm -f mysql8027M33265 mysql8027M33266 mysql8027M33267 mysql8027M33268

3.2 创建映射目录

mkdir -p /mysqlmultiple/master1/conf.d

mkdir -p /mysqlmultiple/master1/data mkdir -p /mysqlmultiple/master2/conf.d mkdir -p /mysqlmultiple/master2/data mkdir -p /mysqlmultiple/master3/conf.d mkdir -p /mysqlmultiple/master3/data mkdir -p /mysqlmultiple/slave/conf.d mkdir -p /mysqlmultiple/slave/data

3.3 创建容器,安装MySQL

  1. docker run -d --name mysql8027M33265 \
  2. -h master1 -p 33265:3306 --net=mysql-network --ip 172.72.0.10 \
  3. -v /mysqlmultiple/master1/conf.d:/etc/mysql/conf.d -v /mysqlmultiple/master1/data:/var/lib/mysql/ \
  4. -e MYSQL_ROOT_PASSWORD=jem \
  5. mysql:8.0.27
  6. docker run -d --name mysql8027M33266 \
  7. -h master2 -p 33266:3306 --net=mysql-network --ip 172.72.0.11 \
  8. -v /mysqlmultiple/master2/conf.d:/etc/mysql/conf.d -v /mysqlmultiple/master2/data:/var/lib/mysql/ \
  9. -e MYSQL_ROOT_PASSWORD=jem \
  10. mysql:8.0.27
  11. docker run -d --name mysql8027M33267 \
  12. -h master3 -p 33267:3306 --net=mysql-network --ip 172.72.0.12 \
  13. -v /mysqlmultiple/master3/conf.d:/etc/mysql/conf.d -v /mysqlmultiple/master3/data:/var/lib/mysql/ \
  14. -e MYSQL_ROOT_PASSWORD=jem \
  15. mysql:8.0.27
  16. docker run -d --name mysql8027S33268 \
  17. -h slave1 -p 33268:3306 --net=mysql-network --ip 172.72.0.13 \
  18. -v /mysqlmultiple/slave/conf.d:/etc/mysql/conf.d -v /mysqlmultiple/slave/data:/var/lib/mysql/ \
  19. -e MYSQL_ROOT_PASSWORD=jem \
  20. mysql:8.0.27

3.4 参数文件配置

  1. cat > /mysqlmultiple/master1/conf.d/my.cnf << "EOF"
  2. [mysqld]
  3. user=mysql
  4. port=3306
  5. character_set_server=utf8mb4
  6. secure_file_priv=
  7. server-id = 802733265
  8. log-bin =
  9. binlog_format=row
  10. expire_logs_days = 30
  11. max_binlog_size = 100M
  12. binlog-ignore-db = mysql
  13. binlog-ignore-db = information_schema
  14. binlog-ignore-db = performance_schema
  15. binlog-ignore-db = sys
  16. replicate_ignore_db=information_schema
  17. replicate_ignore_db=performance_schema
  18. replicate_ignore_db=mysql
  19. replicate_ignore_db=sys
  20. gtid-mode=ON
  21. enforce-gtid-consistency=on
  22. skip_name_resolve
  23. report_host=172.72.0.10
  24. EOF
  25. cat > /mysqlmultiple/master2/conf.d/my.cnf << "EOF"
  26. [mysqld]
  27. user=mysql
  28. port=3306
  29. character_set_server=utf8mb4
  30. secure_file_priv=
  31. server-id = 802733266
  32. log-bin =
  33. binlog_format=row
  34. expire_logs_days = 30
  35. max_binlog_size = 100M
  36. binlog-ignore-db = mysql
  37. binlog-ignore-db = information_schema
  38. binlog-ignore-db = performance_schema
  39. binlog-ignore-db = sys
  40. replicate_ignore_db=information_schema
  41. replicate_ignore_db=performance_schema
  42. replicate_ignore_db=mysql
  43. replicate_ignore_db=sys
  44. gtid-mode=ON
  45. enforce-gtid-consistency=ON
  46. skip_name_resolve
  47. report_host=172.72.0.11
  48. EOF
  49. cat > /mysqlmultiple/master3/conf.d/my.cnf << "EOF"
  50. [mysqld]
  51. user=mysql
  52. port=3306
  53. character_set_server=utf8mb4
  54. secure_file_priv=
  55. server-id = 802733267
  56. log-bin =
  57. binlog_format=row
  58. expire_logs_days = 30
  59. max_binlog_size = 100M
  60. binlog-ignore-db = mysql
  61. binlog-ignore-db = information_schema
  62. binlog-ignore-db = performance_schema
  63. binlog-ignore-db = sys
  64. replicate_ignore_db=information_schema
  65. replicate_ignore_db=performance_schema
  66. replicate_ignore_db=mysql
  67. replicate_ignore_db=sys
  68. gtid-mode=ON
  69. enforce-gtid-consistency=ON
  70. skip_name_resolve
  71. report_host=172.72.0.12
  72. EOF
  73. cat > /mysqlmultiple/slave/conf.d/my.cnf << "EOF"
  74. [mysqld]
  75. user=mysql
  76. port=3306
  77. character_set_server=utf8mb4
  78. secure_file_priv=''
  79. server-id = 802733268
  80. log-bin =
  81. binlog_format=row
  82. expire_logs_days = 30
  83. max_binlog_size = 100M
  84. binlog-ignore-db = mysql
  85. binlog-ignore-db = information_schema
  86. binlog-ignore-db = performance_schema
  87. binlog-ignore-db = sys
  88. replicate_ignore_db=information_schema
  89. replicate_ignore_db=performance_schema
  90. replicate_ignore_db=mysql
  91. replicate_ignore_db=sys
  92. gtid-mode=ON
  93. enforce-gtid-consistency=ON
  94. skip_name_resolve
  95. report_host=172.72.0.13
  96. master-info-repository = table
  97. relay-log-info-repository = table
  98. EOF
  99. docker restart mysql8027M33265
  100. docker restart mysql8027M33266
  101. docker restart mysql8027M33267
  102. docker restart mysql8027S33268
  103. docker ps

登陆容器,确认数据 docker ps --format "table {{.ID}}\t{{.Names}}\t{{.Status}}\t{{.Ports}}"

https://img-blog.csdnimg.cn/img_convert/a5ec004f08eba66fc67a68c3976a0382.png

3.5 登陆MySQL

  1. docker exec -it mysql8027M33265 mysql -uroot -pjem
  2. mysql -uroot -pjem -h192.168.1.54 -P33265 -e "select @@hostname,@@server_id,@@server_uuid"
  3. mysql -uroot -pjem -h192.168.1.54 -P33266 -e "select @@hostname,@@server_id,@@server_uuid"
  4. mysql -uroot -pjem -h192.168.1.54 -P33267 -e "select @@hostname,@@server_id,@@server_uuid"
  5. mysql -uroot -pjem -h192.168.1.54 -P33268 -e "select @@hostname,@@server_id,@@server_uuid"
  6. 远程登陆需要修改密码
  7. docker exec -it mysql8027M33266 mysql -uroot -pjem
  8. mysql> alter user root@'%' identified with mysql_native_password by 'root';   --更改密码
  9. mysql>  flush privileges;
  10. docker exec -it mysql8027S33268 mysql -uroot -pjem

️ 4.主从配置

4.1 主库配置

  1. --在 3 台主库
  2. mysql -uroot -proot -h192.168.1.54 -P33265
  3. mysql -uroot -proot -h192.168.1.54 -P33266
  4. mysql -uroot -proot -h192.168.1.54 -P33267
  5. mysql> create user repl@'%' identified with mysql_native_password by 'root';
  6. mysql> grant all on *.* to repl@'%' with grant option;
  7. mysql> flush privileges;
  8. select user,host,grant_priv,password_last_changed,authentication_string from mysql.user;
  9. show master status \G;
  10. show slave hosts;
  11. select @@hostname,@@server_id,@@server_uuid;

4.2 从库配置

  1. mysql -uroot -proot -h192.168.1.54 -P33268
  2. change master to
  3. master_host='172.72.0.10',
  4. master_port=3306,master_user='repl',
  5. master_password='root',
  6. master_auto_position=1 FOR CHANNEL 'Master1';
  7. show slave status \G;
  8. -- 启动所有 SLAVE
  9. mysql> START SLAVE;
  10. --主库创建数据测试
  11. mysql -uroot -proot -h192.168.1.54 -P33265
  12. mysql> create database test;
  13. --主库2和3
  14. change master to
  15. master_host='172.72.0.11',
  16. master_port=3306,
  17. master_user='repl',
  18. master_password='root',
  19. master_auto_position=1 FOR CHANNEL 'Master2';
  20. change master to
  21. master_host='172.72.0.12',
  22. master_port=3306,
  23. master_user='repl',
  24. master_password='root',
  25. master_auto_position=1 FOR CHANNEL 'Master3';
  26. -- 也可以单独启动需要同步的通道
  27. START SLAVE FOR CHANNEL 'master2';
  28. START SLAVE FOR CHANNEL 'master3';
  29. select a.master_log_pos,a.host,a.user_name,a.user_password,a.port,a.uuid,a.channel_name
  30. from mysql.slave_master_info a;

https://img-blog.csdnimg.cn/img_convert/4de8a867410e0029ec0055be9ab854ee.png

https://img-blog.csdnimg.cn/img_convert/4ed6057a46f7688c4d8dfdf5103b6fae.png

️ 5.测试多源复制

  1. -- mysql -uroot -proot -h192.168.1.54 -P33265
  2. create database master1;
  3. use master1;
  4. CREATE TABLE `test1` (`id` int(11) DEFAULT NULL,`count` int(11) DEFAULT NULL);
  5. insert into test1 values(1,1);
  6. -- mysql -uroot -proot -h192.168.1.54 -P33266
  7. create database master2;
  8. use master2;
  9. CREATE TABLE `test2` (`id` int(11) DEFAULT NULL,`count` int(11) DEFAULT NULL);
  10. insert into test2 values(2,2);
  11. -- mysql -uroot -proot -h192.168.1.54 -P33267
  12. create database master3;
  13. use master3;
  14. CREATE TABLE `test3` (`id` int(11) DEFAULT NULL,`count` int(11) DEFAULT NULL);
  15. insert into test3 values(3,3);
  16. --从库查询
  17. -- mysql -uroot -proot -h192.168.1.54 -P33268
  18. show databases;
  19. SELECT * FROM master1.test1;
  20. SELECT * FROM master2.test2;
  21. SELECT * FROM master3.test3;

️ 6. 注意的点

1、初次配置耗时较长,需要将各个 master 的数据 dump 下来,再 source 到 slave 上。
2、需要考虑各 master 数据增长频率,slave 的数据增长频率是这些数据的总和。如果太高,会导致大量的磁盘 IO,造成数据更新延迟,最严重的是会影响正常的查询。
3、如果多个主数据库实例中存在同名的库,则同名库的表都会放到一个库中;
4、如果同名库中的表名相同且结构相同,则数据会合并到一起;如果结构不同,则先建的有效。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值