这个已经很久之前已经实践成功了,现在正好有时间就来写一写,目前并没有在其他地方有类似的分享,虽然我们自己的业务并没有涉及到云计算的场景,之前还是对rbd镜像这一块做了一些基本的了解,因为一直比较关注故障恢复这一块,东西并不难,总之一切不要等到出了问题再去想办法,提前准备总是好的,如果你有集群的问题,生产环境需要恢复的欢迎找我

前言

rbd的镜像的元数据,这个是什么?这里所提到的元数据信息,是指跟这个image信息有关的元数据信息,就是image的大小名称等等一系列的信息,本篇将讲述怎么去重构这些信息,重构的前提就是做好了信息的记录,然后做重构

记录元数据信息

创建一个image

[root@lab8106 ~]# rbd -p rbd create zp --size 40000

这里是在rbd存储池当中创建的一个名称为zp的,大小为40G的image文件

如果没有其他的image的情况下,我们来查看下对象信息

[root@lab8106 ~]# rados -p rbd ls
rbd_header.60276b8b4567
rbd_directory
rbd_id.zp

将这几个镜像下载下来

[root@lab8106 zp]# rados -p rbd get rbd_header.60276b8b4567 rbd_header.60276b8b4567
[root@lab8106 zp]# rados -p rbd get rbd_directory rbd_directory
[root@lab8106 zp]# rados -p rbd get rbd_id.zp rbd_id.zp

查看下载下来的几个镜像的元数据的文件信息

[root@lab8106 zp]# ll
total 4
-rw-r--r-- 1 root root 0 Jul 1 23:28 rbd_directory
-rw-r--r-- 1 root root 0 Jul 1 23:28 rbd_header.60276b8b4567
-rw-r--r-- 1 root root 16 Jul 1 23:28 rbd_id.zp

有没有发现有两个镜像的文件大小是0,这个是因为rbd format 2 格式下(默认格式),这两个对象的元数据信息是存储在扩展属性里面的,所以下载下来的对象是没有内容,那我们怎么查看这个属性,看下面讲述的查询相关的操作

查询这个image的信息

[root@lab8106 zp]# rbd -p rbd info zp
rbd image 'zp':
size 40000 MB in 10000 objects
order 22 (4096 kB objects)
block_name_prefix: rbd_data.60276b8b4567
format: 2
features: layering
flags:

这里可以看到这个image文件的大小,对象大小,前缀信息,属性相关信息,这是用我们比较常规的方式来查询到的信息,现在用另外一种方式来查询信息,查到的会是另外一种方式,也就是上面一节提到的空对象的扩展属性的查询

[root@lab8106 zp]# rados -p rbd listomapvals rbd_directory
id_60276b8b4567
value (6 bytes) :
00000000 02 00 00 00 7a 70 |....zp|
00000006 name_zp
value (16 bytes) :
00000000 0c 00 00 00 36 30 32 37 36 62 38 62 34 35 36 37 |....60276b8b4567|
00000010

先来查询 rbd_directory 这个的元数据信息,这个里面的信息可以看到两组对应关系

id_60276b8b4567,就是这个image的id,也是前缀信息,后面对应的是一个名称zp

第二组name_zp,对应的就是后面的60276b8b4567,也就是名称对应到id

,那个value值就是后面的字符串对应的16进制的一种方式,这个地方就是需要备份的元数据信息,现在准备做第一次重构,重构rbd_directory这个的元数据信息,这个rbd_directory记录所属存储池有哪些镜像

恢复rbd_directory的元数据信息

先来破坏这个元数据信息,破坏的方式很简单,就是做删除

[root@lab8106 zp]# rados -p rbd rm rbd_directory
[root@lab8106 zp]# rbd ls

可以看到删除了元数据信息以后,再进行镜像的ls,是查询不到信息的

开始做恢复

[root@lab8106 zp]# touch rbd_directory
[root@lab8106 zp]# rados -p rbd put rbd_directory rbd_directory
[root@lab8106 zp]# rados -p rbd listomapvals rbd_directory

上面做的三步是创建一个空文件,然后上传,然后列属性,可以看到,都是空的(这个地方也可以不创建空对象,直接做后面的给属性的时候,集群会自动创建相关的对象)

现在给这个对象写入属性

[root@lab8106 zp]# echo -en \\x02\\x00\\x00\\x00\\x7a\\x70|rados -p rbd setomapval rbd_directory id_60276b8b4567
[root@lab8106 zp]# echo -en \\x0c\\x00\\x00\\x00\\x36\\x30\\x32\\x37\\x36\\x62\\x38\\x62\\x34\\x35\\x36\\x37|rados -p rbd setomapval rbd_directory name_zp

写入的值就是上面让记录下来的信息,这个地方就用这个格式就行了,为什么要这么写,因为16进制的字符是需要转义的,之前不清楚怎么写,在邮件列表中提问后,有一个人低调的给回复了怎么写入这种进制数据,现在就这么固定写法就行了,现在再查询写入以后的属性情况

[root@lab8106 zp]# rados -p rbd listomapvals rbd_directory
id_60276b8b4567
value (6 bytes) :
00000000 02 00 00 00 7a 70 |....zp|
00000006 name_zp
value (16 bytes) :
00000000 0c 00 00 00 36 30 32 37 36 62 38 62 34 35 36 37 |....60276b8b4567|
00000010
[root@lab8106 zp]# rbd ls
zp

到这里 rbd_directory这个的信息就恢复了,下面再进行image的元数据的信息的恢复

恢复image的元数据信息

先查询下这个对象包含的元数据信息

[root@lab8106 zp]# rados -p rbd listomapvals rbd_header.60276b8b4567
features
value (8 bytes) :
00000000 01 00 00 00 00 00 00 00 |........|
00000008 object_prefix
value (25 bytes) :
00000000 15 00 00 00 72 62 64 5f 64 61 74 61 2e 36 30 32 |....rbd_data.602|
00000010 37 36 62 38 62 34 35 36 37 |76b8b4567|
00000019 order
value (1 bytes) :
00000000 16 |.|
00000001 size
value (8 bytes) :
00000000 00 00 00 c4 09 00 00 00 |........|
00000008 snap_seq
value (8 bytes) :
00000000 00 00 00 00 00 00 00 00 |........|
00000008

记录下这个信息,然后进行破坏,跟上面一样的删除掉对象

[root@lab8106 zp]# rados -p rbd rm rbd_header.60276b8b4567
[root@lab8106 zp]# rbd ls
zp
[root@lab8106 zp]# rbd info zp
2016-07-02 00:57:50.150559 7ff4b56b3700 -1 librbd::image::OpenRequest: failed to retreive immutable metadata: (2) No such file or directory
rbd: error opening image zp: (2) No such file or directory

可以看到,在删除了这个对象以后,已经无法查询到镜像信息了,当然也就无法使用了,下面开始进行image的元数据信息的重构

[root@lab8106 zp]# echo -en \\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00|rados -p rbd setomapval rbd_header.60276b8b4567 features
[root@lab8106 zp]# echo -en \\x15\\x00\\x00\\x00\\x72\\x62\\x64\\x5f\\x64\\x61\\x74\\x61\
\x2e\\x36\\x30\\x32\\x37\\x36\\x62\\x38\\x62\\x34\\x35\\x36\\x37 |rados -p rbd setomapval rbd_header.60276b8b4567 object_prefix
[root@lab8106 zp]# echo -en \\x16|rados -p rbd setomapval rbd_header.60276b8b4567 order
[root@lab8106 zp]# echo -en \\x00\\x00\\x00\\xc4\\x09\\x00\\x00\\x00 |rados -p rbd seto
mapval rbd_header.60276b8b4567 size
[root@lab8106 zp]# echo -en \\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00 |rados -p rbd seto
mapval rbd_header.60276b8b4567 snap_seq

设置完了所有属性后查询,验证是否恢复了

[root@lab8106 zp]# rbd -p rbd info zp
rbd image 'zp':
size 40000 MB in 10000 objects
order 22 (4096 kB objects)
block_name_prefix: rbd_data.60276b8b4567
format: 2
features: layering
flags:
[root@lab8106 zp]# rados -p rbd listomapvals rbd_header.60276b8b4567
features
value (8 bytes) :
00000000 01 00 00 00 00 00 00 00 |........|
00000008 object_prefix
value (25 bytes) :
00000000 15 00 00 00 72 62 64 5f 64 61 74 61 2e 36 30 32 |....rbd_data.602|
00000010 37 36 62 38 62 34 35 36 37 |76b8b4567|
00000019 order
value (1 bytes) :
00000000 16 |.|
00000001 size
value (8 bytes) :
00000000 00 00 00 c4 09 00 00 00 |........|
00000008 snap_seq
value (8 bytes) :
00000000 00 00 00 00 00 00 00 00 |........|
00000008

元数据完整的回来了

上面已经将两个导出的空对象元数据信息恢复好了,再看最后一个有文件大小的对象怎么做恢复

[root@lab8106 zp]# cat rbd_id.zp 

60276b8b4567[root@lab8106 zp]#

这个第一种方式是直接备份好,然后倒入的方式

跟上面的方法一样,开始通过删除对象来破坏

[root@lab8106 zp]# rados -p rbd rm rbd_id.zp
[root@lab8106 zp]# rbd -p rbd info zp
rbd: error opening image zp: (2) No such file or directory

可以看到破坏了就无法访问镜像了,下面直接利用备份对象倒入的方式进行恢复

[root@lab8106 zp]# rados -p rbd put rbd_id.zp rbd_id.zp
[root@lab8106 zp]# rbd -p rbd info zp
rbd image 'zp':
size 40000 MB in 10000 objects
order 22 (4096 kB objects)
block_name_prefix: rbd_data.60276b8b4567
format: 2
features: layering
flags:

可以看到,导入后即可,也可以用另外一种方式,记录字符串的方式进行备份

[root@lab8106 zp]# xxd rbd_id.zp
0000000: 0c00 0000 3630 3237 3662 3862 3435 3637 ....60276b8b4567

我们可以查看这个文件的16进制的信息输出,这个信息就是要保留的字符串信息

[root@lab8106 zp]# hexdump -C rbd_id.zp
00000000 0c 00 00 00 36 30 32 37 36 62 38 62 34 35 36 37 |....60276b8b4567|
00000010

需要保留的就是这个信息,我们根据这个信息来重新创建一个文件,然后检查文件内容是不是能跟下载下来的对象一样

[root@lab8106 zp]# echo -en \\x0c\\x00\\x00\\x00\\x36\\x30\\x32\\x37\\x36\\x62\\x38\\x62\\x34\\x35\\x36\\x37   >rbd_id.zpre
[root@lab8106 zp]# hexdump -C rbd_id.zpre
00000000 0c 00 00 00 36 30 32 37 36 62 38 62 34 35 36 37 |....60276b8b4567|
00000010

可以看到,可以用字符串完整恢复这个对象了,然后put进集群即可恢复了

总结

可以看到,所有的元数据信息都可以以字符串的形式保留下来,然后进行元数据重构,其中的rbd_id.zp这个可以保存对象方式,也可以是获取对象后,然后保存16进制字符串信息,然后再进行本地创建对象,然后put的方式,其它的两个空对象可以用设置属性的方式进行恢复,在openstack场景下,这些元数据信息最好都保留下来,一旦有问题的时候,可以很方便的进行数据的重构,备份并不是说所有数据都需要备份,对于这种数据量很小,而且很重要的信息,定期备份一下,也许哪天就用上了

变更记录

Why Who When
创建 武汉-运维-磨渣 2016-07-02

重构rbd镜像的元数据的更多相关文章

  1. 查看,创建,删除,映射rbd镜像

    标签(空格分隔): ceph,ceph实验,pg 1. 创建镜像: [root@node3 ~]# rbd create testpool/foo --size 1024 2. 查看镜像信息: [ro ...

  2. ceph 006 rbd高级特性 rbd快照 镜像克隆 rbd缓存 rbd增量备份 rbd镜像单向同步

    版本 [root@clienta ~]# ceph -v ceph version 16.2.0-117.el8cp (0e34bb74700060ebfaa22d99b7d2cdc037b28a57 ...

  3. 理解 OpenStack + Ceph (4):Ceph 的基础数据结构 [Pool, Image, Snapshot, Clone]

    本系列文章会深入研究 Ceph 以及 Ceph 和 OpenStack 的集成: (1)安装和部署 (2)Ceph RBD 接口和工具 (3)Ceph 物理和逻辑结构 (4)Ceph 的基础数据结构 ...

  4. Ceph 的基础数据结构 [Pool, Image, Snapshot, Clone]

    原文链接:http://www.cnblogs.com/sammyliu/p/4843812.html?utm_source=tuicool&utm_medium=referral 1 Poo ...

  5. ceph之image(转)

    原文地址:http://www.cnblogs.com/sammyliu/p/4843812.html?utm_source=tuicool&utm_medium=referral 2 卷(i ...

  6. 重构克隆rbd的数据

    前言 之前写过一篇重构rbd的元数据的文章,讲的是如果rbd的元数据丢失了,数据还在的时候怎么恢复相关的元数据,但是实际使用的场景是,集群可能崩溃了,数据还在,osd无法拉起来,数据又很重要,需要把数 ...

  7. 配置私有仓库(使用registry镜像搭建一个私有仓库)

    在使用Docker一段时间后,往往会发现手头积累了大量的自定义镜像文件,这些文件通过公有仓库进行管理并不方便:另外有时候只是希望在内部用户之间进行分享,不希望暴露出去.这种情况下,就有必要搭建一个本地 ...

  8. 006 管理Ceph的RBD块设备

    一, Ceph RBD的特性 支持完整和增量的快照 自动精简配置 写时复制克隆 动态调整大小 二.RBD基本应用 2.1 创建RBD池 [root@ceph2 ceph]# ceph osd pool ...

  9. ceph rbd块存储挂载及文件存储建立

    一.rbd块存储挂载 1 创建一个OSD pool # ceph osd pool create rbd1 128 查询存储空间使用 # ceph df GLOBAL: SIZE AVAIL RAW ...

随机推荐

  1. 监听MySQL的binlog日志工具分析:Canal

    Canal是阿里巴巴旗下的一款开源项目,利用Java开发.主要用途是基于MySQL数据库增量日志解析,提供增量数据订阅和消费,目前主要支持MySQL. GitHub地址:https://github. ...

  2. 判断是否是胖子的shell脚本

    read -p "请输入身高(m为单位): " HIGH if [[ ! "$HIGH" =~ [1].?[0-9]{,2}$ ]];then echo &qu ...

  3. 从一个例子入手Istio

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 本文使用的Istio源码是 release 1.5. 本篇是Istio系列的第一篇,希望 ...

  4. 在WPF中一种较好的绑定Enums数据方法

    引言 在你使用wpf应用程序开发的时候,是否需要进行数据绑定到Enum数据呢?在这篇文章中,我将向你展示在WPF中处理Enum数据绑定的方法. 假设存在一个这样的Enum数据的定义,具体内容如下文代码 ...

  5. Tomcat8升级后URL中特殊字符报错出现原因

    请求带上花括号等字符,请求无法送达服务端,报错: Failed to load resource: the server responded with a status of 400 () https ...

  6. F. Moving Points 解析(思維、離散化、BIT、前綴和)

    Codeforce 1311 F. Moving Points 解析(思維.離散化.BIT.前綴和) 今天我們來看看CF1311F 題目連結 題目 略,請直接看原題. 前言 最近寫1900的題目更容易 ...

  7. C语言函数的学习

    0x01.函数 这节就先讲函数吧,函数大致分为四种类型 1.无参数.无返回值的函数格式 void 函数名() { //代码段 } void Hello() { printf("Hello W ...

  8. Software Construction内容归纳

    本篇博文是对于2020春季学期<软件构造>课程的总结归纳,由于原先编辑于word,格式不方便直接导入该博客,可以到本人github中进行自取. https://github.com/zqy ...

  9. Java学习的第四十五

    1.例5.7求三个字符串中的最大值 import java.util.Scanner; public class Cjava { public static void main(String[]arg ...

  10. Spring创建Bean的过程Debug

    目录 Spring流程Debug 1.1 Spring测试环境搭建 1.2 Debug容器创建过程 1.3 AbstractApplicationContext的refresh()包含的13个方法分析 ...