当前位置: 首页 > 科技观察

携程将MySQL迁移到OceanBase的最佳实践

时间:2023-03-16 00:15:15 科技观察

1、前言MySQL在业界风靡多年,很好地支持了携程的业务发展。但是,随着技术的多样化和业务的不断发展,MySQL也遇到了新的挑战,主要体现在:业务数据模型多样化,OLTP和OLAP正在融合;MySQL数据库慢查询管理成本高;使用传统的分库分表方案对开发不友好。核心库改造为分库分表方案,时间一般以年为单位。分布式数据库可以更好地解决上述问题,同时也带来了新的挑战。2021年OceanBase(简称OB)开源,携程将逐步探索OceanBase的基本特性和应用场景。OceanBase兼容MySQL的大部分功能和语法,同时提供水平扩展、强一致性和高可用性,既能满足业务需求,又能降低运维成本。因此,我们开始推动部分MySQL实例向OB的迁移。为了保证顺利迁移,我们设计了迁移评估工具、OB迁移流程、OB监控仪表盘和OB故障诊断工具等,并与大家分享迁移过程中遇到的问题。2.评估工具异构数据库平滑迁移,需要检查兼容性、性能和分区适应性。提前发现并解决不兼容或可能导致迁移异常的场景。官方提供了OceanBaseMigrationAssessment(OMA)工具,用于异构数据库迁移到OB的可行性评估。迁移评估工具OMA有语法兼容性检查和性能评估,但不能完全满足我们的需求。主要体现在以下几点:中间件版本检查,一个DB有多个应用访问,只有某个版本开始支持OceanBase后的中间件,需要检查所有访问该DB的应用的中间件版本,并监督development升级,保证都在支持的OB版本以上。性能采集回放提供的MySQLGeneralLog采集方式存在一定风险,尤其是对于业务量大的数据库,我们需要更流畅的性能采集回放方案。另外对于单实例多DB场景,存在迁移DB和非迁移DB共存的情况,需要进行过滤。线上存在非通过中间件访问的数据库账号,如ETL访问账号、数据查询工具账号、应用直连账号等,需要检查兼容性。因为迁移到OB之后,需要更改数据库登录账号,包括租户信息。OceanBase是分布式数据库,如何对数据进行分区,避免数据过热很重要。一个表可能有多个适合作为分区键的字段。在迁移工具中,需要根据数据分布和访问情况提供表分区建议,以降低迁移成本。因此,我们对OMA评估工具进行了扩展和改造。在不影响现有数据库运行的情况下,省略中间环节,实现一键评估。MySQL数据采集分析流程示意图如下。全量数据导入OceanBase后,我们在目标端使用开源的Locust工具进行SQL回放和压力测试,最终形成评估报告。3.迁移过程在评估过程完成且评估结果满足迁移要求的前提下,可以启动MySQL到OceanBase的自动迁移过程。为了降低迁移成本,我们对迁移流程进行了封装,实现一键自动迁移。自动切换包括以下过程:1)迁移前的配置验证。迁移前,将对所有切换注意事项和相关配置进行全面检查,提前排除配置问题可能带来的切换风险。2)MySQL账号兼容OceanBase,使用租户账号创建。由于OceanBase是多租户管理模式,应用的连接字符串必须指定租户名称,所以需要在目标OB集群中预先创建对应的账号。中间件或工具切换账号时,只需要重置连接,切换到新账号即可。3)数据一致性检查。数据从MySQL通过Canal同步到OB后,我们需要验证一致性。校验的方法是根据表的主键进行拆分,比较结果集是否一致。当遇到热表时,数据校验过程会发起多次尝试,反复校验。4)DDL表结构修改暂停。由于MySQL和OceanBase的表结构变化方式差异较大,当触发MySQL向OceanBase迁移DB的过程时,我们会禁止对源MySQL进行DDL操作。当然,如果开发有紧急发布需求,我们可以放弃流程,等DDL发布完成后,重新开始迁移流程。5)反向同步链路建立。无论之前的迁移评估或流程多么完善,异构数据库的迁移都需要反向同步环节。一旦迁移异常,可以快速回滚。反向同步链路基于OceanBase的CDC服务,在MySQL端回放订阅增量日志,保证迁移后OceanBase端和MySQL端的数据始终一致。当数据同步完成,没有增量延迟时,迁移过程会产生一个特定的切换任务。切换过程如下:我们只需要在预定的时间窗口内点击触发切换过程,就可以完成从MySQL到OceanBase的切换。整个切换过程可在一分钟内完成,业务端无需修改。我们有反向链接,如果有异常情况,我们可以随时安排回滚。反向链接正常情况下会保留两周以上。第四,OceanBase的监控分布式数据库和单机数据库的一个很大区别,分布式监控比单机数据库复杂。一是因为组件太多,需要全局的观点;二是报警点需要聚合。业务刚迁移到OceanBase时,观察集群监控,关注告警信息是判断迁移是否成功的关键。日常冒烟现象或不规律现象需要及时发现和处理,以免问题恶化。准确的监控和及时的告警,可以帮助运维人员快速定位问题,快速解决故障。4.1监控OceanBase的大规模监控数据主要是通过部署在各个Server上的Agent程序直接在本地采集。Agent包含很多组件,内容如下:Agent程序将收集到的数据上报给hickwall,并以模板的形式显示出来,形成一个监控面板。如下图所示:4.2告警邮件OceanBase告警主要是通过订阅hickwall上的监控数据和定时服务巡检来完成的。根据采集到的监控数据建立报警阈值,一旦指标超过阈值就会发出报警通知。此外,我们还将定期检查配置,解决规范性问题等。4.3OceanBaseSQL审计OceanBase接入了携程的SQL审计流程。不同于以往传统的审计插件模式,现在通过抓包分析MySQL协议获取全量的SQL审计信息。接入审计流程后,可以快速定位SQL信息,包括申请号、接入IP、执行参数、是否有报错信息。4.4OceanBase审计应用案例当使用MySQL命令行工具连接OceanBase出错时,我们通过SQL审计日志定位,发现客户端在连接OB的过程中会进行一些元数据查询工作。执行showtables这一步后,会报错断开连接,然后定位到一个特殊的表。表名的最后一个字符是导致此错误的分号(t_sample;)。然后我们在开源社区问题中报告了这个案例。五、OceanBase自动故障诊断随着越来越多的MySQL迁移到OceanBase,对数据库性能、实时性和故障定位准确率的要求越来越高。故障自动诊断系统能够全方位、及时、准确地定位在线问题,为运维和故障排除提供依据。5.1搭建实时性能数仓OceanBase性能数仓搭建流程如下:采集性能指标相关数据,常用性能指标对应的数据源如下:开发数据采集程序,并在服务器数据本地每10秒采集一次以上性能指标的数据。并在数据采集完成后进行结构化处理,包括数值数据的标准化处理和文本数据的时间序列处理。结构化处理后的数据存储在ClickHouse中。5.2自动化分析自动化分析流程图如下:5.3性能指标实时检测通常判断性能异常的指标包括CPU占用率、磁盘IO占用率、ThreadsRunning、QPS、网卡流量等。基于运维经验,可以为每个指标设置相应的阈值。当超过阈值时,则认为当前实例存在性能问题。例如CPU使用率高于65%或者磁盘IO使用率高于80%,则表示服务器异常。5.4异常数据匹配数仓首先,对于数值型数据,分析工具会自动选择故障指标和故障时间段,通过相似度匹配数仓中的数据。所有数值数据包括SQL、Table和Perf。性能指标说明如下:SQL对应的性能指标:执行次数、总耗时、CPU耗时、逻辑读次数、物理读次数等Table对应的性能指标:新增、删除行数,和modified,新增、删除、修改的SQL条数,关联事务条数。Perf对应的性能指标:CPU、I/O、RPC时长、索引缓存大小、缓存命中率等。其次,对于文本类型的数据,分析工具会通过故障时间间隔获取所有时序文本数据,通常包括:数据库服务日志、系统内部任务记录、数据库进程信息等。最后根据前面两类数据进行综合分析。分析要点主要包括:SQL级别:SQL性能消耗的比例,是否有慢SQL在执行,是否有缺失索引,是否有远程执行或分布式执行等。OceanBase内部:OceanBase是否在合并,是否副本是否平衡,是否有其他异常日志等。应用层:客户端是否发布。最后,基于以上自动化分析,实现服务器性能波动真正原因的精准定位,自动生成故障定位分析报告,并通过邮件及时推送给DBA和相关开发人员。5.5应用案例以下是基于该工具自动生成的示例分析报告,介绍该工具的实际应用:报告故障指示部分显示4:30后服务器CPU上升;报告中OceanBase相关表部分显示CPU上升趋势与下表访问趋势一致;报表OceanBase相关SQL部分显示,这张表的访问趋势与后面SQL语句的访问趋势是一致的;报表分析结果部分定位到CPU的增加与tablex表的访问增加有关,而这张表的访问趋势访问增加与这条SQL语句的访问时间增加有关,最终定位到SQL引起的CPU增加。之后联系开发团队确认是正常的业务增长,增加服务器节点缓解CPU负载。6.迁移问题及实践6.1.Net应用访问OceanBase失败在使用和测试OceanBase的过程中,我们发现.Net应用的官方MySQL连接器无法连接OceanBase执行SQL。经过排查,.Net应用依赖了连接中的ConnectionCharSetIndex,而OceanBase没有Cnotallow=83,也就是utf8_bin,只有utf8mb4_bin。为此,我们对OceanBase的源码进行了修复,以满足此类应用对OceaBase的适配。总结:OceanBase并不完美,但是随着时间的推移,通过反复的测试和迭代,它正在逐步完善它的各个方面。我们也参与其中,从运维和产品用户的角度去优化和完善。6.2Druid应用不兼容部分OB语法分析我们在开发Oceanbase表结构设计工具时,发现Druid解析OceanBaseSQL时出现错误。该错误会导致在表结构设计时导入SQLDDL语句时报错。遇到问题后,我们首先调整到最新版本的Druid,发现问题依然存在。我们先从复杂的表结构设计中提炼出最简单的SQLDDL,结合Druid的源码分析,发现原来Druid代码对OceanBase的兼容是在SQLIndexDefinition中实现的,而没有在SQLIndexOptions中实现。根据OceanBase的语法树,应该在SQLIndexOptions中实现才是合理的。找到问题后,我们提交了一个PullRequest,然后合并到Druild主线。问题解决了。总结:开源工具的一个好处就是我们可以在遇到问题后进行代码分析。并快速定位问题,最后反馈到社区。6.3OceanBase读写分离支持读写分离是数据库非常重要的能力。在业务层面,涵盖ETL数据检索、BI报表生成、缓存刷新等多个场景。Oceanbase虽然支持读写分离功能,但需要在代码层显式设置弱一致性读参数,存在对业务侵入性强的缺陷。我们修改了OceanBase访问代理OBProxy的代码,增加了enable_weak_read和weak_read_user_list两个参数,通过代理层控制开启读写分离策略,对应用程序是高度透明的。在读写分离场景下,应用与OBProxy建立连接的过程示意图如下:基于上述代码修改,我们设计了一个优化版的读写分离方案,即:是否使用读写分离由账户维度控制。流量调度示意图如下:总结:OceanBase虽然功能强大,但并不一定100%满足业务场景和需求,需要对其组件进行二次开发。我们不仅为OBProxy适配了相关功能,还根据实际场景需求对cdc、Deploy组件等其他组件进行了调整。6.4查询范围过大导致内存溢出。在前期使用OceanBase的时候,我们有过ServerCrash的经历。当查询条件中IN运算符中的元素过多(超过10000级)时,会弹出栈溢出异常。经过分析和社区交流,我们发现优化器在提取查询范围时消耗了大量内存。但是OceanBase在算法迭代过程中没有检查查询超时,导致查询消耗内存,直到SQLARENA的内存耗尽。这种模式没有很好的防御机制,导致内存溢出和系统崩溃。此问题已在新版本中修复。确认问题后,我们立即通知开发减少IN中的元素数量,并安排版本升级。总结:OceanBase是一个新鲜的产品,社区论坛和Gitissue是获取日常运维和快速排错解决方案的利器。根据各种技术探索和交流分享,学习优质内容,收获前沿知识,快速定位和解决问题。6.5修改执行计划迁移前后,数据库的SQL性能是最值得关注的。OceanBase作为分布式数据库,其优化器比MySQL复杂,而且由于其特殊的存储结构,表的统计直方图刷新频率很低。因此,当可用的索引和查询条件不太适合时,优化器在选择执行计划时可能会出现偏差。OceanBase自带修改执行计划的能力,即通过在数据库层面直接指定同类型的SQL,使用大纲注释的方式,强制绑定执行计划。总结:相对于传统数据库,OceanBase的分布式架构和特殊的存储结构也会提高运维的门槛,但也给了运维人员更高的自由度。运维人员需要熟悉并掌握这些强大的功能和运维技巧,才能让线上业务更加稳定。七、未来展望OceanBase已经开源一年多了,我们的运维工具也逐渐成熟,我们的运维能力也在逐步提升。越来越多的MySQL正在逐步迁移到OceanBase。随着OceanBase4.0的发布,许多新特性正在逐步测试中。我们也非常期待4.0版本的新特性。7.1单机分布式集成架构OceanBase4.0版本引入了单机分布式集成架构,支持类似MySQL的轻量级单机模式部署,必要时也可以快速扩展为分布式模式,提升性能上限.单机和分布式的灵活切换可以大大降低成本,并且基于原有主备数据库的能力,可以快速完成主备容灾切换,具有更强的高可用保障。7.2兼容性增强OceanBase对MySQL的高兼容性一直是我们考虑的重点。高兼容性为开发同仁节省了大量的学习成本和代码成本。4.0版本在字符集、约束、函数、存储过程等方面与MySQL的匹配度更高,在使用上更接近MySQL。当然,兼容还包括与MySQL生态的兼容,包括binlog兼容、canal兼容、flashback工具兼容等等。7.3提升运维能力作为分布式数据库,OceanBase组件众多,运维环境复杂。未来我们将基于现有的日志采集工具和分析工具,完成基于链路的问题诊断,更准确定位性能问题和集群内部任务问题。