本文介绍Oracle 到OceanBase 数据迁移OMS最佳实践。
OceanBase 迁移服务(OceanBase Migration Service,OMS)是 OceanBase 提供的一种支持同构或异构 RDBMS 与 OceanBase 之间进行数据交互的服务,具备在线迁移存量数据和实时同步增量数据的能力。
本文以某客户一级系统FF核心去O为例,介绍Oracle到OceanBase数据迁移最佳实践。
FF系统Oracle 到OceanBase数据迁移OMS案例分析
系统基本信息:Oracle 源端总共有15张表分区表,22亿条记录需要迁移到Oceanbase 目标端。未做专门优化前,全量迁移耗时11个小时,平均每秒5.5w条记录,速度太慢,不符合客户目标。
第一次优化
优化手段
1、oms 参数调整,增大并发线程,
limitator.platform.threads.number 32 --> 64
limitator.select.batch.max 1200 --> 2400
limitator.image.insert.batch.max 200 --> 400
limitator.datasource.image.ob10freecpu.min=0
2、增大链接数
limitator.datasource.connections.max 50 --> 200
3、jvm内存优化
-server -Xms16g -Xmx16g -Xmn8g -Xss256k --> -server -Xms64g -Xmx64g -Xmn48g -Xss256k
11
优化结果:
通过调整oms参数,增大并发、增加链接数,jvm内存优化后,clog 每分钟产生130个64M 日志(约8.5G日志),cpu 跑满,网络out流量500M,observer目标端服务端出现明显瓶颈。
第二次优化
优化手段
1、OBserver开启日志压缩
ALTER SYSTEM SET clog_transport_compress_all = 'true';
ALTER SYSTEM SET clog_transport_compress_func = 'zlib_1.0';
--租户级别日志压缩
alter system set enable_clog_persistence_compress='true';
2、OBserver 加大转储线程
alter system set _mini_merge_concurrency=32;
alter system set minor_merge_concurrency=32;
3、OBserver加大合并线程数
alter system set merge_thread_count=64;
4、OBserver写入限流
alter system set writing_throttling_trigger_percentage =80;
5、降低转储内存阈值,让obsever提前转储
alter system set freeze_trigger_percentage=30;
优化结果
此次主要对observer 内核参数进行优化,调整参数后,每分钟OB日志量下降到20个左后,但是cpu 利用率仍然非常高,原因分析是大分区表truncate后带来的checksumtask的开销问题,如果开始了checksumtask维护,oms还没开始导入任务,observer节点的cpu能耗费将近 50%,这个影响非常大,属于ob缺陷,需要内核后续修复。
第三次优化
手动清理内部表,避免checksumtask 开销占用cpu 资源,同时把租户leader 打散到3个zone,利用3台机器资源多点写入能力同时迁移数据。
优化手段
1、清理truncate 掉的分区表元数据
delete from __all_sstable_checksum where sstable_id in
(select table_id from __all_virtual_table_history where table_name='table_namexxx' minus
select table_id from __all_virtual_table where table_name='table_namexxx');
2、租户leader打散到三个zone
alter tenant tenant_name set primary zone='RANDOM';
优化结果
此次优化,主要是绕过OB内核bug,通过调整OB部署架构,借助多点写入能力提升性能,OMS每秒迁移提升到大约7w条记录,全量迁移减少到7个小时左右完成。
第四次优化
分析OBserver 上面的慢sql,检查发现,慢sql的执行计划为MULTI_PART_INSERT, 分布式执行计划,因为客户使用的分区表,同时有全局索引,会导致执行计划是分布式执行计划,效率比较差。
优化手段
1、分区表改成非分区表
根据历史经验,单表数据不超过10亿行或者单表容量不超过2000GB可以不考虑分区表
2、临时删除二级索引,只保留主键,待全量迁移完毕后再建二级索引
优化结果
此次优化,主要是对schemal表结构进行优化,分区表改造成非分区表以及后建索引,OMS在3个小时内完成全量数据迁移,大大减少了数据迁移时间
OMS数据迁移性能问题排查方法总结
全量迁移关注的性能指标,按照并发维度来,一个并发一般读取源端的网络流量在1-2M之间,使用tsar --traffic --live -i1s查看网络情况,如果网络流入在[并发数*1,并发数*2]M之间则说明正常。rps一般一个并发在1000左右,这个rps和具体的表的数据字段多少,单行记录大小都有关系。
排查指标 |
排查方法 |
确定是否发生内存或者cpu保护 |
grep pausing task.log|tail 如果存在日志,则说明触发了ob的内存或者cpu保护 这是有连个选择: 1. 调整全量防爆阈值,详见上面的参数 2. 找ob同学增加内存或者cpu资源 |
查看读写时间 |
grep selected task.log|tail 这条命令会出来读取源端的时间统计,cost部分就是读取耗时,此时在通过日志中的Migrate-xx-reader grep Migrate-xx task.log 这里会查出切片xx读写相关日志,可以看到写入的情况,一般读写是按比例在1:4以内,超过这说明写入ob有瓶颈 为了明确这个问题,可以使用jstack dump出全量迁移进程中的线程(jstack路径同全量进程Java路径相同即可) jstack pid > 1.log 得到读取线程 grep Migrate- 1.log|grep reader 得到写入线程 grep Migrate- 1.log|grep writer 当reader远远小于writer,说明读取线程早就结束了,切片处理线程都在等待writer结束 |
查看全量进程是否存在gc情况 |
jstat -gcutil pid 1s jstat路径同全量进程Java路径相同即可 如果fullgc情况发生频繁,则说明需要加大jvm内存 通常发生连接超时时可能就和fullgc有关 |
查看是否有异常报错 |
error.log 如果是sql报错,可以在task.log中找到发生异常的地方,一般在异常附近会有执行的sql,需要根据日中具体发生线程的名称匹配一下 |
OMS数据迁移性能优化方法总结
我们将OMS数据迁移常用的优化方法总结为下列表格供大家参考,往往可以达到事半功倍的效果。
组件 |
优化方法 |
优化变更 |
架构优化 |
Oracle 源端共库写入压力大,oms 解析日志成为瓶颈 |
增加中间DSG中间,减少解析日志开销 |
OMS 优化 |
参数优化 |
1. 调大JVM 修改light-checker JVM:编辑/home/ds/bin/checker_new.sh JAVA_OPTS="-server -Xms4096m -Xmx4096m -Xmn768m -Xss256k" 将两个默认值4096m调大如下加大到32g,此参数对之后创建的全量任务生效 JAVA_OPTS="-server -Xms32g -Xmx32g -Xmn16g -Xss256k" 2. 修改最大数据库连接数use oms_drc_cm; select scope, key, value from config_template where task_type='checker' 修改datasource.connections.max=200,默认是50 3. 调节light-thread 在oms console上编辑参数上下文修改 light-thread并发可调到最多200 4. 调节batch配置 增和batch_select(300batch_insert(200)值 5. 调大目标端ob max_allowed_packet (一般512MB) 6. Oracle long类型读取优化 -Doracle.jdbc.useFetchSizeWithLongColumn=true |
OBSERVER优化 |
参数优化 SQL优化 索引优化 |
1、leader 打散到所有机器 alter tenant [tenant_name] primary_zone='RANDOM'; 2、ob clog 日志开启压缩 ALTER SYSTEM SET clog_transport_compress_all = 'true'; ALTER SYSTEM SET clog_transport_compress_func = 'zlib_1.0'; --租户级别 alter system set enable_clog_persistence_compress='true'; 3、租户内存调大,关闭轮转合并,加大转储和合并并发线程 数 --active:是活动的,未冻结的memstore --total是全部的已分配的内存 --mem_limit内存上限 select * from v$memstore --租户级别,当total / mem_limit > 80是限速,限流阈值,达到这个阈值写入慢 alter system set write_throttling_trigger_percentage =80; --转储阈值, 达到这个值转储,当写入数据量很大时,这个值低一点,让obsever提前转储 alter system set freeze_trigger_percentage=30; --转储并发线程数,0表示使用默认2,当机器cpu多时可以加大这个参数提高转储速度 alter system set _mini_merge_concurrency=0; alter system set minor_merge_concurrency=0; --加大合并线程数 alter system set merge_thread_count=64; 4、SQL优化 ALTER SYSTEM FLUSH PLAN CACHE TENANT = 'tenant_name'; 强制走索引 ANALYZE TABLE[table_name] COMPUTE STATISTICS FOR ALL COLUMNS SIZE 128; select/*+index(t1 idx_t1_c1)*/ col1 from t1 |
SCHEMAL优化 |
1、开发规范,所有表必须有主键,Oracle 源端增加主键 2、普通二级索引迁移前删除,待迁移后再增加 3、分区表改成非分区表 |