> ## 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.

# Migrate with AWS Database Migration Service (DMS)

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 for setting up [AWS Database Migration Service (DMS)](https://aws.amazon.com/dms/) to migrate data to CockroachDB from an existing, publicly hosted database containing application data, such as PostgreSQL, MySQL, Oracle, or Microsoft SQL Server.

For a detailed tutorial about using AWS DMS and information about specific migration tasks, see the [AWS DMS documentation site](https://docs.aws.amazon.com/dms/latest/userguide/Welcome.html).

For any issues related to AWS DMS, aside from its interaction with CockroachDB as a migration target, contact [AWS Support](https://aws.amazon.com/contact-us/).

<Note>
  Using CockroachDB as a source database within AWS DMS is unsupported.
</Note>

## Setup

Complete the following items before starting the DMS migration:

* Configure a [replication instance](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_ReplicationInstance.Creating.html) in AWS.

* Configure a [source endpoint](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Source.html) in AWS pointing to your source database.

* Ensure you have a secure, publicly available CockroachDB cluster running the latest <InternalLink version="releases" path="index">production release</InternalLink>, and have created a <InternalLink path="security-reference/authorization#sql-users">SQL user</InternalLink> that you can use for your AWS DMS [target endpoint](#step-1-create-a-target-endpoint-pointing-to-cockroachdb).

* Set the following <InternalLink path="set-vars#supported-variables">session variables</InternalLink> using <InternalLink path="alter-role#set-default-session-variable-values-for-a-role">`ALTER ROLE ... SET session variable`</InternalLink>:

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  ALTER ROLE {username} SET copy_from_retries_enabled = true;
  ```

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  ALTER ROLE {username} SET copy_from_atomic_enabled = false;
  ```

  This prevents a potential issue when migrating especially large tables with millions of rows.

* Manually create all schema objects in the target CockroachDB cluster. If you are migrating from PostgreSQL, MySQL, Oracle, or Microsoft SQL Server, you can <InternalLink version="cockroachcloud" path="migrations-page">use the **Schema Conversion Tool**</InternalLink> to convert and export your schema.

  * All tables must have an explicitly defined primary key. For more guidance, see <InternalLink version="molt" path="migration-strategy#schema-design-best-practices">Migration Strategy</InternalLink>.

  * Drop all <InternalLink path="constraints">constraints</InternalLink> per the [AWS DMS best practices](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_BestPractices.html#CHAP_BestPractices.Performance). You can recreate them after the [full load completes](#step-3-verify-the-migration). AWS DMS can create a basic schema, but does not create <InternalLink path="indexes">indexes</InternalLink> or constraints such as <InternalLink path="foreign-key">foreign keys</InternalLink> and <InternalLink path="default-value">defaults</InternalLink>.

  * Ensure that any schema changes are also reflected on your target tables, or add [transformation rules](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.CustomizingTasks.TableMapping.SelectionTransformation.Transformations.html) to your [table mappings](#step-2-3-table-mappings). If you make substantial schema changes, the AWS DMS migration can fail.

* If you are migrating to a CockroachDB CockroachDB Cloud cluster and plan to [use replication as part of your migration strategy](#step-2-1-task-configuration), you must first **disable** <InternalLink path="take-backups-with-revision-history-and-restore-from-a-point-in-time">revision history for cluster backups</InternalLink> for the migration to succeed.

<Danger>
  You will not be able to run a <InternalLink path="take-backups-with-revision-history-and-restore-from-a-point-in-time#point-in-time-restore">point-in-time restore</InternalLink> as long as revision history for cluster backups is disabled. Once you [verify that the migration succeeded](#step-3-verify-the-migration), you should re-enable revision history.
</Danger>

* If the output of <InternalLink path="show-schedules">`SHOW SCHEDULES`</InternalLink> shows any backup schedules, run <InternalLink path="alter-backup-schedule">`ALTER BACKUP SCHEDULE {schedule_id} SET WITH revision_history = 'false'`</InternalLink> for each backup schedule.

* If the output of `SHOW SCHEDULES` does not show backup schedules, [contact Support](https://support.cockroachlabs.com) to disable revision history for cluster backups.

* If you are migrating to CockroachDB Standard or Advanced, enable <InternalLink version="cockroachcloud" path="export-logs">CockroachDB log export to Amazon CloudWatch</InternalLink> **before** starting the DMS migration. This makes CockroachDB logs accessible for [troubleshooting](#troubleshoot-common-issues). You will also need to select [**Enable CloudWatch logs** in your DMS task settings](#step-2-2-task-settings).

#### Supported database technologies

As of publishing, AWS DMS supports migrations from these relational databases (for the most accurate view of what is currently supported, see [Sources for AWS DMS](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Introduction.Sources.html)):

* Amazon Aurora
* Amazon DocumentDB (with MongoDB compatibility)
* Amazon S3
* IBM Db2 (LUW edition only)
* MariaDB
* Microsoft Azure SQL
* Microsoft SQL Server
* MongoDB
* MySQL
* Oracle
* PostgreSQL
* SAP ASE

## Best practices

* Do not issue reads while AWS DMS is running. AWS DMS runs explicit transactions, which can cause <InternalLink path="performance-best-practices-overview#transaction-contention">contention</InternalLink>. If you need to issue reads, use <InternalLink path="follower-reads">follower reads</InternalLink>.

* Do not run additional workloads (e.g., benchmarking) while AWS DMS is running.

<Tip>
  - To conserve CPU, consider migrating tables in multiple [replication tasks](#step-2-create-a-database-migration-task), rather than performing a full load in a single task.
</Tip>

* If you perform a full load, you can improve performance by defining a *parallel load* setting for selected columns. See [Table Mappings](#step-2-3-table-mappings).

## Step 1. Create a target endpoint pointing to CockroachDB

1. In the AWS Console, open **AWS DMS**.
2. Open **Endpoints** in the sidebar. A list of endpoints will display, if any exist.
3. In the top-right portion of the window, select **Create endpoint**.

   <img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-create-endpoint.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=66448062056cea0c3424fe63c6f50c1b" alt="AWS-DMS-Create-Endpoint" width="3074" height="1388" data-path="images/v25.1/aws-dms-create-endpoint.png" />

   A configuration page will open.
4. In the **Endpoint type** section, select **Target endpoint**.
5. Supply an **Endpoint identifier** to identify the new target endpoint.
6. In the **Target engine** dropdown, select **PostgreSQL**.
7. Under **Access to endpoint database**, select **Provide access information manually**.

   For information about where to find CockroachDB connection parameters, see <InternalLink path="connect-to-the-database">Connect to a CockroachDB Cluster</InternalLink>.
8. Enter the **Server name** and **Port** of your CockroachDB cluster.
9. Supply a **User name**, **Password**, and **Database name** from your CockroachDB cluster.

<Note>
  To connect to a CockroachDB Standard or Basic cluster, set the **Database name** to `{host}.{database}`. For details on how to find these parameters, see <InternalLink version="cockroachcloud" path="connect-to-your-cluster?filters=connection-parameters#connect-to-your-cluster">Connect to your cluster</InternalLink>. Also set **Secure Socket Layer (SSL) mode** to **require**.
</Note>

<img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-endpoint-configuration.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=dcb4025065a110ea123d48ac809c3469" alt="AWS-DMS-Endpoint-Configuration" width="2248" height="2596" data-path="images/v25.1/aws-dms-endpoint-configuration.png" />

1. If needed, you can test the connection under **Test endpoint connection (optional)**.
2. To create the endpoint, select **Create endpoint**.
   <img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-test-endpoint.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=54cfec854ad3f42cafefa803713297ec" alt="AWS-DMS-Test-Endpoint" width="1616" height="1258" data-path="images/v25.1/aws-dms-test-endpoint.png" />

## Step 2. Create a database migration task

A database migration task, also known as a replication task, controls what data are moved from the source database to the target database.

To conserve CPU, consider migrating tables in multiple replication tasks, rather than performing a full load in a single task.

### Step 2.1. Task configuration

1. While in **AWS DMS**, select **Database migration tasks** in the sidebar. A list of database migration tasks will display, if any exist.
2. In the top-right portion of the window, select **Create task**.

   <img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-create-db-migration-task.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=92a00a36a16a4c1b8896126ace2868e8" alt="AWS-DMS-Create-DB-Migration-Task" width="2376" height="1292" data-path="images/v25.1/aws-dms-create-db-migration-task.png" />

   A configuration page will open.
3. Supply a **Task identifier** to identify the replication task.
4. Select the **Replication instance** and **Source database endpoint** you created prior to starting this tutorial.
5. For the **Target database endpoint** dropdown, select the CockroachDB endpoint created in the previous section.
6. Select the appropriate **Migration type** based on your needs.

<Danger>
  If you choose **Migrate existing data and replicate ongoing changes** or **Replicate data changes only**, you must first [disable revision history for backups](#setup).
</Danger>

<img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-task-configuration.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=5f851d434ee829ec177b71030b887207" alt="AWS-DMS-Task-Configuration" width="2008" height="1508" data-path="images/v25.1/aws-dms-task-configuration.png" />

### Step 2.2. Task settings

1. For the **Editing mode** radio button, keep **Wizard** selected.
2. To preserve the schema you manually created, select **Truncate** or **Do nothing** for the **Target table preparation mode**.
   <img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-task-settings.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=c898aa4efe5db2253ae236eee8e404e3" alt="AWS-DMS-Task-Settings" width="1624" height="1474" data-path="images/v25.1/aws-dms-task-settings.png" />
3. Optionally check **Enable validation** to compare the data in the source and target rows, and verify that the migration succeeded. You can view the results in the [**Table statistics**](#step-3-verify-the-migration) for your migration task. For more information about data validation, see the [AWS documentation](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Validating.html).
4. Check the **Enable CloudWatch logs** option. We highly recommend this for troubleshooting potential migration issues.
5. For the **Target Load**, select **Detailed debug**.
   <img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-cloudwatch-logs.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=34560465c872cb9c4022c821b62d0eaa" alt="AWS-DMS-CloudWatch-Logs" width="1258" height="1232" data-path="images/v25.1/aws-dms-cloudwatch-logs.png" />

### Step 2.3. Table mappings

<Note>
  When specifying a range of tables to migrate, the following aspects of the source and target database schema **must** match unless you use [transformation rules](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.CustomizingTasks.TableMapping.SelectionTransformation.Transformations.html):

  * Column names must be identical.
  * Column types must be compatible.
  * Column nullability must be identical.

  1. For the **Editing mode** radio button, keep **Wizard** selected.
  2. Select **Add new selection rule**.
  3. In the **Schema** dropdown, select **Enter a schema**.
  4. Supply the appropriate **Source name** (schema name), **Table name**, and **Action**.
       <img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-table-mappings.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=2187796f9110504a569e83818e21ad1d" alt="AWS-DMS-Table-Mappings" width="1594" height="1780" data-path="images/v25.1/aws-dms-table-mappings.png" />
</Note>

<Note>
  Use `%` as an example of a wildcard for all schemas in a PostgreSQL database. However, in MySQL, using `%` as a schema name imports all the databases, including the metadata/system ones, as MySQL treats schemas and databases as the same.
</Note>

1. To improve full-load performance, consider defining a *parallel load* setting for selected columns. A parallel load splits the full-load task into multiple threads. For example:

   ```json theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
   "parallel-load": {
      "type": "ranges",
      "columns": [
          "id"
      ],
      "boundaries": [
          [
              5000000
          ],
          [
              10000000
          ],
          ...
      ]
   }
   ```

   For details, see the [AWS documentation](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.CustomizingTasks.TableMapping.SelectionTransformation.Tablesettings.html#CHAP_Tasks.CustomizingTasks.TableMapping.SelectionTransformation.Tablesettings.ParallelLoad).

## Step 3. Verify the migration

Data should now be moving from source to target. You can analyze the **Table Statistics** page for information about replication.

1. In **AWS DMS**, open **Database migration tasks** in the sidebar.
2. Select the task you created in Step 2.
3. Select **Table statistics** below the **Summary** section.

If your migration succeeded, you should now:

* [Re-enable revision history](#setup) for cluster backups.
* Re-create any <InternalLink path="constraints">constraints</InternalLink> that you dropped [before migrating](#setup).

If your migration failed for some reason, you can check the checkbox next to the table(s) you wish to re-migrate and select **Reload table data**.

<img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-reload-table-data.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=c488d213201e3dda2d2ce2c461a78b5e" alt="AWS-DMS-Reload-Table-Data" width="2032" height="1274" data-path="images/v25.1/aws-dms-reload-table-data.png" />

## Optional configurations

### AWS PrivateLink

If using CockroachDB Standard or Advanced, you can enable [AWS PrivateLink](https://aws.amazon.com/privatelink/) to securely connect your AWS application with your CockroachDB Standard or Advanced cluster using a private endpoint. To configure AWS PrivateLink with CockroachDB Standard or Advanced, see <InternalLink version="cockroachcloud" path="network-authorization">Network Authorization</InternalLink>.

### `BatchApplyEnabled`

The `BatchApplyEnabled` setting can improve replication performance and is recommended for larger workloads.

1. Open the existing database migration task.
2. Choose your task, and then choose **Modify**.
3. From the **Task settings** section, switch the **Editing mode** from **Wizard** to **JSON editor**. Locate the `BatchApplyEnabled` setting and change its value to `true`. Information about the `BatchApplyEnabled` setting can be found [here](https://aws.amazon.com/premiumsupport/knowledge-center/dms-batch-apply-cdc-replication/).

<img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-batchapplyenabled.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=23ca06f0a71a3317a929cfd75dc9cbff" alt="AWS-DMS-BatchApplyEnabled" width="1604" height="1046" data-path="images/v25.1/aws-dms-batchapplyenabled.png" />

<Note>
  `BatchApplyEnabled` does not work when using **Drop tables on target** as a target table preparation mode. Thus, all schema-related changes must be manually copied over if using `BatchApplyEnabled`.
</Note>

## Troubleshoot common issues

* For visibility into migration problems:

  * Check the [Amazon CloudWatch logs that you enabled](#step-2-2-task-settings) for messages containing `SQL_ERROR`.
  * Check the CockroachDB <InternalLink path="logging-overview#logging-channels">`SQL_EXEC` logs</InternalLink> for messages related to `COPY` statements and the tables you are migrating. To access CockroachDB Standard or Advanced logs, you should have configured log export to Amazon CloudWatch [before beginning the DMS migration](#setup).

<Danger>
  Personally identifiable information (PII) may be exported to CloudWatch unless you <InternalLink path="configure-logs#redact-logs">redact the logs</InternalLink>. Redacting logs may hide the data that is causing the issue, making it more difficult to troubleshoot.
</Danger>

* If you encounter errors like the following:

  In the Amazon CloudWatch logs:

  ```
  2022-10-21T13:24:07 [SOURCE_UNLOAD   ]W:  Value of column 'metadata' in table 'integrations.integration' was truncated to 32768 bytes, actual length: 116664 bytes  (postgres_endpoint_unload.c:1072)
  ```

  In the CockroachDB <InternalLink path="logging-overview">logs</InternalLink>:

  ```
  could not parse JSON: unable to decode JSON: while decoding 51200 bytes at offset 51185
  ```

  Try selecting **Full LOB mode** in your [task settings](#step-2-2-task-settings). If this does not resolve the error, select **Limited LOB mode** and gradually increase the **Maximum LOB size** until the error goes away. For more information about LOB (large binary object) modes, see the [AWS documentation](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.LOBSupport.html).

* The following error in the CockroachDB <InternalLink path="logging-overview">logs</InternalLink> indicates that a large transaction such as an <InternalLink path="insert">`INSERT`</InternalLink> or <InternalLink path="delete">`DELETE`</InternalLink> has created more <InternalLink path="architecture/transaction-layer#write-intents">write intents</InternalLink> than can be quickly resolved:

  ```
  a transaction has hit the intent tracking limit (kv.transaction.max_intents_bytes)
  ```

  This will likely cause high latency and <InternalLink path="transaction-retry-error-reference">transaction retries</InternalLink> due to <InternalLink path="performance-best-practices-overview#transaction-contention">lock contention</InternalLink>. Try raising the value of the <InternalLink path="cluster-settings">`kv.transaction_max_intents_bytes` cluster setting</InternalLink> to configure CockroachDB to use more memory for quick intent resolution. Note that this memory limit is applied **per-transaction**. To prevent unexpected memory usage at higher workload concurrencies, you should also have proper memory accounting.

* When using **Truncate** or **Do nothing** as a target table preparation mode, you cannot include tables with any hidden columns. You can verify which tables contain hidden columns by executing the following SQL query:

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  > SELECT table_catalog, table_schema, table_name, column_name FROM information_schema.columns WHERE is_hidden = 'YES';
  ```

* If you are migrating from PostgreSQL, are using a <InternalLink path="string">`STRING`</InternalLink> as a <InternalLink path="primary-key">`PRIMARY KEY`</InternalLink>, and have selected **Enable validation** in your [task settings](#step-2-2-task-settings), validation can fail due to a difference in how CockroachDB handles case sensitivity in strings.

  To prevent this error, use `COLLATE "C"` on the relevant columns in PostgreSQL or a <InternalLink path="collate">collation</InternalLink> such as `COLLATE "en_US"` in CockroachDB.

* An AWS DMS migration can fail if the target schema has hidden columns. This includes databases with <InternalLink path="hash-sharded-indexes">hash-sharded indexes</InternalLink> and <InternalLink path="multiregion-overview">multi-region clusters</InternalLink> with <InternalLink path="table-localities">regional by row tables</InternalLink>. This is because the `COPY` statement used by DMS is unable to process hidden columns.

  To prevent this error, set the <InternalLink path="session-variables">`expect_and_ignore_not_visible_columns_in_copy` session variable</InternalLink> in the DMS [target endpoint configuration](#step-1-create-a-target-endpoint-pointing-to-cockroachdb). Under **Endpoint settings**, add an **AfterConnectScript** setting with the value `SET expect_and_ignore_not_visible_columns_in_copy=on`.

  <img src="https://mintcdn.com/cockroachlabs/3M6JVFCnEJN7A4hn/images/v25.1/aws-dms-endpoint-settings.png?fit=max&auto=format&n=3M6JVFCnEJN7A4hn&q=85&s=2775a1f69b99cb8161890a9f77dde968" alt="AWS-DMS-Endpoint-Settings" width="1560" height="710" data-path="images/v25.1/aws-dms-endpoint-settings.png" />

* The following error in the CockroachDB <InternalLink path="logging-overview">logs</InternalLink> indicates that AWS DMS is unable to copy into a table with a <InternalLink path="computed-columns">computed column</InternalLink>:

  ```
  cannot write directly to computed column ‹"column_name"›
  ```

  This is expected, as PostgreSQL does not allow copying into tables with a computed column. As a workaround, <InternalLink path="alter-table#drop-column">drop the generated column</InternalLink> in CockroachDB and apply a [transformation](https://docs.aws.amazon.com/dms/latest/userguide/CHAP_Tasks.CustomizingTasks.TableMapping.SelectionTransformation.Transformations.html) in DMS to exclude the computed column. Once the full load is done, add the computed column again in CockroachDB.

* Run the following query from within the target CockroachDB cluster to identify common problems with any tables that were migrated. If problems are found, explanatory messages will be returned in the `cockroach sql` shell.

  ```sql theme={"theme":{"light":"catppuccin-mocha","dark":"catppuccin-mocha"}}
  > WITH
      invalid_columns
          AS (
              SELECT
                  'Table '
                  || table_schema
                  || '.'
                  || table_name
                  || ' has column '
                  || column_name
                  || ' which is hidden. Either drop the column or mark it as not hidden for DMS to work.'
                      AS fix_me
              FROM
                  information_schema.columns
              WHERE
                  is_hidden = 'YES'
                  AND table_name NOT LIKE 'awsdms_%'
          ),
      invalid_version
          AS (
              SELECT
                  'This cluster is on a version of CockroachDB which does not support AWS DMS. CockroachDB v21.2.13+ or v22.1+ is required.'
                      AS fix_me
              WHERE
                  split_part(
                      substr(
                          substring(
                              version(),
                              e'v\\d+\\.\\d+.\\d+'
                          ),
                          2
                      ),
                      '.',
                      1
                  )::INT8
                  < 22
                  AND NOT
                          (
                              split_part(
                                  substr(
                                      substring(
                                          version(),
                                          e'v\\d+\\.\\d+.\\d+'
                                      ),
                                      2
                                  ),
                                  '.',
                                  1
                              )::INT8
                              = 21
                              AND split_part(
                                      substr(
                                          substring(
                                              version(),
                                              e'v\\d+\\.\\d+.\\d+'
                                          ),
                                          2
                                      ),
                                      '.',
                                      2
                                  )::INT8
                                  = 2
                              AND split_part(
                                      substr(
                                          substring(
                                              version(),
                                              e'v\\d+\\.\\d+.\\d+'
                                          ),
                                          2
                                      ),
                                      '.',
                                      3
                                  )::INT8
                                  >= 13
                          )
          ),
      has_no_pk
          AS (
              SELECT
                  'Table '
                  || a.table_schema
                  || '.'
                  || a.table_name
                  || ' has column '
                  || a.column_name
                  || ' has no explicit PRIMARY KEY. Ensure you are not using target mode "Drop tables on target" and that this table has a PRIMARY KEY.'
                      AS fix_me
              FROM
                  information_schema.key_column_usage AS a
                  JOIN information_schema.columns AS b ON
                          a.table_schema = b.table_schema
                          AND a.table_name = b.table_name
                          AND a.column_name = b.column_name
              WHERE
                  b.is_hidden = 'YES'
                  AND a.column_name = 'rowid'
                  AND a.table_name NOT LIKE 'awsdms_%'
          )
  SELECT fix_me FROM has_no_pk
  UNION ALL SELECT fix_me FROM invalid_columns
  UNION ALL SELECT fix_me FROM invalid_version;
  ```

* Refer to Debugging Your AWS DMS Migrations ([Part 1](https://aws.amazon.com/blogs/database/debugging-your-aws-dms-migrations-what-to-do-when-things-go-wrong-part-1/), [Part 2](https://aws.amazon.com/blogs/database/debugging-your-aws-dms-migrations-what-to-do-when-things-go-wrong-part-2/), and [Part 3](https://aws.amazon.com/blogs/database/debugging-your-aws-dms-migrations-what-to-do-when-things-go-wrong-part-3/)) on the AWS Database Blog.

* If the migration is still failing, [contact Support](https://support.cockroachlabs.com) and include the following information when filing an issue:
  * Source database name.
  * CockroachDB version.
  * Source database schema.
  * CockroachDB database schema.
  * Any relevant logs (e.g., the last 100 lines preceding the AWS DMS failure).
  * Ideally, a sample dataset formatted as a database dump file or CSV.

## See Also

* <InternalLink version="molt" path="migration-overview">Migration Overview</InternalLink>
* <InternalLink version="cockroachcloud" path="migrations-page">Schema Conversion Tool</InternalLink>
* <InternalLink path="cockroach-demo">`cockroach demo`</InternalLink>
* [AWS DMS documentation](https://docs.aws.amazon.com/dms/latest/userguide/Welcome.html)
* <InternalLink path="connection-parameters">Client connection parameters</InternalLink>
* <InternalLink path="third-party-database-tools">Third-Party Database Tools</InternalLink>
* <InternalLink path="learn-cockroachdb-sql">Learn CockroachDB SQL</InternalLink>
