Skip to content

Commit

Permalink
WIP++
Browse files Browse the repository at this point in the history
  • Loading branch information
rmloveland committed Jan 22, 2025
1 parent 7662061 commit e90e7f5
Showing 1 changed file with 26 additions and 15 deletions.
41 changes: 26 additions & 15 deletions src/current/v24.3/troubleshoot-replication-zones.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ The most common path by which misconfigurations occur is because of the way inhe

As discussed in [Replication Controls > Level priorities]({% link {{ page.version.version }}/configure-replication-zones.md %}#level-priorities), CockroachDB always uses the most granular replication zone available for each schema object (database, table, etc.). More-specific settings applied to schema objects at lower levels of the inheritance tree will always override the settings of objects above them in the tree. All configurations will therefore be modified versions of the [`default` range](#view-the-default-replication-zone), which acts as the root of the tree. This means that in practice, any changes to a specific schema object's zone configuration values are by definition user-initiated, either via [Multi-region SQL abstractions]({% link {{ page.version.version }}/multiregion-overview.md %}) or manual changes using [`CONFIGURE ZONE`]({% link {{ page.version.version }}/alter-database.md %}#configure-zone).

#### The inheritance hierarchy

The hierarchy of inheritance for zone configs can be visualized using the following outline-style diagram, in which each level of indentation denotes an inheritance relationship.

```
Expand All @@ -69,37 +71,42 @@ The hierarchy of inheritance for zone configs can be visualized using the follow
- ...
```

The way the zone config inheritance hierarchy works can be thought of from "bottom-up" or "top-down", depending on which is easier to understand.

### The "bottom-up" view of inheritance

Because each zone config inherits all of its initial values from its parent object, it only stores the values that differ from its parent. Any fields that are unset will be looked up in the parent object’s zone configuration. This continues recursively up the inheritance tree all the way to the `default` zone config. (To avoid performance impacts, most values are cached.)

In this "bottom-up" view of how zone config inheritance works, we start at the "most specific change" to a schema object at the deepest level in the inheritance tree and work upwards.
In this "bottom-up" view of how zone config inheritance works, we start at the "most specific change" to a schema object at its current level in the inheritance tree and work upwards. This way of looking at how inheritance works is useful when you start a troubleshooting session by [looking at a specific schema object's zone configurations](XXX).

### The "top-down" view of inheritance

[XXX](): REVISE ME

Another way of thinking about how zone config inheritance works is "top-down", as follows.

Given the the tree of schema object zone configs, the system does a depth-first search (DFS) down the tree and, for each node, uses **the most specific modified field from the current node**, unless or until it finds a modifed value of that same field on a node further down the tree. For each field on the current node where it doesn't find any modified value, it inherits that value from the node's parent, which inherits from its parent, and so on all the way back up to the root the tree.

For example, if you set some field _F_ at the database level, that updated value of the field will propagate down the inheritance tree to all of the database's child tables.
Another way of thinking about how zone config inheritance works is "top-down". This is useful when thinking about how the system works as a whole.

However, if you edit _F_ on one of the child tables, that table will no longer inherit the value of _F_ from its parent database. Instead, the field _F_ across these two schema objects is now **in a diverged state**. This means that further changes to the value of _F_ at the database level do not propagate downward to the child table with its own value of _F_.

Put another way, once you touch a schema object _O_ to manually edit some field _F_, a "dirty bit" is set on _O.F_, and you are now responsible for managing the state of _O.F_ via direct calls to `ALTER DATABASE ... CONFIGURE ZONE` without help from CockroachDB. For an example of this behavior, see [Zone config inheritance example](#zone-config-inheritance-example).
Given the the tree of schema object zone configs, the system does a depth-first traversal down the tree and, for each node, uses the value of **the most specific modified field from the current node**, unless or until it finds a modifed value of that same field on a node further down the tree. For each field on the current node where it doesn't find any modified value, it inherits that value from the node's parent, which inherits from its parent, and so on all the way back up to the root the tree.

The following diagram presents the same set of schema objects as in [the previous section](#overview), but using boxes and lines joined with arrows that represent the "top-down" view.
The following diagram presents the same set of schema objects as in [the previous section](#the-inheritance-hierarchy), but using boxes and lines joined with arrows that represent the "top-down" view.

Each box represents a schema object's zone configuration, and each line points from a parent object to its child objects, which will inherit the parent's values unless those values are changed at the child level. The dotted lines between (sub)partitions represent the fact that sub-partitions do not inherit their values from their parent partitions (a.k.a., rows). Instead, subpartitions inherit their values from the parent table. For more information, see [cockroachdb/cockroach#75862](https://github.com/cockroachdb/cockroach/issues/75862).

[XXX](): SHOULD THE ABOVE (cockroachdb/cockroach#75862) BE CONSIDERED A "KNOWN LIMITATION" AND ADDED TO THAT PAGE???
[XXX](): FILE DOCS ISSUE RE: cockroachdb/cockroach#75862 AND LINK ZD ISSUE FROM cockroachlabs/support#3143

<img src="{{ 'images/v24.3/troubleshoot-replication-zones.png' | relative_url }}" alt="Replication zone config inheritance diagram" style="border:1px solid #eee;max-width:100%" />

### Zone config inheritance - example SQL session

For example, in a [demo cluster]({% link {{ page.version.version }}/cockroach-demo.md %}) with the following setup:
For example, given the previous descriptions of how zone config inheritance works, if you set some field _F_ at the database level, the updated value of that field will propagate down the inheritance tree to all of the database's child tables.

However, if you edit _F_ on one of the child tables, that table will no longer inherit the value of _F_ from its parent database. Instead, the field _F_ across these two schema objects is now **in a diverged state**. This means that further changes to the value of _F_ at the database level do not propagate downward to the child table with its own value of _F_.

Put another way, once you touch a schema object _O_ to manually edit some field _F_, a "dirty bit" is set on _O.F_, and you are now responsible for managing the state of _O.F_ via direct calls to `ALTER DATABASE ... CONFIGURE ZONE` without help from CockroachDB. For an example of this behavior, see [Zone config inheritance example](#zone-config-inheritance-example).

We can verify this in a SQL session.

Start a [demo cluster]({% link {{ page.version.version }}/cockroach-demo.md %}). Create a sample database and table:

{% include_cached copy-clipboard.html %}
~~~ sql
Expand All @@ -108,14 +115,14 @@ USE test;
CREATE TABLE IF NOT EXISTS kv (k INT, v INT);
~~~

If you manually set a field at the database level for `test` as follows:
Next, manually set a zone configuration field at the database level:

{% include_cached copy-clipboard.html %}
~~~ sql
ALTER DATABASE test CONFIGURE ZONE USING num_replicas = 1;
~~~

You will see that the table `test.kv` inherits the value:
Check that the child table inherits the value from its parent database:

{% include_cached copy-clipboard.html %}
~~~ sql
Expand All @@ -135,14 +142,16 @@ SHOW ZONE CONFIGURATION FROM TABLE kv;
(1 row)
~~~

However, if you then set the same field on the `kv` table to a different value:
Then set the same field on the table to a different value than its parent database:

{% include_cached copy-clipboard.html %}
~~~ sql
ALTER TABLE kv CONFIGURE ZONE USING num_replicas = 5;
~~~

... it overrides the value set by the parent `test` DB. Importantly, **you are now in a state where the value of this setting for `kv` has now diverged from its database `test` and must be reconciled manually going forward**.
This overrides the value set by the parent database. Importantly, **you are now in a state where the value of this setting for the table has diverged from its parent database, and all state on this field must be managed manually going forward**. This divergence in state and necessity to manage it manually is the source of many errors in configuration. [XXX](): AWKWARD, REPHRASE

[XXX](): EDIT FROM HERE DOWN

Until you discard the changed settings at the table level, the table will no longer inherit those changed values from its parent DB.

Expand Down Expand Up @@ -254,6 +263,8 @@ As you can see from this example, this is how we get into a state where manual "

## Troubleshooting steps

[XXX](): ACTUALLY WRITE ME

### Step 1. Start with target object and see what changed

### Step 2. Move upward in the inheritance hierarchy as needed
Expand Down

0 comments on commit e90e7f5

Please sign in to comment.