MySQL Shell 8.0  /  MySQL InnoDB ReplicaSet  /  InnoDB ReplicaSet Locking

9.8 InnoDB ReplicaSet Locking

From version 8.0.20, AdminAPI uses a locking mechanism to avoid different operations from performing changes on an InnoDB ReplicaSet simultaneously. Previously, different instances of MySQL Shell could connect to an InnoDB ReplicaSet at the same time and process AdminAPI operations simultaneously. This could lead to inconsistent instance states and errors, for example, if ReplicaSet.addInstance() and ReplicaSet.setPrimaryInstance() were processed in parallel.

The InnoDB ReplicaSet operations have the following locking:

  • dba.upgradeMetadata() and dba.createReplicaSet() are globally exclusive operations. This means that if MySQL Shell processes these operations on an InnoDB ReplicaSet, no other operations can be processed against the InnoDB ReplicaSet or any of its instances.

  • ReplicaSet.forcePrimaryInstance() and ReplicaSet.setPrimaryInstance() are operations that change the primary. This means that if MySQL Shell processes these operations against an InnoDB ReplicaSet, no other operations which change the primary, or instance change, operations can be processed until the first operation completes.

  • ReplicaSet.addInstance(), ReplicaSet.rejoinInstance(), and ReplicaSet.removeInstance() are operations that change an instance. This means that if MySQL Shell processes these operations on an instance, the instance is locked for any further instance change operations. However, this lock is only at the instance level and multiple instances of an InnoDB ReplicaSet can each process one of this type of operation simultaneously. In other words, at most one instance change operation can be processed at a time, per instance in the InnoDB ReplicaSet.

  • dba.getReplicaSet() and ReplicaSet.status() are InnoDB ReplicaSet read operations and do not require any locking.

In practice, if you try to process an InnoDB ReplicaSet related operation while another operation that cannot be processed concurrently is still running, you get an error indicating that a lock on a needed resource failed to be acquired. In this case, you should wait for the running operation which holds the lock to complete, and only then try to process the next operation. For example:

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)

In this example, the ReplicaSet.addInstance() operation failed because of the lock on the primary instance (rs1:3306) could not be acquired, for example because a ReplicaSet.setPrimaryInstance() operation (or other similar operation) was still running.