想问下大家对数据迁移有没有什么心得
在最新版(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是什么原因
另外这个Scaling推荐用在生产环境吗(MySQL迁移到MySQL),目前实现了哪些功能,哪些还没实现呢,目前可以支持增量同步吗
有没有公司有尝试在生产环境使用
现在变为100%了
支持增量同步的,incremental_idle_minutes 反映的就是增量同步的状态。使用手册里面有个简单的功能支持情况。
停写、切换配置加锁,目前开源版还没实现,后续可能会在商业版实现。
有客户在试用,有些在用的可能也没反馈给社区。如果是生产环境使用的话,前期各个环境的模拟测试需要做完善。建议把数据一致性校验配置上,校验通过之前新规则是不会生效的,数据对了就不怕。
你好,我昨天尝试了通过先在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_1
和ds_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执行的整个过程
虽然官网有这句话,但感觉没有特别强调:
比如说RESOURCES
和sharding-count
修改了会触发迁移。
另外可以增加一些简单的实战案例,比如单表迁移到多表如何操作这种,我想对于刚用上分表分库中间件的项目还是挺常用的
AutoTable(自动分片)方式使用 RESOURCES
指定资源,并且不能单独配置分库和分表,因此 SHARDING_COLUMN 放在与 RESOURCES 平级的位置。
Table 则是用户指定 DATANODES
,且分库和分表需要配置不同的策略,也能用不同的分片键,因此 SHARDING_COLUMN 是在策略内部定义的。
另外我在用distSQL的scaling部分时感觉踩了些坑,是因为我对他的触发时机其实没有太强的理解,但这在scaling中实际是很重要的,希望可以说明下scaling执行的整个过程
虽然官网有这句话,但感觉没有特别强调:
比如说RESOURCES
和sharding-count
修改了会触发迁移。
另外可以增加一些简单的实战案例,比如单表迁移到多表如何操作这种,我想对于刚用上分表分库中间件的项目还是挺常用的
感谢建议,我们会完善下scaling文档。如果你感兴趣,欢迎提PR来帮社区完善文档。
谢谢你的指导,已经可以顺利使用了
我想问个问题,目前proxy和scaling的代码是全部开源的还是部分开源
自己可以完成编译proxy+scaling吗
好的,谢谢
另外我这边遇到了一个问题,现在全量可以了,增量会报错,希望大佬们帮忙解决下
[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)
我自己在网上查了,可能是连接断开了,可能是useSSL为true了,但我实际上是false的,这个感觉有点奇怪
PROFILING 这个问题是 Navicat 在查询元数据库,目前该操作并不支持,所以有异常日志。但这对你执行的业务操作没有任何影响,可以不管。
迁移的问题期待 sandynz 解答。