From 3953ca11958f277dacbb8468dce2e9f2499b890f Mon Sep 17 00:00:00 2001 From: Ryan Kuo Date: Tue, 29 Jul 2025 14:20:29 -0400 Subject: [PATCH 1/3] FK-based region-column inference --- .../v25.3/misc/table-storage-parameters.md | 17 +- .../sql/regional-by-row-table-description.md | 18 +- src/current/v25.3/alter-table.md | 173 ++++++++++++++++++ src/current/v25.3/foreign-key.md | 5 +- 4 files changed, 195 insertions(+), 18 deletions(-) diff --git a/src/current/_includes/v25.3/misc/table-storage-parameters.md b/src/current/_includes/v25.3/misc/table-storage-parameters.md index 3ca7f601648..4bc63d288cb 100644 --- a/src/current/_includes/v25.3/misc/table-storage-parameters.md +++ b/src/current/_includes/v25.3/misc/table-storage-parameters.md @@ -1,11 +1,12 @@ -| Parameter name | Description | Data type | Default value | -|------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------|-----------|---------------| -| `exclude_data_from_backup` | Exclude the data in this table from any future backups. | Boolean | `false` | -| `schema_locked` | Disallow [schema changes]({% link {{ page.version.version }}/online-schema-changes.md %}) on this table. Enabling `schema_locked` can help [improve performance of changefeeds]({% link {{ page.version.version }}/create-changefeed.md %}#disallow-schema-changes-on-tables-to-improve-changefeed-performance) running on this table. | Boolean | `false` | -| `sql_stats_automatic_collection_enabled` | Enable [automatic statistics collection]({% link {{ page.version.version }}/cost-based-optimizer.md %}#enable-and-disable-automatic-statistics-collection-for-tables) for this table. | Boolean | `true` | -| `sql_stats_automatic_collection_min_stale_rows` | Minimum number of stale rows in this table that will trigger a statistics refresh. | Integer | 500 | -| `sql_stats_automatic_collection_fraction_stale_rows` | Fraction of stale rows in this table that will trigger a statistics refresh. | Float | 0.2 | -| `sql_stats_forecasts_enabled` | Enable [forecasted statistics]({% link {{ page.version.version }}/show-statistics.md %}#display-forecasted-statistics) collection for this table. | Boolean | `true` | +| Parameter name | Description | Data type | Default value | +|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|---------------| +| `exclude_data_from_backup` | Exclude the data in this table from any future backups. | Boolean | `false` | +| `schema_locked` | Disallow [schema changes]({% link {{ page.version.version }}/online-schema-changes.md %}) on this table. Enabling `schema_locked` can help [improve performance of changefeeds]({% link {{ page.version.version }}/create-changefeed.md %}#disallow-schema-changes-on-tables-to-improve-changefeed-performance) running on this table. | Boolean | `false` | +| `sql_stats_automatic_collection_enabled` | Enable [automatic statistics collection]({% link {{ page.version.version }}/cost-based-optimizer.md %}#enable-and-disable-automatic-statistics-collection-for-tables) for this table. | Boolean | `true` | +| `sql_stats_automatic_collection_min_stale_rows` | Minimum number of stale rows in this table that will trigger a statistics refresh. | Integer | 500 | +| `sql_stats_automatic_collection_fraction_stale_rows` | Fraction of stale rows in this table that will trigger a statistics refresh. | Float | 0.2 | +| `sql_stats_forecasts_enabled` | Enable [forecasted statistics]({% link {{ page.version.version }}/show-statistics.md %}#display-forecasted-statistics) collection for this table. | Boolean | `true` | +| `infer_rbr_region_col_using_constraint` | **New in v25.3:** For [`REGIONAL BY ROW`]({% link {{ page.version.version }}/table-localities.md %}#regional-by-row-tables) tables, automatically populate the hidden `crdb_region` column on `INSERT`, `UPDATE`, and `UPSERT` by looking up the region of the referenced parent row. Set this parameter to the name of a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) constraint on the table that includes the `crdb_region` column. The foreign key cannot be dropped while the parameter is set. | String | `NULL` | The following parameters are included for PostgreSQL compatibility and do not affect how CockroachDB runs: diff --git a/src/current/_includes/v25.3/sql/regional-by-row-table-description.md b/src/current/_includes/v25.3/sql/regional-by-row-table-description.md index 6483294d044..2d022b9f5e9 100644 --- a/src/current/_includes/v25.3/sql/regional-by-row-table-description.md +++ b/src/current/_includes/v25.3/sql/regional-by-row-table-description.md @@ -1,16 +1,20 @@ -In a _regional by row_ table, individual rows are optimized for access from different home regions. Each row's home region is specified in a hidden [`crdb_region` column]({% link {{ page.version.version }}/alter-table.md %}#crdb_region), and is by default the region of the [gateway node]({% link {{ page.version.version }}/architecture/life-of-a-distributed-transaction.md %}#gateway) from which the row is inserted. The `REGIONAL BY ROW` setting automatically divides a table and all of [its indexes]({% link {{ page.version.version }}/table-localities.md %}#indexes-on-regional-by-row-tables) into [partitions]({% link {{ page.version.version }}/partitioning.md %}) that use `crdb_region` as the prefix. +In a _regional by row_ table, each row is optimized for access from a specific home region. Each row's home region is specified in a hidden [`crdb_region` column]({% link {{ page.version.version }}/alter-table.md %}#crdb_region), which defaults to the region of the [gateway node]({% link {{ page.version.version }}/architecture/life-of-a-distributed-transaction.md %}#gateway) that inserted the row. The `REGIONAL BY ROW` setting automatically [partitions]({% link {{ page.version.version }}/partitioning.md %}) the table and all of [its indexes]({% link {{ page.version.version }}/table-localities.md %}#indexes-on-regional-by-row-tables) by region using `crdb_region` as the partition key prefix. -Use regional by row tables when your application requires low-latency reads and writes at a row level where individual rows are primarily accessed from a single region. For an example of a table in a multi-region cluster that can benefit from the `REGIONAL BY ROW` setting, see the `users` table from the [MovR application]({% link {{ page.version.version }}/movr.md %}), which could store users' data in specific regions for better performance. +Use regional by row tables when individual rows are frequently accessed from a single region, and your application requires low-latency reads and writes at the row level. A typical `REGIONAL BY ROW` use case is the `users` table in the [MovR application]({% link {{ page.version.version }}/movr.md %}), where user data can be co-located with the user's region for better performance. -To take advantage of regional by row tables: +{% include_cached new-in.html version="v25.3" %} CockroachDB can also infer a row's home region from a foreign key constraint. By enabling the cluster setting [`feature.infer_rbr_region_col_using_constraint.enabled`]({% link {{ page.version.version }}/cluster-settings.md %}#setting-feature-infer-rbr-region-col-using-constraint-enabled) and setting the table storage parameter [`infer_rbr_region_col_using_constraint`]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters) to a foreign key constraint that references a `crdb_region` column, CockroachDB automatically assigns the appropriate region for `INSERT`, `UPDATE`, and `UPSERT` statements. It does this by performing a locality-optimized lookup join on the referenced row and copying its region value. {% include feature-phases/preview.md %} -- Use unique key lookups or queries with [`LIMIT`]({% link {{ page.version.version }}/limit-offset.md %}) clauses to enable [locality optimized searches]({% link {{ page.version.version }}/cost-based-optimizer.md %}#locality-optimized-search-in-multi-region-clusters) that prioritize rows in the gateway node's region. If there is a possibility that the results of the query all live in local rows, CockroachDB will first search for rows in the gateway node's region. The search only continues in remote regions if rows in the local region did not satisfy the query. +To take full advantage of regional by row tables: -- Use [foreign keys]({% link {{ page.version.version }}/foreign-key.md %}#rules-for-creating-foreign-keys) that reference the [`crdb_region` column]({% link {{ page.version.version }}/alter-table.md %}#crdb_region) in [`REGIONAL BY ROW`]({% link {{ page.version.version }}/table-localities.md %}#regional-by-row-tables) tables, unless [auto-rehoming is enabled]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables) for those tables. +- Use unique key lookups or queries with [`LIMIT`]({% link {{ page.version.version }}/limit-offset.md %}) to enable [locality-optimized searches]({% link {{ page.version.version }}/cost-based-optimizer.md %}#locality-optimized-search-in-multi-region-clusters) that prioritize rows in the gateway node's region. If the query can be satisfied by rows in the gateway region, CockroachDB will avoid remote lookups. -- [Turn on auto-rehoming for regional by row tables]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables). A row's home region will be automatically set to the gateway region of any [`UPDATE`]({% link {{ page.version.version }}/update.md %}) or [`UPSERT`]({% link {{ page.version.version }}/upsert.md %}) statements that write to those rows. +- Choose a home-region strategy per table: -For instructions showing how to set a table's locality to `REGIONAL BY ROW` and configure the home regions of its rows, see [`ALTER TABLE ... SET LOCALITY`]({% link {{ page.version.version }}/alter-table.md %}#crdb_region). + - When inserting or updating rows that reference a `REGIONAL BY ROW` table via a foreign key, enable region inference by setting [`infer_rbr_region_col_using_constraint`]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters). This ensures that [`INSERT`]({% link {{ page.version.version }}/insert.md %}), [`UPDATE`]({% link {{ page.version.version }}/update.md %}), and [`UPSERT`]({% link {{ page.version.version }}/upsert.md %}) queries do not need to specify `crdb_region` to ensure that writes are placed in the same region as the referenced row. This requires **disabling** auto-rehoming. For an example, refer to the [`ALTER TABLE` documentation]({% link {{ page.version.version }}/alter-table.md %}#infer-a-rows-home-region-from-a-foreign-key). + + - When rows should move to the region of the latest writer, enable [auto-rehoming]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables). On any [`UPDATE`]({% link {{ page.version.version }}/update.md %}) or [`UPSERT`]({% link {{ page.version.version }}/upsert.md %}), CockroachDB automatically updates the row's `crdb_region` to match the gateway node's region. Auto-rehoming **cannot** be used on tables that are referenced by foreign keys. For an example, refer to the [`ALTER TABLE` documentation]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables). + +For instructions showing how to set a table's locality to `REGIONAL BY ROW` and configure the home regions of its rows, refer to [`ALTER TABLE ... SET LOCALITY`]({% link {{ page.version.version }}/alter-table.md %}#crdb_region). For more information on regional by row tables, see the [Cockroach Labs blog post](https://www.cockroachlabs.com/blog/regional-by-row/). diff --git a/src/current/v25.3/alter-table.md b/src/current/v25.3/alter-table.md index b2dd4c6a65f..313dcf6daf4 100644 --- a/src/current/v25.3/alter-table.md +++ b/src/current/v25.3/alter-table.md @@ -2571,6 +2571,10 @@ SELECT crdb_region, id FROM {table}; UPDATE {table} SET crdb_region = 'eu-west' WHERE id IN (...) ~~~ +{{site.data.alerts.callout_success}} +{% include_cached new-in.html version="v25.3" %} CockroachDB can also [infer a row's home region from a foreign key constraint](#infer-a-rows-home-region-from-a-foreign-key). +{{site.data.alerts.end}} + To add a new row to a regional by row table, you must choose one of the following options. - Let CockroachDB set the row's home region automatically. It will use the region of the [gateway node]({% link {{ page.version.version }}/architecture/life-of-a-distributed-transaction.md %}#gateway) from which the row is inserted. @@ -2614,6 +2618,170 @@ ALTER TABLE rides ADD COLUMN region crdb_internal_region AS ( {% include {{page.version.version}}/sql/locality-optimized-search.md %} +#### Infer a row's home region from a foreign key + +{{site.data.alerts.callout_info}} +{% include feature-phases/preview.md %} +{{site.data.alerts.end}} + +The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters) lets a `REGIONAL BY ROW` child table automatically set the hidden `crdb_region` column by looking up the referenced parent row. The parameter must be set to the name of a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) constraint on the child table that includes the `crdb_region` column. + +{{site.data.alerts.callout_info}} +`infer_rbr_region_col_using_constraint` and [auto-rehoming](#turn-on-auto-rehoming-for-regional-by-row-tables) are mutually exclusive. Enable one mode per `REGIONAL BY ROW` table, not both. +{{site.data.alerts.end}} + +1. Start a [multi-node, multi-region `cockroach demo` cluster]({% link {{ page.version.version }}/cockroach-demo.md %}): + + {% include_cached copy-clipboard.html %} + ~~~ shell + cockroach demo --global --nodes 9 --insecure + ~~~ + + The command opens an interactive SQL shell connected to the temporary, in-memory cluster that is running with three simulated regions. + +1. In the SQL shell, create a multi-region `demo` database: + + {% include_cached copy-clipboard.html %} + ~~~ sql + CREATE DATABASE demo PRIMARY REGION "us-east1" REGIONS "us-west1", "europe-west1"; + USE demo; + ~~~ + +1. Verify the regions that are available to the `demo` database: + + {% include_cached copy-clipboard.html %} + ~~~ sql + SHOW REGIONS FROM DATABASE demo; + ~~~ + + ~~~ + database | region | primary | secondary | zones + -----------+--------------+---------+-----------+---------- + demo | us-east1 | t | f | {b,c,d} + demo | europe-west1 | f | f | {b,c,d} + demo | us-west1 | f | f | {a,b,c} + (3 rows) + ~~~ + +1. Enable the cluster setting to use `infer_rbr_region_col_using_constraint`: + + {% include_cached copy-clipboard.html %} + ~~~ sql + SET CLUSTER SETTING feature.infer_rbr_region_col_using_constraint.enabled = true; + ~~~ + +1. Create a `parent` table that is `REGIONAL BY ROW`: + + {% include_cached copy-clipboard.html %} + ~~~ sql + CREATE TABLE parent ( + id INT PRIMARY KEY, + data TEXT + ) LOCALITY REGIONAL BY ROW; + ~~~ + +1. Create a `child` table whose rows should live in the same region as their parent rows. The table's foreign key includes `crdb_region`, and the `infer_rbr_region_col_using_constraint` parameter is set to the name of the foreign key (`fk_parent`): + + {% include_cached copy-clipboard.html %} + ~~~ sql + CREATE TABLE child ( + id INT PRIMARY KEY, + parent_id INT, + info TEXT, + CONSTRAINT fk_parent FOREIGN KEY (crdb_region, parent_id) REFERENCES parent (crdb_region, id) + ) WITH (infer_rbr_region_col_using_constraint = 'fk_parent') + LOCALITY REGIONAL BY ROW; + ~~~ + +1. Insert a row into `parent` that lives in the primary region (`us-east1`): + + {% include_cached copy-clipboard.html %} + ~~~ sql + INSERT INTO parent (id, data, crdb_region) VALUES (1, 'east row', 'us-east1'); + ~~~ + +1. Run the following command to view information about all 9 nodes in the cluster: + + {% include_cached copy-clipboard.html %} + ~~~ + \demo ls + ~~~ + + ~~~ + node 1: + (webui) http://127.0.0.1:8080 + + Application tenant: + (cli) cockroach sql --insecure -d cluster:demoapp/movr + (sql) postgresql://root@127.0.0.1:26257/movr?options=-ccluster%3Ddemoapp&sslmode=disable + (sql/jdbc) jdbc:postgresql://127.0.0.1:26257/movr?options=-ccluster%3Ddemoapp&sslmode=disable&user=root + (sql/unix) postgresql://root:unused@/defaultdb?host=%2FUsers%2Fryankuo%2F.cockroach-demo&options=-ccluster%3Ddemoapp&port=26257 + (rpc) 127.0.0.1:26357 + + ... + + node 9: + (webui) http://127.0.0.1:8088 + + Application tenant: + (cli) cockroach sql --insecure -p 26265 -d cluster:demoapp/movr + (sql) postgresql://root@127.0.0.1:26265/movr?options=-ccluster%3Ddemoapp&sslmode=disable + (sql/jdbc) jdbc:postgresql://127.0.0.1:26265/movr?options=-ccluster%3Ddemoapp&sslmode=disable&user=root + (sql/unix) postgresql://root:unused@/defaultdb?host=%2FUsers%2Fryankuo%2F.cockroach-demo&options=-ccluster%3Ddemoapp&port=26265 + (rpc) 127.0.0.1:26365 + ~~~ + +1. In a new terminal, connect to a node in a non-primary region (i.e., `us-west1` or `europe-west1`). This should be one of nodes 4-9. The following example connects to node 9: + + {% include_cached copy-clipboard.html %} + ~~~ shell + cockroach sql --insecure -p 26265 -d cluster:demoapp/demo + ~~~ + + {{site.data.alerts.callout_success}} + You can use the [**Network Latency** Page]({% link {{ page.version.version }}/ui-network-latency-page.md %}) in the DB Console to cross-reference nodes and their regions. Open any of the `webui` URLs in the preceding step's output. + {{site.data.alerts.end}} + +1. Verify that node 9 is in a non-primary region: + + {% include_cached copy-clipboard.html %} + ~~~ sql + SHOW LOCALITY; + ~~~ + + ~~~ + locality + ---------------------------- + region=europe-west1,az=d + ~~~ + +1. Insert a row into the `child` table from node 9: + + {% include_cached copy-clipboard.html %} + ~~~ sql + INSERT INTO child (id, parent_id, info) VALUES (10, 1, 'west gateway'); + ~~~ + +1. View the value of the hidden `crdb_region` column. Even though the row was inserted from the `europe-west1` gateway region, CockroachDB uses the `fk_parent` constraint to look up and copy the parent row's region (`us-east1`) into the child row: + + {% include_cached copy-clipboard.html %} + ~~~ sql + SELECT id, parent_id, crdb_region FROM child; + ~~~ + + ~~~ + id | parent_id | crdb_region + -----+-----------+-------------- + 10 | 1 | us-east1 + ~~~ + +1. If you later need to disable the behavior, reset the storage parameter: + + {% include_cached copy-clipboard.html %} + ~~~ sql + ALTER TABLE child RESET (infer_rbr_region_col_using_constraint); + ~~~ + #### Turn on auto-rehoming for `REGIONAL BY ROW` tables {{site.data.alerts.callout_info}} @@ -2635,6 +2803,7 @@ Once enabled, the auto-rehoming behavior described here has the following limita - It **will only apply to newly created `REGIONAL BY ROW` tables**, using an `ON UPDATE` expression that is added to the [`crdb_region`](#crdb_region) column. Existing `REGIONAL BY ROW` tables will not be auto-rehomed. - The [`crdb_region`](#crdb_region) column from a [`REGIONAL BY ROW`](#set-the-table-locality-to-regional-by-row) table cannot be referenced as a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) from another table. +- Auto-rehoming **cannot** be combined with the [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters), which requires `crdb_region` to participate in a foreign key and therefore remain stable. To enable auto-rehoming for an existing `REGIONAL BY ROW` table, manually update it using an [`ALTER TABLE ... ALTER COLUMN`](#alter-column) statement with an `ON UPDATE` expression: @@ -2643,6 +2812,10 @@ To enable auto-rehoming for an existing `REGIONAL BY ROW` table, manually update ALTER TABLE {table} ALTER COLUMN crdb_region SET ON UPDATE rehome_row()::db.public.crdb_internal_region; ~~~ +{{site.data.alerts.callout_info}} +[`infer_rbr_region_col_using_constraint`](#infer-a-rows-home-region-from-a-foreign-key) and auto-rehoming are mutually exclusive. Enable one mode per `REGIONAL BY ROW` table, not both. +{{site.data.alerts.end}} + ##### Example 1. Follow steps 1 and 2 from the [Low Latency Reads and Writes in a Multi-Region Cluster]({% link {{ page.version.version }}/demo-low-latency-multi-region-deployment.md %}) tutorial. This will involve starting a [`cockroach demo`]({% link {{ page.version.version }}/cockroach-demo.md %}) cluster in a terminal window (call it _terminal 1_). diff --git a/src/current/v25.3/foreign-key.md b/src/current/v25.3/foreign-key.md index 55677511e3d..88a094b2a74 100644 --- a/src/current/v25.3/foreign-key.md +++ b/src/current/v25.3/foreign-key.md @@ -30,10 +30,9 @@ To read more about how foreign keys work, see our [What is a Foreign Key? (With - A foreign key column cannot be a virtual [computed column]({% link {{ page.version.version }}/computed-columns.md %}), but it can be a stored computed column. - A single column can have multiple foreign key constraints. For an example, see [Add multiple foreign key constraints to a single column](#add-multiple-foreign-key-constraints-to-a-single-column). - A foreign key column can reference the [`crdb_region` column]({% link {{ page.version.version }}/alter-table.md %}#crdb_region) in [`REGIONAL BY ROW`]({% link {{ page.version.version }}/table-localities.md %}#regional-by-row-tables) tables even if the `crdb_region` column is not explicitly part of a `UNIQUE` constraint. This is possible because `crdb_region` is implicitly included in every index on `REGIONAL BY ROW` tables as the partitioning key. This applies to whichever column is used as the partitioning column, in case a different name is used via `REGIONAL BY ROW AS`. + - {% include_cached new-in.html version="v25.3" %} If [region inference is enabled]({% link {{ page.version.version }}/alter-table.md %}#infer-a-rows-home-region-from-a-foreign-key) on a `REGIONAL BY ROW` table, the foreign key specified in [`infer_rbr_region_col_using_constraint`]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters) **must** include the `crdb_region` column. CockroachDB uses the foreign key to look up the matching row in the parent and copy its region value, ensuring the child row is placed in the same region as the parent. - {{site.data.alerts.callout_info}} - A foreign key column cannot reference a table's `crdb_region` column if [auto-rehoming is enabled]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables) for the table. - {{site.data.alerts.end}} + - If [auto-rehoming is enabled]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables) on a `REGIONAL BY ROW` table, a foreign key column **cannot** reference that table's `crdb_region` column. This is because auto-rehoming may move rows across regions and violate locality guarantees for referencing rows. **Referenced Columns** From f2a60c841fc97ebb088a6126cee58af3e0c53a15 Mon Sep 17 00:00:00 2001 From: Ryan Kuo Date: Fri, 1 Aug 2025 10:53:33 -0400 Subject: [PATCH 2/3] review edits, revert RBR section --- .../sql/regional-by-row-table-description.md | 12 ++---- src/current/v25.3/alter-table.md | 39 ++++++++----------- 2 files changed, 20 insertions(+), 31 deletions(-) diff --git a/src/current/_includes/v25.3/sql/regional-by-row-table-description.md b/src/current/_includes/v25.3/sql/regional-by-row-table-description.md index 2d022b9f5e9..7f47a210bd6 100644 --- a/src/current/_includes/v25.3/sql/regional-by-row-table-description.md +++ b/src/current/_includes/v25.3/sql/regional-by-row-table-description.md @@ -2,17 +2,13 @@ In a _regional by row_ table, each row is optimized for access from a specific h Use regional by row tables when individual rows are frequently accessed from a single region, and your application requires low-latency reads and writes at the row level. A typical `REGIONAL BY ROW` use case is the `users` table in the [MovR application]({% link {{ page.version.version }}/movr.md %}), where user data can be co-located with the user's region for better performance. -{% include_cached new-in.html version="v25.3" %} CockroachDB can also infer a row's home region from a foreign key constraint. By enabling the cluster setting [`feature.infer_rbr_region_col_using_constraint.enabled`]({% link {{ page.version.version }}/cluster-settings.md %}#setting-feature-infer-rbr-region-col-using-constraint-enabled) and setting the table storage parameter [`infer_rbr_region_col_using_constraint`]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters) to a foreign key constraint that references a `crdb_region` column, CockroachDB automatically assigns the appropriate region for `INSERT`, `UPDATE`, and `UPSERT` statements. It does this by performing a locality-optimized lookup join on the referenced row and copying its region value. {% include feature-phases/preview.md %} +To take advantage of regional by row tables: -To take full advantage of regional by row tables: +- Use unique key lookups or queries with [`LIMIT`]({% link {{ page.version.version }}/limit-offset.md %}) clauses to enable [locality optimized searches]({% link {{ page.version.version }}/cost-based-optimizer.md %}#locality-optimized-search-in-multi-region-clusters) that prioritize rows in the gateway node's region. If there is a possibility that the results of the query all live in local rows, CockroachDB will first search for rows in the gateway node's region. The search only continues in remote regions if rows in the local region did not satisfy the query. -- Use unique key lookups or queries with [`LIMIT`]({% link {{ page.version.version }}/limit-offset.md %}) to enable [locality-optimized searches]({% link {{ page.version.version }}/cost-based-optimizer.md %}#locality-optimized-search-in-multi-region-clusters) that prioritize rows in the gateway node's region. If the query can be satisfied by rows in the gateway region, CockroachDB will avoid remote lookups. +- Use [foreign keys]({% link {{ page.version.version }}/foreign-key.md %}#rules-for-creating-foreign-keys) that reference the [`crdb_region` column]({% link {{ page.version.version }}/alter-table.md %}#crdb_region) in [`REGIONAL BY ROW`]({% link {{ page.version.version }}/table-localities.md %}#regional-by-row-tables) tables, unless [auto-rehoming is enabled]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables) for those tables. -- Choose a home-region strategy per table: - - - When inserting or updating rows that reference a `REGIONAL BY ROW` table via a foreign key, enable region inference by setting [`infer_rbr_region_col_using_constraint`]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters). This ensures that [`INSERT`]({% link {{ page.version.version }}/insert.md %}), [`UPDATE`]({% link {{ page.version.version }}/update.md %}), and [`UPSERT`]({% link {{ page.version.version }}/upsert.md %}) queries do not need to specify `crdb_region` to ensure that writes are placed in the same region as the referenced row. This requires **disabling** auto-rehoming. For an example, refer to the [`ALTER TABLE` documentation]({% link {{ page.version.version }}/alter-table.md %}#infer-a-rows-home-region-from-a-foreign-key). - - - When rows should move to the region of the latest writer, enable [auto-rehoming]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables). On any [`UPDATE`]({% link {{ page.version.version }}/update.md %}) or [`UPSERT`]({% link {{ page.version.version }}/upsert.md %}), CockroachDB automatically updates the row's `crdb_region` to match the gateway node's region. Auto-rehoming **cannot** be used on tables that are referenced by foreign keys. For an example, refer to the [`ALTER TABLE` documentation]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables). +- [Turn on auto-rehoming for regional by row tables]({% link {{ page.version.version }}/alter-table.md %}#turn-on-auto-rehoming-for-regional-by-row-tables). A row's home region will be automatically set to the gateway region of any [`UPDATE`]({% link {{ page.version.version }}/update.md %}) or [`UPSERT`]({% link {{ page.version.version }}/upsert.md %}) statements that write to those rows. For instructions showing how to set a table's locality to `REGIONAL BY ROW` and configure the home regions of its rows, refer to [`ALTER TABLE ... SET LOCALITY`]({% link {{ page.version.version }}/alter-table.md %}#crdb_region). diff --git a/src/current/v25.3/alter-table.md b/src/current/v25.3/alter-table.md index 313dcf6daf4..462460f1205 100644 --- a/src/current/v25.3/alter-table.md +++ b/src/current/v25.3/alter-table.md @@ -2624,13 +2624,13 @@ ALTER TABLE rides ADD COLUMN region crdb_internal_region AS ( {% include feature-phases/preview.md %} {{site.data.alerts.end}} -The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters) lets a `REGIONAL BY ROW` child table automatically set the hidden `crdb_region` column by looking up the referenced parent row. The parameter must be set to the name of a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) constraint on the child table that includes the `crdb_region` column. +The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters) lets a [`REGIONAL BY ROW`]({% link {{ page.version.version }}/table-localities.md %}#regional-by-row-tables) child table automatically set the hidden `crdb_region` column by looking up the referenced parent row. The parameter must be set to the name of a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) constraint on the child table that includes the `crdb_region` column. {{site.data.alerts.callout_info}} `infer_rbr_region_col_using_constraint` and [auto-rehoming](#turn-on-auto-rehoming-for-regional-by-row-tables) are mutually exclusive. Enable one mode per `REGIONAL BY ROW` table, not both. {{site.data.alerts.end}} -1. Start a [multi-node, multi-region `cockroach demo` cluster]({% link {{ page.version.version }}/cockroach-demo.md %}): +1. Start a [multi-node, multi-region `cockroach demo` cluster]({% link {{ page.version.version }}/cockroach-demo.md %}#start-a-multi-region-demo-cluster): {% include_cached copy-clipboard.html %} ~~~ shell @@ -2663,14 +2663,14 @@ The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ (3 rows) ~~~ -1. Enable the cluster setting to use `infer_rbr_region_col_using_constraint`: +1. Enable the following cluster setting: {% include_cached copy-clipboard.html %} ~~~ sql SET CLUSTER SETTING feature.infer_rbr_region_col_using_constraint.enabled = true; ~~~ -1. Create a `parent` table that is `REGIONAL BY ROW`: +1. Create a parent table that is `REGIONAL BY ROW`: {% include_cached copy-clipboard.html %} ~~~ sql @@ -2680,7 +2680,7 @@ The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ ) LOCALITY REGIONAL BY ROW; ~~~ -1. Create a `child` table whose rows should live in the same region as their parent rows. The table's foreign key includes `crdb_region`, and the `infer_rbr_region_col_using_constraint` parameter is set to the name of the foreign key (`fk_parent`): +1. Create a child table whose rows should live in the same region as their parent rows. The table's foreign key **must** include `crdb_region`, and the `infer_rbr_region_col_using_constraint` parameter must be set to the name of the foreign key (in this example, `fk_parent`): {% include_cached copy-clipboard.html %} ~~~ sql @@ -2693,14 +2693,14 @@ The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ LOCALITY REGIONAL BY ROW; ~~~ -1. Insert a row into `parent` that lives in the primary region (`us-east1`): +1. Insert a row into the parent table that lives in the primary region (`us-east1`): {% include_cached copy-clipboard.html %} ~~~ sql INSERT INTO parent (id, data, crdb_region) VALUES (1, 'east row', 'us-east1'); ~~~ -1. Run the following command to view information about all 9 nodes in the cluster: +1. Run the following command to view IDs and connection strings for all nodes in the cluster: {% include_cached copy-clipboard.html %} ~~~ @@ -2731,18 +2731,16 @@ The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ (rpc) 127.0.0.1:26365 ~~~ -1. In a new terminal, connect to a node in a non-primary region (i.e., `us-west1` or `europe-west1`). This should be one of nodes 4-9. The following example connects to node 9: +1. Follow one of the `webui` URLs in the preceding output and open the [**Network Latency** Page]({% link {{ page.version.version }}/ui-network-latency-page.md %}) in the DB Console. This page displays the region associated with each node ID. + + In a **new** terminal, connect to a node in a non-primary region (in this example, `us-west1` or `europe-west1`) using its connection string: {% include_cached copy-clipboard.html %} ~~~ shell cockroach sql --insecure -p 26265 -d cluster:demoapp/demo ~~~ - {{site.data.alerts.callout_success}} - You can use the [**Network Latency** Page]({% link {{ page.version.version }}/ui-network-latency-page.md %}) in the DB Console to cross-reference nodes and their regions. Open any of the `webui` URLs in the preceding step's output. - {{site.data.alerts.end}} - -1. Verify that node 9 is in a non-primary region: +1. Verify that the node you're connected to is in a non-primary region: {% include_cached copy-clipboard.html %} ~~~ sql @@ -2755,14 +2753,14 @@ The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ region=europe-west1,az=d ~~~ -1. Insert a row into the `child` table from node 9: +1. Insert a row into the child table from the node you're connected to: {% include_cached copy-clipboard.html %} ~~~ sql - INSERT INTO child (id, parent_id, info) VALUES (10, 1, 'west gateway'); + INSERT INTO child (id, parent_id, info) VALUES (10, 1, 'hello from gateway'); ~~~ -1. View the value of the hidden `crdb_region` column. Even though the row was inserted from the `europe-west1` gateway region, CockroachDB uses the `fk_parent` constraint to look up and copy the parent row's region (`us-east1`) into the child row: +1. View the value of the hidden `crdb_region` column. Even though the row was inserted from a non-primary gateway region, CockroachDB uses the foreign-key constraint to look up and copy the parent row's region into the child row: {% include_cached copy-clipboard.html %} ~~~ sql @@ -2775,7 +2773,7 @@ The [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ 10 | 1 | us-east1 ~~~ -1. If you later need to disable the behavior, reset the storage parameter: +1. If you later need to disable the behavior, [reset the storage parameter](#reset-storage-parameter): {% include_cached copy-clipboard.html %} ~~~ sql @@ -2802,8 +2800,7 @@ SET enable_auto_rehoming = on; Once enabled, the auto-rehoming behavior described here has the following limitations: - It **will only apply to newly created `REGIONAL BY ROW` tables**, using an `ON UPDATE` expression that is added to the [`crdb_region`](#crdb_region) column. Existing `REGIONAL BY ROW` tables will not be auto-rehomed. -- The [`crdb_region`](#crdb_region) column from a [`REGIONAL BY ROW`](#set-the-table-locality-to-regional-by-row) table cannot be referenced as a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) from another table. -- Auto-rehoming **cannot** be combined with the [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters), which requires `crdb_region` to participate in a foreign key and therefore remain stable. +- The [`crdb_region`](#crdb_region) column from a [`REGIONAL BY ROW`](#set-the-table-locality-to-regional-by-row) table cannot be referenced as a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) from another table. This also means the [`infer_rbr_region_col_using_constraint` table storage parameter]({% link {{ page.version.version }}/with-storage-parameter.md %}#table-parameters) cannot be used to [infer a row's home region](#infer-a-rows-home-region-from-a-foreign-key). To enable auto-rehoming for an existing `REGIONAL BY ROW` table, manually update it using an [`ALTER TABLE ... ALTER COLUMN`](#alter-column) statement with an `ON UPDATE` expression: @@ -2812,10 +2809,6 @@ To enable auto-rehoming for an existing `REGIONAL BY ROW` table, manually update ALTER TABLE {table} ALTER COLUMN crdb_region SET ON UPDATE rehome_row()::db.public.crdb_internal_region; ~~~ -{{site.data.alerts.callout_info}} -[`infer_rbr_region_col_using_constraint`](#infer-a-rows-home-region-from-a-foreign-key) and auto-rehoming are mutually exclusive. Enable one mode per `REGIONAL BY ROW` table, not both. -{{site.data.alerts.end}} - ##### Example 1. Follow steps 1 and 2 from the [Low Latency Reads and Writes in a Multi-Region Cluster]({% link {{ page.version.version }}/demo-low-latency-multi-region-deployment.md %}) tutorial. This will involve starting a [`cockroach demo`]({% link {{ page.version.version }}/cockroach-demo.md %}) cluster in a terminal window (call it _terminal 1_). From ad0e550b139e9c7b4c796ed2efdad8a759440714 Mon Sep 17 00:00:00 2001 From: Ryan Kuo Date: Fri, 1 Aug 2025 11:18:17 -0400 Subject: [PATCH 3/3] remove v25.3 callout --- .../v25.3/misc/table-storage-parameters.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/current/_includes/v25.3/misc/table-storage-parameters.md b/src/current/_includes/v25.3/misc/table-storage-parameters.md index d90102f9a34..71d7ae98ba1 100644 --- a/src/current/_includes/v25.3/misc/table-storage-parameters.md +++ b/src/current/_includes/v25.3/misc/table-storage-parameters.md @@ -1,12 +1,12 @@ -| Parameter name | Description | Data type | Default value | -|------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|---------------| -| `exclude_data_from_backup` | Exclude the data in this table from any future backups. | Boolean | `false` | -| `schema_locked` | Disallow [schema changes]({% link {{ page.version.version }}/online-schema-changes.md %}) on this table. Enabling `schema_locked` can help [improve performance of changefeeds]({% link {{ page.version.version }}/create-changefeed.md %}#disallow-schema-changes-on-tables-to-improve-changefeed-performance) running on this table. | Boolean | `false` | -| `sql_stats_automatic_collection_enabled` | Enable [automatic statistics collection]({% link {{ page.version.version }}/cost-based-optimizer.md %}#enable-and-disable-automatic-statistics-collection-for-tables) for this table. | Boolean | `true` | -| `sql_stats_automatic_collection_min_stale_rows` | Minimum number of stale rows in this table that will trigger a statistics refresh. | Integer | 500 | -| `sql_stats_automatic_collection_fraction_stale_rows` | Fraction of stale rows in this table that will trigger a statistics refresh. | Float | 0.2 | -| `sql_stats_forecasts_enabled` | Enable [forecasted statistics]({% link {{ page.version.version }}/show-statistics.md %}#display-forecasted-statistics) collection for this table. | Boolean | `true` | -| `infer_rbr_region_col_using_constraint` | **New in v25.3:** For [`REGIONAL BY ROW`]({% link {{ page.version.version }}/table-localities.md %}#regional-by-row-tables) tables, automatically populate the hidden `crdb_region` column on `INSERT`, `UPDATE`, and `UPSERT` by looking up the region of the referenced parent row. Set this parameter to the name of a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) constraint on the table that includes the `crdb_region` column. The foreign key cannot be dropped while the parameter is set. | String | `NULL` | +| Parameter name | Description | Data type | Default value | +|----------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|---------------| +| `exclude_data_from_backup` | Exclude the data in this table from any future backups. | Boolean | `false` | +| `schema_locked` | Disallow [schema changes]({% link {{ page.version.version }}/online-schema-changes.md %}) on this table. Enabling `schema_locked` can help [improve performance of changefeeds]({% link {{ page.version.version }}/create-changefeed.md %}#disallow-schema-changes-on-tables-to-improve-changefeed-performance) running on this table. | Boolean | `false` | +| `sql_stats_automatic_collection_enabled` | Enable [automatic statistics collection]({% link {{ page.version.version }}/cost-based-optimizer.md %}#enable-and-disable-automatic-statistics-collection-for-tables) for this table. | Boolean | `true` | +| `sql_stats_automatic_collection_min_stale_rows` | Minimum number of stale rows in this table that will trigger a statistics refresh. | Integer | 500 | +| `sql_stats_automatic_collection_fraction_stale_rows` | Fraction of stale rows in this table that will trigger a statistics refresh. | Float | 0.2 | +| `sql_stats_forecasts_enabled` | Enable [forecasted statistics]({% link {{ page.version.version }}/show-statistics.md %}#display-forecasted-statistics) collection for this table. | Boolean | `true` | +| `infer_rbr_region_col_using_constraint` | For [`REGIONAL BY ROW`]({% link {{ page.version.version }}/table-localities.md %}#regional-by-row-tables) tables, automatically populate the hidden `crdb_region` column on `INSERT`, `UPDATE`, and `UPSERT` by looking up the region of the referenced parent row. Set this parameter to the name of a [foreign key]({% link {{ page.version.version }}/foreign-key.md %}) constraint on the table that includes the `crdb_region` column. The foreign key cannot be dropped while the parameter is set. | String | `NULL` | The following parameters are included for PostgreSQL compatibility and do not affect how CockroachDB runs: