作者简介:严军(花名吉远),十年以上专注于数据库存储领域,对大数据、分布式、高并发、高性能、高可用有丰富的经验.主导过蚂蚁集团核心系统去IOE,数据库LDC单元化多活项目,常年负责蚂蚁重大数据库活动(如双11、双12、春节红包大促),现任阿里云分布式数据库架构师和云数据库架构师,专注于金融行业数字化转型过程中头部客户同构和重构数据库架构和迁移咨询工作。精通Oracle、Mysql、OceanBase数据库 ,擅长分布式数据库架构设计、数据库优化、容灾高可用方案设计。
OceanBase 迁移服务(OceanBase Migration Service,OMS)是 OceanBase 提供的一种支持同构或异构 RDBMS 与 OceanBase 之间进行数据交互的服务,具备在线迁移存量数据和实时同步增量数据的能力。本文以国内某保险客户核心系统FF数据库升级为例,介绍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.找运维同学增加内存或者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(300),batch_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优化 刷新plan cache 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、 分区表改成非分区表,避免分布式事务 |