暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

分布式数据库学习Note184:OceanBase社区版中,分析诊断&决策流程有哪几步?

欢迎访问OceanBase官网获取更多信息:https://www.oceanbase.com/


数据库应急的处理流程一般分为事件感知、异常信息收集、分析诊断、决策处理几个步骤。本文以一些常见的场景为例,提供几种可以辅助用户快速定位并判断问题根因的分析决策方法。

事件感知

应急事件的感知通常以应用系统告警、数据库告警、用户上报反馈、日常巡检等方式发现。无论以哪种方式发现,事件/故障应急的第一步都应该是故障信息同步(包括当前影响以及接手处理人),以及异常报错信息的快速收集,为下一步的分析和应急处理提供依据。

异常信息收集

通常来说,异常信息应按照以下的维度收集并整理:

  1. 异常表现:一般第一层是业务相关的信息,如用户无法登录、提交订单失败、无法打开指定页面等。异常信息收集的第一步是需要从业务告警、监控信息中定位寻找到数据库相关的告警信息。例如从应用的 DAL 层日志、中间件、客户端等报出的数据库相关异常信息等。

  2. 异常时间点:确认故障/异常开始的具体时间点,以及持续时间。

  3. 异常范围:确认异常发生在单个应用还是全部应用,对应的 OB 集群是全局受影响,还是某个集群或租户。对于全局范围的影响,往往先从基础设施异常入手排查。对于局部的故障异常,需要确认具体的集群、租户、数据库、obproxy 详细信息。

  4. 报错相关日志:收集异常触发期间报错日志信息,一般来自应用 DAL 层日志以及客户端日志。

  5. 是否有变更/发布:确认故障时间点前后业务是否有发布或变更,如果有需要收集具体信息。在实际场景中,大量的故障和异常往往都是由变更导致。

  6. 对关联业务的影响:确认当前故障的影响面,如果持续,是否会影响上下游其他系统,参考对应信息决策是否需提前降级或限流。这部分涉及不仅仅是数据库,属于站点可用性(SRE)的整体策略,此处不做过多叙述。

分析诊断&决策树

如前所述,应急事件的来源分为两大类,一类是应用发现的异常,另一类来自数据库自身的巡检和告警。对于后者,一般指向为具体的 DB 事件,详细的应急处理方法会在本章接下来的章节进行详细的分析。本节重点介绍业务侧的报错和异常,通过逐步分析判断,尽可能快速的定位问题的思路和方法。

快速基础排查

排查思路

  • 先快速执行一遍 OB 集群健康检查 。

    在开始排查任何应急事件之前,将最基础的异常情况尽早排除,避免无效排查。影响 OceanBase 正常工作的几个最基础的软硬件因素主要包括:

    • NTP 时钟是否同步

    • 是否服务器宕机

    • 是否有日志磁盘、数据磁盘空间满

    • 机房网络是否抖动

    • 负载均衡设备/组件(如 F5/LVS 等)是否故障

      对于集群基础的健康检查项目,OceanBase 云平台已经提供了快速的健康巡检功能,详情参考 OCP 用户指南。

  • 确认异常期间业务是否有流量冲高

    排除了最基本的外部异常,其次要确认的是异常期间外部业务请求量是否比平时有明显升高,即业务正常的流量冲高导致的各种资源不足等异常问题。

  • 从应用层分析数据库相关报错或异常

    前面两种情况,在实际生产实践中,能够快速确认的信息往往只有一部分(例如明确的硬件宕机、断网、磁盘满、以及业务流量增长等)。而真实的场景中很多因素无法在一开始就能快速确认(例如 IO/网络抖动、数据分布变化、较少命中的业务逻辑集中出现),此时就需要进一步分析。一般来说从应用层暴露出的数据库相关错误和异常,通常分为以下几大类:

    • 应用连接池满

    • 应用请求超时

    • 应用建连失败

    • 应用写入失败

    • 应用锁冲突

下面对几种场景分别介绍。

应用连接池满/应用请求超时

连接池满是应用端最常见的数据库异常现象之一,很多的异常事件层层传导,最终都会表现为应用端的连接池满,无法建立新连接。连接池满的直接原因是应用请求超时。从实际情况来看,导致问题的因素按出现频率由高到低大致分别为:

  1. 数据库中有执行计划异常的慢 SQL,响应时间变长,导致应用端不断重试连接。

    此时的解决方案是对慢 SQL 的执行计划进行干预或者直接限流,详细处理流程请参见 SQL 查询导致的异常 。

  2. 数据库中 SQL 响应时间长(但未发现明显异常执行计划),或者有事务长时间未能提交。此时一般分为两种情况:

    1. 查看正在执行的会话请求,以及结合业务信息判断事务执行情况。此时较多见的是 OBserver 节点异常比如 IO/内存/网络异常,此时可以先尝试隔离嫌疑节点观察是否可以恢复;再针对具体的异常做降级处理,详情请参见 其他硬件&网络相关问题

    2. 硬件未发现明确问题,但是发现及节点的 IO 负载非常高,或者网卡负载过高,导致 SQL 请求超时。此时的处理方法参考 节点网卡负载过高 和 节点 IO 负载过高 。

    3. 还有一类导致 SQL 查询时间异常的情况,是类 LSM-tree 架构数据库特有的现象,OceanBase 中称之为"buffer 表问题",详情请参见 buffer 表问题 。

  3. 数据库节点 CPU/内存容量不足,CPU 不足导致可租户队列积压,内存满可导致写入失败。进而导致SQL RT 增长。

    此时建议先检查确认 CPU 水位和租户内存水位,根据需要扩容或采取其他相应手段处理,详情请参见 租户队列积压 和 租户内存写满 。

应用建连失败

应用创建连接失败一般分为两种情况,一种是到 obproxy 创建连接失败,另一种是到 observer 创建连接失败。相比直接建连失败,连接超时的情况更多见。

  1. 到 obproxy 创建连接失败

    应用到 obproxy 创建连接失败,首先需要排除应用到 obproxy 的网络链路问题,其次排查 obproxy 上层是否配置了负载均衡设备和组件,是否存在故障。这两种情况排除后,可能是 obproxy 自身的故障或者因流量上升,obproxy 线程用满(报错信息类似 too many sessions)。此时的处理方法参见 ODP 端故障 以及 ODP 线程满 。

  2. 到 observer 创建连接失败

    对于到 observer 创建连接失败的问题,我们首先要快速排除的也是网络故障,也就是 obproxy 到observer 的通路。对于基础设施稳定的环境,网络线路问题出现几率实际上较低,如果没有明确指标指向是网络问题,没必要花太多时间分析。往往更为多见的是 observer 本身连接出现了问题。此时可以通过以下几个路径分析定位:

    1. sys 租户或其他内部租户是否有队列积压。查看 observer 日志判断是否有 SYS 队列积压。OceanBase 集群处理连接创建的首先是 sys 租户,出现问题会导致连接失败。处理方法请参见 sys 租户队列积压 。

    2. 是否节点 CPU/IO 飙高。查看 observer 日志判断是否有用户租户队列积压。用户租户资源不足也可能导致连接超时。处理方法请参见 用户租户队列积压 。

    3. 异常 SQL 导致的资源占用问题,排查思路详见 SQL 查询导致的异常 。

应用写入失败

OceanBase 写入相关的问题分为几大类,大多数和内存直接相关,实际生产过程中,按发生频率排序可从以下几个层面分析诊断:

  1. 短时间内批量写操作(如批量导入、订正、删除操作)导致的用户租户内存满。

    这是最常见的情况,报错信息往往体现为 Over tenant memory limits,OceanBase 是基于 LSM-tree 结构的准内存数据库,任何写操作都需要消耗内存资源,达到一定阈值后,只有在转储/合并完成后才能够释放。所以当转储速度跟不上内存的消耗速度时,内存最终将被耗尽,从而导致应用写入跌零。这种场景下的处理方式详见 租户内存写满 。

  2. 长事务、悬挂事务导致的转储卡住,内存无法释放进而导致内存满。

    同样是内存满,还有一类内存满是因为有未能提交的事务,导致活跃的内存无法被冻结并转储,进而导致内存爆。可以通过查看长时间未结束的语句,或者通过命令行 SQL 查看来判断正在执行的长事务。具体处理方法请参见 事务 。

  3. 租户内部其他模块内存占用过多,导致 memstore 无法分配,进而报内存满。

    这种情况并非是由于写入过大导致的 memstore 内存满,而是一些其他 SQL 问题触发的租户非memstore 模块内存,此时的现象是租户 memstore 内存占用并不高,但是写入时会遇到报错。参见 系统内部模块内存不足/泄漏 。

  4. Clog 日志盘满,导致 paxos 多数派无法同步,分区无主,业务无法写入。

    Clog 是 OceanBase 的事务日志,同样采用 WAL 机制,当磁盘写满后必然导致写入提交失败。处理方法参考 节点日志盘空间满 。

  5. 系统RS模块异常,导致合并冻结卡住,期间无法写入。

    这种场景相对比较少见,OceanBase 在写入转储达到一定阈值后,或者在每日合并前,会先执行大版本的冻结操作,也就是将活跃内存冻结,再进行转储/合并。冻结操作在正常情况下会在 1 秒内完成,但是异常场景可能会更长,此时用户无法写入。这种场景应急处理的手段是手动切换或重启 RS,参考 集群冻结/合并卡住 。

应用锁冲突

当遇到一些场景中对特定的行进行并发更新的情况,很容易出现行锁冲突问题,此时可能导致各个请求等待时间变长。还可能进一步传导到应用连接池满问题。导致锁冲突一般分为以下集中情况:

  • 业务侧 SQL RT 升高,导致行锁无法释放,锁冲突是 RT 升高导致的结果。此时需要解决 RT 升高的问题。详情请参见上面章节 应用连接池满/应用请求超时

  • 行上面有事务未提交,或者悬挂事务。此时处理参考 事务 。

  • 热点行并发导致的锁冲突,反过来导致 RT 升高。

热点行更新是关系型数据库的通用问题,这类问题在应急处理的时刻往往没有很好的手段(业务形态导致,一般考虑限流降级)。从长期优化角度来看,可以考虑优化调整事务逻辑(如select for update wait 1的方式)。OceanBase 在热点并发方面一直在做积极的探索,并且已经落地了有效的优化方案。详细参考OceanBase 的 提前解行锁 特性,提高单行并发的性能。

变更实施/回滚 & 注意事项

通过上面章节的分析定位,相信大家已经对常见应急事件的处理有了一定了解。剩下的就是实施对应的应急动作,恢复数据库正常工作了。对于 OceanBase 的应急处理,还要重点注意如下几个方面:

  • 明确记录并复核下发的每个应急变更操作,作为如果恢复失败后继续深入诊断的参考信息

  • 建议尽可能记录备份现场信息,包括异常期间的 observer 日志、core 文件等

  • 本章讨论的应急恢复操作,默认以不破坏集群数据多数派,保证数据一致性为前提,如果遇到多副本故障需要激活单副本、需要处理多副本clog等操作,请联系 OceanBase 技术支持。

当应急动作执行完毕,业务已经止血恢复后,建议将一些参数配置的变更进行回滚,并对问题/故障进行复盘。基于应急期间保留的现场信息,问题的根因排查工作也就可以就此展开。


欢迎访问OceanBase官网获取更多信息:https://www.oceanbase.com/

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论