github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/kv/kvserver/concurrency/lock/locking.proto (about)

     1  // Copyright 2020 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  syntax = "proto3";
    12  package cockroach.kv.kvserver.concurrency.lock;
    13  option go_package = "lock";
    14  
    15  import "gogoproto/gogo.proto";
    16  
    17  // Strength represents the different locking modes that determine how key-values
    18  // can be accessed by concurrent transactions.
    19  //
    20  // Locking modes apply to locks that are held with a per-key granularity. It is
    21  // up to users of the key-value layer to decide on which keys to acquire locks
    22  // for when imposing structure that can span multiple keys, such as SQL rows
    23  // (see column families and secondary indexes).
    24  //
    25  // Locking modes have differing levels of strength, growing from "weakest" to
    26  // "strongest" in the order that the variants are presented in the enumeration.
    27  // The "stronger" a locking mode, the more protection it provides for the lock
    28  // holder but the more restrictive it is to concurrent transactions attempting
    29  // to access the same keys.
    30  //
    31  // Compatibility Matrix
    32  //
    33  // The following matrix presents the compatibility of locking strengths with one
    34  // another. A cell with an X means that the two strengths are incompatible with
    35  // each other and that they can not both be held on a given key by different
    36  // transactions, concurrently. A cell without an X means that the two strengths
    37  // are compatible with each other and that they can be held on a given key by
    38  // different transactions, concurrently.
    39  //
    40  //  +-----------+-----------+-----------+-----------+-----------+
    41  //  |           |   None    |  Shared   |  Upgrade  | Exclusive |
    42  //  +-----------+-----------+-----------+-----------+-----------+
    43  //  | None      |           |           |           |     X^†   |
    44  //  +-----------+-----------+-----------+-----------+-----------+
    45  //  | Shared    |           |           |     X     |     X     |
    46  //  +-----------+-----------+-----------+-----------+-----------+
    47  //  | Upgrade   |           |     X     |     X     |     X     |
    48  //  +-----------+-----------+-----------+-----------+-----------+
    49  //  | Exclusive |     X^†   |     X     |     X     |     X     |
    50  //  +-----------+-----------+-----------+-----------+-----------+
    51  //
    52  // [†] reads under optimistic concurrency control in CockroachDB only conflict
    53  // with Exclusive locks if the read's timestamp is equal to or greater than the
    54  // lock's timestamp. If the read's timestamp is below the Exclusive lock's
    55  // timestamp then the two are compatible.
    56  enum Strength {
    57    option (gogoproto.goproto_enum_prefix) = false;
    58  
    59    // None represents the absence of a lock or the intention to acquire locks.
    60    // It corresponds to the behavior of transactions performing key-value reads
    61    // under optimistic concurrency control. No locks are acquired on the keys
    62    // read by these requests when they evaluate. However, the reads do respect
    63    // Exclusive locks already held by other transactions at timestamps equal to
    64    // or less than their read timestamp.
    65    //
    66    // Optimistic concurrency control (OCC) can improve performance under some
    67    // workloads because it avoids the need to perform any locking during reads.
    68    // This can increase the amount of concurrency that the system can permit
    69    // between ongoing transactions. However, OCC does mandate a read validation
    70    // phase if/when transactions need to commit at a different timestamp than
    71    // they performed all reads at. CockroachDB calls this a "read refresh",
    72    // which is implemented by the txnSpanRefresher. If a read refresh fails due
    73    // to new key-value writes that invalidate what was previously read,
    74    // transactions are forced to restart. See the comment on txnSpanRefresher
    75    // for more.
    76    None = 0;
    77    
    78    // Shared (S) locks are used by read-only operations and allow concurrent
    79    // transactions to read under pessimistic concurrency control. Shared locks
    80    // are compatible with each other but are not compatible with Upgrade or
    81    // Exclusive locks. This means that multiple transactions can hold a Shared
    82    // lock on the same key at the same time, but no other transaction can
    83    // modify the key at the same time. A holder of a Shared lock on a key is
    84    // only permitted to read the key's value while the lock is held.
    85    //
    86    // Share locks are currently unused, as all KV reads are currently performed
    87    // optimistically (see None).
    88    Shared = 1;
    89  
    90    // Upgrade (U) locks are a hybrid of Shared and Exclusive locks which are
    91    // used to prevent a common form of deadlock. When a transaction intends to
    92    // modify existing KVs, it is often the case that it reads the KVs first and
    93    // then attempts to modify them. Under pessimistic concurrency control, this
    94    // would correspond to first acquiring a Shared lock on the keys and then
    95    // converting the lock to an Exclusive lock when modifying the keys. If two
    96    // transactions were to acquire the Shared lock initially and then attempt
    97    // to update the keys concurrently, both transactions would get stuck
    98    // waiting for the other to release its Shared lock and a deadlock would
    99    // occur. To resolve the deadlock, one of the two transactions would need to
   100    // be aborted.
   101    //
   102    // To avoid this potential deadlock problem, an Upgrade lock can be used in
   103    // place of a Shared lock. Upgrade locks are not compatible with any other
   104    // form of locking. As with Shared locks, the lock holder of a Shared lock
   105    // on a key is only allowed to read from the key while the lock is held.
   106    // This resolves the deadlock scenario presented above because only one of
   107    // the transactions would have been able to acquire an Upgrade lock at a
   108    // time while reading the initial state of the KVs. This means that the
   109    // Shared-to-Exclusive lock upgrade would never need to wait on another
   110    // transaction to release its locks.
   111    //
   112    // Under pure pessimistic concurrency control, an Upgrade lock is equivalent
   113    // to an Exclusive lock. However, unlike with Exclusive locks, reads under
   114    // optimistic concurrency control do not conflict with Upgrade locks. This
   115    // is because a transaction can only hold an Upgrade lock on keys that it
   116    // has not yet modified. This improves concurrency between read and write
   117    // transactions compared to if the writing transaction had immediately
   118    // acquired an Exclusive lock.
   119    //
   120    // The trade-off here is twofold. First, if the Upgrade lock holder does
   121    // convert its lock on a key to an Exclusive lock after an optimistic read
   122    // has observed the state of the key, the transaction that performed the
   123    // optimistic read may be unable to perform a successful read refresh if it
   124    // attempts to refresh to a timestamp at or past the timestamp of the lock
   125    // conversion. Second, the optimistic reads permitted while the Upgrade lock
   126    // is held will bump the timestamp cache. This may result in the Upgrade
   127    // lock holder being forced to increase its write timestamp when converting
   128    // to an Exclusive lock, which in turn may force it to restart if its read
   129    // refresh fails.
   130    Upgrade = 2;
   131  
   132    // Exclusive (X) locks are used by read-write and read-only operations and
   133    // provide a transaction with exclusive access to a key. When an Exclusive
   134    // lock is held by a transaction on a given key, no other transaction can
   135    // read from or write to that key. The lock holder is free to read from and
   136    // write to the key as frequently as it would like.
   137    Exclusive = 3;
   138  }
   139  
   140  // Durability represents the different durability properties of a lock acquired
   141  // by a transaction. Durability levels provide varying degrees of survivability,
   142  // often in exchange for the cost of lock acquisition.
   143  enum Durability {
   144    option (gogoproto.goproto_enum_prefix) = false;
   145  
   146    // Replicated locks are held on at least a quorum of Replicas in a Range.
   147    // They are slower to acquire and release than Unreplicated locks because
   148    // updating them requires both cross-node coordination and interaction with
   149    // durable storage. In exchange, Replicated locks provide a guarantee of
   150    // survivability across lease transfers, leaseholder crashes, and other
   151    // forms of failure events. They will remain available as long as their
   152    // Range remains available and they will never be lost.
   153    Replicated = 0;
   154  
   155    // Unreplicated locks are held only on a single Replica in a Range, which is
   156    // typically the leaseholder. Unreplicated locks are very fast to acquire
   157    // and release because they are held in memory or on fast local storage and
   158    // require no cross-node coordination to update. In exchange, Unreplicated
   159    // locks provide no guarantee of survivability across lease transfers or
   160    // leaseholder crashes. They should therefore be thought of as best-effort
   161    // and should not be relied upon for correctness.
   162    Unreplicated = 1;
   163  }