MySQL InnoDB集群节点异常后加入失败问题处理
问题:
一. 节点异常后重新加入 报错如下:
MySQL 192.168.35.49:3306 ssl JS >MySQL 192.168.35.49:3306 ssl JS > cluster.rejoinInstance("root@192.168.35.50:3306")ERROR: RuntimeError: The instance 'mgrnode50x:3306' does not belong to the cluster: 'mycluster'.Cluster.rejoinInstance: The instance 'mgrnode50x:3306' does not belong to the cluster: 'mycluster'. (RuntimeError)
二. 移除异常节点 报错如下:
MySQL 192.168.35.49:3306 ssl JS >MySQL 192.168.35.49:3306 ssl JS > cluster.removeInstance("root@192.168.35.50:3306");ERROR: The instance 192.168.35.50:3306 does not belong to the cluster.ERROR: MYSQLSH 51104: Metadata for instance 192.168.35.50:3306 not foundCluster.removeInstance: Metadata for instance 192.168.35.50:3306 not found (MYSQLSH 51104)
三. 按照节点从新加入 报错如下
MySQL 192.168.35.49:3306 ssl JS >MySQL 192.168.35.49:3306 ssl JS > cluster.addInstance('root@192.168.35.50:3306')ERROR: RuntimeError: The instance 'mgrnode50x:3306' is already part of another Replication GroupCluster.addInstance: The instance 'mgrnode50x:3306' is already part of another Replication Group (RuntimeError)
问题分析:
从错误信息来看,MySQL实例 192.168.35.50:3306 出现了元数据缺失或不属于集群的情况,同时又提示该实例已经属于另一个复制组。这种情况可能是由于集群的元数据不一致,或在实例从集群中脱离后没有正确清除复制组信息。
可以按照以下步骤来解决这个问题:
1. 检查集群的当前状态
首先检查集群的当前状态,确认哪些节点在集群中。
cluster.status();
2. 从复制组中强制移除实例
在某些情况下,实例可能残留在复制组中而无法正常重新加入。这时,可以尝试手动从复制组中移除该实例。
在192.168.35.50:3306节点上,使用以下命令强制清除复制组信息:
STOP GROUP_REPLICATION;RESET SLAVE ALL;RESET MASTER;
这将清除复制组和任何从属复制设置,确保实例从先前的复制组中移除。
3. 再次尝试重新加入实例
在清除复制组信息后,再次尝试将实例重新加入集群:
cluster.addInstance('root@192.168.35.50:3306');
如果这一步仍然失败,尝试使用 force: true
参数强制加入:
cluster.addInstance('root@192.168.35.50:3306', {force: true});
4. 如果问题依然存在,检查集群元数据
有时,集群元数据可能会损坏,导致实例无法正确加入。在这种情况下,可以尝试重新初始化集群元数据或检查元数据表是否存在问题。
- 登录到集群的一个主要节点上。
- 检查集群的 mysql_innodb_cluster_metadata 表是否正常:USE mysql_innodb_cluster_metadata;SHOW TABLES;确保表结构和数据正常。如果发现有损坏或缺失,可以通过重新部署或修复元数据来解决。
5. 验证网络和防火墙配置
确保集群节点之间的网络通信正常,尤其是端口3306、33060(MySQL Shell)、以及复制相关的端口是否开放。确认节点之间可以通过相互的IP进行正常通信。
6. 重新初始当前节点从新加入集群
使用 MySQL Shell
来初始化节点、重新将节点加入 InnoDB 集群,并获取集群状态的步骤如下:
1. 进入 MySQL Shell
首先,启动 MySQL Shell 并连接到集群中的某个已存在的节点(通常是集群的 Primary 节点)。
mysqlsh root@<primary-node-ip>:3306 --mysql
如果你使用密码验证,系统会提示你输入 root
用户的密码。
2. 初始化新节点
在将新的 MySQL 实例加入集群之前,需要确保它已经初始化并能被集群接受。以下是初始化新节点的基本步骤:
- 连接到新节点连接到想要加入集群的节点:\connect root@192.168.35.50:3306
- 使用 MySQL Shell 进行实例配置使用 dba.configureInstance() 来检查并自动配置实例:dba.configureInstance('root@192.168.35.50:3306');你可能需要输入管理员密码。
3. 重新将节点加入集群
假设你已经连接到一个集群节点(比如 Primary 节点),你可以使用 cluster.addInstance()
或 cluster.rejoinInstance()
将新节点或旧节点重新加入到集群。
- 连接到现有集群的节点如果你还没有连接到集群中的一个节点,请使用 MySQL Shell 连接到一个主节点。\connect root@<primary-node-ip>:3306
- 重新加入节点使用以下命令重新加入脱离的节点(假设是 192.168.35.50:3306):var cluster = dba.getCluster();cluster.rejoinInstance('root@192.168.35.50:3306');如果该实例不属于集群,可以使用 addInstance() 进行加入:cluster.addInstance('root@192.168.35.50:3306');
4. 查看集群状态
当实例成功加入集群后,可以使用以下命令查看集群状态,确保所有节点都已正常加入:
var cluster = dba.getCluster();cluster.status();
你将看到集群的详细状态信息,包括各个节点的状态(在线、同步等)、角色(Primary/Secondary)、以及集群的健康状况。
示例输出
{ "clusterName": "myCluster", "defaultReplicaSet": { "name": "default", "primary": "192.168.35.49:3306", "status": "OK", "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", "topology": { "192.168.35.49:3306": { "address": "192.168.35.49:3306", "mode": "R/W", "role": "PRIMARY", "status": "ONLINE" }, "192.168.35.50:3306": { "address": "192.168.35.50:3306", "mode": "R/O", "role": "SECONDARY", "status": "ONLINE" }, "192.168.35.51:3306": { "address": "192.168.35.51:3306", "mode": "R/O", "role": "SECONDARY", "status": "ONLINE" } } }}
这个输出展示了集群的当前状态,所有节点的状态、角色以及读写模式。
5. 其他有用的集群操作命令
- 查看集群配置:cluster.describe();
- 重新检查集群健康状况:cluster.checkInstanceState('root@192.168.35.50:3306');
- 移除节点:cluster.removeInstance('root@192.168.35.50:3306');
通过这些步骤,可以重新初始化并加入节点到 MySQL InnoDB 集群,同时监控集群的健康状况。