导入和导出数据的最佳做法

此页面介绍了使用 Cloud SQL 导入和导出数据的最佳做法。要了解将数据导入 Cloud SQL 的分步说明,请参阅导入数据

如需从 Cloud SQL 导出数据以在您管理的 MySQL 实例中使用,请参阅导出数据

导入和导出最佳做法

以下是导入和导出数据时要考虑的最佳做法:

使用相同的 SQL 模式来执行导入和导出操作

SQL 模式设置会影响 Cloud SQL 解释 SQL 查询的方式。例如,如果您从没有启用严格 SQL 的数据库中导出数据,然后尝试将数据导入到 Cloud SQL(默认启用严格 SQL),则导入操作可能会失败。最佳做法是在导入时使用导出操作所用的相同 SQL 模式。

请检查源数据库和目标数据库上的 SQL 模式是否兼容。 请特别注意启用严格 SQL 模式的标志。 如果您的数据库未设置严格 SQL,则您可能需要在 Cloud SQL 中移除严格 SQL。如果您移除严格 SQL,则必须设置其他标志。

如需验证您的 Cloud SQL 实例已设置所需的模式,请运行 SELECT @@GLOBAL.sql_mode;

请勿使用 Cloud Storage 请求者付款存储分区

您无法使用启用了请求者付款功能的 Cloud Storage 存储分区来将数据导入 Cloud SQL 以及从 Cloud SQL 导出数据。

使用无服务器导出从主实例分流导出操作

从 Cloud SQL 执行标准导出时,导出操作会在数据库在线时运行。当导出的数据库比较小时,影响很小。但是,对于大型数据库或大型对象(例如数据库中的 BLOB),导出操作可能会降低数据库性能。这可能会影响对数据库执行数据库查询和操作所需的时间。启动导出操作后,如果数据库响应开始变得缓慢,则您无法停止导出操作。

为了防止导出期间响应缓慢,您可以使用无服务器导出功能。使用无服务器导出功能时,Cloud SQL 会创建一个单独的临时实例来分流导出操作。如果分流导出操作,则主实例上的数据库可以按正常的性能速率继续处理查询和执行操作。数据导出操作完成后,临时实例会被自动删除。

使用带有 offload 标志的 gcloud 或 REST API 导出函数执行无服务器导出操作。

在无服务器导出操作期间,您可以运行一些其他操作,例如实例修改、导入和故障转移。但是,如果您选择 delete,导出操作会在您删除实例一段时间后停止,并且不会导出任何数据。

与标准导出操作相比,无服务器导出操作需要的时间更长,因为创建临时实例需要时间。实际需要的时间超过五分钟;对于较大的数据库,需要的时间可能更长。在确定要使用哪种类型的导出功能之前,请考虑其对时间和性能的影响。

您可以在主实例或读取副本上使用无服务器导出功能。

创建 SQL 转储文件时使用正确的标志

如果在将数据导出到 SQL 转储文件时未使用正确的标志,则导入操作可能会失败。要了解如何创建 SQL 转储文件以导入 Cloud SQL,请参阅创建 SQL 转储文件

压缩数据以减少费用

Cloud SQL 支持导入和导出压缩文件及未压缩文件。压缩文件可以节省 Cloud Storage 上的大量存储空间并减少存储费用,这在导出大型实例时尤为明显。

导出 SQL 转储文件或 CSV 文件时,请将数据压缩成扩展名为 .gz 的文件。导入扩展名为 .gz 的文件时,系统会自动将其解压缩。

减少长时间运行的导入和导出过程

使用导入功能(通过 Cloud Storage 存储分区)导入到 Cloud SQL 以及从 Cloud SQL 导出可能需要很长时间才能完成,具体取决于数据库的大小。这可能产生以下影响:

  • 您无法停止长时间运行的 Cloud SQL 实例操作。
  • 针对每个实例,每次仅可执行一项导入或导出操作。

对小批量数据使用 Cloud SQL 导入或导出功能可以缩短每项操作的完成时间。

对于导出,您可以使用无服务器导出来最大限度地降低对数据库性能的影响,并允许其他操作在导出运行时在实例上运行。

如需更多提示,请参阅诊断 Cloud SQL 实例的问题

使用 InnoDB

InnoDB 是 MySQL 实例唯一支持的存储引擎。

您可以通过 sed 脚本经管道输送 mysqldump 的输出,将表从 MyISAM 转换为 InnoDB,如下所示:

mysqldump --databases [DATABASE_NAME] \
-h [INSTANCE_IP] -u [USERNAME] -p [PASSWORD] \
--hex-blob --default-character-set=utf8mb4 | sed 's/ENGINE=MyISAM/ENGINE=InnoDB/g' > [DATABASE_FILE].sql

包含具有 DEFINER 子句的元数据的 MySQL 导入和迁移作业

因为 MySQL 导入或迁移作业不会迁移用户数据,所以包含用户用 DEFINER 子句定义的元数据的源和转储文件将无法导入或迁移,因为那里尚不存在用户。

如需确定元数据中存在哪些 DEFINER 值,请使用以下查询(或在转储文件中搜索),以检查是否存在 root%localhost 的条目,或者不存在于目标实例中的用户的条目。

SELECT DISTINCT DEFINER FROM INFORMATION_SCHEMA.EVENTS;
SELECT DISTINCT DEFINER FROM INFORMATION_SCHEMA.ROUTINES;
SELECT DISTINCT DEFINER FROM INFORMATION_SCHEMA.TRIGGERS;
SELECT DISTINCT DEFINER FROM INFORMATION_SCHEMA.VIEWS;

如需从包含此元数据的源运行导入或迁移作业,您可以执行以下操作之一:

  • 在开始导入或迁移作业之前,请在目标 Cloud SQL 实例上创建用户。
  • 在开始导入或迁移作业之前,将源 MySQL 实例或转储文件中的 DEFINER 子句更新为 INVOKER

验证导入的数据库

导入操作完成后,连接到您的数据库并运行相应的数据库命令,以确保内容正确无误。例如,连接并列出数据库、表和特定条目。

已知限制

Cloud Storage 支持的单个对象大小上限为 5TB。如果您的数据库大小大于 5TB,则到 Cloud Storage 的导出操作将失败。在这种情况下,您需要将导出文件细分为几个较小的部分。

问题排查

点击表中的链接可查看详细信息:

针对此问题… 可能的原因… 请尝试以下操作…
导入时间太长。 过多的有效连接可能会干扰导入操作。 关闭未使用的连接,或者在开始执行导入操作之前重启 Cloud SQL 实例。
导入失败。 导出的文件可能包含尚不存在的数据库用户。 请先清理发生故障的数据库,然后再重试导入。在导入之前先创建数据库用户
导入时出错:表不存在。 所需的表目前不存在。 在开始导入时停用 FOREIGN_KEY_CHECKS
错误消息:ERROR 1045 (28000) at line {line_number}: Access denied for user 'cloudsqlimport'@'localhost' DEFINER 存在于转储文件中,但不存在于数据库中。 详细了解 Cloud SQL 中的 DEFINER 用法以及可能的解决方法。
错误消息:Unknown table 'COLUMN_STATISTICS' in information_schema 如果您使用 MySQL 8.0 中的 mysqldump 二进制文件转储 MySQL 5.7 数据库中的数据,并将其导入 MySQL 8.0 数据库,则会发生这种情况。 如果您转储 MySQL 5.7 数据库中的数据,并将其导入 MySQL 8.0 数据库,请确保使用 MySQL 5.7 中的 mysqldump 二进制文件。如果您使用的是 MySQL 8.0 中的 mysqldump 二进制文件,则需要添加 --column-statistics=0 标志。

导入时间太长

导入时间太长,阻止了其他操作。

可能的原因

过多的有效连接可能会干扰导入操作。连接会消耗 CPU 和内存,从而限制可用的资源。

可以尝试的操作

关闭未使用的操作。检查 CPU 和内存用量,以确保有大量的可用资源。确保将最多资源用于导入操作的最佳方法是在开始执行操作之前重启实例。重启后,系统会执行以下操作:

  • 关闭所有连接。
  • 结束任何可能正在消耗资源的任务。


导入失败

如果导出的 SQL 转储文件中引用的一个或多个用户不存在,则导入会失败。

可能的原因

在导入 SQL 转储之前,拥有对象或获得了对转储数据库中的对象权限的所有数据库用户都必须存在。如果不存在,则恢复将无法重新创建具有原始所有权和/或权限的对象。

可以尝试的操作

请先清理发生故障的数据库,然后再重试导入。在导入 SQL 转储之前,先创建数据库用户


导入时出错:表不存在

导入操作因表不存在而失败。

可能的原因

表可以与其他表有外键依赖关系,根据操作的顺序,其中一个或多个表可能在导入操作期间还不存在。

可以尝试的操作

在转储文件的开头添加以下行:

  SET FOREIGN_KEY_CHECKS=0;

此外,请在转储文件的末尾添加以下行:

  SET FOREIGN_KEY_CHECKS=1;

这些设置会在导入操作执行期间停用数据完整性检查,并在加载数据后重新激活数据完整性检查。这不会影响数据库中数据的完整性,因为数据在创建转储文件期间已经过验证。


错误消息:ERROR 1045 (28000) at line {line_number}: Access denied for user 'cloudsqlimport'@'localhost'

您会看到错误 ERROR 1045 (28000) at line {line_number}: Access denied for user 'cloudsqlimport'@'localhost'

可能的原因

根本原因是转储文件中具有 DEFINER 子句的用户不存在于数据库中,而且该用户在数据库的对象定义中交叉引用。

可以尝试的操作

如需了解如何在转储文件中使用 DEFINER 子句导入数据库,请参阅文档。您可能需要先在数据库中创建一个或多个用户。


错误消息:information_schema 中的未知表“COLUMN_STATISTICS”

您看到错误消息 Unknown table 'COLUMN_STATISTICS' in information_schema

可能的原因

如果您使用 MySQL 8.0 中的 mysqldump 二进制文件转储 MySQL 5.7 数据库中的数据,并将其导入 MySQL 8.0 数据库,则会发生这种情况。

可以尝试的操作

如果您转储 MySQL 5.7 数据库中的数据,并将其导入 MySQL 8.0 数据库,请确保使用 MySQL 5.7 中的 mysqldump 二进制文件。如果您使用的是 MySQL 8.0 中的 mysqldump 二进制文件,则需要添加 --column-statistics=0 标志。

点击表中的链接可查看详细信息:

针对此问题… 可能的原因… 请尝试以下操作…
无法查看当前操作状态。 用户界面仅显示成功或失败。 使用相关数据库命令了解详情。
在导出过程中出现 408 Error (Timeout) SQL 导出可能需要很长时间,具体取决于数据库大小和导出内容。 使用多个 CSV 导出以减小每项操作的规模
CSV 导出成功,但 SQL 导出失败。 SQL 导出更有可能遇到 Cloud SQL 的兼容性问题。 使用 CSV 导出以仅导出您需要的文件。
导出时间太长。 Cloud SQL 不支持并发同步操作。 使用导出分流。了解详情
Error 1412: Table definition has changed 导出期间表发生了更改。 从转储操作中移除任何表更改语句
连接在导出操作期间关闭。 查询必须在前 7 分钟内生成数据。 手动测试查询。了解详情
导出过程中出现未知错误。 可能存在带宽问题。 确保实例和 Cloud Storage 存储分区位于同一区域
您想要自动执行导出。 Cloud SQL 不提供自动执行导出的方法。 构建您自己的流水线来执行此功能。了解详情
错误消息:Access denied; you need (at least one of) the SUPER privilege(s) for this operation 转储文件中可能有使用 super user@localhost(例如 root@localhost)的事件、视图、函数或过程。Cloud SQL 不支持此功能。 详细了解 Cloud SQL 中的 DEFINER 用法以及可能的解决方法。

无法查看操作状态

您无法查看正在进行的操作的状态。

可能的原因

Google Cloud Console 在完成后仅报告成功或失败,不会返回警告。

可以尝试的操作

连接到数据库并运行 SHOW WARNINGS


导出过程中出现 408 错误(超时)

您在 Cloud SQL 中执行导出作业时看到错误消息 408 Error (Timeout)

可能的原因

CSV 和 SQL 格式的导出方式不同。SQL 格式会导出整个数据库,可能需要较长的时间才能完成。CSV 格式可让您定义要导出的数据库元素。

可以尝试的操作

使用 CSV 格式,并运行多个较小的导出作业,以减小每项操作的规模和长度。


CSV 导出成功,但 SQL 导出失败

CSV 导出成功,但 SQL 导出失败。

可能的原因

CSV 和 SQL 格式的导出方式不同。SQL 格式会导出整个数据库,可能需要较长的时间才能完成。CSV 格式可让您定义要导出的数据库元素。

可以尝试的操作

使用 CSV 导出以仅导出您需要的内容。


导出时间太长

导出时间太长,阻止了其他操作。

可能的原因

Cloud SQL 不支持并发同步操作。

可以尝试的操作

尝试一次导出较小的数据集。


mysqldump:错误 1412:表定义已更改

您看到错误消息 mysqldump: Error 1412: Table definition has changed, retry transaction when dumping the table

可能的原因

在导出过程中,表发生了更改。

可以尝试的操作

如果在导出操作期间使用以下语句,则转储事务可能会失败:

  • ALTER TABLE
  • CREATE TABLE
  • DROP TABLE
  • RENAME TABLE
  • TRUNCATE TABLE
从转储操作中移除所有这些语句。


连接在导出操作期间关闭

连接在导出操作期间关闭。

可能的原因

与 Cloud Storage 的连接可能超时,因为在导出中运行的查询在导出启动后的 7 分钟内未生成任何数据。

可以尝试的操作

手动测试查询,方法是从任何客户端连接,然后使用以下命令将查询的输出发送到 STDOUT:

COPY (INSERT_YOUR_QUERY_HERE) TO STDOUT WITH ( FORMAT csv, DELIMITER ',', ENCODING 'UTF8', QUOTE '"', ESCAPE '"' )

这是预期行为,因为启动导出后,客户端应立即开始发送数据。在未发送数据情况下保持连接最终会断开连接,最后导致导出失败,使操作处于不确定状态。此外,以下是来自 gcloud 的错误消息:

operation is taking longer than expected


导出过程中出现未知错误

您在尝试将数据库导出到 Cloud Storage 存储分区时看到错误消息 Unknown error

可能的原因

转移可能由于带宽问题失败。

可以尝试的操作

Cloud SQL 实例可能与 Cloud Storage 存储分区位于不同区域。从一个大洲读取数据并将数据写入另一个大洲涉及很多网络用量,可能会导致类似的问题。检查实例和存储分区所在的区域。


想要自动执行导出

您想要自动执行导出。

可能的原因

Cloud SQL 不提供自动执行导出的方法。

可以尝试的操作

您可以使用 Cloud Scheduler、Pub/Sub 和 Cloud Functions 等 Google Cloud 产品构建自己的自动导出系统。


出现 ERROR_RDBMS 系统错误

您看到错误消息 [ERROR_RDBMS] system error occurred

可能的原因

  • 用户可能没有所需的所有 Cloud Storage 权限。
  • 数据库表可能不存在。

可以尝试的操作

  1. 检查核实您对存储分区至少拥有 WRITER 权限,并且对导出文件至少拥有 READER 权限。如需详细了解如何在 Cloud Storage 中配置访问权限控制,请参阅创建和管理访问权限控制列表
  2. 确保表已存在。如果表已存在,请确认您对存储分区拥有正确的权限。

访问遭拒;您需要(至少其中一种)SUPER 特权才能执行此操作

您会看到错误 Access denied; you need (at least one of) the SUPER privilege(s) for this operation

可能的原因

转储文件中可能有使用 super user@localhost(例如 root@localhost)的事件、视图、函数或过程。Cloud SQL 不支持此功能。

可以尝试的操作

如需了解如何使用 DEFINER 子句导入数据库,请参阅此文档

后续步骤