将现场300G的数据导入OceanBase在每日合并时报错

【 使用环境 】测试环境
【 OB or 其他组件 】
ob3.1.4
【 环境说明 】
业务租户内存75G,如下图
image

【问题描述】我们尝试将现场两张数据量比较多的表导入oceanbase报错,csv文件大小约300G,导入程序是我们自己写的,基本原理就是jdbc1000条提交一次这么写

jdbc:mysql://xx.xx.xx.xx:2883/$dbname?useLocalSessionState=true&allowBatch=true&allowMultiQueries=true&rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false

【复现路径】

  • 我们原本没有对任何系统参数的修改,导入时发现每晚在合并期间会报错
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [REPLACE INTO `HIS_02004_2021` (`UPDATE_TIME`,`POINT_ID`,`UPLOAD_TIME`,`VAL`) VALUES (?,?,?,?)]; SQL state [HY000]; error code [4030]; Over tenant memory limits; nested exception is java.sql.BatchUpdateException: Over tenant memory limits
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:662)

  • 于是我们调整了一些参数
freeze_trigger_percentage 50 --> 35
writing_throttling_trigger_percentage 100 --> 95
ob_sql_work_area_percentage 5 --> 10
  • 又在ocp页面启用了轮转合并并调整了下时间

  • 然后发现轮转合并第一个Zone结束以后程序又发生了错误:“Transaction is killed”
org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [REPLACE INTO `HIS_02004_2022` (`UPDATE_TIME`,`POINT_ID`,`UPLOAD_TIME`,`VAL`,`QUALITY_TYPE`,`VALID_RANGE`,`ZERO_DRIFT`) VALUES (?,?,?,?,?,?,?)]; SQL state [25000]; error code [6002]; Transaction is killed; nested exception is java.sql.BatchUpdateException: Transaction is killed
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:662)
	at org.springframework.jdbc.core.JdbcTemplate.batchUpdate(JdbcTemplate.java:950)

【问题现象及影响】
无法导入数据做后续测试
【附件】

导数期间 memstore_limit_percentage 可以调大,另外 writing_throttling_trigger_percentage 可以再调小点,比如70

可以用obloader进行数据导入吗?或者忽略Transaction is killed,进行单语句的重试

我们研究下这个工具

我们试试,轮转合并是不是取消比较好,我们现在的错误发生在轮转合并第一个Zone和第二个Zone交替期间。
image
出现错误的时间刚好是晚上1点50分

我昨天按照这个配置配了一下,并且关闭了轮转合并,晚上2点41分报了一个超时错误“Statement is timeout”:

Caused by: org.springframework.jdbc.UncategorizedSQLException: PreparedStatementCallback; uncategorized SQLException for SQL [REPLACE INTO `HIS_08003_2022` (`UPDATE_TIME`,`POINT_ID`,`UPLOAD_TIME`,`VAL`,`QUALITY_TYPE`,`VALID_RANGE`,`ZERO_DRIFT`) VALUES (?,?,?,?,?,?,?)]; SQL state [25000]; error code [4012]; Statement is timeout; nested exception is java.sql.BatchUpdateException: Statement is timeout
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:84)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)

依然在合并期间

这个问题看起来是 导数事务被合并任务给kill。 kill的原因看不出来,也没有一个确定的参数或者数字说一定不杀事务。
分析的关键是捕捉到报错前后那段时间的 租户的内存利用率。

可以先参考这个:https://mp.weixin.qq.com/s/DYTOri_Cq6XWKOmZc5EeBg 看看OB内存的原理。3.x版本内存原理和参数可能有些小变化,具体再查官方文档确认。
脚本 dooba.py 在 oceanbase/dooba.py at 3.1 · oceanbase/oceanbase · GitHub

你用的企业版 OCP 里也有跟 上面脚本里相对应的监控项,看起来会更方便。
转储和合并都会消耗一定内存,导数期间也要消耗大量内存,通过几个 内存参数设置,把租户剩余内存控制在一个安全的范围内,应该可以避免报错。

合并期间限流一下 降个速试试

能不能有什么办法限制一下合并的资源占用率,我考虑到的是,即使和通过限制导入速度解决了这个问题,但是如果我们在夜晚期间的业务任务量大的话,都要针对性的限速,感觉有点麻烦,如果合并资源占用降低了,哪怕集群性能下降了一些也能接受

嗯嗯,我调整了一下内存,昨晚倒是没有报错,今晚再看看

好像有参数控制合并并发度

修改合并配置

本节主要介绍合并相关的参数及参数的修改方法。

https://www.oceanbase.com/docs/community-observer-cn-10000000000450797

非常感谢!

昨晚没有报错,数据仍在导入中

导了6天以后还是报错了,我会有时间再尝试