MySQL迁移OceanBase问题记录

Maven 依赖调整

1. mysql 驱动:OceanBase 官方 推荐使用5.1.47版本

OceanBase分布式数据库-海量数据 笔笔算数

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    <version>5.1.47</version>
</dependency>

2. druid 连接池:1.1.21后新版本DbType增加jdbc:oceanbase 类型,同时修复mybatisplus 3.2 LocalDateTime类型不兼容问题

Release Druid发布1.1.21版本,修复mybatisplus 3.2 LocalDateTime类型不兼容问题 · alibaba/druid · GitHub

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.6</version>
</dependency>

3. Flyway: flyway不支持OceanBase,取消依赖

https://en.wikipedia.org/wiki/Flyway_(software)

<!--        flyway 官网 Supported Databases不包含oceanbase
            <dependency>-->
<!--            <groupId>org.flywaydb</groupId>-->
<!--            <artifactId>flyway-core</artifactId>-->
<!--        </dependency>-->

4. 引入本地 oceanbase-client

<dependency>
    <groupId>com.oceanbase</groupId>
    <artifactId>oceanbase-client</artifactId>
    <version>2.2.5</version>
    <scope>system</scope>
    <!--    <systemPath>${project.basedir}/lib/oceanbase-client-2.2.5.jar</systemPath> -->
    <systemPath>${project.basedir}/lib/oceanbase-client-2.2.10.1jar</systemPath>
</dependency>

5.mybatis-plus 分页插件 3.4.0才支持oceanbase

Release v3.4.0 · baomidou/mybatis-plus · GitHub

<!--mybatis plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.0</version>
</dependency>

<!--mybatis plus 代码生成器 -->
<!--mybatis-plus 分页插件 3.4.0才支持oceanbase  
com.baomidou.mybatisplus.annotation.DbType GitHub 提交记录-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.0</version>
    <scope>provided</scope>
</dependency>

6.升级druid和mybatis-plus版本之后导致druid和Localdatetime不兼容。在prepareStatement时会将Localdatetime类型的参数丢失

<!-- druid和localdatetime不兼容的问题-->
<dependency> 
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-typehandlers-jsr310</artifactId>
    <version>1.0.2</version>
</dependency>

MySQL、Oracle、OceanBase 参数配置差异

Oracle

        Oracle数据库中,SQL语句的执行时间没有上限。如果SQL长时间执行而没有返回结果,Oracle不会干预,该SQL将一直运行,连接也会保持。如果SQL持有锁,锁和事务都将一直持续。SQL执行慢的原因通常有两类:

        一是SQL性能问题,可能是因为需要扫描大量数据或进行大型数据集之间的连接,常见于数据仓库业务中;

        二是SQL被其他会话阻塞,例如SQL在申请记录锁时,与其他会话发生锁冲突。

        Oracle的策略是将处理慢SQL或阻塞问题的责任交给应用开发者。通常,这些问题由运维人员来解决,例如,通过脚本定时查询长时间运行的SQL(使用v$session_longops视图)或检测长时间被阻塞的会话,然后通过kill session命令终止这些会话。业务研发人员对此策略意见不一。部分数据库连接驱动提供了查询超时功能,可能在检测到SQL长时间未返回时,自动执行kill session

MySQL

        MySQL中,慢SQL的处理更灵活。MySQL提供了设置SQL执行时间的超时参数。超时达到阈值时,SQL会提前返回或报错。在MySQL 5.6版本中,该参数为max_statement_time(单位:毫秒),在5.7及之后版本为max_execution_time(单位:毫秒)。默认值为0,表示永不超时。

        相比之下,MySQL对慢SQL提供了更多主动控制的选项,而Oracle的策略更依赖应用和运维人员进行处理。

      MySQL(特别是InnoDB引擎中),针对DML操作在申请锁被阻塞时,MySQL有一个参数用于设置锁等待的超时时间,称为innodb_lock_wait_timeout(默认:50秒)。如果SQL在等待锁时超过了这个超时时间,MySQL会报错:"Lock wait timeout exceeded; try restarting transaction"。这表明锁等待超时,但不会自动回滚当前事务。应用程序需要捕获这个异常,并根据需要主动决定是回滚还是继续处理。

        事务在锁等待超时时是否自动回滚取决于innodb_rollback_on_timeout参数的设置,默认情况下是OFF,意味着即使发生锁等待超时,事务也不会自动回滚。因此,应用程序需要谨慎处理这些错误,确保数据完整性,并决定是重新尝试事务、回滚还是采取其他措施。

        Mysql SQLNonTransientConnectionException 异常处理

        innodb_lock_wait_timeout , 默认值为 50秒 , 数据库锁超过这个时间,导致报错。

OceanBase

        OceanBase对慢SQL处理只有一种策略。即针对每个SQL的执行时间设置一个超时阈值。参数是​​ob_query_timeout​​,默认值是10000000(微秒us),即10秒。这个默认时间很短,所以在OB里跑慢SQL很容易就碰到这个报错(​​-4012:Timeout​​)。这个参数是个租户(实例)变量,需要运维手动修改一下。

show session variables like 'ob_%timeout%';
+---------------------+-----------+
| Variable_name       | Value     |
+---------------------+-----------+
| ob_query_timeout    |  10000000 |
| ob_trx_idle_timeout | 120000000 |
| ob_trx_timeout      | 100000000 |
+---------------------+-----------+

set session ob_query_timeout=7000000;

set global ob_query_timeout=100000000;

        注意,如果是修改租户(实例)变量的范围是全局(​​global​​),则需要会话重新连接才会生效。这个机制是跟​​MySQL​​保持一致的。也可以在会话层面修改。

        OceanBase比MySQL做得更进一步的是针对未提交事务也增加了两个超时限制。一个是事务闲置超时时间,变量​​ob_trx_idle_timeout​​控制,默认值是120000000(微秒us),即120秒。第二个是事务提交超时时间,变量​​ob_trx_timeout​​控制,默认值是100000000(微秒us),即100秒。

      OceanBase之所以在SQL执行和事务提交时设置超时时间,是为了避免慢SQL或阻塞的事务长时间占用数据库资源(如连接、内存等)。在高并发的互联网业务中,慢SQL或未提交的事务可能对数据库造成极大的压力。因此,即使因为超时而报错,这种策略也是明智的。

        当业务系统频繁收到超时报错时,可能意味着应用设计存在问题,需要进行分析和优化。如果确实发现设计缺陷,应与运维团队协商,调整租户(实例)的全局超时设置。但如果全局设置的更改会影响所有连接,则可以考虑在会话级别调整超时值。例如,在批量处理逻辑中,事务可能需要较长时间运行,这时可以通过会话级别的配置来确保不受全局设置的限制。

        OceanBase常见超时参数

        OceanBase 租户在刚开始使用的时候,建议调大租户的几个超时参数。

        1.ob_query_timeout:语句执行超时时间,单位 us, 默认值是 10000000 (也就是 10 秒)。 建议根据业务 SQL 平均执行时间水平调整。OLTP 场景调整短一些,OLAP 场景调整大一些。 初学者建议调大 10倍;

        2.ob_trx_idle_timeout :事务空闲超时时间,单位 us, 默认值是 120000000(也就是 120 秒)。建议根据业务事务平均空闲时间水平调整。空闲事务会占用连接、可能持有锁不释放, 导致高并发时阻塞和死锁概率增加。不建议调大;

        3.ob_trx_timeout :事务未提交超时时间,单位 us,默认值是 100000000 (也就是 100 秒)。 建议根据业务事务平均持续时间水平调整。事务长期不提交,会占用连接、可能持有锁不释 放,导致高并发时阻塞和死锁概率增加。不建议调大。如果是后台跑批业务,建议在会话级 别调大;

        4.ob_trx_lock_timeout:事务申请加锁等待超时时间,单位 us,默认值是 -1(也就是不控制。 超时依然会受;

        5.ob_query_timeout 限制。当调大了语句超时时间变量(ob_query_timeout)后,可以将 这个锁等待超时改为 10000000(即 10s)。减少阻塞和死锁的概率。

        数据库针对慢SQL或者未提交的事务,Oracle、MySQL、OceanBase选择了不同的策略去处理。OceanBase是分布式数据库,业务场景并发压力可能非常大,所以OceanBase选择了超时释放资源的策略。应用从Oracle或MySQL迁移到OceanBase时,需要根据业务需求动态调整上面所说的参数配置。

数据迁移

        使用 DataX 迁移 MySQL 表数据到 OceanBase 数据库,见OceanBase 官网:OceanBase分布式数据库-海量数据 笔笔算数

  • 58
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值