From 2aa0a5cf5872c32f417a089ec7ea78ebd703d624 Mon Sep 17 00:00:00 2001 From: Chaoguang Lin Date: Fri, 3 Sep 2021 12:15:56 -0700 Subject: [PATCH] The lock special key has the lock UID as the value --- documentation/sphinx/source/special-keys.rst | 2 +- fdbclient/SpecialKeySpace.actor.cpp | 16 ++++++++++++---- .../SpecialKeySpaceCorrectness.actor.cpp | 3 ++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/documentation/sphinx/source/special-keys.rst b/documentation/sphinx/source/special-keys.rst index a0a6d7b3da..0dd5840ab8 100644 --- a/documentation/sphinx/source/special-keys.rst +++ b/documentation/sphinx/source/special-keys.rst @@ -199,7 +199,7 @@ that process, and wait for necessary data to be moved away. While the key is set, any commit that tries to set a key in the range will fail with the ``special_keys_api_failure`` error. #. ``\xff\xff/management/data_distribution/`` Read/write. Changing these two keys will change the two corresponding system keys ``\xff/dataDistributionMode`` and ``\xff\x02/rebalanceDDIgnored``. The value of ``\xff\xff/management/data_distribution/mode`` is a literal text of ``0`` (disable) or ``1`` (enable). Transactions committed with invalid values will throw ``special_keys_api_failure`` . The value of ``\xff\xff/management/data_distribution/rebalance_ignored`` is empty. If present, it means data distribution is disabled for rebalance. Any transaction committed with non-empty value for this key will throw ``special_keys_api_failure``. For more details, see help text of ``fdbcli`` command ``datadistribution``. #. ``\xff\xff/management/consistency_check_suspended`` Read/write. Set or read this key will set or read the underlying system key ``\xff\x02/ConsistencyCheck/Suspend``. The value of this special key is unused thus if present, will be empty. In particular, if the key exists, then consistency is suspended. For more details, see help text of ``fdbcli`` command ``consistencycheck``. -#. ``\xff\xff/management/db_locked`` Read/write. A single key that can be read and modified. Set the key will lock the database and clear the key will unlock. If the database is already locked, then the commit will fail with the ``special_keys_api_failure`` error. For more details, see help text of ``fdbcli`` command ``lock`` and ``unlock``. +#. ``\xff\xff/management/db_locked`` Read/write. A single key that can be read and modified. Set the key with a 32 bytes hex string UID will lock the database and clear the key will unlock. Read the key will return the UID string as the value. If the database is already locked, then the commit will fail with the ``special_keys_api_failure`` error. For more details, see help text of ``fdbcli`` command ``lock`` and ``unlock``. #. ``\xff\xff/management/auto_coordinators`` Read-only. A single key, if read, will return a set of processes which is able to satisfy the current redundency level and serve as new coordinators. The return value is formatted as a comma delimited string of network addresses of coordinators, i.e. ``,,...,``. #. ``\xff\xff/management/excluded_locality/`` Read/write. Indicates that the cluster should move data away from processes matching ````, so that they can be safely removed. See :ref:`removing machines from a cluster ` for documentation for the corresponding fdbcli command. #. ``\xff\xff/management/failed_locality/`` Read/write. Indicates that the cluster should consider matching processes as permanently failed. This allows the cluster to avoid maintaining extra state and doing extra work in the hope that these processes come back. See :ref:`removing machines from a cluster ` for documentation for the corresponding fdbcli command. diff --git a/fdbclient/SpecialKeySpace.actor.cpp b/fdbclient/SpecialKeySpace.actor.cpp index 71a3e964c6..4d1af8aac3 100644 --- a/fdbclient/SpecialKeySpace.actor.cpp +++ b/fdbclient/SpecialKeySpace.actor.cpp @@ -1290,7 +1290,8 @@ ACTOR Future getLockedKeyActor(ReadYourWritesTransaction* ryw, KeyR Optional val = wait(ryw->getTransaction().get(databaseLockedKey)); RangeResult result; if (val.present()) { - result.push_back_deep(result.arena(), KeyValueRef(kr.begin, val.get())); + UID uid = UID::fromString(BinaryReader::fromStringRef(val.get().substr(10), Unversioned()).toString()); + result.push_back_deep(result.arena(), KeyValueRef(kr.begin, Value(uid.toString()))); } return result; } @@ -1313,11 +1314,10 @@ Future LockDatabaseImpl::getRange(ReadYourWritesTransaction* ryw, K } } -ACTOR Future> lockDatabaseCommitActor(ReadYourWritesTransaction* ryw) { +ACTOR Future> lockDatabaseCommitActor(ReadYourWritesTransaction* ryw, UID uid) { state Optional msg; ryw->getTransaction().setOption(FDBTransactionOptions::LOCK_AWARE); Optional val = wait(ryw->getTransaction().get(databaseLockedKey)); - UID uid = deterministicRandom()->randomUniqueID(); if (val.present() && BinaryReader::fromStringRef(val.get().substr(10), Unversioned()) != uid) { // check database not locked @@ -1348,7 +1348,15 @@ ACTOR Future> unlockDatabaseCommitActor(ReadYourWritesTran Future> LockDatabaseImpl::commit(ReadYourWritesTransaction* ryw) { auto lockId = ryw->getSpecialKeySpaceWriteMap()[SpecialKeySpace::getManagementApiCommandPrefix("lock")].second; if (lockId.present()) { - return lockDatabaseCommitActor(ryw); + std::string uidStr = lockId.get().toString(); + UID uid; + try { + uid = UID::fromString(uidStr); + } catch (Error& e) { + return Optional( + ManagementAPIError::toJsonString(false, "lock", "Invalid UID hex string: " + uidStr)); + } + return lockDatabaseCommitActor(ryw, uid); } else { return unlockDatabaseCommitActor(ryw); } diff --git a/fdbserver/workloads/SpecialKeySpaceCorrectness.actor.cpp b/fdbserver/workloads/SpecialKeySpaceCorrectness.actor.cpp index b98298d292..8e79b7c515 100644 --- a/fdbserver/workloads/SpecialKeySpaceCorrectness.actor.cpp +++ b/fdbserver/workloads/SpecialKeySpaceCorrectness.actor.cpp @@ -809,7 +809,8 @@ struct SpecialKeySpaceCorrectnessWorkload : TestWorkload { try { tx->setOption(FDBTransactionOptions::SPECIAL_KEY_SPACE_ENABLE_WRITES); // lock the database - tx->set(SpecialKeySpace::getManagementApiCommandPrefix("lock"), LiteralStringRef("")); + UID uid = deterministicRandom()->randomUniqueID(); + tx->set(SpecialKeySpace::getManagementApiCommandPrefix("lock"), uid.toString()); // commit wait(tx->commit()); break;