From 89e5c30fdf5919f2512ead117650d174d2e43944 Mon Sep 17 00:00:00 2001 From: Airton Lastori <6343615+alastori@users.noreply.github.com> Date: Fri, 20 Mar 2026 00:56:40 -0400 Subject: [PATCH 1/6] cloud/dm: add LOCK TABLES to source privilege prerequisites MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cloud DM uses consistency=flush for full data migration, which requires LOCK TABLES on the source — but the docs omitted it. Every user following the documented GRANT hits a cryptic access-denied error on full migration. - Add LOCK TABLES to privilege table and GRANT statement - Add troubleshooting entry for the access-denied error --- .../migrate-from-mysql-using-data-migration.md | 3 ++- .../tidb-cloud-dm-precheck-and-troubleshooting.md | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/tidb-cloud/migrate-from-mysql-using-data-migration.md b/tidb-cloud/migrate-from-mysql-using-data-migration.md index d708402cb6502..551227655a9c2 100644 --- a/tidb-cloud/migrate-from-mysql-using-data-migration.md +++ b/tidb-cloud/migrate-from-mysql-using-data-migration.md @@ -436,13 +436,14 @@ For production workloads, it is recommended to have a dedicated user for data du |:----------|:------|:--------| | `SELECT` | Tables | Allows reading data from all tables | | `RELOAD` | Global | Ensures consistent snapshots during full dump | +| `LOCK TABLES` | Tables | Required for consistent full data export (`consistency=flush`) | | `REPLICATION SLAVE` | Global | Enables binlog streaming for incremental data migration | | `REPLICATION CLIENT` | Global | Provides access to binlog position and server status | For example, you can use the following `GRANT` statement in your source MySQL instance to grant corresponding privileges: ```sql -GRANT SELECT, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'dm_source_user'@'%'; +GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'dm_source_user'@'%'; ``` #### Grant required privileges in the target TiDB Cloud cluster diff --git a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md index 7f419a96114d7..cb10fe1480d83 100644 --- a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md +++ b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md @@ -94,6 +94,18 @@ Failed to create a schema in the downstream TiDB cluster. This error means that To resolve this issue, you can create a schema in the TiDB cluster based on a [supported collation](/character-set-and-collation.md#character-sets-and-collations-supported-by-tidb), and then resume the task by clicking **Restart**. +### Error message: "LOCK TABLES ... Access denied" + +The full data export failed because the source database user does not have the `LOCK TABLES` privilege. Cloud DM uses `consistency=flush` for full data migration, which requires this privilege to ensure a consistent snapshot. + +To resolve this issue, grant the missing privilege to the migration user in the source MySQL database: + +```sql +GRANT LOCK TABLES ON *.* TO 'dm_source_user'@'%'; +``` + +Then resume the task by clicking **Restart**. + ## Alerts You can subscribe to TiDB Cloud alert emails to be informed in time when an alert occurs. From 4cc1f1e842f28ad08e13e4d7ecef464159c110c3 Mon Sep 17 00:00:00 2001 From: Airton Lastori Date: Fri, 20 Mar 2026 01:11:22 -0400 Subject: [PATCH 2/6] Apply suggestions from code review Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md index cb10fe1480d83..5dd844839a7a8 100644 --- a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md +++ b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md @@ -96,7 +96,7 @@ To resolve this issue, you can create a schema in the TiDB cluster based on a [s ### Error message: "LOCK TABLES ... Access denied" -The full data export failed because the source database user does not have the `LOCK TABLES` privilege. Cloud DM uses `consistency=flush` for full data migration, which requires this privilege to ensure a consistent snapshot. +This error indicates that the user for your source database lacks the `LOCK TABLES` privilege. Data Migration uses `consistency=flush` for full data migration, which requires this privilege to ensure a consistent snapshot. To resolve this issue, grant the missing privilege to the migration user in the source MySQL database: From 98c28d95f51eea7b002078e3917cee5417f82182 Mon Sep 17 00:00:00 2001 From: Airton Lastori <6343615+alastori@users.noreply.github.com> Date: Fri, 20 Mar 2026 02:11:08 -0400 Subject: [PATCH 3/6] fix: correct consistency explanation in LOCK TABLES descriptions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The privilege is needed for the lock fallback path, not flush directly. DM uses consistency=auto which resolves to flush (FTWRL), but falls back to lock (LOCK TABLES) if FTWRL fails — that's when the privilege is required. --- tidb-cloud/migrate-from-mysql-using-data-migration.md | 2 +- tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tidb-cloud/migrate-from-mysql-using-data-migration.md b/tidb-cloud/migrate-from-mysql-using-data-migration.md index 551227655a9c2..a99480efd9de9 100644 --- a/tidb-cloud/migrate-from-mysql-using-data-migration.md +++ b/tidb-cloud/migrate-from-mysql-using-data-migration.md @@ -436,7 +436,7 @@ For production workloads, it is recommended to have a dedicated user for data du |:----------|:------|:--------| | `SELECT` | Tables | Allows reading data from all tables | | `RELOAD` | Global | Ensures consistent snapshots during full dump | -| `LOCK TABLES` | Tables | Required for consistent full data export (`consistency=flush`) | +| `LOCK TABLES` | Tables | Required for table-level locking during full data export | | `REPLICATION SLAVE` | Global | Enables binlog streaming for incremental data migration | | `REPLICATION CLIENT` | Global | Provides access to binlog position and server status | diff --git a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md index 5dd844839a7a8..11f4315904fe2 100644 --- a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md +++ b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md @@ -96,7 +96,7 @@ To resolve this issue, you can create a schema in the TiDB cluster based on a [s ### Error message: "LOCK TABLES ... Access denied" -This error indicates that the user for your source database lacks the `LOCK TABLES` privilege. Data Migration uses `consistency=flush` for full data migration, which requires this privilege to ensure a consistent snapshot. +The full data export failed because the source database user does not have the `LOCK TABLES` privilege. During full data migration, DM might fall back to locking individual tables when the global flush lock is unavailable, which requires this privilege. To resolve this issue, grant the missing privilege to the migration user in the source MySQL database: From 21d1454bd117066a0cb3aa37789afd931a84e834 Mon Sep 17 00:00:00 2001 From: Airton Lastori <6343615+alastori@users.noreply.github.com> Date: Fri, 20 Mar 2026 17:04:06 -0400 Subject: [PATCH 4/6] scope LOCK TABLES privilege to managed MySQL sources LOCK TABLES is only required when migrating from managed MySQL services (RDS, Aurora) where FTWRL is restricted. Self-managed MySQL instances do not need this privilege. Updated privilege table, GRANT examples, and troubleshooting to reflect the managed-MySQL-specific scope. Lab evidence: https://github.com/alastori/tidb-sandbox/tree/main/labs/dm/lab-06-lock-tables-privilege --- tidb-cloud/migrate-from-mysql-using-data-migration.md | 6 +++++- tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/tidb-cloud/migrate-from-mysql-using-data-migration.md b/tidb-cloud/migrate-from-mysql-using-data-migration.md index a99480efd9de9..58f7fa73a146e 100644 --- a/tidb-cloud/migrate-from-mysql-using-data-migration.md +++ b/tidb-cloud/migrate-from-mysql-using-data-migration.md @@ -436,13 +436,17 @@ For production workloads, it is recommended to have a dedicated user for data du |:----------|:------|:--------| | `SELECT` | Tables | Allows reading data from all tables | | `RELOAD` | Global | Ensures consistent snapshots during full dump | -| `LOCK TABLES` | Tables | Required for table-level locking during full data export | | `REPLICATION SLAVE` | Global | Enables binlog streaming for incremental data migration | | `REPLICATION CLIENT` | Global | Provides access to binlog position and server status | +| `LOCK TABLES` | Tables | Required when the source is a managed MySQL service (such as Amazon RDS or Aurora) where `FLUSH TABLES WITH READ LOCK` is restricted. In this case, DM falls back to `LOCK TABLES` for consistency during full data export. Not required for self-managed MySQL instances. | For example, you can use the following `GRANT` statement in your source MySQL instance to grant corresponding privileges: ```sql +-- For self-managed MySQL: +GRANT SELECT, RELOAD, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'dm_source_user'@'%'; + +-- For managed MySQL (Amazon RDS, Aurora, etc.), also grant LOCK TABLES: GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'dm_source_user'@'%'; ``` diff --git a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md index 11f4315904fe2..86599ae6cebb1 100644 --- a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md +++ b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md @@ -96,7 +96,9 @@ To resolve this issue, you can create a schema in the TiDB cluster based on a [s ### Error message: "LOCK TABLES ... Access denied" -The full data export failed because the source database user does not have the `LOCK TABLES` privilege. During full data migration, DM might fall back to locking individual tables when the global flush lock is unavailable, which requires this privilege. +The full data export failed because the source database user does not have the `LOCK TABLES` privilege. This error typically occurs when migrating from a managed MySQL service (such as Amazon RDS or Aurora) where `FLUSH TABLES WITH READ LOCK` (FTWRL) is restricted by the cloud provider. In this case, DM's default `consistency=auto` mode falls back to `LOCK TABLES` for data consistency during full export, which requires this privilege. + +> **Note:** This error does not occur on self-managed MySQL instances where FTWRL is available. To resolve this issue, grant the missing privilege to the migration user in the source MySQL database: From b44c2b7fc564e6098db4fd296aa71f979e76b11b Mon Sep 17 00:00:00 2001 From: Airton Lastori <6343615+alastori@users.noreply.github.com> Date: Fri, 20 Mar 2026 17:51:07 -0400 Subject: [PATCH 5/6] review fixes: expand provider list, fix troubleshooting note accuracy - Add Azure Database for MySQL and Google Cloud SQL to all provider lists - Fix troubleshooting note: LOCK TABLES error CAN occur on self-managed MySQL if FTWRL is unavailable for other reasons (e.g., missing RELOAD) - Use "not permitted" instead of "restricted" for consistency --- tidb-cloud/migrate-from-mysql-using-data-migration.md | 2 +- tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tidb-cloud/migrate-from-mysql-using-data-migration.md b/tidb-cloud/migrate-from-mysql-using-data-migration.md index 58f7fa73a146e..3f54965b1793a 100644 --- a/tidb-cloud/migrate-from-mysql-using-data-migration.md +++ b/tidb-cloud/migrate-from-mysql-using-data-migration.md @@ -438,7 +438,7 @@ For production workloads, it is recommended to have a dedicated user for data du | `RELOAD` | Global | Ensures consistent snapshots during full dump | | `REPLICATION SLAVE` | Global | Enables binlog streaming for incremental data migration | | `REPLICATION CLIENT` | Global | Provides access to binlog position and server status | -| `LOCK TABLES` | Tables | Required when the source is a managed MySQL service (such as Amazon RDS or Aurora) where `FLUSH TABLES WITH READ LOCK` is restricted. In this case, DM falls back to `LOCK TABLES` for consistency during full data export. Not required for self-managed MySQL instances. | +| `LOCK TABLES` | Tables | Required when the source is a managed MySQL service (such as Amazon RDS, Aurora, Azure Database for MySQL, or Google Cloud SQL) where `FLUSH TABLES WITH READ LOCK` is not permitted. In this case, DM falls back to `LOCK TABLES` for consistency during full data export. Not required for self-managed MySQL instances where FTWRL is available. | For example, you can use the following `GRANT` statement in your source MySQL instance to grant corresponding privileges: diff --git a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md index 86599ae6cebb1..dea38ffe061ab 100644 --- a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md +++ b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md @@ -96,9 +96,9 @@ To resolve this issue, you can create a schema in the TiDB cluster based on a [s ### Error message: "LOCK TABLES ... Access denied" -The full data export failed because the source database user does not have the `LOCK TABLES` privilege. This error typically occurs when migrating from a managed MySQL service (such as Amazon RDS or Aurora) where `FLUSH TABLES WITH READ LOCK` (FTWRL) is restricted by the cloud provider. In this case, DM's default `consistency=auto` mode falls back to `LOCK TABLES` for data consistency during full export, which requires this privilege. +The full data export failed because the source database user does not have the `LOCK TABLES` privilege. This error typically occurs when migrating from a managed MySQL service (such as Amazon RDS, Aurora, Azure Database for MySQL, or Google Cloud SQL) where `FLUSH TABLES WITH READ LOCK` (FTWRL) is not permitted by the cloud provider. In this case, DM's default `consistency=auto` mode falls back to `LOCK TABLES` for data consistency during full export, which requires this privilege. -> **Note:** This error does not occur on self-managed MySQL instances where FTWRL is available. +> **Note:** This error can also occur on self-managed MySQL instances if FTWRL is unavailable for other reasons (for example, missing `RELOAD` privilege). To resolve this issue, grant the missing privilege to the migration user in the source MySQL database: From c77ad9bbcb3425ec156527e6bb4d93d4e3b07335 Mon Sep 17 00:00:00 2001 From: Airton Lastori <6343615+alastori@users.noreply.github.com> Date: Fri, 20 Mar 2026 17:59:28 -0400 Subject: [PATCH 6/6] add ApsaraDB RDS for MySQL to managed provider list --- tidb-cloud/migrate-from-mysql-using-data-migration.md | 2 +- tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tidb-cloud/migrate-from-mysql-using-data-migration.md b/tidb-cloud/migrate-from-mysql-using-data-migration.md index 3f54965b1793a..fd2a58aff49c7 100644 --- a/tidb-cloud/migrate-from-mysql-using-data-migration.md +++ b/tidb-cloud/migrate-from-mysql-using-data-migration.md @@ -438,7 +438,7 @@ For production workloads, it is recommended to have a dedicated user for data du | `RELOAD` | Global | Ensures consistent snapshots during full dump | | `REPLICATION SLAVE` | Global | Enables binlog streaming for incremental data migration | | `REPLICATION CLIENT` | Global | Provides access to binlog position and server status | -| `LOCK TABLES` | Tables | Required when the source is a managed MySQL service (such as Amazon RDS, Aurora, Azure Database for MySQL, or Google Cloud SQL) where `FLUSH TABLES WITH READ LOCK` is not permitted. In this case, DM falls back to `LOCK TABLES` for consistency during full data export. Not required for self-managed MySQL instances where FTWRL is available. | +| `LOCK TABLES` | Tables | Required when the source is a managed MySQL service (such as Amazon RDS, Aurora, ApsaraDB RDS for MySQL, Azure Database for MySQL, or Google Cloud SQL) where `FLUSH TABLES WITH READ LOCK` is not permitted. In this case, DM falls back to `LOCK TABLES` for consistency during full data export. Not required for self-managed MySQL instances where FTWRL is available. | For example, you can use the following `GRANT` statement in your source MySQL instance to grant corresponding privileges: diff --git a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md index dea38ffe061ab..ece9f52a3ef2b 100644 --- a/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md +++ b/tidb-cloud/tidb-cloud-dm-precheck-and-troubleshooting.md @@ -96,7 +96,7 @@ To resolve this issue, you can create a schema in the TiDB cluster based on a [s ### Error message: "LOCK TABLES ... Access denied" -The full data export failed because the source database user does not have the `LOCK TABLES` privilege. This error typically occurs when migrating from a managed MySQL service (such as Amazon RDS, Aurora, Azure Database for MySQL, or Google Cloud SQL) where `FLUSH TABLES WITH READ LOCK` (FTWRL) is not permitted by the cloud provider. In this case, DM's default `consistency=auto` mode falls back to `LOCK TABLES` for data consistency during full export, which requires this privilege. +The full data export failed because the source database user does not have the `LOCK TABLES` privilege. This error typically occurs when migrating from a managed MySQL service (such as Amazon RDS, Aurora, ApsaraDB RDS for MySQL, Azure Database for MySQL, or Google Cloud SQL) where `FLUSH TABLES WITH READ LOCK` (FTWRL) is not permitted by the cloud provider. In this case, DM's default `consistency=auto` mode falls back to `LOCK TABLES` for data consistency during full export, which requires this privilege. > **Note:** This error can also occur on self-managed MySQL instances if FTWRL is unavailable for other reasons (for example, missing `RELOAD` privilege).