当前位置: 首页 > 编程日记 > 正文

再记一次ceph object unfound的艰辛历程

文章目录

        • 先说问题:
        • 再说解决
          • 尝试1:
          • 尝试2(该尝试建议先在自己环境搭配对应业务测试通过后再现场尝试):

感谢 学无止境996同学的陪伴和vigourtyy美丽女友的支持,直到这个解决问题的深夜

先说问题:

ceph 12.2.1生产环境:3副本 tier + 3副本data
机房在拥有业务的情况下重启集群交换机,产生如下场景:

  • time 1: osd.1 down, osd.2 osd.3 up
    此时数据先落到2,3上(2为primary)
  • time 2: osd.1 osd.2 osd.3 up
    此时状态机触发peering,根据pg_info和pg_log,构建missing列表,依据此列表进行后续的recovery(默认此时仅pg部分数据有变化,可通过权威日志恢复),但此时recovery并未完全恢复
  • time 3: osd.1 osd.2 up, osd.3 down
    根据此时osd的状态,因为上一个时间点osd.3上部分数据并未完全recover到osd.1上,此时osd.3就down了,但是对于osd.1来说已经获取到了missing列表并且将该列表中的对象操作数据追加到了pg_log_entry中,依此来pull或者push数据。但是此时osd.3已经down,这一些数据无法成功获取到osd.1上。此时集群的状态就会出现object unfound的情况,如下图:
    在这里插入图片描述

我们的生产环境更是异常问题的叠加,因为出现unfound的对象,同时又出现osd无法成功Recover而报出的段错误无法启动,此时丢掉的对象如果想要恢复,貌似只有revert或者delete了

关于PGlog的相关描述以及pg_log和pg_info如何参与到状态机中进行peer,recover和backfill的相关过程可以参考PGlog写流程梳理

知道了问题,并且能够复现问题,接下来就是如何解决的过程了。

再说解决

首先我们知道部分数据并未完全丢失,它可能是存在于down掉的osd中,为了后续的恢复,我们先将down掉的osd进行数据备份。
使用dd将down掉的osd所在的磁盘数据备份到一块空的磁盘上即可。

操作前先分析当前异常环境的处境以及我们想要达到的最终目标:

我们拥有的资源:备份完好的osd磁盘(数据未丢失)
我们的处境:对象丢失,深层含义就是当前环境没有任何一个up的osd承载该对象,但是该对象的操作版本被pg_log记录,环境曾经有过该对象。

分析:加入我们没有备份好的数据资源,遇到这样的情况貌似只能对unfound对象所在pg进行revert和delete了,但是我们备份了数据

最终要做的就是尽可能完整得将我们备份的数据迁移至现有集群,让改集群unfound的对象一一恢复

尝试1:

对象级别的操作工具我们能够想到的ceph-object-toolrados这两个利器
对象的构成我们宏观来看:即数据+元数据
刚好,ceph-object-tool工具拥有参数get-bytes,set-bytes,get-attr,set-attr这样的子命令。

于是我们尝试将备份的磁盘数据中将对应的丢失对象使用get-bytes获取出来,然后再使用set-bytes将该对象的数据写回集群,同时将对应对象的属性也设置回集群,这样我们猜想,osd起来之后有了对象以及对象的元数据,即可成功恢复。操作如下:

  • 挂载备份数据的磁盘分区
    a. mkdir /ceph-0
    b. mount /dev/sdb1 /ceph-0

  • 查看丢失的对象
    a. ceph health detail 获取丢失对象的pg id
    b. ceph pg 14.20 list_missing列出丢失对象的pg 14.20的丢失对象信息

  • 从备份的磁盘分区中获取丢失的对象数据和元数据
    a. ceph-objectstore-tool --data-path /ceph-0/ --type bluestore obj470 get-bytes obj470.txt 获取对象obj470的数据,并放入到obj470.txt文件
    关于ceph-object-tool工具的使用可以参考ceph-object-tool使用详解
    b. ceph-objectstore-tool --data-path /ceph-0/ --type bluestore obj470 get-attrs _ > obj470.attr 获取对象obj470的属性数据,即元数据信息到obj470.attr中
    src/common/ceph_objectstore_tool.cc中可以看到该属性信息为object_info_t数据
    在这里插入图片描述
    则我们可以通过命令ceph-dencoder来解码查看,关于ceph-dencoder命令的使用可以参考文档ceph-dencoder使用详解
    ceph-dencoder type object_info_t import obj470.attr decode dump_json
    在这里插入图片描述

  • 将获取到的数据设置到集群osd中,此时需要osd的状态为down,能够操作/var/lib/ceph/osd/ceph-id目录
    a. ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --type bluestore obj470 set-attrs _ obj470.attr 设置对象属性
    b. ceph-objectstore-tool --data-path /var/lib/ceph/osd/ceph-0/ --type bluestore obj470 set-bytes obj470.txt 设置对象数据信息
    此时有两种情况:
    如果对象的have版本为0'0,即对象当前并不存在于集群中,集群只有一个初始的空版本对象,执行以上命令会有如下输出
    No object id 'get-bytes' found or invalid JSON specified

显然该方案走到这里即出现阻塞性的情况,对应对象版本为0'0的对象该如何修复?

尝试2(该尝试建议先在自己环境搭配对应业务测试通过后再现场尝试):

至此我们已经能够获取到对象的数据,但是因为集群中对象版本为0'0的对象是不存在的,所以无法设置这样的对象

那么我们可以尝试如下操作,首先对象在其未加入集群时会通过crush算法计算好自己即将映射到的osd以及对应的pg
ceph osd map pool_name obj_name命令可以看到该映射关系,那么我们可以认为只要知道对象的名字,那么它的映射关系实不会变化的。

依据以上过程,我们即可尝试这样的方案:

  1. 先从备份的磁盘上获取对应丢失对象的数据,通过 ceph-objectstore-toolget-bytes参数来获取
  2. 从备份的磁盘双获取对应丢失对象的元数据,通过ceph-objectstore-toolget-attr _获取object_info_t属性,通过get-attr snapset获取快照属性
  3. 每获取完一个pg上所有的unfound对象之后,即将该pg上的unfound对象都delete掉 ceph pg 8.32 mark_unfound_lost delete
  4. 使用rados命令,重新put同一个对象名,并指定我们第一步获取到的对象文件
  5. 将备份好的对象的oi属性和ss属性在osd down掉的情况设置进去

以上步骤可以简化为如下脚本:


#!/bin/bash
tier_pool=$1pg_list=`ceph health detail |grep unfound|grep has|awk '{print $2}'`for i in ${pg_list}
do# 按照PG编号,获取丢失对象列表ceph pg $i list_missing|grep "rbd_dat"|sed 's/"/ /g'|awk -F: '{print $2}'|awk '{print $1}' > "$i".txt#以PG为编号,从备份的磁盘挂载点获取丢失对象的数据for j in `cat "$i".txt` doceph-objectstore-tool --data-path /test_ceph0/ --type bluestore --pgid $i $j get-bytes "$i"/"$j".txtceph-objectstore-tool --data-path /test_ceph0/ --type bluestore --pgid $i $j get-attr _ > "$i"/"$j".oiceph-objectstore-tool --data-path /test_ceph0/ --type bluestore --pgid $i $j get-attr snapset  > "$i"/"$j".ssecho $i $jdoneif [ -e "$i".txt ];then #检测到按PG编号 存储对象列表的文件存在,则进行pg的delete操作ceph pg $i mark_unfound_lost deleteelseecho "$i.txt is not exists,please check"exit 1fiecho $ifor k in `cat "$i".txt` #将拷贝出来的对象文件,按照对象名重新put到资源池dorados -p $tier_pool put $k "$i"/"$k".txt;echo $kdonesleep 100 #处理完一个pg,睡眠100秒,让上一个PG数据重构一会
done

该尝试能够将对象最原本的数据恢复到集群异常前的最新状态,目前在使用rbd-nbd命令挂载的rbd块设备复现对象丢失的情况能够正常恢复。

相关文章:

2014-01-04 SQL练习

目标数据库 250,czzznew/czzznew *关于执行计划:在PL/SQL选中查询的语句后,按下F5即可,其中Cost列表示当前操作的代价(消耗),值越大代表性能越差 t_rkxx表 (1):用2种以上方法查出xm(姓名)为test或者Test的人…

多重集表示合json数据_计数DP(划分数,多重集组合数)

划分数:把n个无区别的物品划分成不超过m组。 dp[i][j]j的i划分的总数。 dp[i[j]dp[i][j-i]dp[i-1][j] 即:将j个物品分成i份,有两种情况:每份划分都大于等于1 dp[i][j-i]; 存在有一份以上用0划分dp[i-1][j]int main(){int n,m;cin&…

搭建PHP环境遇到的问题!!

为什么80%的码农都做不了架构师?>>> 问题1: 再次./configure以下错误发生 configure: error: xml2-config not found. Please check your libxml2 installation. 解决方法: 安装libxml2 # yum install libxml2-devel 问题2&…

linux进程间通信:shell管道 | 的实现

文章目录介绍重定向函数介绍总结linux terminal输入如下命令,其中"|"符号即为我们上文中所说的无名管道介绍 正如我们上文中所描述的"|“无名管道提供了具有亲缘关系的进程之间的通信,它由于直接使用系统调用,运行效率较高。…

Golang的接口

当一只鸟走路像鸭子,游泳像鸭子,叫起来也像鸭子,那么我们就认为它就是鸭子。 Duck typing 的理念因此比喻得名。 Golang 通过 interface 实现 duck typing。 Effective Go 文章中这样描述 interface: interface 指定了一种描述对象行为的方法…

mysql 5.6.15_mysql-5.6.15-win32.zip免安装配置

此随笔是根据网上的资料整理的:环境:Windows XP系统软件来源:mysql官网下载1.下载mysql-5.6.15-win32.zip;2.解压MySQL压缩包;以下以加压到“F:\Program Files\Mysql\mysql-5.6.15-win32”为例:3.将解压目录…

jquery treeview 树形插件

jquery treeview 插件参数说明 treeview开源地址:https://github.com/jzaefferer/jquery-treeview 1、animated:String or Number 设置展开子节点时的显示速度,有 slow、normal、fast 或者指定速度值,与 jQuery 的 hide&#xff0…

spark调优(一)-开发调优,数据倾斜,shuffle调优

主要分为开发调优、资源调优、数据倾斜调优、shuffle调优几个部分。 开发调优和资源调优是所有Spark作业都需要注意和遵循的一些基本原则,是高性能Spark作业的基础;数据倾斜调优,主要讲解了一套完整的用来解决Spark作业数据倾斜的解决方案&am…

linux进程间通信:popen函数通过管道与shell通信

函数描述 FILE *popen(const char* command,const char* type) 该函数的执行过程如下: a. 调用pipe创建一个管道,并fork创建一个子进程来执行shell,shell会创建一个子进程来执行commad b. 将父进程的输入输出重定向到管道,建立一个单向的数据…

新的小游戏发布啦。Pop Jungle

丛林爱消除是一款画面清新,效果绚丽的消除类休闲游戏。你只需要选中尽可能多的图块,并消除它们就可以得到高分,并有无限多的关卡等待你去征服。一旦你开始玩儿你将无法停止下来,如果你还是消除星星的粉丝,那你更加不能…

mysql thread safe_Windows环境下完全手工配置Apache、MySQL和PHP(Thread Safe)

happydagui:现在LAMP(Linux、Apache、MySQL、PHP/Perl/Python的简称)已经很流行了。在Windows下也有类似的,比如 WAMP(Apache, MySQL, PHP on Windows)。这篇文章主要是介绍如何在Windows环境下完全手工配置Apache、MySQL和PHP,都是解压后直接…

点滴积累【C#】---检验编号在本表中自动生成,与其他表无关

检验编号在本表中自动生成,与其他表无关 效果: 描述:在本表中自动生成编号,与其他表无关。 调用: 1 protected void Page_Load(object sender, EventArgs e)2 {3 Response.Expires -1;4 …

Alpha冲刺(9/10)

团队信息 队名:爸爸饿了组长博客:here作业博客:here组员情况 组员1(组长):王彬 过去两天完成了哪些任务 学习jQuery的AJAX部分的基础知识,对web端如何异步获取服务器信息有了初步认识接下来的计划 & 还…

linux进程通信:pipe实现进程同步

文章目录通过管道同步进程实现代码管道缓冲区设置缓冲区大小总结 :pipe的特点通过管道同步进程 管道自带同步互斥机制: 管道的内核实现:fs/pipe.c ,主要通过内核的锁以及等待队列等机制实现 管道的write操作会阻塞进程 当内存缓冲…

(转)MySQL联表查询

资料源于网络 一.内联结、外联结、左联结、右联结的含义及区别在SQL标准中规划的(Join)联结大致分为下面四种:1.内联结:将两个表中存在联结关系的字段符合联结关系的那些记录形成记录集的联结。2.外联结:分为外左联结和…

极小连通子图和极大连通子图_强连通分量与拓扑排序

前言由于GacUI里面开始多处用上拓扑排序,我决定把之前瞎JB搞出来的算法换掉,换成个正式的。之前我自己弄了个写起来很简单的算法,然后每一处需要用到的地方我就重新做一遍。当然这样肯定也是不行的,我觉得也差不多积累到重构的临界…

INTERVAL数据类型-007学习笔记

http://baggio785.itpub.net/post/31233/286119 INTERVAL数据类型用来存储两个时间戳之间的时间间隔。 可以指定years and months,或者days,hours,minuts,seconds之间的间隔。本文为oracle的学习笔记,结合实例介绍INTERVAL数据类型。 INTERVAL数据类型用…

scrapy模拟用户登录

scrapy框架编写模拟用户登录的三种方式: 方式一:携带cookie登录,携带cookie一般请求的url为登录后的页面,获取cookie信息应在登录后的页面获取,cookie参数应转成字典形式 # -*- coding: utf-8 -*- import re import sc…

linux 系统调用 open函数使用

函数介绍 本文仅仅将open系统调用的使用简单总结一下&#xff0c;关于其实现原理大批的大佬分享可以自行学习。open系统调用主要用于打开或者创建一个文件&#xff0c;并返回文件描述符。 头文件 #include <fcntl.h>函数名称 a. int open(const char *pathname, int fl…

配置zendframework开始工作(加入环境变量)

首先需要把把两个路径加入到环境变量中 1、我用的php环境是xampp&#xff0c;安装在di盘&#xff0c;我要把d:/xampp/php/这个路径加入到环境变量 2、下载zendframework&#xff08;我用的版本是1.&#xff09;,把安装包中的bin目录加入到环境变量 3、关于设置php/php.ini中设置…

mysql计算两gps坐标的距离_mysql 计算两坐标间的距离

mysql 5.6.1 加入了空间数据支持功能&#xff0c;新增了st_*相关函数&#xff0c;可以非常方便的计算两个地理坐标点的距离了。如下例子&#xff1a;按我的坐标计算周边坐标的距离并由近到远排序select name,st_distance(point(113.327955,23.129717),point)*111195 as distanc…

(转)mxArray数据类型

1 、数据类型mxArray的操作 在上节的Matlab引擎函数中&#xff0c;所有与变量有关的数据类型都是mxArray类型。数据结构mxArray以及大量的mx开头的函数&#xff0c;广泛用于Matlab 引擎程序和Matlab C数学库中。mxArray是一种很复杂的数据结构&#xff0c;与Matlab中的array相对…

Bootstrap笔记(记录不会的知识)

head&#xff1a; <link rel"stylesheet" href"bootstrap.min.css" /> 引入bootstrap.min.css文件 <meta name"viewport" content"widthdevice-width,initial-scale1" /> content"widthdevice-width&#xff1a;设为…

linux 系统调用 read,write和lseek 使用

read系统调用 头文件 #include <unistd.h>函数使用 ssize_t read(int fd, void *buf, size_t count) read 函数会从文件描述符fd中读取指定的count长度的内容&#xff0c;并且将读到的结果放入到buf缓冲区中返回值 count 读取成功&#xff0c;则会返回读到的字节数 小于…

简单有趣的matlab小程序_超实用有趣的五个小程序推荐

大家好&#xff0c;我是小胖。废话不多说&#xff0c;进入正题。1.一周CP共读有趣的灵魂总会相遇。一个极简的社交小程序。通过选择自己喜欢的一本书&#xff0c;匹配到那个跟自己有着一样有趣灵魂的TA。选择好要阅读哪本书之后&#xff0c;填写下资料&#xff0c;就能在看一本…

一些linux下的性能监测工具

1.gprof http://blog.csdn.net/stanjiang2010/article/details/5655143 2.系统性能调优 http://www.ibm.com/developerworks/cn/linux/l-time/part2/index.html?cadrs perf http://www.ibm.com/developerworks/cn/linux/l-cn-perf1/ oprofile http://www.ibm.com/developerwor…

uva 10183 How many Fibs?

数学题&#xff1a; 给你一个区间[a,b]在该区间内有多少个费波那列数&#xff08;包括a&#xff0c;b&#xff09;&#xff0c;数据规模达到10^100。 这题的原理很简单&#xff0c;基本没什么算法&#xff0c;其实更偏重于编程能力&#xff0c;需要用到高精度。另外找区间的地方…

2018/11/29 一个64位操作系统的设计与实现 02 (安装nasm)

操作系统: Centos7 在nasm官网上的到通过yum安装nasm的方法 首先在/etc/yum.repos.d/目录下 新建一个名为nasm.repo的文件, 在这么文件中写入内容如下 : [nasm] nameThe Netwide Assembler baseurlhttp://www.nasm.us/pub/nasm/stable/linux/ enabled1 gpgcheck0[nasm-testing]…

a-awk 计算数值最大,最小,平均值并保留指定位数

awk 计算最大值 echo -e "1\n2\n3\n10\n9\n5\n11\n"|awk BEGIN {max 0} {if ($1>max) max$1 } END {print "Max", max} 输出为&#xff1a;Max 11 或者可以使用sort命令更为便捷&#xff1a; cho -e "1\n2\n3\n10\n9\n5\n11\n"|sort -n |tai…

第18章:MYSQL分区

第18章&#xff1a;分区 目录 18.1. MySQL中的分区概述18.2. 分区类型18.2.1. RANGE分区18.2.2. LIST分区18.2.3. HASH分区18.2.4. KEY分区18.2.5. 子分区18.2.6. MySQL分区处理NULL值的方式18.3. 分区管理18.3.1. RANGE和LIST分区的管理18.3.2. HASH和KEY分区的管理18.3.3. 分…