从 8.0.20 版开始,AdminAPI 使用锁定机制来避免不同的操作同时对 InnoDB ReplicaSet 执行更改。以前,MySQL Shell 的不同实例可以同时连接到 InnoDB ReplicaSet, 同时处理 AdminAPI 操作。这可能会导致实例状态不一致和错误,例如,如果并行处理 ReplicaSet.addInstance()
和 ReplicaSet.setPrimaryInstance()
。
InnoDB ReplicaSet 操作具有以下锁:
dba.upgradeMetadata()
和dba.createReplicaSet()
是全局独占操作。这意味着,如果 MySQL Shell 在 InnoDB ReplicaSet 上处理这些操作,则无法对 InnoDB ReplicaSet 或其任何实例处理其他操作。ReplicaSet.forcePrimaryInstance()
和ReplicaSet.setPrimaryInstance()
是更改主实例的操作。这意味着,如果 MySQL Shell 针对 InnoDB ReplicaSet 处理这些操作,则在第一个操作完成之前,无法处理其他更改主实例操作或实例更改的操作。ReplicaSet.addInstance()
、ReplicaSet.rejoinInstance()
和ReplicaSet.removeInstance()
是更改实例的操作。这意味着,如果 MySQLShell 在实例上处理这些操作,则该实例将被锁定,以进行任何进一步的实例更改操作。然而,此锁仅在实例级别,InnoDB ReplicaSet 的多个实例可以同时处理此类操作中的任一操作。换句话说,在 InnoDB ReplicaSet 中的每个实例,一次最多只能处理一个实例更改操作。dba.getReplicaSet()
和ReplicaSet.status()
是 InnoDB ReplicaSet 读取操作,不需要任何锁。
实际上,如果您试图在另一个无法同时处理的操作仍在运行时处理与 InnoDB ReplicaSet 相关的操作,则会收到一个错误,表明无法获取所需资源的锁。在这种情况下,您应该等待持有锁的正在运行的操作完成,然后才尝试处理下一个操作。例如:
mysql-js> rs.addInstance("admin@rs2:3306");
ERROR: The operation cannot be executed because it failed to acquire the lock on
instance 'rs1:3306'. Another operation requiring exclusive access to the
instance is still in progress, please wait for it to finish and try again.
ReplicaSet.addInstance: Failed to acquire lock on instance 'rs1:3306' (MYSQLSH
51400)
在此示例中,ReplicaSet.addInstance()
操作失败,因为无法获取主实例(rs1:3306)上的锁,例如,因为ReplicaSet.setPrimaryInstance()
(或其他类似操作)仍在运行。