当前位置:   article > 正文

mysql8.0高可用集群架构实战_mysql 8 社区版 高可用

mysql 8 社区版 高可用

MySQL :: MySQL Shell 8.0 :: 7 MySQL InnoDB Cluster

基本概述

InnoDB Cluster是MySQL官方实现高可用+读写分离的架构方案,其中包含以下组件

  • MySQL Group Replication,简称MGR,是MySQL的主从同步高可用方案,包括数据同步及角色选举
  • Mysql Shell 是InnoDB Cluster的管理工具,用来创建和管理集群
  • Mysql Router 是业务流量入口,支持对MGR的主从角色判断,可以配置不同的端口分别对外提供读写服务,实现读写分离

MySQL Router与组复制和MySQL Shell高度整合,只有将其与组复制和MySQL Shell共同使用,才能够称为InnoDB Cluster。

集群架构

nnoDB Cluster将三个MySQL数据库实例构成一个高可用集群。其中一个实例是具有读/写能力的主要成员,其他两个实例是具有只读能力的次要成员。组复制将数据从主要成员复制到次要成员。MySQL Router将客户端应用程序连接到集群的主要成员。

搭建一主两从InnoDB集群
1. 安装3个数据库实例

参考:Docker 安装 MySQL8.0 

可以利用docker快速部署3个MySQL实例

  1. # 创建组复制的网络 保证三个mysql容器之间可以通过容器名访问
  2. docker network create --driver bridge --subnet 172.19.0.0/24 --gateway 172.19.0.1 mgr-network
  3. mkdir -p /mysql/mgr/node1/data /mysql/mgr/node1/conf /mysql/mgr/node1/log
  4. mkdir -p /mysql/mgr/node2/data /mysql/mgr/node2/conf /mysql/mgr/node2/log
  5. mkdir -p /mysql/mgr/node3/data /mysql/mgr/node3/conf /mysql/mgr/node3/log
  6. #以mgr-node1配置为例,创建/mysql/mgr/node1/conf/custom.cnf,添加以下配置:
  7. vim /mysql/mgr/node1/conf/custom.cnf
  8. [mysql]
  9. # 设置mysql客户端默认编码
  10. default-character-set=utf8
  11. [mysqld]
  12. #指定sever_id,三个Mysql实例需要分别改为对应的sever_id
  13. server_id=1
  14. # 必须开启GTID支持
  15. gtid_mode=ON
  16. enforce_gtid_consistency=ON
  17. # 启用二进制日志
  18. log-bin=mysql-bin
  19. #启用并行复制
  20. binlog_transaction_dependency_tracking=WRITESET
  21. replica_preserve_commit_order=ON
  22. replica_parallel_type=LOGICAL_CLOCK
  23. transaction_write_set_extraction=XXHASH64
  24. #对于Group Replication,数据必须存储在InnoDB事务存储引擎中
  25. disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
  26. # mgr-node2和mgr-node3同上,注意配置文件路径和修改server_id
  27. vim /mysql/mgr/node2/conf/custom.cnf
  28. [mysql]
  29. # 设置mysql客户端默认编码
  30. default-character-set=utf8
  31. [mysqld]
  32. #指定sever_id,三个Mysql实例需要分别改为对应的sever_id
  33. server_id=2
  34. # 必须开启GTID支持
  35. gtid_mode=ON
  36. enforce_gtid_consistency=ON
  37. # 启用二进制日志
  38. log-bin=mysql-bin
  39. #启用并行复制
  40. binlog_transaction_dependency_tracking=WRITESET
  41. replica_preserve_commit_order=ON
  42. replica_parallel_type=LOGICAL_CLOCK
  43. transaction_write_set_extraction=XXHASH64
  44. #对于Group Replication,数据必须存储在InnoDB事务存储引擎中
  45. disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
  46. vim /mysql/mgr/node3/conf/custom.cnf
  47. [mysql]
  48. # 设置mysql客户端默认编码
  49. default-character-set=utf8
  50. [mysqld]
  51. #指定sever_id,三个Mysql实例需要分别改为对应的sever_id
  52. server_id=3
  53. # 必须开启GTID支持
  54. gtid_mode=ON
  55. enforce_gtid_consistency=ON
  56. # 启用二进制日志
  57. log-bin=mysql-bin
  58. #启用并行复制
  59. binlog_transaction_dependency_tracking=WRITESET
  60. replica_preserve_commit_order=ON
  61. replica_parallel_type=LOGICAL_CLOCK
  62. transaction_write_set_extraction=XXHASH64
  63. #对于Group Replication,数据必须存储在InnoDB事务存储引擎中
  64. disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
  65. #运行mysql容器
  66. # 为了便于测试,启动容器时指定好IP、hostname
  67. docker run -d \
  68. --name mgr-node1 \
  69. --privileged=true \
  70. --restart=always \
  71. --ip 172.19.0.10 \
  72. --hostname mgr-node1 \
  73. --add-host mgr-node2:172.19.0.11 \
  74. --add-host mgr-node3:172.19.0.12 \
  75. --network mgr-network \
  76. -p 3321:3306 \
  77. -v /mysql/mgr/node1/data:/var/lib/mysql \
  78. -v /mysql/mgr/node1/conf:/etc/mysql/conf.d \
  79. -v /mysql/mgr/node1/log:/logs \
  80. -e MYSQL_ROOT_PASSWORD=123456 \
  81. -e TZ=Asia/Shanghai mysql:8.0.27 \
  82. --lower_case_table_names=1
  83. docker run -d \
  84. --name mgr-node2 \
  85. --privileged=true \
  86. --restart=always \
  87. --ip 172.19.0.11 \
  88. --hostname mgr-node2 \
  89. --add-host mgr-node1:172.19.0.10 \
  90. --add-host mgr-node3:172.19.0.12 \
  91. --network mgr-network \
  92. -p 3322:3306 \
  93. -v /mysql/mgr/node2/data:/var/lib/mysql \
  94. -v /mysql/mgr/node2/conf:/etc/mysql/conf.d \
  95. -v /mysql/mgr/node2/log:/logs \
  96. -e MYSQL_ROOT_PASSWORD=123456 \
  97. -e TZ=Asia/Shanghai mysql:8.0.27 \
  98. --lower_case_table_names=1
  99. docker run -d \
  100. --name mgr-node3 \
  101. --privileged=true \
  102. --restart=always \
  103. --ip 172.19.0.12 \
  104. --hostname mgr-node3 \
  105. --add-host mgr-node1:172.19.0.10 \
  106. --add-host mgr-node2:172.19.0.11 \
  107. --network mgr-network \
  108. -p 3323:3306 \
  109. -v /mysql/mgr/node3/data:/var/lib/mysql \
  110. -v /mysql/mgr/node3/conf:/etc/mysql/conf.d \
  111. -v /mysql/mgr/node3/log:/logs \
  112. -e MYSQL_ROOT_PASSWORD=123456 \
  113. -e TZ=Asia/Shanghai mysql:8.0.27 \
  114. --lower_case_table_names=1
  115. # 在宿主机上配置mysql容器的ip和host映射
  116. vim /etc/hosts
  117. 172.19.0.10 mgr-node1
  118. 172.19.0.11 mgr-node2
  119. 172.19.0.12 mgr-node3

 所有实例分别配置远程访问

  1. # 以node1为例
  2. docker exec -it mgr-node1 /bin/bash
  3. mysql -u root -p123456
  4. #进入mysql执行
  5. ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
  6. flush privileges;

2. 安装mysqlrouter和安装mysqlshell

MySQL Router是MySQL Proxy的后继产品,它提供了MySQL协议的路由器功能,可以用来实现读写分离、负载均衡和高可用性解决方案。

安装mysql-router

下载地址:https://downloads.mysql.com/archives/router/

  1. # 以centos7为例
  2. wget https://downloads.mysql.com/archives/get/p/41/file/mysql-router-community-8.0.27-1.el7.x86_64.rpm
  3. rpm -ivh mysql-router-community-8.0.27-1.el7.x86_64.rpm

安装mysql-shell

下载地址:MySQL :: Download MySQL Shell (Archived Versions)

  1. # 以centos7为例
  2. wget https://downloads.mysql.com/archives/get/p/43/file/mysql-shell-8.0.27-1.el7.x86_64.rpm
  3. rpm -ivh mysql-shell-8.0.27-1.el7.x86_64.rpm
  4. # 远程连接mysql
  5. mysqlsh root@192.168.65.223:3321 --js
  6. mysqlsh root@mgr-node1:3306 --js

 MySQL Shell 教程: 有道云笔记

3. InnoDB Cluster 初始化
3.1 参数及权限配置预需求检测

在添加实例到集群中前,使用该方法检查实例配置是否满足InnoDB 集群要求。

  1. mysqlsh root@192.168.65.223:3321 --js
  2. // 检查实例是否符合InnoDB Cluster的参数及权限配置要求
  3. dba.checkInstanceConfiguration('root@mgr-node1:3306')
  4. dba.checkInstanceConfiguration('root@mgr-node2:3306')
  5. dba.checkInstanceConfiguration('root@mgr-node3:3306')

如果验证通过返回ok。 

如果验证没通过,比如出现下面的日志提示,需要mysql实例开启gtid和指定server_id

搭建InnoDB Cluster需要满足的要求如下:

InnoDB集群使用了Group Replication,因此必须满足使用组复制的要求。具体可以参考https://dev.mysql.com/doc/refman/8.0/en/group-replication-requirements.html。其中比较重要的几点有:

  • 必须开启二进制日志,并且日志格式为ROW,即--log-bin和binlog_format=row(默认);
  • 必须开启副本更新日志,即log_replica_updates=ON(默认) ;
  • 必须开启GTID,即gtid_mode=ON和enforce_gtid_consistency=ON。
  • 存储引擎只能使用InnoDB。最好禁用其他存储引擎:
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
  • 从8.0.23开始,集群中的实例要启用并行复制。需要配置以下系统变量:
  1. binlog_transaction_dependency_tracking=WRITESET
  2. slave_preserve_commit_order=ON
  3. slave_parallel_type=LOGICAL_CLOCK
  4. transaction_write_set_extraction=XXHASH64
 3.2 初始化InnoDB Cluster相关配置
  1. // 对实例配置InnoDB Cluster相关参数
  2. dba.configureInstance('root@mgr-node1:3306')
  3. dba.configureInstance('root@mgr-node2:3306')
  4. dba.configureInstance('root@mgr-node3:3306')

4.创建一主两从InnoDB集群 

集群常用命令

  1. #会列出dba相关指令
  2. dba.help();
  3. #列出详细指令的用法
  4. dba.help('deploySandboxInstance');
  5. #检查节点配置实例,用于加入cluster之前
  6. dba.checkInstanceConfiguration("root@hostname:3306");
  7. #节点初始化
  8. dba.configureInstance('root@hostname:3306');
  9. #重启集群
  10. dba.rebootClusterFromCompleteOutage('myCluster');
  11. #会列出集群相关指令
  12. cluster.help();
  13. #创建集群
  14. var cluster = dba.createCluster('myCluster');
  15. #获取当前集群实例
  16. var cluster = dba.getCluster('myCluster');
  17. 查看集群状态
  18. cluster.status();
  19. #检查cluster节点状态
  20. cluster.checkInstanceState("root@hostname:3306") ;
  21. #增加节点
  22. cluster.addInstance("root@hostname:3306") ;
  23. #删除节点
  24. cluster.removeInstance("root@hostname:3306") ;
  25. #强制删除节点
  26. cluster.removeInstance('root@hostname:3306',{force:true});
  27. # 状态为missing的节点可以重新加入集群
  28. cluster.rejoinInstance("root@hostname:3306")
  29. #解散集群
  30. cluster.dissolve({force:true}) ;
  31. #集群描述
  32. cluster.describe();

进入主节点创建集群

初始化完第一个实例后,就可以创建集群了。

  1. # 进入主节点创建集群
  2. mysqlsh root@192.168.65.223:3321 --js
  3. # 创建一个 cluster,命名为 'myCluster'
  4. var cluster = dba.createCluster('myCluster');
  5. # 创建成功后,查看cluster状态
  6. cluster.status();

当前集群的状态如下

 

添加副本实例

添加副本实例到创建好的集群。

  1. #初始化第二个和第三个实例:
  2. cluster.addInstance('root@mgr-node2:3306');
  3. cluster.addInstance('root@mgr-node3:3306');
  4. #查看cluster状态
  5. cluster.status();

如果提示副本实例的GTID与集群不一致,选择通过Clone方式覆盖副本实例上的数据即可。

 

小结:完整的集群创建步骤
  1. #进入主节点
  2. mysqlsh root@mgr-node1:3306 --js
  3. #mgr-node1
  4. # 参数权限检查
  5. dba.checkInstanceConfiguration('root@mgr-node1:3306');
  6. # 初始化
  7. dba.configureInstance('root@mgr-node1:3306');
  8. # 创建集群
  9. var cluster = dba.createCluster('myCluster');
  10. #查看cluster状态
  11. cluster.status();
  12. #mgr-node2
  13. # 参数权限检查
  14. dba.checkInstanceConfiguration('root@mgr-node2:3306');
  15. # 初始化
  16. dba.configureInstance('root@mgr-node2:3306');
  17. # 添加副本
  18. cluster.addInstance('root@mgr-node2:3306');
  19. #mgr-node3
  20. # 参数权限检查
  21. dba.checkInstanceConfiguration('root@mgr-node3:3306');
  22. # 初始化
  23. dba.configureInstance('root@mgr-node3:3306');
  24. # 添加副本
  25. cluster.addInstance('root@mgr-node3:3306');
  26. #查看cluster状态
  27. cluster.status();

 搭建一主两从集群架构最终效果如下:

注意到集群状态已变为"status": "OK"和"statusText": "Cluster is ONLINE and can tolerate up to ONE failure."。

集群节点状态:

  • ONLINE - 节点状态正常。
  • OFFLINE - 实例在运行,但没有加入任何Cluster。
  • RECOVERING - 实例已加入Cluster,正在同步数据。
  • ERROR - 同步数据发生异常。
  • UNREACHABLE - 与其他节点通讯中断,可能是网络问题,可能是节点crash。
  • MISSING - 节点已加入集群,但未启动group replication

测试数据是否同步

  1. #主节点 mgr-node1
  2. [root@192-168-65-223 ~]# docker exec -it mgr-node1 bash
  3. root@mgr-node1:/# mysql -uroot -p123456
  4. mysql>
  5. create database test;
  6. use test;
  7. create table t(x int primary key auto_increment,y int);
  8. insert into t(x,y) value(1,1);

注意:如果创建表没有设置主键,会抛出错误:ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin. 

  1. # 查看其他节点,数据是否同步
  2. [root@192-168-65-223 ~]# docker exec -it mgr-node2 bash
  3. root@mgr-node2:/# mysql -uroot -p123456
  4. mysql> use test;
  5. Reading table information for completion of table and column names
  6. You can turn off this feature to get a quicker startup with -A
  7. Database changed
  8. mysql> select * from t;
  9. +---+------+
  10. | x | y |
  11. +---+------+
  12. | 1 | 1 |
  13. +---+------+
  14. 1 row in set (0.00 sec)
测试主从切换 
  1. #停掉主节点
  2. [root@192-168-65-223 ~]# docker stop mgr-node1
  3. # 连接到mgr-node2
  4. MySQL mgr-node1:3306 ssl JS > \connect root@mgr-node2:3306
  5. # 获取集群实例
  6. MySQL mgr-node2:3306 ssl JS > var cluster=dba.getCluster();
  7. # 查看集群状态
  8. MySQL mgr-node2:3306 ssl JS > cluster.status()
  9. {
  10. "clusterName": "myCluster",
  11. "defaultReplicaSet": {
  12. "name": "default",
  13. "primary": "mgr-node2:3306",
  14. "ssl": "REQUIRED",
  15. "status": "OK_NO_TOLERANCE",
  16. "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active.",
  17. "topology": {
  18. "mgr-node1:3306": {
  19. "address": "mgr-node1:3306",
  20. "memberRole": "SECONDARY",
  21. "mode": "n/a",
  22. "readReplicas": {},
  23. "role": "HA",
  24. "shellConnectError": "MySQL Error 2003: Could not open connection to 'mgr-node1:3306': Can't connect to MySQL server on 'mgr-node1:3306' (113)",
  25. "status": "(MISSING)"
  26. },
  27. "mgr-node2:3306": {
  28. "address": "mgr-node2:3306",
  29. "memberRole": "PRIMARY",
  30. "mode": "R/W",
  31. "readReplicas": {},
  32. "replicationLag": null,
  33. "role": "HA",
  34. "status": "ONLINE",
  35. "version": "8.0.27"
  36. },
  37. "mgr-node3:3306": {
  38. "address": "mgr-node3:3306",
  39. "memberRole": "SECONDARY",
  40. "mode": "R/O",
  41. "readReplicas": {},
  42. "replicationLag": null,
  43. "role": "HA",
  44. "status": "ONLINE",
  45. "version": "8.0.27"
  46. }
  47. },
  48. "topologyMode": "Single-Primary"
  49. },
  50. "groupInformationSourceMember": "mgr-node2:3306"
  51. }

 

可以看到mgr-node2升级为主节点

  1. # 启动mgr-node1节点
  2. [root@192-168-65-223 ~]# docker start mgr-node1
  3. # 查看集群状态,发现mgr-node1正在恢复,最终正常
  4. MySQL mgr-node2:3306 ssl JS > cluster.status()
  5. {
  6. "clusterName": "myCluster",
  7. "defaultReplicaSet": {
  8. "name": "default",
  9. "primary": "mgr-node2:3306",
  10. "ssl": "REQUIRED",
  11. "status": "OK_NO_TOLERANCE",
  12. "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active.",
  13. "topology": {
  14. "mgr-node1:3306": {
  15. "address": "mgr-node1:3306",
  16. "instanceErrors": [
  17. "NOTE: group_replication is stopped."
  18. ],
  19. "memberRole": "SECONDARY",
  20. "memberState": "OFFLINE",
  21. "mode": "R/O",
  22. "readReplicas": {},
  23. "role": "HA",
  24. "status": "(MISSING)",
  25. "version": "8.0.27"
  26. },
  27. "mgr-node2:3306": {
  28. "address": "mgr-node2:3306",
  29. "memberRole": "PRIMARY",
  30. "mode": "R/W",
  31. "readReplicas": {},
  32. "replicationLag": null,
  33. "role": "HA",
  34. "status": "ONLINE",
  35. "version": "8.0.27"
  36. },
  37. "mgr-node3:3306": {
  38. "address": "mgr-node3:3306",
  39. "memberRole": "SECONDARY",
  40. "mode": "R/O",
  41. "readReplicas": {},
  42. "replicationLag": null,
  43. "role": "HA",
  44. "status": "ONLINE",
  45. "version": "8.0.27"
  46. }
  47. },
  48. "topologyMode": "Single-Primary"
  49. },
  50. "groupInformationSourceMember": "mgr-node2:3306"
  51. }
  52. MySQL mgr-node2:3306 ssl JS > cluster.status()
  53. {
  54. "clusterName": "myCluster",
  55. "defaultReplicaSet": {
  56. "name": "default",
  57. "primary": "mgr-node2:3306",
  58. "ssl": "REQUIRED",
  59. "status": "OK",
  60. "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
  61. "topology": {
  62. "mgr-node1:3306": {
  63. "address": "mgr-node1:3306",
  64. "memberRole": "SECONDARY",
  65. "mode": "R/O",
  66. "readReplicas": {},
  67. "replicationLag": null,
  68. "role": "HA",
  69. "status": "ONLINE",
  70. "version": "8.0.27"
  71. },
  72. "mgr-node2:3306": {
  73. "address": "mgr-node2:3306",
  74. "memberRole": "PRIMARY",
  75. "mode": "R/W",
  76. "readReplicas": {},
  77. "replicationLag": null,
  78. "role": "HA",
  79. "status": "ONLINE",
  80. "version": "8.0.27"
  81. },
  82. "mgr-node3:3306": {
  83. "address": "mgr-node3:3306",
  84. "memberRole": "SECONDARY",
  85. "mode": "R/O",
  86. "readReplicas": {},
  87. "replicationLag": null,
  88. "role": "HA",
  89. "status": "ONLINE",
  90. "version": "8.0.27"
  91. }
  92. },
  93. "topologyMode": "Single-Primary"
  94. },
  95. "groupInformationSourceMember": "mgr-node2:3306"
  96. }

更多的常见操作

参数配置

可以用cluster.options()查看当前集群的配置属性,集群参数配置分为两种方式:

  • cluster.setOption() 用来设置所有节点的参数
  • cluster.setInstanceOption() 用来对指定节点配置属性
  1. # 将所有节点的权重都改为50
  2. var cluster = dba.getCluster()
  3. cluster.setOption("memberWeight",50)
  4. # 重新加入集群重试次数改为5
  5. cluster.setOption("autoRejoinTries",5)
  6. # 将其中一个节点的权重改为75
  7. cluster.setInstanceOption("mgr-node2:3306","memberWeight",75)
  8. # 重新加入集群重试次数改为10
  9. cluster.setInstanceOption("mgr-node2:3306","autoRejoinTries",10)

配置节点权重

memberWeight选项的值域为0到100之间的整数,缺省值为50。该值是故障转移时自动选举主节点的百分比权重,具有较高memberWeight值的实例更有可能在单主群集中被选为主节点

  1. // 查看集群的参数配置(包括memberWeight优先级配置)
  2. cluster.options()
  3. // 在集群创建时配置
  4. dba.createCluster('myCluster', {memberWeight:75}) // 第一个节点配置方式
  5. var cluster = dba.getCluster()
  6. cluster.addInstance('mgr-node2:3306',{memberWeight:50})
  7. cluster.addInstance('mgr-node3:3306',{memberWeight:25})
  8. // 在集群创建完成后修改权重
  9. var cluster = dba.getCluster()
  10. cluster.setInstanceOption('mgr-node1:3306','memberWeight',100)
  11. cluster.setInstanceOption('mgr-node2:3306','memberWeight',50)
  12. cluster.setInstanceOption('mgr-node3:3306','memberWeight',25)

将节点重新加入集群

状态为mssing的节点,通常是组复制关闭或中断状态,可以用cluster.rejoinInstance()重新加入集群,会重新对该节点设置MGR相关参数(持久化到mysqld-auto.conf中)

 

cluster.removeInstance('root@hostname:3306',{force:true});    

如果一些参数做了修改,如server_uuid变更,导致rejoin失败,则需要将节点从集群中删除后重新加入

  1. cluster.removeInstance("root@hostname:3306",{force:true})
  2. cluster.rescan()
  3. cluster.addInstance("root@hostname:3306")

 

集群多数节点异常,恢复

当集群多个节点异常,则失去了仲裁机制,剩下的一个节点

  1. // 将集群剥离为单节点运行
  2. JS > cluster.forceQuorumUsingPartitionOf("root@hostname:3306")
  3. // 重新加另外2个节点加入
  4. JS > cluster.rejoinInstance("root@hostname2:3306")
  5. JS > cluster.rejoinInstance("root@hostname3:3306")

集群节点角色切换

在MGR的管理下提供了一下3种方式进行角色切换,mysqlsh对其进行了封装调用

  • group_replication_set_as_primary(member_uuid);
    • cluster.setPrimaryInstance("homename:3306")
  • group_replication_switch_to_single_primary_mode()
    • cluster.switchToSinglePrimaryMode("homename:3306")
  • group_replication_switch_to_multi_primary_mode()
    • cluster.switchToMultiPrimaryMode()

 单主模式-指定主节点切换

  1. var cluster = dba.getCluster()
  2. cluster.setPrimaryInstance('homename:3306')
  3. cluster.status()

单主模式和多主模式相互切换

  1. // 切换为多主模式
  2. var cluster = dba.getCluster()
  3. cluster.switchToMultiPrimaryMode()
  4. // 指定明确的主节点将多主模式切换为单主模式
  5. cluster.switchToSinglePrimaryMode("homename:3306")

将单主模式切换为多主模式的效果

销毁集群

删除与群集关联的所有元数据和配置,并禁用实例上的组复制,但不会删除在实例之间复制的任何数据。要再次创建集群,使用dba.createCluster()

  1. var cluster = dba.getCluster()
  2. cluster.dissolve()

 创建集群管理用户

cluster.setupAdminAccount('fox')

# 经典MySQL协议连接 mysqlsh --mysql -hmgr-node1 -ufox # X协议连接 mysqlsh --mysqlx -hmgr-node1 -ufox 

7.使用MySQL Router连接集群 

配置路由器

  1. mysqlrouter --bootstrap root@mgr-node2:3306 --force --user=root
  2. #或者指定host
  3. mysqlrouter --bootstrap root@mgr-node2:3306 --force --user=root --report-host mgr

注意,如果用户之前为该实例配置过路由,则可以通过指定force选项强制引导启动。

上面的内容是引导启动路由器时输出的信息,信息提示,MySQL经典协议使用6446端口和6447端口,X协议使用6448端口和6449端口,每种协议使用的两个端口分别用于读写和只读。

在一个运行的集群中,AdminAPI 可以引导多个路由器。用户可以使用cluster.listRouters()方法显示所有注册的路由器列表。

启动路由器:mysqlrouter &

路由器已经成功启动。现在,使用MySQL Shell连接路由器进行验证 

  1. #连接mysqlrouter
  2. [root@192-168-65-223 ~]# mysqlsh root@localhost:6446 --sql
  3. MySQL localhost:6446 ssl SQL > use test;
  4. MySQL localhost:6446 ssl test SQL > select * from t;

 查看集群成员信息

MySQL  localhost:6446 ssl  test  SQL > select * from performance_schem

测试

测试读写端口6446

用户可以通过连接本机的6446端口连接到MySQL实例

6446为读写端口,也可以插入数据 

 

测试只读端口6647:插入数据报错 

MySQL InnoDB ReplicaSet

基本概述

MySQL Innodb Cluster = MySQL Shell + MySQL Router + MySQL Group Replication(MGR),全程由 MySQL Shell 来管理操作 MGR 的聚合套件。MySQL 8.0.19 发布后,这种组合延伸到 MySQL Replication(主从复制),也就是 MySQL Shell + MySQL Router + MySQL Replication。

InnoDB ReplicaSet至少由两个MySQL服务器实例组成,并提供用户熟知的主从复制功能,例如读取横向扩展和数据安全性。InnoDB ReplicaSet使用以下MySQL技术。

  • MySQL Shell:MySQL的高级客户端、管理工具,可以用来管理复制集。
  • MySQL复制:一组MySQL实例,通过复制能够提供可用性和异步读取的横向扩展。
  • MySQL Router:一种轻量级的中间件,可在应用程序和InnoDB ReplicaSet之间提供透明的路由。InnoDB ReplicaSet的接口类似于InnoDB Cluster,用户可以利用MySQL Shell使用MySQL实例和MySQL Router。

与InnoDB集群相比,InnoDB ReplicaSet具有多个限制,因此,官方建议尽可能部署InnoDB群集。通常,InnoDB ReplicaSet本身不能提供高可用性。InnoDB ReplicaSet的限制包括:

  • 没有自动故障转移。如果主服务器不可用,则需要使用AdminAPI手动触发故障转移,然后才能再次进行任何更改。但是,辅助实例仍然可用于读取。
  • 无法防止因意外停止或不可用而导致部分数据丢失。暂停之前尚未应用的事务可能会丢失。
  • 无法防止崩溃或不可用后出现不一致情况。如果故障转移在辅助节点仍可用的情况下提升了辅助节点(例如,由于网络分区),则可能会因脑裂而引起不一致。
搭建一主一从的复制集

1. 安装2个数据库实例

参考:Docker 安装 MySQL8.0 

可以利用docker快速部署2个MySQL实例

  1. # 创建组复制的网络 保证三个mysql容器之间可以通过容器名访问
  2. docker network create --driver bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 rs-network
  3. mkdir -p /mysql/rs/node1/data /mysql/rs/node1/conf /mysql/rs/node1/log
  4. mkdir -p /mysql/rs/node2/data /mysql/rs/node2/conf /mysql/rs/node2/log
  5. #以rs-node1配置为例,创建/mysql/rs/node1/conf/custom.cnf,添加以下配置:
  6. vim /mysql/rs/node1/conf/custom.cnf
  7. [mysql]
  8. # 设置mysql客户端默认编码
  9. default-character-set=utf8
  10. [mysqld]
  11. #指定sever_id,多个Mysql实例需要分别改为对应的sever_id
  12. server_id=21
  13. # 必须开启GTID支持
  14. gtid_mode=ON
  15. enforce_gtid_consistency=ON
  16. # 启用二进制日志
  17. log-bin=mysql-bin
  18. #启用并行复制
  19. binlog_transaction_dependency_tracking=WRITESET
  20. replica_preserve_commit_order=ON
  21. replica_parallel_type=LOGICAL_CLOCK
  22. transaction_write_set_extraction=XXHASH64
  23. # rs-node2同上,注意配置文件路径和修改server_id
  24. vim /mysql/rs/node2/conf/custom.cnf
  25. [mysql]
  26. # 设置mysql客户端默认编码
  27. default-character-set=utf8
  28. [mysqld]
  29. #指定sever_id,多个Mysql实例需要分别改为对应的sever_id
  30. server_id=22
  31. # 必须开启GTID支持
  32. gtid_mode=ON
  33. enforce_gtid_consistency=ON
  34. # 启用二进制日志
  35. log-bin=mysql-bin
  36. #启用并行复制
  37. binlog_transaction_dependency_tracking=WRITESET
  38. replica_preserve_commit_order=ON
  39. replica_parallel_type=LOGICAL_CLOCK
  40. transaction_write_set_extraction=XXHASH64
  41. #运行mysql容器
  42. # 为了便于测试,启动容器时指定好IP、hostname
  43. docker run -d \
  44. --name rs-node1 \
  45. --privileged=true \
  46. --restart=always \
  47. --ip 172.20.0.20 \
  48. --hostname rs-node1 \
  49. --add-host rs-node2:172.20.0.21 \
  50. --network rs-network \
  51. -p 3331:3306 \
  52. -v /mysql/rs/node1/data:/var/lib/mysql \
  53. -v /mysql/rs/node1/conf:/etc/mysql/conf.d \
  54. -v /mysql/rs/node1/log:/logs \
  55. -e MYSQL_ROOT_PASSWORD=123456 \
  56. -e TZ=Asia/Shanghai mysql:8.0.27 \
  57. --lower_case_table_names=1
  58. docker run -d \
  59. --name rs-node2 \
  60. --privileged=true \
  61. --restart=always \
  62. --ip 172.20.0.21 \
  63. --hostname rs-node2 \
  64. --add-host rs-node1:172.20.0.20 \
  65. --network rs-network \
  66. -p 3332:3306 \
  67. -v /mysql/rs/node2/data:/var/lib/mysql \
  68. -v /mysql/rs/node2/conf:/etc/mysql/conf.d \
  69. -v /mysql/rs/node2/log:/logs \
  70. -e MYSQL_ROOT_PASSWORD=123456 \
  71. -e TZ=Asia/Shanghai mysql:8.0.27 \
  72. --lower_case_table_names=1
  73. # 在宿主机上配置mysql容器的ip和host映射
  74. vim /etc/hosts
  75. 172.20.0.20 rs-node1
  76. 172.20.0.21 rs-node2

所有实例分别配置远程访问

  1. # 以node1为例
  2. docker exec -it rs-node1 /bin/bash
  3. mysql -u root -p123456
  4. #进入mysql执行
  5. ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
  6. flush privileges;

 

 

 

 

2. 配置复制集

1)初始化主节点,创建复制集

  1. #进入主节点
  2. mysqlsh root@rs-node1:3306 --js
  3. # 初始化
  4. dba.configureReplicaSetInstance('root@rs-node1:3306')
  5. # 创建复制集,使用异步复制
  6. var rs = dba.createReplicaSet("myrs")
  7. #查看状态
  8. rs.status()

 

2)添加副本节点 

  1. #将实例添加到复制集
  2. rs.addInstance('root@rs-node2:3306')

 

 

测试数据是否同步

  1. #主节点 rs-node1
  2. [root@192-168-65-223 ~]# docker exec -it rs-node1 bash
  3. root@mgr-node1:/# mysql -uroot -p123456
  4. mysql>
  5. create datebase test;
  6. use test;
  7. create table t(x int primary key auto_increment,y int);
  8. insert into t(x,y) value(1,1);
  9. select * from t;
  10. # 进入从节点rs-node2,查看数据是否同步过来
  11. [root@192-168-65-223 ~]# docker exec -it rs-node2 bash
  12. root@rs-node2:/# mysql -uroot -p123456
  13. mysql: [Warning] Using a password on the command line interface can be insecure.
  14. Welcome to the MySQL monitor. Commands end with ; or \g.
  15. Your MySQL connection id is 1596
  16. Server version: 8.0.27 MySQL Community Server - GPL
  17. Copyright (c) 2000, 2021, Oracle and/or its affiliates.
  18. Oracle is a registered trademark of Oracle Corporation and/or its
  19. affiliates. Other names may be trademarks of their respective
  20. owners.
  21. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
  22. mysql> use test;
  23. Reading table information for completion of table and column names
  24. You can turn off this feature to get a quicker startup with -A
  25. Database changed
  26. mysql> select * from t;
  27. +---+------+
  28. | x | y |
  29. +---+------+
  30. | 1 | 1 |
  31. +---+------+
  32. 1 row in set (0.00 sec)

3. 配置 MySQL Router 路由器

[root@192-168-65-223 ~]# mysqlrouter --bootstrap root@rs-node1:3306 --force --user=root

 

 

重启Mysql Router

  1. [root@192-168-65-223 ~]# ps -ef|grep mysqlrouter
  2. root 16993 14238 6 11:30 pts/1 00:18:01 mysqlrouter
  3. root 21637 14178 0 16:22 pts/0 00:00:00 grep --color=auto mysqlrouter
  4. [root@192-168-65-223 ~]# kill -9 16993
  5. # 启动Mysql Router
  6. [root@192-168-65-223 ~]# mysqlrouter &

4. 测试

用户可以通过连接本机的6446端口连接到MySQL实例

  1. [root@192-168-65-223 ~]# mysqlsh root@localhost:6446 --sql
  2. # 可以查询到插入的测试数据
  3. MySQL localhost:6446 ssl SQL > select * from test.t;
  4. +---+---+
  5. | x | y |
  6. +---+---+
  7. | 1 | 1 |
  8. +---+---+

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/709307
推荐阅读
相关标签
  

闽ICP备14008679号