Joh*_*man 2 mysql mysqldump migration data-synchronization amazon-rds
我有 2 个 Amazon RDS MySQL 实例,一个是 MySql v5.5,新的一个是 5.6。我想把5.5升级到5.6,但你现在不能升级,所以我们正在尝试迁移数据。我做了 5.5 的转储并将转储导入 5.6 但由于我需要将停机时间保持在最低限度,我决定尝试在两者之间进行数据同步。
我有什么选择?
我需要尽量保持在 5 小时以内!
RDS for MySQL 5.6 支持使用 MySQL 本地复制的实时工作负载的“in”和“out”迁移策略,但 RDS for MySQL 5.5,它们只支持“in”迁移……这是不幸的,因为基本上除了一个之外的所有可能的组合您需要的可用。那会很好。:(
如果您的转储下载用了 3 个小时,而您的上传用了 4 个多小时,好消息是,您只需要 4 个多小时,因为您可以同时进行……这取决于您是从 EC2 还是从 EC2 进行测试你自己的网络,可能更快。
我的建议是绑mysqldump
到mysql
使用管道,让你同时从旧的服务器读取和写入到新的服务器。但是,为了使其正常工作,我们需要添加一些曲折。然后一些额外的曲折使它几乎变得有趣。
我认为您的理想情况是在同一地区的 EC2 中启动一台一次性 linux 机器,其中您还没有一台可用的……最好是与您的服务器相同的可用区,因为这会给您可以在所涉及的 3 个组件中获得最大的潜在带宽,而这又是一件让您放慢速度的事情。
接下来,在数据来自的源服务器上,您需要发出SET GLOBAL NET_WRITE_TIMEOUT = 600;
. 当然,您几乎无法SET GLOBAL
在 RDS 上做任何事情,因此您必须通过 RDS 参数组更改此设置。 NET_WRITE_TIMEOUT
是 MySQL 服务器在中止尝试写入阻塞的客户端之前将等待的时间量。当您将转储的输出直接通过管道传输到另一台服务器时,目标服务器将定期阻塞,有时会超过默认的 60 秒。有一个伴随变量 ,NET_READ_TIMEOUT
您可能希望将其设置为类似的值,尽管我认为该变量在转储环境中没有任何相关性。这将防止源服务器在目标服务器花费太长时间来执行其中一项大规模插入时超时mysqldump
建立。如果您有MyISAM
表,则需要将其设置得更高,因为ALTER TABLE ... ENABLE KEYS
在目标上完全恢复表后可能需要永远运行……但希望您没有。
值“600”(10 分钟)有点武断,但它是我用于此类操作的。
正如mysqldump
从远程服务器读取并将管道写入mysql
命令行客户端一样,当mysql
向目标发送大插入时,它会停止从管道读取,这会阻止mysqldump
写入管道,从而阻止从管道mysqldump
读取直到目标服务器准备好接收更多数据。除了这导致的超时之外,它还会因多种不同的原因浪费大量时间......mysqldump
花费大量时间发现表结构并启动其SELECT *
查询,我们希望避免所有浪费的时间。对此的票证是使用 unixdd
实用程序设置双缓冲区。
如果我们调用 dd 指定一个大的输出块大小而不指定一个输入块大小,它将从它的输入中读取一个小块大小(默认 512 字节),直到它读取了它的输出块大小指定的数据量,然后块它的输入并在一次大规模写入中将该数据从其输出中刷新出来。
dd obs=16384K
Run Code Online (Sandbox Code Playgroud)
这将导致 dd 以尽可能快的速度接受 16 MB 的数据,然后,一旦它可以将该块刷新到其输出,它就会接受更多。
如果我们堆叠其中的两个,我们会得到一个双缓冲区。:)
mysqldump [options] | dd obs=16384K | dd obs=16384K | mysql [options]
Run Code Online (Sandbox Code Playgroud)
使用这种结构,我们可以始终在 RAM 中保留 16 到 32 MB 的数据,在传输中,始终在源服务器和目标服务器之间......所以我们基本上可以保证一旦目标服务器准备好对于数据,我们可以立即为它准备好数据,无需等待原点......并且原点可以让自己忙于保持我们的缓冲区已满。
16 MB 并不是真正的大量数据,因此甚至可能需要更大的缓冲区,但我们不想让它们太大,因为当它们都已满时,起点必须等到目的地可以在第一个缓冲区可以刷新到第二个缓冲区之前从第二个缓冲区读取整个 16 MB,这会导致第一个缓冲区解除阻塞并开始接受来自源的更多数据......但是,如果需要,我们可以通过链接保持更多数据在飞行中甚至更多的 dd 副本。它们将使用 100% 的指定内存,但它们使用很少的 CPU。我通常至少链接 4 个。
顺便说一句,如果您在两者之间插入一些 dd,同样的 hack 也会让您获得更快的 mysqldump-pipe-to-gzip(bzip、xz 等),因为它显着增加了您始终拥有可用数据的可能性您的压缩程序要处理,保持压缩程序的处理器利用率最大化,这意味着更快的完成,因为由于处理器的充分利用,可以在更短的挂钟时间内完成处理。
您可能还应该--compress
在两者上都使用该选项mysqldump
,mysql
以便数据在两个方向上通过线路进行压缩。压缩不是免费的,但这种压缩只是 zlib 充气/放气,所以它对 CPU 本身来说并不是一笔很大的开支。正如您所指出的,像这样的操作中最慢的部分是在目的地,而目的地所要做的就是成本较低的减压。
添加--verbose
选项mysqldump
以便您可以观察数据流动。
而且,为了额外的甜蜜,几个吞吐量表:
$ sudo apt-get install pv
Run Code Online (Sandbox Code Playgroud)
这将允许您密切关注程序,终端上的输出类似于此示例:
inbound: 128MB 0:07:02 [ 0B/s] [ 364kB/s]
outbound: 96MB 0:06:00 [ 154kB/s] [ 334kB/s]
Run Code Online (Sandbox Code Playgroud)
如果您大约知道转储有多大,您可以使用其他选项来pv
提示该大小,它会以百分比计算进度。
您的最终命令如下所示(作为单行,为清晰起见,此处格式化为多行):
mysqldump --compress --verbose [other options] |
pv -pterabc -N inbound |
dd obs=16384K |
dd obs=16384K |
dd obs=16384K |
dd obs=16384K |
pv -pterabc -N outbound |
mysql --compress [other options]
Run Code Online (Sandbox Code Playgroud)
[其他选项]当然是您在之前进行还原时与 mysqldump 和 mysql 客户端一起使用的常用身份验证凭据和其他选项。
如果您有多个模式或想要以其他方式去运行mysqldump | mysql
它的并行副本的麻烦可能值得一试以减少您的总时间,以及......恢复时间是目标服务器上 CPU 和 IO 容量的产物,并且使用 RDS 似乎您可能会看到两个并行线程的总吞吐量比 1 个线程快。
我认为RDS 也有一个官方支持的选项,可以在恢复转储文件时暂时禁用二进制日志记录。您也可以探索它,因为它可能会缩短恢复时间……只要您在完成后重新打开它。
归档时间: |
|
查看次数: |
8904 次 |
最近记录: |