> ## Documentation Index
> Fetch the complete documentation index at: https://cockroachlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshoot Replication Zones

export const InternalLink = ({version, path = "", children, ...props}) => {
  let detectedVersion = version || "stable";
  if (typeof window !== 'undefined' && !version) {
    const match = window.location.pathname.match(/\/docs\/([^/]+)/);
    if (match) {
      detectedVersion = match[1];
    }
  }
  const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
  return <a href={`/docs/${detectedVersion}/${normalizedPath}`} {...props}>
      {children}
    </a>;
};

This page has instructions showing how to troubleshoot scenarios where you believe replicas are not behaving as specified by your <InternalLink path="configure-replication-zones">zone configurations</InternalLink>.

Cockroach Labs  <InternalLink path="configure-replication-zones#why-manual-zone-config-management-is-not-recommended">does not recommend modifying zone configurations manually</InternalLink>.  [does not recommend modifying zone configurations manually](#why-manual-zone-config-management-is-not-recommended).

Most users should use <InternalLink path="multiregion-overview">multi-region SQL statements</InternalLink> instead. If additional control is needed, use <InternalLink path="zone-config-extensions">Zone Config Extensions</InternalLink> to augment the multi-region SQL statements.

## Prerequisites

This page assumes you have read and understood the following:

* <InternalLink path="configure-replication-zones#replication-zone-levels">Replication controls > Replication zone levels</InternalLink>, which describes how the inheritance hierarchy of replication zones works. **This is critical to understand for troubleshooting.**
* <InternalLink path="monitoring-and-alerting#critical-nodes-endpoint">Monitoring and alerting > Critical nodes endpoint</InternalLink>, which is used to monitor if any of your cluster's ranges are under-replicated, or if your data placement constraints are being violated.
* <InternalLink path="show-zone-configurations">`SHOW ZONE CONFIGURATIONS`</InternalLink>, which is the SQL statement used to view details about the replication zone configuration of various schema objects.

## Types of problems

The most common types of problems you may encounter when <InternalLink path="configure-replication-zones#manage-replication-zones">manually configuring replication zones</InternalLink> are:

1. The *replica location* problem, a.k.a., "The replicas are not **where** they should be". For replica location problems, the following <InternalLink path="configure-replication-zones#replication-zone-variables">zone config variables</InternalLink> may be involved:
   * <InternalLink path="configure-replication-zones">`constraints`</InternalLink>
   * <InternalLink path="configure-replication-zones">`lease_preferences`</InternalLink>
   * <InternalLink path="configure-replication-zones">`voter_constraints`</InternalLink>
   * <InternalLink path="configure-replication-zones">`global_reads`</InternalLink>
2. The *replica state* problem, a.k.a., "The replicas are not **how** they should be". For replica state problems, the following <InternalLink path="configure-replication-zones#replication-zone-variables">zone config variables</InternalLink> may be involved:
   * <InternalLink path="configure-replication-zones">`range_min_bytes`</InternalLink>
   * <InternalLink path="configure-replication-zones">`range_max_bytes`</InternalLink>
   * <InternalLink path="configure-replication-zones">`gc.ttlseconds`</InternalLink>
   * <InternalLink path="configure-replication-zones">`num_replicas`</InternalLink>
   * <InternalLink path="configure-replication-zones">`num_voters`</InternalLink>

The replica location problem is the most common. It is most often caused by misconfiguration introduced by manually configuring replication zones, which is <InternalLink path="configure-replication-zones#why-manual-zone-config-management-is-not-recommended">why manual zone config management is not recommended</InternalLink>. Most users should use the <InternalLink path="multiregion-overview">multi-region SQL statements</InternalLink>. If additional control is needed, <InternalLink path="zone-config-extensions">Zone config extensions</InternalLink> can be used to augment the multi-region SQL statements.

<Note>
  If you just did a <InternalLink path="restore#full-cluster">cluster restore</InternalLink> and are seeing problems with your zone configs, it may be because [zone configs are overwritten by a cluster restore](#zone-configs-are-overwritten-during-cluster-restore).
</Note>

## Troubleshooting steps

Use the following steps to determine which schema objects (if any) have zone configurations that are misconfigured.

The examples assume a local multi-region <InternalLink path="cockroach-demo">`cockroach demo`</InternalLink> cluster started using the following command:

```shell theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
cockroach demo --global --nodes 9 --insecure
```

Next, execute the following statements to set the <InternalLink path="multiregion-overview#database-regions">database regions</InternalLink> for the <InternalLink path="movr#the-movr-database">`movr` database</InternalLink>:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER DATABASE movr SET PRIMARY REGION "us-east1";
ALTER DATABASE movr ADD REGION "us-west1";
ALTER DATABASE movr ADD REGION "europe-west1";
```

<a id="step1" />

### Step 1. Start with a target schema object

Look at the zone configuration for the schema object that you think may be misconfigured. Depending on the [type of problem](#types-of-problems), you might have come to this conclusion by [monitoring the critical nodes endpoint](#monitoring).

Use the <InternalLink path="show-zone-configurations">`SHOW ZONE CONFIGURATION`</InternalLink> statement to inspect the target object's zone configurations.

For example, to view the zone configuration for the `movr.rides` table:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
SHOW ZONE CONFIGURATION FOR TABLE movr.users;
```

```
----------------+-------------------------------------------------------------------------------------------
  DATABASE movr | ALTER DATABASE movr CONFIGURE ZONE USING
                |     range_min_bytes = 134217728,
                |     range_max_bytes = 536870912,
                |     gc.ttlseconds = 14400,
                |     num_replicas = 5,
                |     num_voters = 3,
                |     constraints = '{+region=europe-west1: 1, +region=us-east1: 1, +region=us-west1: 1}',
                |     voter_constraints = '[+region=us-east1]',
                |     lease_preferences = '[[+region=us-east1]]'
(1 row)
```

The preceding output is expected for a multi-region cluster spread across 9 nodes that was configured using <InternalLink path="multiregion-overview">multi-region SQL</InternalLink>. Since nothing about the zone configuration has been manually modified, the output shows that `movr.users` is using the zone configuration from its parent `movr` database. For more information about how this works, see <InternalLink path="configure-replication-zones#how-zone-config-inheritance-works">How zone config inheritance works</InternalLink>.

However, if the zone configuration had been manually modified, there could be inconsistencies in the output that would show a misconfiguration.

For example:

* If the [type of problem](#types-of-problems) were a [constraint violation](#monitoring), you'd want to check whether the values in <InternalLink path="configure-replication-zones">`constraints`</InternalLink>, <InternalLink path="configure-replication-zones">`voter_constraints`</InternalLink>, and <InternalLink path="configure-replication-zones">`lease_preferences`</InternalLink> are logically inconsistent, which would cause constraint violations.
* If the [type of problem](#types-of-problems) were an [under-replicated range](#monitoring), you'd want to check the values of <InternalLink path="configure-replication-zones">`num_replicas`</InternalLink> and <InternalLink path="configure-replication-zones">`num_voters`</InternalLink>. Modifying these values can cause under-replication. For example, `num_replicas` could be set too low. It's also easy to make an arithmetic mistake when configuring `num_voters`; if `num_voters` is less than `num_replicas`, the difference dictates the number of <InternalLink path="architecture/replication-layer#non-voting-replicas">non-voting replicas</InternalLink>. This is why most users should control non-voting replica placement with the high-level <InternalLink path="multiregion-overview">multi-region SQL features</InternalLink> instead.
* If <InternalLink path="common-errors#split-failed-while-applying-backpressure-are-rows-updated-in-a-tight-loop">range splits are failing</InternalLink>, the value of <InternalLink path="configure-replication-zones">`gc.ttlseconds`</InternalLink> may be too high.

If the zone configuration for the target schema object looks good, [move to Step 2](#step2).

If the zone configuration does not look right, repair it now using <InternalLink path="alter-table#configure-zone">`ALTER TABLE ... CONFIGURE ZONE`</InternalLink>. You can set the problem-causing field to another value, but often the best thing to do is to discard the changed settings using <InternalLink path="alter-table#remove-a-replication-zone">`ALTER TABLE ... CONFIGURE ZONE DISCARD`</InternalLink> so that it returns to inheriting values from its parent object:

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
ALTER TABLE movr.users CONFIGURE ZONE DISCARD;
```

<a id="step2" />

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

If the target schema object looked good in [Step 1](#step1), look at its parent schema object at the next level up in <InternalLink path="configure-replication-zones#how-zone-config-inheritance-works">the inheritance hierarchy</InternalLink>.

This is the new target schema object. Return to [the previous step](#step1) and follow the instructions there.

Continue this process recursively until you either find the misconfigured zone configuration or make it all the way up to <InternalLink path="configure-replication-zones#view-the-default-replication-zone">the `default` replication zone</InternalLink> and confirm that all of your schema objects have the expected zone configurations.

## Considerations

<a id="monitoring" />

### Monitor for ranges that are under-replicated or violating constraints

Monitor the output of the <InternalLink path="monitoring-and-alerting#critical-nodes-endpoint">critical nodes endpoint</InternalLink> to see if you have ranges that are under-replicated or violating constraints.

Using the range IDs from that endpoint, you can map from range IDs to schema objects as described in the following example. This will give you [a target schema object to start from](#step1).

* To monitor for under-replicated range IDs, see <InternalLink path="monitoring-and-alerting">Critical nodes endpoint > Replication status - under-replicated ranges</InternalLink>.

* To monitor for range IDs that are violating constraints, see <InternalLink path="monitoring-and-alerting">Critical nodes endpoint > Replication status - constraint violation</InternalLink>.

Once you have a range ID, you need to map from that ID to the name of a schema object that you can pass to <InternalLink path="show-zone-configurations">`SHOW ZONE CONFIGURATIONS`</InternalLink>.

The following example query uses the <InternalLink path="show-ranges">`SHOW RANGES`</InternalLink> statement to show, for each range ID, which tables and indexes use that range for their underlying storage. The query assumes the <InternalLink path="movr#the-movr-database">`movr` schema</InternalLink> that is loaded by <InternalLink path="cockroach-demo">`cockroach demo`</InternalLink>, so you'll need to modify it to work with your schema.

```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
    WITH movr_tables AS (SHOW RANGES FROM DATABASE movr WITH TABLES),
         movr_indexes AS (SHOW RANGES FROM DATABASE movr WITH INDEXES)
  SELECT array_agg(movr_indexes.range_id) AS ranges,
         movr_tables.table_name,
         movr_indexes.index_name
    FROM movr_tables, movr_indexes
   WHERE movr_tables.range_id = movr_indexes.range_id
GROUP BY movr_tables.table_name, movr_indexes.index_name
ORDER BY table_name, index_name
```

In the following output, each range ID in the leftmost column maps to a table name and index name in the subsequent columns. For example, given this output, if the <InternalLink path="monitoring-and-alerting#critical-nodes-endpoint">critical nodes endpoint</InternalLink> said the constraint violation was for range ID `101`, we would know to look at the zone configuration(s) for the `users` table and the `users_pkey` primary index.

```
                ranges               |         table_name         |                  index_name
-------------------------------------+----------------------------+------------------------------------------------
  {150}                              | promo_codes                | promo_codes_pkey
  {150}                              | promo_codes                | rides_auto_index_fk_city_ref_users
  {150}                              | promo_codes                | rides_auto_index_fk_vehicle_city_ref_vehicles
  {150}                              | promo_codes                | rides_pkey
  {150}                              | promo_codes                | user_promo_codes_pkey
  {150}                              | promo_codes                | vehicle_location_histories_pkey
  {150}                              | rides                      | promo_codes_pkey
  {150}                              | rides                      | rides_auto_index_fk_city_ref_users
  {150}                              | rides                      | rides_auto_index_fk_vehicle_city_ref_vehicles
  {83,153,152,96,154,95,141,140,150} | rides                      | rides_pkey
  {150}                              | rides                      | user_promo_codes_pkey
  {150}                              | rides                      | vehicle_location_histories_pkey
  {83}                               | rides                      | vehicles_auto_index_fk_city_ref_users
  {83}                               | rides                      | vehicles_pkey
  {150}                              | user_promo_codes           | promo_codes_pkey
  {150}                              | user_promo_codes           | rides_auto_index_fk_city_ref_users
  {150}                              | user_promo_codes           | rides_auto_index_fk_vehicle_city_ref_vehicles
  {150}                              | user_promo_codes           | rides_pkey
  {150}                              | user_promo_codes           | user_promo_codes_pkey
  {150}                              | user_promo_codes           | vehicle_location_histories_pkey
  {101,73,72,71,100,70,81,80,90}     | users                      | users_pkey
  {90}                               | users                      | vehicles_pkey
  {150}                              | vehicle_location_histories | promo_codes_pkey
  {150}                              | vehicle_location_histories | rides_auto_index_fk_city_ref_users
  {150}                              | vehicle_location_histories | rides_auto_index_fk_vehicle_city_ref_vehicles
  {150}                              | vehicle_location_histories | rides_pkey
  {150}                              | vehicle_location_histories | user_promo_codes_pkey
  {150}                              | vehicle_location_histories | vehicle_location_histories_pkey
  {83}                               | vehicles                   | rides_pkey
  {90}                               | vehicles                   | users_pkey
  {83}                               | vehicles                   | vehicles_auto_index_fk_city_ref_users
  {90,94,93,92,85,91,84,82,83}       | vehicles                   | vehicles_pkey
(32 rows)
```

### Replication system priorities: data placement vs. data durability

As noted in <InternalLink path="data-domiciling">Data Domiciling with CockroachDB</InternalLink>:

<blockquote markdown="1">
  *<InternalLink path="configure-replication-zones">Zone configs</InternalLink> can be used for data placement but these features were historically built for performance, not for domiciling. The <InternalLink path="architecture/replication-layer">replication system</InternalLink>'s top priority is to prevent the loss of data and it may override the zone configurations if necessary to ensure data durability.*
</blockquote>

### Performance

Changes you make to a schema object's zone configuration may take some time to be reflected in the schema object's actual state, and can result in an increase in CPU usage, IOPS, and network traffic while the cluster rebalances replicas to meet the provided constraints. This is especially true for larger clusters.

For more information about how replica rebalancing works, see <InternalLink path="architecture/replication-layer#load-based-replica-rebalancing">Load-based replica rebalancing</InternalLink>.

### Zone configs are overwritten during cluster restore

During a <InternalLink path="restore#full-cluster">cluster restore</InternalLink>, any <InternalLink path="configure-replication-zones">zone configurations</InternalLink> present on the destination cluster are **overwritten** with the zone configurations from the <InternalLink path="backup#back-up-a-cluster">backed-up cluster</InternalLink>. If no customized zone configurations were on the cluster when the backup was taken, then after the restore the destination cluster will use the zone configuration from the <InternalLink path="configure-replication-zones#view-the-default-replication-zone">`RANGE DEFAULT` configuration</InternalLink>.

For more information, see <InternalLink path="restore#considerations">`RESTORE` considerations</InternalLink>.

## See also

* <InternalLink path="troubleshooting-overview">Troubleshooting overview</InternalLink>
* <InternalLink path="cluster-setup-troubleshooting#replication-issues">Troubleshoot Self-Hosted Setup > Replication issues</InternalLink>
* <InternalLink path="configure-replication-zones">Replication Controls</InternalLink>
* <InternalLink path="monitoring-and-alerting#critical-nodes-endpoint">Critical nodes status endpoint</InternalLink>: check the status of your cluster's data replication, data placement, and zone constraint conformance.
