关于单表迁移到分表上,有没有什么好的办法,可以直接用ShardingSphere-Scaling 吗

想问下大家对数据迁移有没有什么心得

在最新版(5.0.0和master分支),Scaling已经融入到Proxy了。

单表迁移到分表:
现阶段需要先在Proxy配置sharding rule,配置为单分片,然后可以按照Scaling的流程做迁移。
后面会考虑源端单表不配置sharding rule,系统自动转换,方便使用。

建议使用master分支做测试,Scaling的操作方式在5.0.0刚调整为DistSQL,相关rule和DistSQL的支持在master分支支持更为完善。

你好,我想了解下目前master和5.x的支持有哪些不同
如果只用scaling的话,4.x和5.x除了distSQL有什么区别,更建议使用4.x还是5.x呢

Scaling还是实验性质的功能,在持续进化中。master分支功能会更完善一些。

除了操作方式之外,4.x和5.x的其他主要区别就在bug修复了,有个别客户在4.x出现过同步中断的问题,可能和具体数据也有关系,当时5.0.0-RC1没发现问题。
建议测试5.x版本,发现的问题会在5.x修复。

你好,我这边尝试了你说的Proxy配置sharding rule规则,测试是可以的
我想问下当我执行show scaling status 时,后面两个字段是0是什么原因
image

另外这个Scaling推荐用在生产环境吗(MySQL迁移到MySQL),目前实现了哪些功能,哪些还没实现呢,目前可以支持增量同步吗
有没有公司有尝试在生产环境使用

image
现在变为100%了

支持增量同步的,incremental_idle_minutes 反映的就是增量同步的状态。使用手册里面有个简单的功能支持情况。

停写、切换配置加锁,目前开源版还没实现,后续可能会在商业版实现。

有客户在试用,有些在用的可能也没反馈给社区。如果是生产环境使用的话,前期各个环境的模拟测试需要做完善。建议把数据一致性校验配置上,校验通过之前新规则是不会生效的,数据对了就不怕。

1 个赞

你好,我昨天尝试了通过先在config-sharding.yaml定义单分片,然后通过修改分片规则添加资源的方式触发迁移,虽然触发了分片,但也导致分片到了不同的数据库(ds_0, ds_1),我希望是分片到我指定的数据库中,比如我只想分片到ds_1

于是我的想法是:
先alter sharding rule user 到 ds_1
然后alter sharding rule user到ds_0

1、但我发现,直接alter到ds_0后,直接就进行了短暂的同步,其实我只想将ds_0中的表拆分到ds_1,请问这个要怎么做到呢
2、另外我想直接alter table rule时候去指定数据库的策略,让他只路由到新的数据库上

以下是官网的例子:

ALTER SHARDING TABLE RULE t_order (
RESOURCES(ds_0),
SHARDING_COLUMN=order_id,
TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=4)),
GENERATED_KEY(COLUMN=another_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
),t_order_item (
DATANODES("ds_0.user"),
DATABASE_STRATEGY(TYPE=standard,SHARDING_COLUMN=id,SHARDING_ALGORITHM=database_inline),
TABLE_STRATEGY(TYPE=standard,SHARDING_COLUMN=id,SHARDING_ALGORITHM=user_inline),
GENERATED_KEY(COLUMN=p_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
);

我发现第一个表的DATANODES、DATABASE_STRATEGY、TABLE_STRATEGY加上去报错,请问这是正常的吗,如果是,那我想指定第一个表只路由到新的数据库应该怎么做呢

DATANODES("resource_${0..1}.t_order_item_${0..1}"),
DATABASE_STRATEGY(TYPE=standard,SHARDING_COLUMN=user_id,SHARDING_ALGORITHM=database_inline),
TABLE_STRATEGY(TYPE=standard,SHARDING_COLUMN=order_id,SHARDING_ALGORITHM=table_inline),

以下是我的配置文件:
config-sharding.yaml

schemaName: sharding_db

dataSources:
 ds_0:
   url: jdbc:mysql://127.0.0.1:3306/account?serverTimezone=UTC&useSSL=false
   username: root
   password: rootroot
   connectionTimeoutMilliseconds: 30000
   idleTimeoutMilliseconds: 60000
   maxLifetimeMilliseconds: 1800000
   maxPoolSize: 50
   minPoolSize: 1

 ds_1:
   url: jdbc:mysql://127.0.0.1:3306/account_shard?serverTimezone=UTC&useSSL=false
   username: root
   password: rootroot
   connectionTimeoutMilliseconds: 30000
   idleTimeoutMilliseconds: 60000
   maxLifetimeMilliseconds: 1800000
   maxPoolSize: 50
   minPoolSize: 1

rules:
- !SHARDING
 tables:
   user:
     actualDataNodes: ds_0.user
     databaseStrategy:
       standard:
         shardingColumn: id
         shardingAlgorithmName: database_inline
     tableStrategy:
       standard:
         shardingColumn: id
         shardingAlgorithmName: user_inline
     keyGenerateStrategy:
       column: p_id
       keyGeneratorName: snowflake
 
 shardingAlgorithms:
   database_inline:
     type: INLINE
     props:
       algorithm-expression: ds_1
   user_inline:
     type: INLINE
     props:
       algorithm-expression: user_${id % 16}
 
 keyGenerators:
   snowflake:
     type: SNOWFLAKE
     props:
       worker-id: 123

ALTER SHARDING TABLE RULE user (
RESOURCES(ds_0,ds_4),
SHARDING_COLUMN=id,
TYPE(NAME=hash_mod,PROPERTIES("sharding-count"=16)),
DATABASE_STRATEGY(TYPE=standard,SHARDING_COLUMN=user_id,SHARDING_ALGORITHM=database_inline),
TABLE_STRATEGY(TYPE=standard,SHARDING_COLUMN=order_id,SHARDING_ALGORITHM=t_order_inline),
GENERATED_KEY(COLUMN=p_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
);

DistSQL报错请 @RaigorJiang 帮忙看下。

scaling目前只支持把数据迁移到新的数据库集群。
比如说你目前只有ds_0、需要把数据迁移到ds_1ds_2。大致步骤如下:
1,add resource ds_1 和 ds_2。
2,alter sharding table rule 指定 DATANODES 指向 ds_1 和 ds_2,触发迁移。

我自己测试的例子:
使用config-sharding.yaml默认配置,数据源包括:ds_0, ds_1。我把数据迁移到 ds_2, ds_3, ds_4,DistSQL可以这样写:

ALTER SHARDING ALGORITHM database_inline (
TYPE(NAME=INLINE,PROPERTIES("algorithm-expression"="ds_${user_id % 3 + 2}"))
);

ALTER SHARDING TABLE RULE t_order (
DATANODES("ds_${2..4}.t_order_${0..1}"),
DATABASE_STRATEGY(TYPE=standard,SHARDING_COLUMN=user_id,SHARDING_ALGORITHM=database_inline),
TABLE_STRATEGY(TYPE=standard,SHARDING_COLUMN=order_id,SHARDING_ALGORITHM=t_order_inline),
GENERATED_KEY(COLUMN=order_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
), t_order_item (
DATANODES("ds_${2..4}.t_order_item_${0..1}"),
DATABASE_STRATEGY(TYPE=standard,SHARDING_COLUMN=user_id,SHARDING_ALGORITHM=database_inline),
TABLE_STRATEGY(TYPE=standard,SHARDING_COLUMN=order_id,SHARDING_ALGORITHM=t_order_item_inline),
GENERATED_KEY(COLUMN=order_item_id,TYPE(NAME=snowflake,PROPERTIES("worker-id"=123)))
);

我晚点把scaling的使用文档升级下。

你好,通过以上描述我不太能获得准确的信息:
1、第一个表是哪一个
2、报什么错?

谢谢你们的耐心指导,我大概知道问题了,
SHARDING_COLUMN和DATABASE_STRATEGY或TABLE_STRATEGY大概是不能同时存在的
但我想问下,是什么原因导致它们不能同时存在:
我猜是因为:他们表示的意思存在相同的部分,因此存在冲突
我想了解下SHARDING_COLUMN的含义,与DATABASE_STRATEGY或TABLE_STRATEGY的关系

希望后续的文档中可以说明下:
1、SHARDING_COLUMN等每个字段的含义
2、以及是否会与其他关键字存在冲突

另外我在用distSQL的scaling部分时感觉踩了些坑,是因为我对他的触发时机其实没有太强的理解,但这在scaling中实际是很重要的,希望可以说明下scaling执行的整个过程
虽然官网有这句话,但感觉没有特别强调:
比如说RESOURCESsharding-count 修改了会触发迁移。

另外可以增加一些简单的实战案例,比如单表迁移到多表如何操作这种,我想对于刚用上分表分库中间件的项目还是挺常用的

1 个赞

@imchao9 是的,这里其实有两种配置方式,但你刚好把它们混用了。这是文档表述不够清楚的问题,感谢你的发现和提出的建议。

AutoTable(自动分片)方式使用 RESOURCES 指定资源,并且不能单独配置分库和分表,因此 SHARDING_COLUMN 放在与 RESOURCES 平级的位置。
Table 则是用户指定 DATANODES,且分库和分表需要配置不同的策略,也能用不同的分片键,因此 SHARDING_COLUMN 是在策略内部定义的。

另外我在用distSQL的scaling部分时感觉踩了些坑,是因为我对他的触发时机其实没有太强的理解,但这在scaling中实际是很重要的,希望可以说明下scaling执行的整个过程
虽然官网有这句话,但感觉没有特别强调:
比如说RESOURCESsharding-count 修改了会触发迁移。
另外可以增加一些简单的实战案例,比如单表迁移到多表如何操作这种,我想对于刚用上分表分库中间件的项目还是挺常用的

感谢建议,我们会完善下scaling文档。如果你感兴趣,欢迎提PR来帮社区完善文档。


主要是这个报错,报的不太明显,后续可以优化下

谢谢你的指导,已经可以顺利使用了
我想问个问题,目前proxy和scaling的代码是全部开源的还是部分开源
自己可以完成编译proxy+scaling吗

开源的,可以自己编译。 GitHub 仓库

1 个赞

好的,谢谢
另外我这边遇到了一个问题,现在全量可以了,增量会报错,希望大佬们帮忙解决下

[ERROR] 2021-12-07 19:49:00.885 [nioEventLoopGroup-4-1] o.a.s.cdc.mysql.client.MySQLClient - protocol resolution error

java.lang.RuntimeException: Bad handshake

at org.apache.shardingsphere.cdc.mysql.client.netty.MySQLNegotiateHandler.channelRead(MySQLNegotiateHandler.java:100)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)

at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:302)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)

at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)

at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)

at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)

at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)

at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)

at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)

at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)

at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)

at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)

at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)

at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)

at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)

at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)

at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)

at java.lang.Thread.run(Thread.java:748)

[ERROR] 2021-12-07 19:49:00.886 [ShardingSphere-Scaling-execute-4] o.a.s.s.c.job.schedule.JobScheduler - Incremental task execute failed.

java.lang.RuntimeException: java.util.concurrent.ExecutionException: java.lang.RuntimeException: Bad handshake

at org.apache.shardingsphere.cdc.mysql.client.MySQLClient.waitExpectedResponse(MySQLClient.java:216)

at org.apache.shardingsphere.cdc.mysql.client.MySQLClient.connect(MySQLClient.java:94)

at org.apache.shardingsphere.cdc.mysql.MySQLIncrementalDumper.dump(MySQLIncrementalDumper.java:104)

at org.apache.shardingsphere.cdc.mysql.MySQLIncrementalDumper.start(MySQLIncrementalDumper.java:96)

at org.apache.shardingsphere.scaling.core.job.task.incremental.IncrementalTask.start(IncrementalTask.java:86)

at org.apache.shardingsphere.schedule.core.executor.AbstractLifecycleExecutor.run(AbstractLifecycleExecutor.java:47)

at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)

at com.google.common.util.concurrent.TrustedListenableFutureTask$TrustedFutureInterruptibleTask.runInterruptibly(TrustedListenableFutureTask.java:125)

at com.google.common.util.concurrent.InterruptibleTask.run(InterruptibleTask.java:69)

at com.google.common.util.concurrent.TrustedListenableFutureTask.run(TrustedListenableFutureTask.java:78)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)

at java.lang.Thread.run(Thread.java:748)

Caused by: java.util.concurrent.ExecutionException: java.lang.RuntimeException: Bad handshake

at io.netty.util.concurrent.DefaultPromise.get(DefaultPromise.java:350)

at org.apache.shardingsphere.cdc.mysql.client.MySQLClient.waitExpectedResponse(MySQLClient.java:204)

... 12 common frames omitted

Caused by: java.lang.RuntimeException: Bad handshake

at org.apache.shardingsphere.cdc.mysql.client.netty.MySQLNegotiateHandler.channelRead(MySQLNegotiateHandler.java:100)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)

at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:302)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)

at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)

at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)

at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:324)

at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:296)

at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)

at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)

at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)

at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)

at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)

at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:719)

at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)

at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)

at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)

at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986)

at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)

at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)

... 1 common frames omitted

另外,执行的过程中会一直报这个错,想了解下为什么会报这个错

[ERROR] 2021-12-07 19:49:22.742 [ShardingSphere-Command-1] o.a.s.p.f.c.CommandExecutorTask - Exception occur: 
java.lang.UnsupportedOperationException: unsupported table : `PROFILING`
	at org.apache.shardingsphere.proxy.backend.text.admin.mysql.MySQLInformationSchemaExecutorFactory.newInstance(MySQLInformationSchemaExecutorFactory.java:52)
	at org.apache.shardingsphere.proxy.backend.text.admin.mysql.MySQLAdminExecutorFactory.newInstance(MySQLAdminExecutorFactory.java:105)
	at org.apache.shardingsphere.proxy.backend.text.admin.DatabaseAdminBackendHandlerFactory.newInstance(DatabaseAdminBackendHandlerFactory.java:78)
	at org.apache.shardingsphere.proxy.backend.text.TextProtocolBackendHandlerFactory.newInstance(TextProtocolBackendHandlerFactory.java:90)
	at org.apache.shardingsphere.proxy.frontend.mysql.command.query.text.query.MySQLComQueryPacketExecutor.<init>(MySQLComQueryPacketExecutor.java:55)
	at org.apache.shardingsphere.proxy.frontend.mysql.command.MySQLCommandExecutorFactory.newInstance(MySQLCommandExecutorFactory.java:73)
	at org.apache.shardingsphere.proxy.frontend.mysql.command.MySQLCommandExecuteEngine.getCommandExecutor(MySQLCommandExecuteEngine.java:60)
	at org.apache.shardingsphere.proxy.frontend.command.CommandExecutorTask.executeCommand(CommandExecutorTask.java:102)
	at org.apache.shardingsphere.proxy.frontend.command.CommandExecutorTask.run(CommandExecutorTask.java:77)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)

image

我自己在网上查了,可能是连接断开了,可能是useSSL为true了,但我实际上是false的,这个感觉有点奇怪

@sandynz @RaigorJiang

PROFILING 这个问题是 Navicat 在查询元数据库,目前该操作并不支持,所以有异常日志。但这对你执行的业务操作没有任何影响,可以不管。

迁移的问题期待 sandynz 解答。

1 个赞

建议排查下这几个方面:
1,MySQL binlog是否开启及配置选项
2,迁移使用的MySQL账号权限
3,是否开启了多个proxy节点,目前限单节点使用

可以参考下使用手册

京ICP备2021015875号