-
Notifications
You must be signed in to change notification settings - Fork 470
clarify isolation level upgrades #19490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACID) that determines how concurrency is controlled, and ultimately guarantees consistency. CockroachDB offers two transaction isolation levels: [`SERIALIZABLE`]({% link {{ page.version.version }}/demo-serializable.md %}) and [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}). For a demonstration of how `SERIALIZABLE` prevents write skew anomalies, see [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, refer to [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
|
||
{% include_cached new-in.html version="v23.2" %} CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and [retries]({% link {{ page.version.version }}/developer-basics.md %}#transaction-retries). Depending on your workload requirements, this may be desirable. For more information, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
{% include_cached new-in.html version="v23.2" %} CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` and `READ UNCOMMITTED` transactions no longer [upgrade to `SERIALIZABLE`]({% link {{ page.version.version }}/transactions.md %}#isolation-level-upgrades). `READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and [retries]({% link {{ page.version.version }}/developer-basics.md %}#transaction-retries). Depending on your workload requirements, this may be desirable. For more information, refer to [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
{% include {{ page.version.version }}/sql/mixed-isolation-levels.md %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACID) that determines how concurrency is controlled, and ultimately guarantees consistency. CockroachDB offers two transaction isolation levels: [`SERIALIZABLE`]({% link {{ page.version.version }}/demo-serializable.md %}) and [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, see [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, refer to [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
|
||
CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
`READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, refer to [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
{% include {{ page.version.version }}/sql/mixed-isolation-levels.md %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACID) that determines how concurrency is controlled, and ultimately guarantees consistency. CockroachDB offers two transaction isolation levels: [`SERIALIZABLE`]({% link {{ page.version.version }}/demo-serializable.md %}) and [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, see [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, refer to [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
|
||
CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
`READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, refer to [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
{% include {{ page.version.version }}/sql/mixed-isolation-levels.md %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACID) that determines how concurrency is controlled, and ultimately guarantees consistency. CockroachDB offers two transaction isolation levels: [`SERIALIZABLE`]({% link {{ page.version.version }}/demo-serializable.md %}) and [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, see [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, refer to [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
|
||
CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
`READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, refer to [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
{% include {{ page.version.version }}/sql/mixed-isolation-levels.md %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
Isolation is an element of [ACID transactions](https://en.wikipedia.org/wiki/ACID) that determines how concurrency is controlled, and ultimately guarantees consistency. CockroachDB offers two transaction isolation levels: [`SERIALIZABLE`]({% link {{ page.version.version }}/demo-serializable.md %}) and [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, see [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
By default, CockroachDB executes all transactions at the strongest ANSI transaction isolation level: `SERIALIZABLE`, which permits no concurrency anomalies. To place all transactions in a serializable ordering, `SERIALIZABLE` isolation may require [transaction restarts]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) and [client-side retry handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). For a demonstration of how `SERIALIZABLE` prevents anomalies such as write skew, refer to [Serializable Transactions]({% link {{ page.version.version }}/demo-serializable.md %}). | ||
|
||
CockroachDB can be configured to execute transactions at [`READ COMMITTED`]({% link {{ page.version.version }}/read-committed.md %}) instead of `SERIALIZABLE` isolation. If [enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation), `READ COMMITTED` is no longer an alias for `SERIALIZABLE` . `READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, see [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
`READ COMMITTED` permits some concurrency anomalies in exchange for minimizing transaction aborts and removing the need for client-side retries. Depending on your workload requirements, this may be desirable. For more information, refer to [Read Committed Transactions]({% link {{ page.version.version }}/read-committed.md %}). | ||
|
||
{% include {{ page.version.version }}/sql/mixed-isolation-levels.md %} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -206,23 +206,37 @@ To view the current priority of a transaction, use `SHOW transaction_priority` o | |
|
||
{% include {{ page.version.version }}/sql/isolation-levels.md %} | ||
|
||
### Comparison to ANSI SQL isolation levels | ||
### Isolation level upgrades | ||
|
||
CockroachDB uses slightly different isolation levels than [ANSI SQL isolation levels](https://wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels). | ||
By default, CockroachDB executes all transactions at `SERIALIZABLE` isolation. Under certain conditions, transactions issued at weaker isolation levels are automatically upgraded to stronger isolation levels. | ||
|
||
If `sql.txn.read_committed_isolation.enabled` is set to `true` ([enabling `READ COMMITTED` isolation]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation)): | ||
|
||
#### Aliases | ||
| Isolation level | Upgrades to | | ||
|--------------------|------------------| | ||
| `READ UNCOMMITTED` | `READ COMMITTED` | | ||
| `READ COMMITTED` | -- | | ||
| `REPEATABLE READ` | `SNAPSHOT` | | ||
| `SNAPSHOT` | `SERIALIZABLE` | | ||
| `SERIALIZABLE` | -- | | ||
|
||
`SNAPSHOT`, `READ UNCOMMITTED`, `READ COMMITTED`, and `REPEATABLE READ` are aliases for `SERIALIZABLE`. | ||
{{site.data.alerts.callout_info}} | ||
In this configuration, `REPEATABLE READ` effectively upgrades to `SERIALIZABLE`. | ||
{{site.data.alerts.end}} | ||
|
||
{% include_cached new-in.html version="v23.2" %} If [`READ COMMITTED` isolation is enabled]({% link {{ page.version.version }}/read-committed.md %}#enable-read-committed-isolation) using the `sql.txn.read_committed_isolation.enabled` [cluster setting]({% link {{ page.version.version }}/cluster-settings.md %}), `READ COMMITTED` is no longer an alias for `SERIALIZABLE`, and `READ UNCOMMITTED` becomes an alias for `READ COMMITTED`. | ||
If `sql.txn.read_committed_isolation.enabled` is set to `false` (disabling `READ COMMITTED` isolation), all isolation levels upgrade to `SERIALIZABLE`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion: It might be clearer to make "transactions" the subject of the sentence rather than "isolation levels", something like:
|
||
|
||
#### Comparison | ||
If a transaction includes [DDL]({% link {{ page.version.version }}/sql-statements.md %}#data-definition-statements) or [`AOST`]({% link {{ page.version.version }}/as-of-system-time.md %}) statements, all isolation levels upgrade to `SERIALIZABLE`. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I played around with this a bit, and I think we should not say anything about AOST. I believe the upgrade to serializable behavior for AOST transactions happens entirely in the KV layer. The SQL layer still considers AOST transactions to have read committed isolation, so it probably just confuses things to say they're upgraded. @rafiss is this correct about DDL? Do we silently commit the transaction and start a new one for DDL? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with not mentioning AOST here. As for DDL, yes that's correct, we will upgrade the transaction to SERIALIZABLE if possible -- meaning as long as the transaction hasn't performed any work yet, it will be upgraded. (https://github.com/cockroachdb/cockroach/blob/3acb6e287300ad4df232e2e4028af2f2435c5220/pkg/sql/conn_executor_ddl.go#L76) Let's not mention autocommit behavior around DDLs here though. That's a separate piece of functionality, controlled by the autocommit_before_ddl setting. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks both for clarifying these points. I'm just going to avoid talking about AOST and DDL txns altogether, since we have this open issue that could update the behavior again at some point. |
||
|
||
### Comparison to ANSI SQL isolation levels | ||
|
||
CockroachDB uses slightly different isolation levels than [ANSI SQL isolation levels](https://wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels). | ||
|
||
The CockroachDB `SERIALIZABLE` isolation level is stronger than the ANSI SQL `READ UNCOMMITTED`, `READ COMMITTED`, and `REPEATABLE READ` levels and equivalent to the ANSI SQL `SERIALIZABLE` level. | ||
The CockroachDB `SERIALIZABLE` isolation level is stronger than the ANSI SQL `READ UNCOMMITTED`, `READ COMMITTED`, and `REPEATABLE READ` levels, as well as the `SNAPSHOT` level. It is equivalent to the ANSI SQL `SERIALIZABLE` level. | ||
|
||
The CockroachDB `READ COMMITTED` isolation level is stronger than the PostgreSQL `READ COMMITTED` isolation level, and is the strongest isolation level that does not experience [serialization errors]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}) that require [client-side handling]({% link {{ page.version.version }}/transaction-retry-error-reference.md %}#client-side-retry-handling). | ||
|
||
For more information about the relationship between these levels, see [A Critique of ANSI SQL Isolation Levels](https://arxiv.org/ftp/cs/papers/0701/0701157.pdf). | ||
For more information about the relationship between these levels, read [A Critique of ANSI SQL Isolation Levels](https://arxiv.org/ftp/cs/papers/0701/0701157.pdf). | ||
|
||
## Limit the number of rows written or read in a transaction | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Sorry, this is bikeshedding, you can ignore this comment unless you feel convinced 🙂.)
This table isn't incorrect, but IMO the REPEATABLE READ -> SNAPSHOT -> SERIALIZABLE upgrade chain idea is a little confusing and puts more emphasis on "upgrades" than I think they're worth.
If I were writing this I think I would say first (or last) that READ UNCOMMITTED is an alias for READ COMMITTED and REPEATABLE READ is an alias for SNAPSHOT and then I wouldn't mention those levels again. And then I would only describe the upgrades in terms of READ COMMITTED, SNAPSHOT, and SERIALIZABLE, which are the three "real" isolation levels we support. I think that would put the emphasis in the right place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this! The reason I thought to highlight
READ UNCOMMITTED
as an 'upgrade' toREAD COMMITTED
is because the Upgrades to SQL Isolation Level chart seems to track that exact 'upgrade,' which became part of a customer issue recently. That's why I've been confused about "alias" vs "upgrade". cc @rafissThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, thanks for explaining. Now I understand.
From some experimentation, looks like:
So I guess only REPEATABLE READ could be considered an alias for SNAPSHOT, and the rest are upgrades?
Here's how I figured that out:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1, let's treat READ UNCOMMITTED -> READ COMMITTED as an upgrade of the isolation level, since they are clearly defined as different levels in PG docs and in the SQL standard.
And also +1 to treating SNAPSHOT and REPEATABLE READ as pure aliases of each other. However, the caveat with this is that this isolation level is not enabled by default. It's gated behind the cluster setting
sql.txn.repeatable_read_isolation.enabled
, which defaults to false (and this setting also has an aliassql.txn.snapshot_isolation.enabled
). I'm just pointing this out in case we want to mention that setting here.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops, i see the setting is mentioned already. lgtm!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nevermind, i got myself confused again. the current PR mentions
sql.txn.read_committed_isolation.enabled
which is true by default, but notsql.txn.repeatable_read_isolation.enabled
which is false by default. given that we don't really mention repeatable read anywhere else in the docs, i'm not really sure how we want to discuss it here. i recall @dikshant mentioning he wanted to wait a bit before advertising that we support it (https://cockroachlabs.slack.com/archives/C051DMXEGMV/p1733255496192269?thread_ts=1733251940.956479&cid=C051DMXEGMV)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense -- I'm removing the row with
REPEATABLE READ
but leaving the one withSNAPSHOT
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of the product decision to not mention
REPEATABLE READ
here, the same concerns would apply to mentioningSNAPSHOT
. The usage of either of them is gated behind thesql.txn.repeatable_read_isolation.enabled
/sql.txn.snapshot_isolation.enabled
cluster setting, which are aliases of each other.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, got it! Amending.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Yeah good to leave out repeatable read for now.