以前,不同 MySQL Shell 实例可以同时连接到同一资源并处理 AdminAPI 操作。这可能会导致不一致的状态和错误,例如,如果
和 Cluster
.addInstance()
并行处理。Cluster
.setPrimaryInstance()
AdminAPI 使用 MySQL 锁定服务来提供以下锁定类型
读或共享锁:允许在阻止独占操作时并发执行某些操作。如果某个操作尝试获取共享锁,但由于存在独占锁而无法获取,则该操作将中止,而不会进行任何更改。如果当前操作具有共享锁,并且新操作需要共享锁,则允许新操作访问。
写或独占锁:阻止执行所有其他操作,直到当前操作完成并释放独占锁。如果某个操作尝试获取独占锁,但由于存在现有锁而无法获取,则该操作将中止,而不会进行任何更改。
有关更多信息,请参阅 锁定服务。
下表列出了每个 AdminAPI 操作的锁定
DBA 锁定:列出
dba.
操作的锁。operationName
集群锁定:列出
操作的锁。Cluster
.operationName
集群集锁定:列出
操作的锁。ClusterSet
.operationName
InnoDB 副本集锁定:列出
操作的锁。ReplicaSet
.operationName
未列出不需要锁的操作。
在实践中,如果您尝试在另一个无法并发执行的操作仍在运行时执行操作,则会收到一个错误,指示无法获取所需资源上的锁。在这种情况下,您应该等待持有锁的正在运行的操作完成,然后才能尝试处理下一个操作。例如
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()
如果实例作为克隆操作或请求的重启的一部分而重启,则该锁将被释放。因此,在以毫秒为单位的短时间内,另一个 Shell 会话可以在重启时访问该实例并锁定它。但是,集群和/或集群集上的原始锁仍然存在,因此可以锁定新重启实例的新命令无法请求集群或集群集锁。
本节列出
操作的锁。dba
.operationName
表 6.1 DBA 操作锁
操作 | 锁定类型 |
---|---|
|
目标实例上的独占锁 |
|
目标实例上的独占锁 |
|
所有可联系集群成员上的独占锁。 如果集群是副本集群,并且是集群集的一部分,则它也会作为操作的一部分重新加入集群集。在这种情况下,该操作还会获取与 |
|
|
|
目标实例上的独占锁。 |
|
目标实例上的独占锁。 |
|
如果拓扑是集群集,则在集群集和主集群上获取独占锁;如果拓扑是独立集群,则在集群和目标实例上获取独占锁。 |
本节列出
操作的锁。cluster
.operationName
表 6.2 集群操作锁
操作 | 集群锁定类型 | 目标实例锁定类型 |
---|---|---|
|
独占 |
独占 |
|
独占 |
|
|
独占 |
|
|
独占 |
|
|
独占 |
|
|
独占 |
|
|
共享 |
独占 |
|
独占 |
独占 |
|
独占 |
|
|
独占 |
|
|
独占 选项 |
|
|
独占 选项 |
|
|
独占 |
|
|
共享 |
|
|
共享 |
|
|
独占 |
|
|
独占 |
|
|
独占 |