将数据导入 MySQL 数据库实例 - Amazon Relational Database Service

将数据导入 MySQL 数据库实例

您可以使用多种不同的技术将数据导入到 RDS for MySQL 数据库实例。最佳的方法取决于数据来源、数据量,以及是一次性完成导入还是持续导入。如果随数据一起迁移应用程序,还请考虑您可以承受的停机时间。

概述

在下表中查找将数据导入到 RDS for MySQL 数据库实例的方法。

来源 数据量 一次性或持续 应用程序停机时间 方法 更多信息

本地或 Amazon EC2 上的现有 MySQL 数据库

任何

一次性

一段时间

创建本地数据库的备份,将其存储在 Amazon S3 上,然后将该备份文件还原到运行 MySQL 的新 Amazon RDS 数据库实例上。

将备份还原到 Amazon RDS for MySQL 数据库实例

任何现有数据库

任何

一次性或持续

最低

使用 AWS Database Migration Service 可在最少停机时间下迁移数据库,对于很多数据库引擎,将继续进行持续复制。

AWS Database Migration Service 用户指南中的什么是 AWS Database Migration Service将与 MySQL 兼容的数据库作为 AWS DMS 的目标

现有 MySQL 数据库实例

任何

一次性或持续

最低

为正在进行的复制创建只读副本。提升只读副本用于一次性创建新数据库实例。

使用数据库实例只读副本

现有 MariaDB 或 MySQL 数据库

小型

一次性

一段时间

使用命令行实用程序,将数据直接复制到您的 MySQL 数据库实例。

将数据从外部 MariaDB 或 MySQL 数据库导入到 RDS for MariaDB 或 RDS for MySQL 数据库实例

未存储在现有数据库中的数据

一次性

一段时间

使用 MySQL LOAD DATA LOCAL INFILE 语句创建平面文件并导入这些文件。

从任意源将数据导入 MariaDB 或 MySQL 数据库实例

本地或 Amazon EC2 上的现有 MariaDB 或 MySQL 数据库

任何

持续

最低

配置复制,使用现有 MariaDB 或 MySQL 数据库作为复制源。

配置与外部源实例之间的二进制日志文件位置复制

将数据导入到停机时间更少的 Amazon RDS MariaDB 或 MySQL 实例

注意

'mysql' 系统数据库包含登录到数据库实例并访问数据所需的身份验证和授权信息。在数据库实例中删掉、改动、重命名或截取 'mysql' 数据库中的表、数据或其他内容可能会导致错误,并可能导致无法访问数据库实例和数据。如果发生此情况,您可以使用 AWS CLI restore-db-instance-from-db-snapshot 命令从快照中还原数据库实例。您可以使用 AWS CLI restore-db-instance-to-point-in-time 命令恢复数据库实例。

导入数据的注意事项

在下面,您可以找到有关将数据加载到 MySQL 中的其他技术信息。此信息面向熟悉 MySQL 服务器架构的高级用户。

二进制日志

与关闭二进制日志记录后加载相同数据的情况相比,启用二进制日志记录后加载数据会导致性能损失,并需要额外的可用磁盘空间 (高达四倍以上)。性能损失的严重程度和所需的可用磁盘空间量与加载数据所使用的事务大小成正比。

事务大小

事务大小在 MySQL 数据加载中起着重要的作用。它对资源消耗、磁盘空间使用率、恢复过程、恢复时间和输入格式 (平面文件或 SQL) 有重大影响。本部分介绍了事务大小如何影响二进制日志记录以及让案例在大数据加载过程中禁用二进制日志记录。如前文所述,通过设置 Amazon RDS 自动备份保留期,可启用和禁用二进制日志记录。非零值会启用二进制日志记录,零会将其禁用。我们还介绍了大型事务对 InnoDB 的影响以及将事务大小保持在较小状态的重要性。

小型事务

对于小型事务,二进制日志记录会使加载数据所需的磁盘写入次数翻倍。这种影响会严重降低其他数据库会话的性能,并增加数据加载所需的时间。体验到的降级部分取决于上传速率、加载期间发生的其他数据库活动以及 Amazon RDS 数据库实例的容量。

此外,二进制日志占用的磁盘空间大致等于数据备份和删除前加载的数据量。幸好 Amazon RDS 会频繁备份并删除二进制日志,以尽量减少这种情况。

大型事务

大型事务对启用二进制日志记录的 IOPS 和磁盘占用量的不良影响可达 3 倍。这是因为二进制日志缓存会溢到磁盘,占用磁盘空间并会为每次写入增加额外 IO。事务提交或回滚前,无法将缓存写入二进制日志,因此,其会根据数据加载量按比例占用磁盘空间。提交事务后,必须将缓存复制到二进制日志,为磁盘上的数据创建第三副本。

因此,启用二进制日志记录后加载数据所使用的可用磁盘空间必须至少为禁用二进制日志记录加载过程的三倍。例如,在加载过程中,作为单个事务加载的 10 GiB 数据将至少占用 30 GiB 磁盘空间。它使用表的 10 GiB + 二进制日志缓存的 10 GiB + 二进制日志本身的 10 GiB。缓存文件会一直保存在磁盘上,直至创建缓存文件的会话终止或在另一事务处理期间会话再次填充其二进制日志缓存。备份前二进制日志必须保存在磁盘上,因此可能要过一段时间才会释放额外的 20 GiB 空间。

在使用 LOAD DATA LOCAL INFILE 加载数据的情况下,如果数据库必须从加载前创建的备份中恢复,请为数据创建另一个副本。在恢复期间,MySQL 将二进制日志中的数据提取到平面文件中。然后,MySQL 运行 LOAD DATA LOCAL INFILE,就如在原始事务中一样。不过,这次输入文件位于数据库服务器本地。继续上述示例,除非可以使用的可用磁盘空间至少达到 40 GiB,否则恢复将失败。

禁用二进制日志记录

在可能的情况下,在大数据加载过程中禁用二进制日志记录,以避免资源开销和增加磁盘空间要求。在 Amazon RDS 中,只需将备份保留期设置为零就可以禁用二进制日志记录。如果您这样做,我们建议您先制作数据库实例的数据库快照,接着再加载。这样,在需要的情况下,可快速轻松地撤消在加载期间进行的更改。

加载后,将备份保留期设置回相应 (非零) 值。

如果数据库实例是只读副本的源数据库实例,您就无法将备份保留期设置为零。

InnoDB

本部分中的信息为使用 InnoDB 时保持小型事务提供了有力论据。

撤消

InnoDB 可以生成撤消以支持事务回滚和 MVCC 等功能。撤消可存储在 InnoDB 系统表空间 (通常为 ibdata1) 中,并且在清除线程删除前会一直保留。清除线程无法超越最早的活动事务撤消,因此,直到此事务提交或完成回滚后才能有效地阻止此线程。如果在加载期间数据库正在处理其他事务,则其撤消同样会在系统表空间中累计并且无法删除,即使它们已提交并且其他事务不需要撤消 MVCC。在这种情况下,访问由任一事务 (不仅仅是负载事务) 更改的任一行的所有事务 (包括只读事务) 都会减速。之所以减速,是因为它们会通过撤消进行扫描,而这些撤消如果不适用于长期运行的负载事务,就可能会被清除。

撤消数据存储在系统表空间中,并且系统表空间大小从不收缩。因此,大数据负载事务可能会导致系统表空间变得很大,如果不从头开始重新创建数据库,这些占用的磁盘空间就无法回收。

回滚

InnoDB 已针对提交进行了优化。回滚大型事务可能需要很长时间。在某些情况下,执行时间点恢复或还原数据库快照可能会更快。

输入数据格式

MySQL 可以接受以下两种传入数据格式之一:平面文件和 SQL。本部分说明了每一种格式的一些主要优势和劣势。

平面文件

只要将事务保持在相对较小的状态,使用 LOAD DATA LOCAL INFILE 加载平面文件就是最快速、最经济的数据加载方式。由于减少了数据库中的开销,因而与使用 SQL 加载相同的数据相比,平面文件需要的网络流量通常更少、传输成本更低并且加载速度快得多。

一个大事务

LOAD DATA LOCAL INFILE 会将整个平面文件作为一个事务进行加载。这不一定是一件坏事。如果可以将单个文件大小保持在较小状态,会有很多优势:

  • 恢复功能 – 跟踪已加载的文件非常轻松。如果在加载期间出现问题,只需简要操作就可以从停止处继续加载。可能要将一些数据重新传送到 Amazon RDS,但使用小文件,就可以将重新传输的量减少至最低水平。

  • 并行加载数据 – 如果 IOPS 和网络带宽足以支持单一文件的加载,那么并行加载就可以节省时间。

  • 限制加载速率 – 数据加载是否影响其他进程? 通过增加文件之间的时间间隔限制负载。

注意

LOAD DATA LOCAL INFILE 的优势会随着事务大小的增加而迅速减弱。如果无法将一个大数据集分成几个较小的数据集,SQL 可能是更好的选择。

SQL

与平面文件相比,SQL 的一个主要优势为:易于将事务大小保持在较小状态。不过,SQL 的加载时间显著长于平面文件,并且在发生故障后,难以确定加载恢复点。例如,Mysqldump 文件不可重新启动。如果加载 Mysqldump 文件时出现故障,需要在加载恢复前修改或替换该文件。另一种方法是在纠正故障的原因后,还原到加载前的时间点,然后回放此文件。

使用 Amazon RDS 快照采集检查点

如果加载将持续数小时甚至几天时间,那么无二进制日志记录加载过程的前景并不非常诱人,除非您可以采集定期检查点。这就是 Amazon RDS 数据库快照功能带来的便利之处。数据库快照创建时间点一致的数据库实例副本,可以使用该副本将数据库还原到发生崩溃或其他故障之前的时间点。

要创建检查点,只需创建一个数据库快照。可以删除以前为检查点创建的任何数据库快照,而不会影响持久性或还原时间。

创建快照的速度也很快,因此,频繁地检验检查点不会显著增加加载时间。

减少加载时间

这里有一些可以减少加载时间的其他技巧:

  • 加载前创建所有辅助索引。对于熟悉其他数据库的人而言,这样做违反常规。添加或修改辅助索引会使 MySQL 创建一个指数发生变化的新表,将数据从现有表复制到新表并删掉原始表。

  • 以 PK 顺序加载数据。这对 InnoDB 表尤为有用,其中加载时间可减少 75% 到 80%,数据文件大小可减小一半。

  • 禁用外键约束 foreign_key_checks=0。对于使用 LOAD DATA LOCAL INFILE 加载的平面文件,在很多情况下都需要这一操作。对于任何加载过程,禁用 FK 检查都会提供显著的性能收益。请务必确保启用约束并验证加载后的数据。

  • 并行加载,除非已经接近资源限制。适当时使用分区表。

  • 使用 SQL 加载时使用多值插入,以最大限度地减少运行语句时的开销。使用 Mysqldump 时,这会自动完成。

  • 减少 InnoDB 日志 IO innodb_flush_log_at_trx_commit=0

  • 如果您要将数据加载到没有只读副本的数据库实例,请在加载数据时将 sync_binlog 参数设置为 0。数据加载完毕后,将 sync_binlog 参数设置回 1。

  • 在将数据库实例转换为多可用区部署之前加载数据。不过,如果数据库实例已经使用多可用区部署,则不建议切换为单可用区部署来加载数据,因为这样做只能提高利润。

注意

使用 innodb_flush_log_at_trx_commit=0 会导致 InnoDB 每秒都刷新其日志,而不是在每次提交时刷新。这提供了很大的速度优势,但在崩溃期间可能导致数据丢失。请谨慎使用。