云时代已经来临,云上很多场景下都需要数据的迁移、备份和流转,各大云厂商也大都提供了自己的迁移工具。本文主要介绍京东云数据库为解决用户数据迁移的常见场景所提供的解决方案。
数据迁移上云是最常见的一类场景,目前京东云提供了两个DTS(Data Transformation Service)迁移工具供选择,一个是数据迁移,一个是数据同步:
二者的主要区别如下:

下面是这两个工具使用中的一些常见问题:
01 两个迁移工具的原理是什么?
以MySQL为例,两个工具都有全量迁移/增量迁移/数据校验三个阶段,这三个阶段的主要原理如下:
全量阶段:
数据迁移使用mysqldump --single-transaction来取得一致性快照,但无法保证非事务引擎表的数据一致性,加上增量才可以保证数据的最终一致性,这个过程是串行操作;
数据同步使用多表并行的select方式,根据主键顺序分批获取记录,循环执行,如果没有主键,则进行全表查询。为了最大限度减少对源实例的影响,这个过程不加锁,也不用开启事务获得一致读,因此全量期间迁移的数据是不一致的,通过增量阶段可以达到最终一致性。所以数据同步只提供了‘全量+增量’和‘增量’两种选项,不提供单独的‘全量’选项。
增量阶段:
数据迁移和数据同步一样,都是通过迁移启动前记录的gtid点位,抓取对应binlog同步apply到目标端,二者区别在于迁移是串行的,同步会将同一个表的事务合并后一次提交,效率更高。
数据校验:
将源库的数据分块计算crc,每个块的元数据和校验信息记录到目标实例_jdts_check为前缀的库下checksum表中。目标库同步完成后根据同样算法进行计算,比较对应块号的crc值是否一致来判断校验是否成功。
02 迁移速度可以调整吗?
数据迁移不可以,数据同步可以选择更大的迁移实例和增加更多的并发来调整,但由于并发机制是基于表粒度的,对于少量大表的情况,增加并发并不会有明显作用。
03 迁移进度为什么显示超过100%?
为了效率更高,迁移显示的进度是根据已经迁移的记录数除以数据字典记录的记录数显示,数据字典的值并不完全准确,因此理论上会出现进度超过100%的现象。
04 迁移延时为什么很长?
大多情况是源库写操作压力大导致目标库binlog apply进度赶不上源库的写入速度,也有可能是目标库读写压力大或者迁移实例压力大,具体需要联系京东云技术服务及时介入。
05 迁移期间目标库是否可以读写数据?
理论上可以读写,但不建议在迁移期间操作,主要有两个弊端:
06 目标端如果有同名库表是否会被覆盖?
不会的,如果目标库库表有数据,预检的时候会报错不通过;如果是空的库表,则可以直接写入。
07 自检提示源或目标库网络不通怎么办?
检查源库和目标库的白名单限制,需要加上dts迁移实例的ip,在迁移任务配置的时候会在页面提示。
08 目标库中的_jdts为前缀的库可以删除吗?
迁移完成可以删除。
09 可以从只读实例同步吗?
只要源实例是gtid方式复制的,都可以通过主实例或只读实例同步。
10 数据迁移选择内网时,为啥只能用json格式,不能图形化选择库表?
因为数据迁移创建任务的时候,迁移实例还未创建,无法判断内网连通性;数据同步已经做了改进,内外网均可以通过图形化方式选择库表。
11 迁移期间对源实例有影响吗?
无论数据迁移还是数据同步,都需要对源实例库表做select,会有一定的读IO压力,建议尽量在业务低峰期同步或从只读实例同步。对于数据同步任务, 可通过控制台暂停任务,待源库负载降低,再启动数据同步任务。
12 mysql系统库应该如何迁移?
目前不支持迁移MySQL库,建议用户迁移时提前在目标库创建配置好对应的用户和权限。或者通过mysqldump等工具从源库导入。
13 迁移过程出现Got fatal error 1236 ... 的报错怎么办?
这个报错可能会在增量迁移过程出现,主要原因是增量需要的binlog在源端被删除所致,因此迁移期间尽量将源端binlog保留较长的时间。如果出现此类报错,如果无法找回被删binlog,只能重新开始迁移。
14 源端目标端版本必须一致吗?
数据迁移要求两边版本一致;数据同步目前支持低->高版本迁移。
用户经常会对数据有异地灾备的需求,京东云目前提供了两种方式,一种是可以配置跨地域备份同步,如下图:
这种方式简单免费,会定期将最新备份同步到异地,缺点是数据是非实时的,如果灾备恢复会有数据丢失。
另外一种方案是灾备同步(目前暂只支持MySQL),可以在京东云控制台创建一个异地灾备实例,然后利用DTS的数据同步功能将灾备实例和源实例进行数据同步,同步方式选择灾备同步。和普通同步机制不同,灾备同步利用的是MySQL的原生复制,因此灾备实例和源实例是完全一致的,相当于一个异地的只读实例,这样就可以达到异地灾备的目的。
对于灾备实例,有几点需要注意:
很多业务场景都会用到数据订阅,比如订阅数据到ES扩展搜索、上下游订阅价格变更/服务通知、多业务库数据合并/构建宽表等。京东云提供了数据订阅功能来满足类似需求,目前源端支持
MySQL/Percona/MariaDB/PostgreSQL,目标端仅支持Kafka。
目标端使用json格式记录订阅信息,下面是一个update操作的例子:
{
"version": "0.1",
"database": "dbtest",
"table": "t1",
"type": "update",
"ts": 1582617997,
"time_zone": "Asia/Shanghai",
"host": "mysql-internet-cn-north-1-c52cb616874d4d29.rds.jdcloud.com",
"data": {
"created": "2020-02-25 16:01:46",
"flag": "10691",
"info": "dts_test",
"pkid": "11663",
"uuid": "11cae53d-57a5-11ea-98a6-fa163ea31339"
},
"old": {
"created": "2020-02-25 16:01:46",
"flag": "10691",
"info": null,
"pkid": "11663",
"uuid": "11cae53d-57a5-11ea-98a6-fa163ea31339"
},
"pks": {
"pkid": "11663"
}
}
数据订阅有几点需要注意:
用户经常有这样的需求,是否可以用自建MySQL来同步云上MySQL?或者反过来,是否可以云上MySQL作为自建MySQL的从库来满足某些场景?
作者:翟振兴
如何正确创建Rails迁移,以便将表更改为MySQL中的MyISAM?目前是InnoDB。运行原始执行语句会更改表,但它不会更新db/schema.rb,因此当在测试环境中重新创建表时,它会返回到InnoDB并且我的全文搜索失败。我如何着手更改/添加迁移,以便将现有表修改为MyISAM并更新schema.rb,以便我的数据库和相应的测试数据库得到相应更新? 最佳答案 我没有找到执行此操作的好方法。您可以像有人建议的那样更改您的schema.rb,然后运行:rakedb:schema:load,但是,这将覆盖您的数据。我的做法是(假设
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
我们的git存储库中目前有一个Gemfile。但是,有一个gem我只在我的环境中本地使用(我的团队不使用它)。为了使用它,我必须将它添加到我们的Gemfile中,但每次我checkout到我们的master/dev主分支时,由于与跟踪的gemfile冲突,我必须删除它。我想要的是类似Gemfile.local的东西,它将继承从Gemfile导入的gems,但也允许在那里导入新的gems以供使用只有我的机器。此文件将在.gitignore中被忽略。这可能吗? 最佳答案 设置BUNDLE_GEMFILE环境变量:BUNDLE_GEMFI
这似乎非常适得其反,因为太多的gem会在window上破裂。我一直在处理很多mysql和ruby-mysqlgem问题(gem本身发生段错误,一个名为UnixSocket的类显然在Windows机器上不能正常工作,等等)。我只是在浪费时间吗?我应该转向不同的脚本语言吗? 最佳答案 我在Windows上使用Ruby的经验很少,但是当我开始使用Ruby时,我是在Windows上,我的总体印象是它不是Windows原生系统。因此,在主要使用Windows多年之后,开始使用Ruby促使我切换回原来的系统Unix,这次是Linux。Rub
我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_