zoukankan      html  css  js  c++  java
  • 重构rbd镜像的元数据

    这个已经很久之前已经实践成功了,现在正好有时间就来写一写,目前并没有在其他地方有类似的分享,虽然我们自己的业务并没有涉及到云计算的场景,之前还是对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
  • 相关阅读:
    无线路由器的工作模式
    php 利用root 权限执行shell脚本
    shell 终端常用插件
    linux space/mark设置
    推送唯一标识符
    微信支付跨平台软件架构
    celery 动态配置定时任务
    两个报文是如何进行 TCP 分组传输
    接口 Interfaces
    How does Circus stack compare to a classical stack?
  • 原文地址:https://www.cnblogs.com/zphj1987/p/13575357.html
Copyright © 2011-2022 走看看