From 248db3bc9ef7659a08fe3c6a18ee75b56b3b4cb8 Mon Sep 17 00:00:00 2001 From: Stephanie Bodoff Date: Wed, 1 Dec 2021 15:08:06 -0800 Subject: [PATCH 1/8] Disambiguate different types of contention. --- .../v21.2/performance/statement-contention.md | 2 +- ...dvanced-client-side-transaction-retries.md | 2 +- v21.2/architecture/transaction-layer.md | 4 +- ...uild-a-spring-app-with-cockroachdb-jdbc.md | 2 +- ...build-a-spring-app-with-cockroachdb-jpa.md | 2 +- ...d-a-spring-app-with-cockroachdb-mybatis.md | 2 +- v21.2/crdb-internal.md | 8 ++-- v21.2/delete-data.md | 2 +- v21.2/developer-guide-overview.md | 2 +- v21.2/error-handling-and-troubleshooting.md | 6 +-- v21.2/flyway.md | 2 +- v21.2/insert-data.md | 2 +- v21.2/liquibase.md | 2 +- v21.2/make-queries-fast.md | 4 +- v21.2/migrate-from-oracle.md | 2 +- v21.2/movr-flask-use-case.md | 2 +- v21.2/operational-faqs.md | 2 +- v21.2/performance-best-practices-overview.md | 46 +++++++++++-------- v21.2/performance-recipes.md | 10 ++-- v21.2/query-behavior-troubleshooting.md | 4 +- v21.2/query-data.md | 2 +- v21.2/run-multi-statement-transactions.md | 2 +- v21.2/select-for-update.md | 4 +- v21.2/sql-faqs.md | 14 ++---- v21.2/transaction-retry-error-reference.md | 16 +++---- v21.2/transactions.md | 6 +-- v21.2/update-data.md | 2 +- 27 files changed, 80 insertions(+), 74 deletions(-) diff --git a/_includes/v21.2/performance/statement-contention.md b/_includes/v21.2/performance/statement-contention.md index e0249eec440..8dd5d6873fc 100644 --- a/_includes/v21.2/performance/statement-contention.md +++ b/_includes/v21.2/performance/statement-contention.md @@ -13,4 +13,4 @@ Find the transactions and statements within the transactions that are experienci > SELECT * FROM movr.crdb_internal.cluster_contended_tables; ~~~ -After identifying the transactions or statements that are experiencing contention, follow the steps in [Understanding and avoiding transaction contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). +After you identify the transactions or statements that are causing contention, follow the steps in the next section [to avoid contention](performance-best-practices-overview.html#avoid-contention). diff --git a/v21.2/advanced-client-side-transaction-retries.md b/v21.2/advanced-client-side-transaction-retries.md index a2b3cdfbca9..fbc2828f497 100644 --- a/v21.2/advanced-client-side-transaction-retries.md +++ b/v21.2/advanced-client-side-transaction-retries.md @@ -12,7 +12,7 @@ If you are an application developer who needs to implement an application-level ## Overview -To improve the performance of transactions that fail due to [contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention), CockroachDB includes a set of statements (listed below) that let you retry those transactions. Retrying transactions using these statements has the following benefits: +To improve the performance of transactions that fail due to [contention](performance-best-practices-overview.html#transaction-contention), CockroachDB includes a set of statements (listed below) that let you retry those transactions. Retrying transactions using these statements has the following benefits: 1. When you use savepoints, you "hold your place in line" between attempts. Without savepoints, you're starting from scratch every time. 2. Transactions increase their priority each time they're retried, increasing the likelihood they will succeed. This has a lesser effect than #1. diff --git a/v21.2/architecture/transaction-layer.md b/v21.2/architecture/transaction-layer.md index eac97e5a98d..307ae1af11d 100644 --- a/v21.2/architecture/transaction-layer.md +++ b/v21.2/architecture/transaction-layer.md @@ -332,7 +332,7 @@ The transaction coordinator is able to do this while maintaining correctness gua For an example showing how the Parallel Commits feature works in more detail, see [Parallel Commits - step by step](#parallel-commits-step-by-step). {{site.data.alerts.callout_info}} -The latency until intents are resolved is unchanged by the introduction of Parallel Commits: two rounds of consensus are still required to resolve intents. This means that [contended workloads](../performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) are expected to profit less from this feature. +The latency until intents are resolved is unchanged by the introduction of Parallel Commits: two rounds of consensus are still required to resolve intents. This means that [contended workloads](../performance-best-practices-overview.html#transaction-contention) are expected to profit less from this feature. {{site.data.alerts.end}} #### Parallel Commits - step by step @@ -396,7 +396,7 @@ Additionally, when other transactions encounter a transaction in `STAGING` state The non-blocking transaction protocol and replication scheme differ from standard read-write transactions as follows: - Non-blocking transactions use a replication scheme over the [ranges](overview.html#terms) they operate on that allows all followers in these ranges to serve consistent (non-stale) reads. -- Non-blocking transactions are minimally disruptive to reads over the data they modify, even in the presence of read/write [contention](../performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). +- Non-blocking transactions are minimally disruptive to reads over the data they modify, even in the presence of read/write [contention](../performance-best-practices-overview.html#transaction-contention). These properties of non-blocking transactions combine to provide predictable read latency for a configurable subset of data in [global deployments](../multiregion-overview.html). This is useful since there exists a sizable class of data which is heavily skewed towards read traffic. diff --git a/v21.2/build-a-spring-app-with-cockroachdb-jdbc.md b/v21.2/build-a-spring-app-with-cockroachdb-jdbc.md index efef3f6cc60..7d998d1ca92 100644 --- a/v21.2/build-a-spring-app-with-cockroachdb-jdbc.md +++ b/v21.2/build-a-spring-app-with-cockroachdb-jdbc.md @@ -784,7 +784,7 @@ On verifying that the transaction is active (using `TransactionSynchronizationMa #### Transaction retries -Transactions may require retries if they experience deadlock or [transaction contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) that cannot be resolved without allowing [serialization](demo-serializable.html) anomalies. To handle transactions that are aborted due to transient serialization errors, we highly recommend writing [client-side transaction retry logic](transactions.html#client-side-intervention) into applications written on CockroachDB. +Transactions may require retries if they experience deadlock or [transaction contention](performance-best-practices-overview.html#transaction-contention) that cannot be resolved without allowing [serialization](demo-serializable.html) anomalies. To handle transactions that are aborted due to transient serialization errors, we highly recommend writing [client-side transaction retry logic](transactions.html#client-side-intervention) into applications written on CockroachDB. In this application, transaction retry logic is written into the methods of the `RetryableTransactionAspect` class. This class is declared an aspect with the `@Aspect` annotation. The `@Order` annotation on this aspect class is passed `Ordered.LOWEST_PRECEDENCE-2`, a level of precedence above the primary transaction advisor. This indicates that the transaction retry advisor must run outside the context of a transaction. Here are the contents of [`RetryableTransactionAspect.java`](https://github.com/cockroachlabs/roach-data/blob/master/roach-data-jdbc/src/main/java/io/roach/data/jdbc/RetryableTransactionAspect.java): diff --git a/v21.2/build-a-spring-app-with-cockroachdb-jpa.md b/v21.2/build-a-spring-app-with-cockroachdb-jpa.md index 9e16114e6d8..24e342cd679 100644 --- a/v21.2/build-a-spring-app-with-cockroachdb-jpa.md +++ b/v21.2/build-a-spring-app-with-cockroachdb-jpa.md @@ -673,7 +673,7 @@ For more details about advice ordering, see [Advice Ordering](https://docs.sprin #### Transaction retries -Transactions may require retries if they experience deadlock or [transaction contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) that cannot be resolved without allowing [serialization](demo-serializable.html) anomalies. To handle transactions that are aborted due to transient serialization errors, we highly recommend writing [client-side transaction retry logic](transactions.html#client-side-intervention) into applications written on CockroachDB. +Transactions may require retries if they experience deadlock or [transaction contention](performance-best-practices-overview.html#transaction-contention) that cannot be resolved without allowing [serialization](demo-serializable.html) anomalies. To handle transactions that are aborted due to transient serialization errors, we highly recommend writing [client-side transaction retry logic](transactions.html#client-side-intervention) into applications written on CockroachDB. In this application, transaction retry logic is written into the methods of the `RetryableTransactionAspect` class, declared an aspect with the `@Aspect` annotation. Here are the contents of [`RetryableTransactionAspect.java`](https://github.com/cockroachlabs/roach-data/blob/master/roach-data-jpa/src/main/java/io/roach/data/jpa/RetryableTransactionAspect.java): diff --git a/v21.2/build-a-spring-app-with-cockroachdb-mybatis.md b/v21.2/build-a-spring-app-with-cockroachdb-mybatis.md index 2fc973c606c..772fbd14bc2 100644 --- a/v21.2/build-a-spring-app-with-cockroachdb-mybatis.md +++ b/v21.2/build-a-spring-app-with-cockroachdb-mybatis.md @@ -371,7 +371,7 @@ Instances of the `BatchResults` class, defined in `src/main/java/com/example/coc MyBatis-Spring supports Spring's [declarative, aspect-oriented transaction management syntax](https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative), including the [`@Transactional`](https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative-annotations) annotation and [AspectJ's AOP annotations](https://docs.spring.io/spring/docs/current/spring-framework-reference/data-access.html#transaction-declarative-aspectj). -Transactions may require retries if they experience deadlock or [transaction contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) that cannot be resolved without allowing [serialization](demo-serializable.html) anomalies. To handle transactions that are aborted due to transient serialization errors, we highly recommend writing [client-side transaction retry logic](transactions.html#client-side-intervention) into applications written on CockroachDB. In this application, transaction retry logic is written into the methods of the `RetryableTransactionAspect` class, defined in `src/main/java/com/example/cockroachdemo/RetryableTransactionAspect.java`: +Transactions may require retries if they experience deadlock or [transaction contention](performance-best-practices-overview.html#transaction-contention) that cannot be resolved without allowing [serialization](demo-serializable.html) anomalies. To handle transactions that are aborted due to transient serialization errors, we highly recommend writing [client-side transaction retry logic](transactions.html#client-side-intervention) into applications written on CockroachDB. In this application, transaction retry logic is written into the methods of the `RetryableTransactionAspect` class, defined in `src/main/java/com/example/cockroachdemo/RetryableTransactionAspect.java`: {% include_cached copy-clipboard.html %} ~~~ java diff --git a/v21.2/crdb-internal.md b/v21.2/crdb-internal.md index ac36cc1c28f..81797585fa3 100644 --- a/v21.2/crdb-internal.md +++ b/v21.2/crdb-internal.md @@ -24,10 +24,10 @@ Table | Description `active_range_feeds` | Contains information about [range feeds](architecture/distribution-layer.html) on nodes in your cluster. `backward_dependencies` | Contains information about backward dependencies. `builtin_functions` | Contains information about supported [functions](functions-and-operators.html). -`cluster_contended_indexes` | Contains information about [contended](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) indexes in your cluster. -`cluster_contended_keys` | Contains information about [contended](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) keys in your cluster. -`cluster_contended_tables` | Contains information about [contended](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) tables in your cluster. -`cluster_contention_events` | Contains information about [contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) in your cluster. +`cluster_contended_indexes` | Contains information about [contended](performance-best-practices-overview.html#transaction-contention) indexes in your cluster. +`cluster_contended_keys` | Contains information about [contended](performance-best-practices-overview.html#transaction-contention) keys in your cluster. +`cluster_contended_tables` | Contains information about [contended](performance-best-practices-overview.html#transaction-contention) tables in your cluster. +`cluster_contention_events` | Contains information about [contention](performance-best-practices-overview.html#transaction-contention) in your cluster. `cluster_database_privileges` | Contains information about the [database privileges](authorization.html#privileges) on your cluster. `cluster_distsql_flows` | Contains information about the flows of the [DistSQL execution](architecture/sql-layer.html#distsql) scheduled in your cluster. `cluster_inflight_traces` | Contains information about in-flight [tracing](show-trace.html) in your cluster. diff --git a/v21.2/delete-data.md b/v21.2/delete-data.md index cc60e93bb1e..1a11feda54a 100644 --- a/v21.2/delete-data.md +++ b/v21.2/delete-data.md @@ -238,7 +238,7 @@ Reference information related to this task: - [Disk space usage after deletes](delete.html#disk-space-usage-after-deletes) - [`TRUNCATE`](truncate.html) - [`DROP TABLE`](drop-table.html) -- [Understanding and Avoiding Transaction Contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) +- [Transaction Contention](performance-best-practices-overview.html#transaction-contention) Other common tasks: diff --git a/v21.2/developer-guide-overview.md b/v21.2/developer-guide-overview.md index fb35cc865c9..428ba745be1 100644 --- a/v21.2/developer-guide-overview.md +++ b/v21.2/developer-guide-overview.md @@ -37,7 +37,7 @@ Managing transactions is an important part of CockroachDB application developmen CockroachDB guarantees [`SERIALIZABLE`](https://en.wikipedia.org/wiki/Serializability) transaction [isolation](https://en.wikipedia.org/wiki/Isolation_(database_systems)) (the "I" of ACID semantics). If transactions are executed concurrently, the final state of the database will appear as if the transactions were executed serially. `SERIALIZABLE` isolation, the strictest level of isolation, provides the highest level of data consistency and protects against concurrency-based attacks and bugs. -To guarantee `SERIALIZABLE` isolation, CockroachDB locks the data targeted by an open transaction. If a separate transaction attempts to modify data that are locked by an open transaction, the newest transaction will not succeed, as committing it could result in a violation of the `SERIALIZABLE` isolation level. This scenario is called *transaction contention*, and should be avoided when possible. For a more detailed explanation of transaction contention, and tips on how to avoid it, see [Understand and Avoid Transaction Contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). +To guarantee `SERIALIZABLE` isolation, CockroachDB locks the data targeted by an open transaction. If a separate transaction attempts to modify data that are locked by an open transaction, the newest transaction will not succeed, as committing it could result in a violation of the `SERIALIZABLE` isolation level. This scenario is called *transaction contention*, and should be avoided when possible. For a more detailed explanation of transaction contention, and tips on how to avoid it, see [Understand and Avoid Transaction Contention](performance-best-practices-overview.html#transaction-contention). #### Transaction retries diff --git a/v21.2/error-handling-and-troubleshooting.md b/v21.2/error-handling-and-troubleshooting.md index 40f8c8adae0..312a4d4599b 100644 --- a/v21.2/error-handling-and-troubleshooting.md +++ b/v21.2/error-handling-and-troubleshooting.md @@ -24,7 +24,7 @@ If you aren't sure whether SQL query performance needs to be improved on your cl ## Transaction retry errors -Messages with the Postgres error code `40001` indicate that a transaction failed because it [conflicted with another concurrent or recent transaction accessing the same data](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). The transaction needs to be retried by the client. +Messages with the Postgres error code `40001` indicate that a transaction failed because it [conflicted with another concurrent or recent transaction accessing the same data](performance-best-practices-overview.html#transaction-contention). The transaction needs to be retried by the client. If your language's client driver or ORM implements transaction retry logic internally (e.g., if you are using Python and [SQLAlchemy with the CockroachDB dialect](build-a-python-app-with-cockroachdb-sqlalchemy.html)), then you do not need to handle this logic from your application. @@ -33,7 +33,7 @@ If your driver or ORM does not implement this logic, then you will need to imple {% include {{page.version.version}}/misc/client-side-intervention-example.md %} {{site.data.alerts.callout_info}} -If a consistently high percentage of your transactions are resulting in transaction retry errors, then you may need to evaluate your schema design and data access patterns to find and remove sources of contention. For more information about contention, see [Understanding and Avoiding Transaction Contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). +If a consistently high percentage of your transactions are resulting in transaction retry errors, then you may need to evaluate your schema design and data access patterns to find and remove sources of contention. For more information about contention, see [Transaction Contention](performance-best-practices-overview.html#transaction-contention). For more information about what is causing a specific transaction retry error code, see the [Transaction Retry Error Reference](transaction-retry-error-reference.html). {{site.data.alerts.end}} @@ -77,7 +77,7 @@ Reference information related to this page: - [Common errors](common-errors.html) - [Transactions](transactions.html) - [Transaction retries](transactions.html#client-side-intervention) -- [Understanding and Avoiding Transaction Contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) +- [Transaction Contention](performance-best-practices-overview.html#transaction-contention) - [SQL Layer][sql] Other common tasks: diff --git a/v21.2/flyway.md b/v21.2/flyway.md index fd02be2bfdf..9d8aabba431 100644 --- a/v21.2/flyway.md +++ b/v21.2/flyway.md @@ -163,7 +163,7 @@ When used with most databases, [Flyway wraps the statements in a migration withi ### Transaction retries -When multiple, concurrent transactions or statements are issued to a single CockroachDB cluster, [transaction contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) can cause schema migrations to fail. In the event of transaction contention, CockroachDB returns a `40001 SQLSTATE` (i.e., a serialization failure), and Flyway automatically retries the migration. For more information about client-side transaction retries in CockroachDB, see [Transaction Retries](transactions.html#transaction-retries). +When multiple, concurrent transactions or statements are issued to a single CockroachDB cluster, [transaction contention](performance-best-practices-overview.html#transaction-contention) can cause schema migrations to fail. In the event of transaction contention, CockroachDB returns a `40001 SQLSTATE` (i.e., a serialization failure), and Flyway automatically retries the migration. For more information about client-side transaction retries in CockroachDB, see [Transaction Retries](transactions.html#transaction-retries). ### Transactional schema changes diff --git a/v21.2/insert-data.md b/v21.2/insert-data.md index 6e1ab76ba88..89ca58734ab 100644 --- a/v21.2/insert-data.md +++ b/v21.2/insert-data.md @@ -114,7 +114,7 @@ Reference information related to this task: - [Import performance](import.html#performance) - [`INSERT`](insert.html) - [`UPSERT`](upsert.html) -- [Understanding and Avoiding Transaction Contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) +- [Transaction Contention](performance-best-practices-overview.html#transaction-contention) - [Multi-row DML best practices](performance-best-practices-overview.html#dml-best-practices) - [Insert Multiple Rows](insert.html#insert-multiple-rows-into-an-existing-table) diff --git a/v21.2/liquibase.md b/v21.2/liquibase.md index dd14f6a06d2..391025bdb50 100644 --- a/v21.2/liquibase.md +++ b/v21.2/liquibase.md @@ -487,7 +487,7 @@ If `runInTransaction="false"` for a changeset, and an error occurs while Liquid ### Transaction retries -When multiple, concurrent transactions or statements are issued to a single CockroachDB cluster, [transaction contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) can cause schema migrations to fail. In the event of transaction contention, CockroachDB returns a `40001 SQLSTATE` (i.e., a serialization failure). +When multiple, concurrent transactions or statements are issued to a single CockroachDB cluster, [transaction contention](performance-best-practices-overview.html#transaction-contention) can cause schema migrations to fail. In the event of transaction contention, CockroachDB returns a `40001 SQLSTATE` (i.e., a serialization failure). Liquibase does not automatically retry transactions. To handle transaction failures, we recommend writing client-side transaction retry logic. For more information about client-side transaction retries in CockroachDB, see [Transaction Retries](transactions.html#transaction-retries). diff --git a/v21.2/make-queries-fast.md b/v21.2/make-queries-fast.md index ec178e2c49c..d913b02c6ea 100644 --- a/v21.2/make-queries-fast.md +++ b/v21.2/make-queries-fast.md @@ -474,7 +474,7 @@ You can avoid contention with the following strategies: - Make transactions smaller by operating on less data per transaction. This will offer fewer opportunities for transactions' data access to overlap. - [Split the table across multiple ranges](split-at.html) to distribute its data across multiple nodes for better load balancing of some write-heavy workloads. -For more information about how to avoid performance problems caused by contention, see [Understanding and Avoiding Transaction Contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). +For more information about how to avoid performance problems caused by contention, see [Transaction Contention](performance-best-practices-overview.html#transaction-contention). ## Cluster topology @@ -491,7 +491,7 @@ Reference information: - [SQL Tuning with `EXPLAIN`](sql-tuning-with-explain.html) - [Joins](joins.html) - [CockroachDB Performance](performance.html) -- [Understanding and Avoiding Transaction Contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention) +- [Transaction Contention](performance-best-practices-overview.html#transaction-contention) - [Topology Patterns](topology-patterns.html) Specific tasks: diff --git a/v21.2/migrate-from-oracle.md b/v21.2/migrate-from-oracle.md index df586925f64..a0dd02a6f84 100644 --- a/v21.2/migrate-from-oracle.md +++ b/v21.2/migrate-from-oracle.md @@ -325,7 +325,7 @@ Both Oracle and CockroachDB support [multi-statement transactions](transactions. Regarding locks, Cockroach utilizes a [lightweight latch](architecture/transaction-layer.html#latch-manager) to serialize access to common keys across concurrent transactions. Oracle and CockroachDB transaction control flows only have a few minor differences; for more details, refer to [Transactions - SQL statements](transactions.html#sql-statements). -As CockroachDB does not allow serializable anomalies, [transactions](begin-transaction.html) may experience deadlocks or [read/write contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). This is expected during concurrency on the same keys. These can be addressed with either [automatic retries](transactions.html#automatic-retries) or [client-side intervention techniques](transactions.html#client-side-intervention). +As CockroachDB does not allow serializable anomalies, [transactions](begin-transaction.html) may experience deadlocks or [read/write contention](performance-best-practices-overview.html#transaction-contention). This is expected during concurrency on the same keys. These can be addressed with either [automatic retries](transactions.html#automatic-retries) or [client-side intervention techniques](transactions.html#client-side-intervention). ### SQL dialect diff --git a/v21.2/movr-flask-use-case.md b/v21.2/movr-flask-use-case.md index 4a691c73a27..bc60be8b0c6 100644 --- a/v21.2/movr-flask-use-case.md +++ b/v21.2/movr-flask-use-case.md @@ -25,7 +25,7 @@ In the [example deployment](movr-flask-deployment.html), the application and the If the MovR application and database are deployed in a single region, latency can become a serious problem when users are located in cities outside the deployment region. Deploying the application and database in multiple regions is not guaranteed to improve latency if client requests are sent to any regional deployment, without consideration for the client's location. -Limiting latency improves the user experience, and it can also help you avoid problems with data integrity, like [transaction contention](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). +Limiting latency improves the user experience, and it can also help you avoid problems with data integrity, like [transaction contention](performance-best-practices-overview.html#transaction-contention). For the purpose of this tutorial, we'll focus on two types of latency: diff --git a/v21.2/operational-faqs.md b/v21.2/operational-faqs.md index bae1eb42b39..3032ec81782 100644 --- a/v21.2/operational-faqs.md +++ b/v21.2/operational-faqs.md @@ -120,7 +120,7 @@ In addition to using ballast files, it is important to actively [monitor remaini If queries operate on different data, then increasing the number of nodes should improve the overall throughput (transactions/second or QPS). -However, if your queries operate on the same data, you may be observing transaction contention. For details, see [SQL Performance Best Practices](performance-best-practices-overview.html#understanding-and-avoiding-transaction-contention). +However, if your queries operate on the same data, you may be observing transaction contention. For details, see [SQL Performance Best Practices](performance-best-practices-overview.html#transaction-contention). ## Why does CockroachDB collect anonymized cluster usage details by default? diff --git a/v21.2/performance-best-practices-overview.md b/v21.2/performance-best-practices-overview.md index e31af9040a7..4c253f44240 100644 --- a/v21.2/performance-best-practices-overview.md +++ b/v21.2/performance-best-practices-overview.md @@ -323,42 +323,50 @@ If you have long-running queries (such as analytics queries that perform full ta However, because `AS OF SYSTEM TIME` returns historical data, your reads might be stale. -## Understanding and avoiding transaction contention +## Contention -Transaction contention occurs when the following three conditions are met: +There are two types of contention: -- There are multiple concurrent transactions or statements (sent by multiple clients connected simultaneously to a single CockroachDB cluster). -- They operate on the same data, specifically over table rows with the same index key values (either on [primary keys](primary-key.html) or secondary [indexes](indexes.html)) or using index key values that are close to each other, and thus place the indexed data on the same [data ranges](architecture/overview.html). -- At least one of the transactions modify the data. +- Transactions that operate on the same range but _different index key values_ will be limited by the overall hardware capacity of a single node (the range lease holder). This is referred to as _resource contention_. -A set of transactions that all contend on the same keys will be limited in performance to the maximum processing speed of a single node (limited horizontal scalability). Non-contended transactions are not affected in this way. +- Transactions that operate on the _same index key values_ (specifically, that operate on the same [column family](column-families.html) for a given index key) will be more strictly serialized to obey transaction isolation semantics. This is referred to as _transaction contention_ or _lock contention_. -There are two levels of contention: + Transaction contention can also increase the rate of transaction restarts, and thus make the proper implementation of [client-side transaction retries](transactions.html#client-side-intervention) more critical. -- Transactions that operate on the same range but different index key values will be limited by the overall hardware capacity of a single node (the range lease holder). +### Resource contention -- Transactions that operate on the same index key values (specifically, that operate on the same [column family](column-families.html) for a given index key) will be more strictly serialized to obey transaction isolation semantics. +Resource contention occurs when a range is indexed on a column of data that is sequential in nature such that all incoming writes to the range will be the last (or first) item in the index and appended to the end of the range. As a result, the system cannot find a point in the range that evenly divides the traffic, and the range cannot benefit from load-based splitting, creating a hotspot on the single range. -Transaction contention can also increase the rate of transaction restarts, and thus make the proper implementation of [client-side transaction retries](transactions.html#client-side-intervention) more critical. +To avoid resource contention, use index key values with a random distribution of values, so that transactions over different rows are more likely to operate on separate data ranges. See the [SQL FAQs](sql-faqs.html) on row IDs for suggestions. -### Find contention + -{% include {{ page.version.version }}/performance/statement-contention.md %} +### Transaction contention -### Avoid contention +Transaction contention occurs when the following three conditions are met: -To avoid contention, you can apply multiple strategies: +- There are multiple concurrent transactions or statements (sent by multiple clients connected simultaneously to a single CockroachDB cluster). +- They operate on the same data, specifically over table rows with the _same index key values_ (either on [primary keys](primary-key.html) or secondary [indexes](indexes.html)) or using index key values that are close to each other, and thus place the indexed data on the same [data ranges](architecture/overview.html). +- At least one of the transactions modify the data. -- Use index key values with a more random distribution of values, so that transactions over different rows are more likely to operate on separate data ranges. See the [SQL FAQs](sql-faqs.html) on row IDs for suggestions. +A set of transactions that all contend on the same keys will be limited in performance to the maximum processing speed of a single node (limited horizontal scalability). Non-contended transactions are not affected in this way. + +#### Find transaction contention + +{% include {{ page.version.version }}/performance/statement-contention.md %} -- Make transactions smaller, so that each transaction has less work to do. In particular, avoid multiple client-server exchanges per transaction. For example, use [common table expressions](common-table-expressions.html) to group multiple [`SELECT`](select-clause.html) and [`INSERT`](insert.html)/[`UPDATE`](update.html)/[`DELETE`](delete.html)/[`UPSERT`](upsert.html) clauses together in a single SQL statement. +#### Avoid transaction contention + +To avoid transaction contention: + +- Make transactions smaller, so that each transaction has less work to do. In particular, avoid multiple client-server exchanges per transaction. For example, use [common table expressions](common-table-expressions.html) to group multiple [`SELECT`](select-clause.html) and [`INSERT`](insert.html), [`UPDATE`](update.html), [`DELETE`](delete.html), and [`UPSERT`](upsert.html) clauses together in a single SQL statement. - For an example showing how to break up large transactions in an application, see [Break up large transactions into smaller units of work](build-a-python-app-with-cockroachdb-sqlalchemy.html#break-up-large-transactions-into-smaller-units-of-work). - If you are experiencing contention (retries) when doing bulk deletes, see [Bulk-delete data](bulk-delete-data.html). -- In combination with the above, if you are able to [send all of the statements in your transaction in a single batch](transactions.html#batched-statements), CockroachDB can automatically retry the transaction for you. +- [Send all of the statements in your transaction in a single batch](transactions.html#batched-statements) so that CockroachDB can automatically retry the transaction for you. -- Use the [`SELECT FOR UPDATE`](select-for-update.html) statement in scenarios where a transaction performs a read and then updates the row(s) it just read. It orders transactions by controlling concurrent access to one or more rows of a table. It works by locking the rows returned by a [selection query](selection-queries.html), such that other transactions trying to access those rows are forced to wait for the transaction that locked the rows to finish. These other transactions are effectively put into a queue that is ordered based on when they try to read the value of the locked row(s). +- Use the [`SELECT FOR UPDATE`](select-for-update.html) statement in scenarios where a transaction performs a read and then updates the row(s) it just read. The statement orders transactions by controlling concurrent access to one or more rows of a table. It works by locking the rows returned by a [selection query](selection-queries.html), such that other transactions trying to access those rows are forced to wait for the transaction that locked the rows to finish. These other transactions are effectively put into a queue that is ordered based on when they try to read the value of the locked row(s). - When replacing values in a row, use [`UPSERT`](upsert.html) and specify values for all columns in the inserted rows. This will usually have the best performance under contention, compared to combinations of [`SELECT`](select-clause.html), [`INSERT`](insert.html), and [`UPDATE`](update.html). @@ -366,6 +374,8 @@ To avoid contention, you can apply multiple strategies: - If the application strictly requires operating on very few different index key values, consider using [`ALTER ... SPLIT AT`](split-at.html) so that each index key value can be served by a separate group of nodes in the cluster. +### Maximize performance in the presence of contention + It is always best to avoid contention as much as possible via the design of the schema and application. However, sometimes contention is unavoidable. To maximize performance in the presence of contention, you'll need to maximize the performance of a single range. To achieve this, you can apply multiple strategies: - Minimize the network distance between the replicas of a range, possibly using zone configs and partitioning. diff --git a/v21.2/performance-recipes.md b/v21.2/performance-recipes.md index 849c0b7a152..63723443866 100644 --- a/v21.2/performance-recipes.md +++ b/v21.2/performance-recipes.md @@ -34,8 +34,8 @@ This section describes how to use CockroachDB commands and dashboards to identif
  • The SQL Statement Errors graph in the DB Console is showing spikes in retries over time.
  • - - + + - +