From 6ea7dedabe568423bdbbc7fc63f86b7b1af1d5e0 Mon Sep 17 00:00:00 2001 From: Ran Date: Fri, 12 Jun 2020 14:33:30 +0800 Subject: [PATCH 1/5] update optimistic transaction --- optimistic-transaction.md | 57 ++++++++++----------------------------- 1 file changed, 14 insertions(+), 43 deletions(-) diff --git a/optimistic-transaction.md b/optimistic-transaction.md index 6fc28ebcf88e7..af84bf7f4559b 100644 --- a/optimistic-transaction.md +++ b/optimistic-transaction.md @@ -7,35 +7,36 @@ aliases: ['/docs/dev/reference/transactions/transaction-optimistic/','/docs/dev/ # TiDB Optimistic Transaction Model -This document introduces the principles of TiDB's optimistic transaction model. This document assumes that you have a basic understanding of [TiDB architecture](/architecture.md), [Percolator](https://ai.google/research/pubs/pub36726), and the [ACID](/glossary.md#acid) properties of transactions. +This document introduces the principles of TiDB's optimistic transaction model and related features. -In TiDB's optimistic transaction model, the two-phase commit begins right after the client executes the `COMMIT` statement. Therefore, the write-write conflict can be observed before the transactions are actually committed. +TiDB uses the optimistic transaction model by default. In TiDB's optimistic transaction model, the two-phase commit begins only after the transaction is committed. > **Note:** > -> Starting from v3.0.8, TiDB uses the [pessimistic transaction model](/pessimistic-transaction.md) by default. However, this does not affect your clusters if you upgrading from v3.0.7 or earlier to v3.0.8 (and later). In other words, **only newly created clusters default to using the pessimistic transaction model**. +> Starting from v3.0.8, the newly created TiDB clusters use the [pessimistic transaction model](/pessimistic-transaction.md) by default. However, this does not affect your clusters if you upgrading from v3.0.7 or earlier to v3.0.8 (and later). In other words, **only newly created clusters default to using the pessimistic transaction model**. ## Principles of optimistic transactions -TiDB adopts Google's Percolator transaction model, a variant of two-phase commit (2PC) to ensure the correct completion of a distributed transaction. The procedure is as follows: +To support distributed transactions, TiDB adopts two-phase commit (2PC) in the optimistic transaction model. The procedure is as follows: ![2PC in TiDB](/media/2pc-in-tidb.png) 1. The client begins a transaction. - TiDB receives the start version number (monotonically increasing in time and globally unique) from PD and mark it as `start_ts`. + TiDB receives the timestamp (monotonically increasing in time and globally unique) from PD as the unique transaction ID of the current transaction, which is called `start_ts`. TiDB implements multi-version concurrency control, so `start_ts` also serves as the database snapshot version obtained by this transaction. The transaction can only read the data available for the `start_ts` version. 2. The client issues a read request. + 1. TiDB receives routing information (how data is distributed among TiKV nodes) from PD. 2. TiDB receives the data of the `start_ts` version from TiKV. 3. The client issues a write request. - TiDB checks whether the written data satisfies consistency constraints (to ensure the data types are correct and the unique index is met etc.) **Valid data is stored in the memory**. + TiDB checks whether the written data satisfies constraints (to ensure the data types are correct, the not null constraint is met, etc.) **Valid data is stored in the private memory of this transaction in TiDB**. 4. The client issues a commit request. -5. TiDB begins 2PC to ensure the atomicity of distributed transactions and persist data in store. +5. TiDB begins 2PC to ensure the atomicity of transactions and persist data in store. 1. TiDB selects a Primary Key from the data to be written. 2. TiDB receives the information of Region distribution from PD, and groups all keys by Region accordingly. @@ -60,18 +61,16 @@ From the process of transactions in TiDB above, it is clear that TiDB transactio However, TiDB transactions also have the following disadvantages: * Transaction latency due to 2PC -* In need of a centralized version manager +* In need of a centralized timestamp allocation service * OOM (out of memory) when extensive data is written in the memory -To avoid potential problems in application, refer to [transaction sizes](/transaction-overview.md#transaction-size) to see more details. - ## Transaction retries -TiDB uses optimistic concurrency control by default whereas MySQL applies pessimistic concurrency control. This means that MySQL checks for conflicts during the execution of SQL statements, so there are few errors reported in heavy contention scenarios. For the convenience of MySQL users, TiDB provides a retry function that runs inside a transaction. +In the optimistic transaction model, transactions might fail to be committed because of write–write conflict in heavy contention scenarios. TiDB uses optimistic concurrency control by default, whereas MySQL applies pessimistic concurrency control. This means that MySQL adds locks during the execution of a SQL statement, and its Repeatable Read isolation level allows for non-repeatable reads, so commits generally do not encounter exceptions. To lower the difficulty of adapting applications, TiDB provides a retry function that runs inside the database. ### Automatic retry -If there is a conflict, TiDB retries the write operations automatically. You can set `tidb_disable_txn_auto_retry` and `tidb_retry_limit` to enable or disable this default function: +If write-write conflict occurs during a transaction commit, TiDB retries the write operations automatically. You can enable or disable this default function by setting `tidb_disable_txn_auto_retry` to `off` and set the retry limit by configuring `tidb_retry_limit`: ```toml # Whether to disable automatic retry. ("on" by default) @@ -113,7 +112,7 @@ You can enable the automatic retry in either session level or global level: > **Note:** > -> The `tidb_retry_limit` variable decides the maximum number of retries. When this variable is set to `0`, none of the transactions automatically retries, including the implicit single statement transactions that are automatically committed. This is the way to completely disable the automatic retry mechanism in TiDB. After the automatic retry is disabled, all conflicting transactions report failures (includes the `try again later` string) to the application layer in the fastest way. +> The `tidb_retry_limit` variable decides the maximum number of retries. When this variable is set to `0`, none of the transactions automatically retries, including the implicit single statement transactions that are automatically committed. This is the way to completely disable the automatic retry mechanism in TiDB. After the automatic retry is disabled, all conflicting transactions report failures (including the `try again later` message) to the application layer in the fastest way. ### Limits of retry @@ -131,37 +130,9 @@ If your application can tolerate lost updates, and does not require `REPEATABLE ## Conflict detection -For the optimistic transaction, it is important to detect whether there are write-write conflicts in the underlying data. Although TiKV reads data for detection **in the prewrite phase**, a conflict pre-detection is also performed in the TiDB clusters to improve the efficiency. - -Because TiDB is a distributed database, the conflict detection in the memory is performed in two layers: - -* The TiDB layer. If a write-write conflict in the instance is observed after the primary write is issued, it is unnecessary to issue the subsequent writes to the TiKV layer. -* The TiKV layer. TiDB instances are unaware of each other, which means they cannot confirm whether there are conflicts or not. Therefore, the conflict detection is mainly performed in the TiKV layer. - -The conflict detection in the TiDB layer is disabled by default. The specific configuration items are as follows: - -```toml -[txn-local-latches] -# Whether to enable the latches for transactions. Recommended -# to use latches when there are many local transaction conflicts. -# ("false" by default) -enabled = false -# Controls the number of slots corresponding to Hash. ("204800" by default) -# It automatically adjusts upward to an exponential multiple of 2. -# Each slot occupies 32 Bytes of memory. If set too small, -# it might result in slower running speed and poor performance -# when data writing covers a relatively large range. -capacity = 2048000 -``` - -The value of the `capacity` configuration item mainly affects the accuracy of conflict detection. During conflict detection, only the hash value of each key is stored in the memory. Because the probability of collision when hashing is closely related to the probability of misdetection, you can configure `capacity` to controls the number of slots and enhance the accuracy of conflict detection. - -* The smaller the value of `capacity`, the smaller the occupied memory and the greater the probability of misdetection. -* The larger the value of `capacity`, the larger the occupied memory and the smaller the probability of misdetection. - -When you confirm that there is no write-write conflict in the upcoming transactions (such as importing data), it is recommended to disable the function of conflict detection. +Because TiDB is a distributed database, the conflict detection in the memory is performed in the TiKV layer, mainly in the prewrite phase. TiDB instances are stateless and unaware of each other, which means they cannot confirm whether there are conflicts or not. Therefore, the conflict detection is performed in the TiKV layer. -TiKV also uses a similar mechanism to detect conflicts, but the conflict detection in the TiKV layer cannot be disabled. You can only configure `scheduler-concurrency` to control the number of slots that defined by the modulo operation: +The configuration is as follows: ```toml # Controls the number of slots. ("2048000" by default) From 8aea41cf1c5fa73249a35cd89f91d5cafc974e22 Mon Sep 17 00:00:00 2001 From: Ran Date: Fri, 12 Jun 2020 14:36:56 +0800 Subject: [PATCH 2/5] fix typos --- optimistic-transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optimistic-transaction.md b/optimistic-transaction.md index af84bf7f4559b..76dd6cd4277d6 100644 --- a/optimistic-transaction.md +++ b/optimistic-transaction.md @@ -32,7 +32,7 @@ To support distributed transactions, TiDB adopts two-phase commit (2PC) in the o 3. The client issues a write request. - TiDB checks whether the written data satisfies constraints (to ensure the data types are correct, the not null constraint is met, etc.) **Valid data is stored in the private memory of this transaction in TiDB**. + TiDB checks whether the written data satisfies constraints (to ensure the data types are correct, the NOT NULL constraint is met, etc.). **Valid data is stored in the private memory of this transaction in TiDB**. 4. The client issues a commit request. From 0c14e7b83e8a7da0bab98665d3245ef124fd7bb1 Mon Sep 17 00:00:00 2001 From: Ran Date: Fri, 12 Jun 2020 17:14:46 +0800 Subject: [PATCH 3/5] align the second sentence --- optimistic-transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optimistic-transaction.md b/optimistic-transaction.md index 76dd6cd4277d6..d28afa22b5bfd 100644 --- a/optimistic-transaction.md +++ b/optimistic-transaction.md @@ -9,7 +9,7 @@ aliases: ['/docs/dev/reference/transactions/transaction-optimistic/','/docs/dev/ This document introduces the principles of TiDB's optimistic transaction model and related features. -TiDB uses the optimistic transaction model by default. In TiDB's optimistic transaction model, the two-phase commit begins only after the transaction is committed. +TiDB uses the optimistic transaction model by default. In TiDB's optimistic transaction model, for write-write conflicts, the two-phase commit begins only when the transaction is committed. > **Note:** > From 4d78f741d1e7377a68390f89eecec7515aee060c Mon Sep 17 00:00:00 2001 From: Ran Date: Fri, 12 Jun 2020 17:19:01 +0800 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- optimistic-transaction.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/optimistic-transaction.md b/optimistic-transaction.md index d28afa22b5bfd..2169be916aad2 100644 --- a/optimistic-transaction.md +++ b/optimistic-transaction.md @@ -13,11 +13,11 @@ TiDB uses the optimistic transaction model by default. In TiDB's optimistic tran > **Note:** > -> Starting from v3.0.8, the newly created TiDB clusters use the [pessimistic transaction model](/pessimistic-transaction.md) by default. However, this does not affect your clusters if you upgrading from v3.0.7 or earlier to v3.0.8 (and later). In other words, **only newly created clusters default to using the pessimistic transaction model**. +> Starting from v3.0.8, newly created TiDB clusters use the [pessimistic transaction model](/pessimistic-transaction.md) by default. However, this does not affect your existing cluster if you upgrade it from v3.0.7 or earlier to v3.0.8 or later. In other words, **only newly created clusters default to using the pessimistic transaction model**. ## Principles of optimistic transactions -To support distributed transactions, TiDB adopts two-phase commit (2PC) in the optimistic transaction model. The procedure is as follows: +To support distributed transactions, TiDB adopts two-phase commit (2PC) in optimistic transactions. The procedure is as follows: ![2PC in TiDB](/media/2pc-in-tidb.png) @@ -36,7 +36,7 @@ To support distributed transactions, TiDB adopts two-phase commit (2PC) in the o 4. The client issues a commit request. -5. TiDB begins 2PC to ensure the atomicity of transactions and persist data in store. +5. TiDB begins 2PC, and persist data in store while guaranteeing the atomicity of transactions. 1. TiDB selects a Primary Key from the data to be written. 2. TiDB receives the information of Region distribution from PD, and groups all keys by Region accordingly. @@ -66,11 +66,11 @@ However, TiDB transactions also have the following disadvantages: ## Transaction retries -In the optimistic transaction model, transactions might fail to be committed because of write–write conflict in heavy contention scenarios. TiDB uses optimistic concurrency control by default, whereas MySQL applies pessimistic concurrency control. This means that MySQL adds locks during the execution of a SQL statement, and its Repeatable Read isolation level allows for non-repeatable reads, so commits generally do not encounter exceptions. To lower the difficulty of adapting applications, TiDB provides a retry function that runs inside the database. +In the optimistic transaction model, transactions might fail to be committed because of write–write conflict in heavy contention scenarios. TiDB uses optimistic concurrency control by default, whereas MySQL applies pessimistic concurrency control. This means that MySQL adds locks during SQL execution, and its Repeatable Read isolation level allows for non-repeatable reads, so commits generally do not encounter exceptions. To lower the difficulty of adapting applications, TiDB provides an internal retry mechanism. ### Automatic retry -If write-write conflict occurs during a transaction commit, TiDB retries the write operations automatically. You can enable or disable this default function by setting `tidb_disable_txn_auto_retry` to `off` and set the retry limit by configuring `tidb_retry_limit`: +If a write-write conflict occurs during the transaction commit, TiDB automatically retries the SQL statement that includes write operations. You can enable the automatic retry by setting `tidb_disable_txn_auto_retry` to `off` and set the retry limit by configuring `tidb_retry_limit`: ```toml # Whether to disable automatic retry. ("on" by default) @@ -130,7 +130,7 @@ If your application can tolerate lost updates, and does not require `REPEATABLE ## Conflict detection -Because TiDB is a distributed database, the conflict detection in the memory is performed in the TiKV layer, mainly in the prewrite phase. TiDB instances are stateless and unaware of each other, which means they cannot confirm whether there are conflicts or not. Therefore, the conflict detection is performed in the TiKV layer. +As a distributed database, TiDB performs in-memory conflict detection in the TiKV layer, mainly in the prewrite phase. TiDB instances are stateless and unaware of each other, which means they cannot know whether their writes result in conflicts across the cluster. Therefore, conflict detection is performed in the TiKV layer. The configuration is as follows: From 6dcc4372029e6bf01a36b7811dfe59f98e05b70e Mon Sep 17 00:00:00 2001 From: Jack Yu Date: Mon, 15 Jun 2020 16:42:02 +0800 Subject: [PATCH 5/5] Apply suggestions from code review Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- optimistic-transaction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/optimistic-transaction.md b/optimistic-transaction.md index 2169be916aad2..c2d90fe129cef 100644 --- a/optimistic-transaction.md +++ b/optimistic-transaction.md @@ -23,7 +23,7 @@ To support distributed transactions, TiDB adopts two-phase commit (2PC) in optim 1. The client begins a transaction. - TiDB receives the timestamp (monotonically increasing in time and globally unique) from PD as the unique transaction ID of the current transaction, which is called `start_ts`. TiDB implements multi-version concurrency control, so `start_ts` also serves as the database snapshot version obtained by this transaction. The transaction can only read the data available for the `start_ts` version. + TiDB gets a timestamp (monotonically increasing in time and globally unique) from PD as the unique transaction ID of the current transaction, which is called `start_ts`. TiDB implements multi-version concurrency control, so `start_ts` also serves as the version of the database snapshot obtained by this transaction. This means that the transaction can only read the data from the database at `start_ts`. 2. The client issues a read request.