ceph deep-scrub卡住导致业务中断问题分析

ceph deep-scrub卡住导致业务中断问题分析1 问题背景一个 pgscrub 了 14 天 前端虚机挂掉大半 2 分析过程 2 1 查看 scrubpg 的主 OSD 日志从日志里可以看出 pg 13 832 有 slowop 该 oldestslowop 等待时间 s 14 天这些 op 都处于 waitingforsc 什么场景会导致 op 处于 waitingforsc 首先从字面上可以理解这些 op 是等待

1. 问题背景

一个pg scrub了14天,前端虚机挂掉大半

2. 分析过程

2.1 查看scrub pg的主OSD日志

在这里插入图片描述
从日志里可以看出pg[13.832]:

  • 有slow op,该oldest slow op等待时间s==14天
  • 这些op 都处于waiting for scrub

2.2 分析scrub过程那些场景会导致scrub阻塞,首先看下scrub状态机

在这里插入图片描述

从上面的scrub状态变迁过程可以看出,有4种情况会导致scrub阻塞,分别是

  • WAIT_PUSHES: wait for pushes to apply
  • WAIT_LAST_UPDATE: wait for writes to flush
  • WAIT_REPLICAS: wait for replicas to build scrub map
  • WAIT_DIGEST_UPDATES: waiting on digest updates

从主osd日志并不能看出当前pg scruber处于那个状态,接下来分析其他从副本日志看看有什么线索。

2.3 分析从副本osd.227日志,过滤13.832的日志

在这里插入图片描述
从上面过滤出的日志,发现13.832这个pg

  • 出现了slow op,该slow op 等待时间为s==11天
  • 这些op处于currently reached_pg,说明已经开始交给pg层处理了
  • 这些op类型是replica scrub即主副本发来scrub请求,请看下图
PrimaryA B C INACTIVE NEWCHUNK BUILD_MAP _request_scrub_map _request_scrub_map WAIT_REPLICAS CEPH_OSD_OP_SCRUB_MAP CEPH_OSD_OP_SCRUB_MAP COMPARE_MAPS FINISH INACTIVE PrimaryA B C

从上面的流程可以知道主PG当前的状态是为WAIT_REPLICAS即主副本上所有的io请求都是因为等待从副本osd.227 scrub完成而阻塞

既然都已经reached_pg,那接下来分析那些场景会阻塞replica scrub op。

2.4 分析那些场景会导致replica scrub阻塞

分析replica scrub调用过程,有3种情况会阻塞replica scrub op,分别为

  • sharedwq共享线程池被阻塞了
  • 当前的replica scrub op中scrub_to记录的版本号大于当前osd记录的last_update_applied,即这些scrub对象数据还没更新到和主OSD一致
  • 当前osd正在做数据恢复即active_pushes不为0

首先排除sharedwq共享线程池被阻塞了,因为sharedwq的线程会被加入到HeartbeatMap监控中心,一旦线程被阻塞了HeartbeatMap就会检查到并且会在日志中打印timeout的告警严重的话会造成线程自杀,而日志并无这些异常打印,所以这种情况排除掉

其次排除掉因为数据恢复导致的这种情况,因为当前集群运行正常并未做任何的数据恢复,并且恢复的过程中是不会进行scrub校验的

剩下的只有一种情况即scrub_to记录的版本号大于当前osd记录的last_update_applied这一种情况了,什么场景会出现scrub_to大于last_update_applied情况呢?

首先明确一点scrub_to是主osd封装的,记录是本次选中参与scrub的所有scrub对象最新的pglog版本

其次明确last_update_applied本地副本自己on_apply到filestore后更新的,因此就会存在同一时刻不同副本的last_update_applied的版本号不一致,如下图

PrimaryA B C last_update_applied = 1748’25607 client write op issue_op issue_op queue_transaction sub_op_modify_impl sub_op_modify_impl queue_transaction queue_transaction on_applied(last_update_applied = 1748’25609) sched_scrub chunk_scrub(scrub_to = 1748’25609) _request_scrub_map _request_scrub_map WAIT_REPLICAS replica_scrub(last_update_applied = 1748’25607 < scrub_to = 1748’25609) 将srub op挂起 scrubber.active_rep_scrub = op on_appled(last_update_applied = 1748’25609) scrub_to != last_update_applied, scrub op一直被挂起 CEPH_OSD_OP_SCRUB_MAP PrimaryA B C

从上图可以看出当从副本B在收到scrub op请求时如果此时op还未on_applied到filestore就会把scrub op挂起等待op applied完成后重新调度该op,而重新调度的前提是last_update_applied等于scrub_to否则scrub op就会永远被挂起,就会出现这个问题。所以什么场景会导致last_upate_applied不是一个一个版本递增的呢?

2.5 分析什么场景会导致last_update_applied版本不是按照一个版本一个版本方式增加的?

分析代码有一种场景会导致op on_applied成功后last_update_applied是增加了两个版本,即clone场景

当打了快照或者克隆触发clone操作时候版本就会增加两次,如果此时恰好这些对象又被选中参与scrub过程并按照上面假设的时序进行就会复现该问题了

3. 原因分析

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/230696.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Sqlserver2005日志文件太大,使其减小的方法

    Sqlserver2005日志文件太大,使其减小的方法: 运行下面的三行dbName为数据库名: backuplogdbNamewithNO_LOG backup

    2021年12月26日
    37
  • 注意Mikrotik ROS Webproxy的“漏洞”

    注意Mikrotik ROS Webproxy的“漏洞”在使用ROSWebproxy做代理时,外网的IP也可以连入,将你的ROS代理服务器当作跳板!这种情况会引起外网网卡流量和内网网卡对不上的情况:如下图于是用Torch检查的时候发现了问题:1080口流量超大,而且在转发连表里没有流量,但是在WAN口的input连表里有高流量。也就是说和这个1080口连接的IP并没有和内网进行通!关闭代理后连接消失!…

    2022年6月21日
    77
  • 创建eureka注册中心_微服务注册中心和网关

    创建eureka注册中心_微服务注册中心和网关目录关于SpringCloud版本单机模式Eureka注册中心搭建引入Eureka-Server依赖创建启动类添加配置高可用Eureka注册中心搭建双节点注册中心修改配置文件修改hosts文件启动测试多节点注册中心修改配置文件启动测试常见问题参考文章SpringCloud是一系列框架的集合,它利用SpringBoot的开发便利性巧…

    2022年8月21日
    6
  • LightGBM源码阅读+理论分析(处理特征类别,缺省值的实现细节)[通俗易懂]

    LightGBM源码阅读+理论分析(处理特征类别,缺省值的实现细节)[通俗易懂]前言关于LightGBM,网上已经介绍的很多了,笔者也零零散散的看了一些,有些写的真的很好,但是最终总觉的还是不够清晰,一些细节还是懵懵懂懂,大多数只是将原论文翻译了一下,可是某些技术具体是怎么做的呢?即落实到代码是怎么做的呢?网上资料基本没有,所以总有一种似懂非懂的感觉,貌似懂了LightGBM,但是又很陌生,很不踏实,所以本篇的最大区别或者优势是:源码分析,看看其到底怎么实现的,同时会将源…

    2025年6月6日
    3
  • linux下使用sed命令查看tomcat某段时间的日志信息

    linux下使用sed命令查看tomcat某段时间的日志信息

    2021年7月16日
    150
  • 使用VScode配置Java环境—JDK-17

    使用VScode配置Java环境—JDK-17一、JDK的安装与环境配置1、在java的官网下载页面找到安装包进行安装。找到对应的操作系统,第一个是直接下载压缩包,第二个是下载一个下载器再安装,我是直接下的第一个。2、修改环境变量,先建立一个JAVA_HOME变量,将JDK的安装下载位置设为值。3、点击系统变量中的Path,然后点击编辑,然后把bin的路径填上。按道理来说其实填路径这一步,直接把bin的路径加到Path中也可以,但是网上好多教的都是做一个JAVA_HOME变量,我也不知道为啥。记得退出环境…

    2022年10月3日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号