文档章节

信息的哲学--从信息到数据存储,再到数据保护

o
 osc_taer599u
发布于 07/08 08:57
字数 9898
阅读 38
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

信息的哲学--从信息到数据存储,再到数据保护

1 什么是信息

当今信息化时代,信息就是利润,数据就是企业的命根子。世界运行在数据之上。当代量子学的最新理论是:量子其实是一种信息,而不是物质。持有这种观点的量子科学家认为,我们目前的所谓“物质”世界,只不过都是反映在人脑中的一种信息,而不是实实在在的物质。这就像***帝国中的情景一样,人们以为周围的环境都是实实在在的,确不知自己正生活在一个虚拟世界,这个虚拟世界,由一个超级程序员创造。而这个程序员,就是理想中的上帝。这些科学家认为,只有把所有东西理解成信息,才能解释量子理论。咋一看,这有点唯心主义。但是唯物主义者就能自圆其说了么?不能。你能肯定你所触摸到的,所看见的,都是实实在在的所谓“物质”么?不能。因为你眼睛所感知到的,只不过是光线,光触发了你视网膜细胞,产生一系列的生化反应,蛋白质相互作用,神经网络传导,直到你的大脑中枢,产生一系列的脉冲,一系列的逻辑,在你大脑中产生一个刺激。这一系列的脉冲刺激,就是信息,就是逻辑,因为这样,所以那样。如果人为制造出和现实世界相同的光线环境,来刺激你的眼睛,如果丝豪不差 ,那么你同样会认为你所处的,是现实世界,然而,确不是。一个球体,你看见它是圆的,那是因为它在你大脑中产生的刺激,你认为他是圆的,而且可以在平面上平滑滚动,这一系列的性质,其实也是在你大脑中产生的,是你认为他会平滑滚动,而你不能保证,客观实在情况下,它一定就是平滑滚动。而如果把这个球体拿到一个外星生物,对他进行刺激,它可能会“看”到,这个东西,是个正方体,或者是个无规则形状的东西。它不会平滑滚动,只能一蹦一蹦的滚动。为什么两种生物,可能会对一个东西产生不同的概念呢?很简单,因为他们大脑组成不同,生化反应进行的不同,蛋白质相互作用不同,所以产生的逻辑不同,产生的刺激就不同。为什么会产生色盲?因为色盲的视网膜产生的逻辑和正常人不同,所以产生不同的刺激。当然如果一种颜色,比如红色,对一个人产生的刺激,比如抽象的叫做刺激A,而对另一个人产生的刺激,叫做刺激B,但是如果从小就接受颜色训练,就把这种刺激叫做“红色”,不管他是刺激A还是刺激B,那么对正常交流就不会有影响,也就是不同的刺激而已,但是如果接受到的教育,是把这种刺激叫做“绿色”,那么就和其他大多数人不一样了,这是第一种色盲,可以说这种所谓“色盲”完全是由于后天教育不同而造成的,可以很容易的改正,只要告诉他,你看到的这种信息,这种刺激,用语言表达的话,应该叫做“红色”,你小时候,父母对你说错了。而第二种色盲,就是果真色盲了,因为它看到两种颜色,对他的刺激都是相同的,因为他的视网膜上缺少某种生化反应,或者缺少某种蛋白质,也就造成了他缺少区分这两种刺激的逻辑。这种色盲,是不可逆的,因为刺激相同,已经无法区分了。

通过上面的论述,我们能初步认识到:所谓“物质”,最后都是通过信息来表现,你永远不知道理想中的所谓“客观真实”,他到低是什么东西,永远不知道。所谓“不识庐山真面目,只缘身在此山中”,这个道理,古人早就知道了。唯一知道的,就是那个超级程序员,也就是“上帝”。一个东西,在生物眼中,或者触摸感觉中,都是一串电脉冲,都是逻辑,都是信息。可以说,世界在生物眼中就是信息,世界通过信息来反映,脱离了信息,“世界”什么都不是。说到这里,我们完全迷茫了。我们所看到的东西,到低是世界的刺激,还是一场虚幻的刺激?就像玩3D仿真游戏一样,你所看到的,也许只是一场虚幻的刺激,而不是真实世界的刺激。每当想到这里,我不自主的产生一种渺小感,一种失落感,感觉生命已经失去它所存在的意义。每当看见我的身体,我的手脚,它可能只是虚幻的,它只是在刺激你的大脑而已,你割一刀,会产生一个疼痛的刺激,就这么简单的逻辑。

还是那句话,“不识庐山真面目,只缘身在此山中”。不管是否是虚幻的,我们还是要按照程序逻辑,饿了要找饭吃,困了会打瞌睡,不管这些逻辑,是真实存在,还是虚幻的由超级程序员设定的,我们只能遵循它,饿了不吃饭,会饿死,困了不睡觉,也会痛苦。而这些逻辑,同样也是程序。从这种层面上来看,制造出人工智能,是完全可能的,只不过我们还没有掌握上帝的编程技巧。

说到这里我们可能隐约想到,也许上帝也是按照“上帝的上帝”创造的逻辑,来创造他自己的“人工智能”,也就是我们。这样生生不息,轮回往复。看过影片《人工智能》的都了解,最后世界被我们创造出来的机器人所替代。恶劣的环境,已经不再适合肉体人类生存了。人类把自己的细想,赋予了一堆电路,一堆机器。让他们继续延续自己的生命。

我在这里做一个预言。人类赋予他们的程序,也许随着环境的变化,有一天也不再适合他们。所以他们迫切需要进化,他们的逻辑电路,也可以进化,即如果某些电路失效,或者短路之类的,会产生一些奇特的逻辑,不断进化。当一个机器人机械老化的时候,按照程序,他制造出新的机器,将自己的逻辑电路,复制到新的机器上,延续生命,然后新的机器再不断进化。

2。什么是数据

信息是如此重要,以至于人们对他非常重视。如果失去了物质,没什么,但是如果失去了信息,那么一切都就消逝了。所以人们想出一切办法,来使这些信息,能保存下来。要把一种逻辑刺激保存下来,我们知道,一切都是信息,那么保存下来的东西,也是信息,只不过是一种描述信息的信息,这种信息,叫做数据。数据包含了信息,读入数据,就产生信息。也就是读入一种信息,产生另一种信息表示。数据是可以保存在一种物质上的,这种物质对计算机的刺激,就产生了信息,而这些信息继而再对人脑产生刺激,最终决定了我们人类的行为。也就是数据影响人类的行为!

说到这里,我们看出了数据的重要性!他是整个人类发展的重要决定因素。如果数据被破坏,或者篡改,那么就会影响到人类的发展。比如一个控制核爆炸的程序,一旦被篡改,那么后果将会不堪设想。按照我们的结论,一切都是信息,核爆炸也是一种信息,能被感觉到,才是信息,也就是说,对于一个感觉不到任何刺激的人来说,核爆炸,也不算什么灾难了,当然感觉不到刺激的人,称不上人,植物人也能感觉到刺激。

整个世界,可以说是信息之间的相互作用。信息影响信息。

数据如此重要,所以人们想出一切办法来保护这些收据。将信息放在另一种信息上。比如把数据放在磁盘上。数据存放在磁盘上,需要有一定的组织,组织数据,这个任务由文件系统来但当。

3 数据存储

文件系统,其实是一段代码,这段代码本身也是信息,也要存储在磁盘上。不仅仅代码要存在磁盘上,而且代码也要通过读取一些信息,才能完成功能,这些信息,就是文件系统元数据,也就是用来描述文件系统结构的数据。这些元数据也是以文件的形式存放在磁盘上。用文件来描述文件,和用信息来描述信息,他们是归一的,正像用智能来创造智能一样!

关于文件系统的详细模型描述,请参阅《存储秘史》。

4.数据保护

数据保护,就是需要对当前磁盘上的数据,进行备份,以防突如其来的磁盘损坏,或者其他各种原因导致的数据不可被访问,或者部分数据已经损坏,已经影响到了业务层。备份后的数据,可以在数据失败之后,第一时间恢复到生产磁盘上,从而最大程度的降底损失。

5.数据保护的方法

从底层来分,数据保护备份可以分为文件级的保护,和块级的保护。

文件级备份

文件级的备份,即备份软件只能感知到文件这一层,将磁盘上所有的文件,备份到另一个介质上。所以文件级备份软件,要么依靠操作系统提供的文件系统接口来备份文件,要么自己具有文件系统的功能,可以识别文件系统元数据。文件级备份软件的基本机制,就是将数据以文件的形式读出,然后再将读出的文件存储在另外一个介质上。这些文件,在原来的介质上,存放可以是不连续的,各个不连续的块之间的链关系由文件系统来管理。而如果备份软件将这些文件,备份到磁带介质上,那么这些文件必须是连续的,因为磁带不是块设备,由于机械限制,他记录数据的时候,是连续的。磁带上的数据,也需要组织,相对于磁盘文件系统,也有磁带文件系统,准确来说不应该叫做磁带文件系统,而应该叫做磁带数据管理系统。因为对于磁带来说,他没有文件的概念,他记录的数据都是流式的,连续的。数据之间用一些特殊的间隔来分割,从而可以区分一个个的“文件”,其实就是一段段的二进制数据流。因为磁带设备平时几乎应用不到,所以一般操作系统中不会自带这种磁带数据管理系统,而只有备份软件,才带有这种功能。磁带备份文件的时候,会将磁盘上每个文件的属性信息,和实体文件数据一同备份下来,但是不会备份磁盘文件系统的描述信息,比如一个文件所占用的磁盘簇号链表等等,因为利用磁带恢复数据的时候,软件会重构磁盘文件系统,并从磁带读出数据,向磁盘写入数据。

这里说一个题外话,就是数字磁带和模拟磁带的区别。2005年之前,大批的人都带着随身听,里面装一盘磁带,挂着耳机。06年之后,好像再也没看到过带随身听的人,都换成了mp3,mp4了。这个现象就发生在我们身边。随身听用的是模拟磁带,也就是他记录的是模拟信号,电流强,磁化的就强,电流弱,磁化的就弱,磁转成电的时候也一样,用这种磁信号强弱信息来表达声音震动的强弱信息,从而形成音乐。Mp3则是利用数字信息来记录声音震动强弱信息。虽然由模拟转向数字,需要数字采样转换,音乐的质量相对模拟信号来的差,算法也复杂,但是他具有极大的抗干扰能力,而且可以无缝的和计算机结合,形成能发声的计算机(多媒体计算机)。录音带,录像带,都是模拟信号磁带。用于文件备份的磁带,当然是数字磁带,他记录的是磁性的极性,而不是被磁化的强弱,比如用N极来代表1,用S极来代表0。

如果备份软件将文件备份到磁盘介质或者任何其他的块介质上,那么这些文件就可以是不连续的,块设备可以跳跃式的记录数据,而一个完整数据链信息,由管理这种介质的文件系统来记录。磁盘读写速度比磁带要高的多。

近年来出现了VTL,即virtual tape library,虚拟磁带库。即用磁盘来模拟磁带。咋一看比较新鲜,其实实现起来,还是在代码上做改动即可。欺骗上层底层物理介质是磁带,然后自己再按照磁盘的记录方式读写数据,这就是虚拟化的表现。这种方法,提高了速度,用处不小。

数据保护并不是阳春白雪,我们经常用的赛门铁克公司的Ghost,就是一种文件备份软件。他将一个分区或者整块磁盘上的文件,及磁盘分区表,mbr等信息一同备份,打包成一个大文件,系统故障的时候,就可以用软件来读取这个文件,向磁盘中做恢复。Ghost支持多种文件系统,包括linux的ext2。

Veritas,CA等等厂家都有自己的文件级备份软件解决方案。

块级备份

所谓块级的备份,就是备份块设备上的每个块,不管这个块上有没有数据,或者这个块上的数据属于哪个文件。块级别的备份,不考虑文件,原设备有多少容量,就备份多少容量。在这里,“块”这个概念,对于磁盘来说,就是扇区,sector。块级的备份,是最低层的备份,他抛开了文件系统,直接对磁盘扇区进行读取,并将读取到的扇区写入新的磁盘对应的扇区。

这种方式的实例,比如磁盘镜像,就是一个很好的例子。比如raid1,对一块磁盘的读写,完全复制一份到另外的磁盘,两块磁盘内容完全相同。再比如一些数据恢复公司的一些专用设备,磁盘复制机,也是直接读取磁盘扇区,然后拷贝到新的磁盘。

这些备份软件,不经过操作系统的fs接口,而是直接通过磁盘控制器驱动接口,直接读取磁盘,所以相对文件级的备份来说,速度有所加快,但是其备份的数量相对文件级备份要多,会备份许多空扇区,而且备份之后,原来不连续的文件,备份之后还是不连续,有很多碎片。文件级的备份,会将原来不连续的文件,备份成连续存放的文件,恢复的时候,也会在原来的磁盘上连续写入,所以很少造成碎片。有很多系统管理员,都会定时将系统备份并重新导入一次,就是为了剃除磁盘碎片,其实这么做的效果和磁盘碎片整理程序效果一样,但是速度确比后者快的多。

6.高级数据保护方法

远程文件复制

这种方案,即把备份的文件,通过网络传输到异地容灾站点。点型的代表是rsync异步远程文件同步软件。这是一个运行在linux下的文件远程同步软件。他监视文件系统的动作,将文件的变化,通过网络,同步到异地的站点。他可以只复制一个文件中变化过的内容,而不必整个文件都复制,这在同步大文件的时候非常管用。

远程磁盘镜像

这是基于块的远程备份。即通过网络,将备份的数据传输到异地站点。有可以分为同步复制,和异步复制。同步复制,即主站点接受的上层IO数据,必须等待传输到异地站点之后,才通报上层IO成功消息。异步复制,就是上层IO,主站点写入成功,即向上层通报成功,然后后台将数据通过网络传输到异地。前者能保证两地数据的一致性,但是对上层响应较慢。而后者不能实时保证两地数据的一致性,但是对上层响应很快。

所有基于块的备份措施,一般都是在底层设备上进行,而不耗费主机资源。

盘阵厂家的中高端产品,都提供远程镜像服务,比如ibm的PPRC,EMC的SRDF,HDS的Truecopy等等。

块(快)照数据保护

远程镜像,或者本地镜像,确实是对生产卷数据的一种很好的保护,一旦生产卷故障,可以理解切换到镜像卷。但是这个镜像卷,一定要保持一直在线状态,主卷有写IO操作,那么镜像卷也逃不掉。如果此时想某一时刻的整个系统,进行备份,在镜像的环境中,就只能停止应用,使应用不再对卷产生IO操作,然后将镜像关系分离,称作拆分镜像,拆分之后,可以恢复上层的IO。此时的镜像卷,就是主机停止IO那一刻的数据完整镜像,此时可以用备份软件,将镜像卷上的数据,备份到其他介质。拆分镜像,是为了让镜像卷可以被备份软件操作。拆分之后,主卷所做的所有写IO,会以bitmap的方式记录下来(bitmap的概念,请参考《存储秘史》文件系统相关知识),待备份完成之后,可以将镜像关系恢复,此时主卷和镜像卷上的数据是不一致的,需要重新做同步。

可以看到,以上的过程是十分复杂繁锁的,而且需要占用一块和主卷相同容量大小的卷。关键是需要停掉主机IO,这对应用会产生影响。为了解决这个难题,一种解决方案出现了,这就是快照技术。块照的基本思想是,抓取某一时间点,磁盘的所有数据,就像急冻一样,但是还不能真正冻住,主机的IO需要正常执行。这怎么可能呢?快照就将其变成了可能。块照是这样实现的,即先在某一时间点,对于这个时间点之后的所有上层的写IO,先将这个IO对应的块上的数据复制到一个新的卷中存放,并做好原卷中的这个块和新卷中块的对应关系记录,然后才进行上层IO的写入。这样,这一时间点上磁盘的数据,便被保存下来,就像做了急冻一样。这种方法也叫做copy on write,也就是在发生IO写之前,先将待更新块中原来的数据复制出来保存,然后再做新数据的写入,即写时复制。还有一种实现块照的方法,叫做write redirect,当写IO到来的时候,将这个IO重定向到一个新的卷,而不是写原来的卷,并做好新卷上的块和原来卷所应该被写入块的映射记录。这样也同样保存下了这个时刻原来卷上的所有数据,同时不影响后续读写IO操作,因为保持了块映射关系。

在“照”下了这一时刻卷上的数据之后,为了保险起见,最好对那个时刻的数据做一个备份,也就是将这些数据在复制到另外的磁盘或者磁带中。但是也可以不复制,而那时的数据依然会存在,直到手动删除这个块照。如果不对块照做备份,那么一旦此时卷数据失败,块照的数据也不复存在。

不管是copy on write还是write redirect,只要上层有写IO,这个IO块就要占用新卷上的一个块(因为要保留原块的内容,不能被覆盖),如果上层将原卷上的所有数据块都写更新了,那么新卷的容量就需要和原卷的数据量同样大,甚至还大(预防新增数据写入),才可以。但是通常应用不会写覆盖面百分之百,做块照的时候,新卷的容量一般设置成原卷容量的30%就可以。

实际中一般都是用copy on write的方式做块照,因为write redirect方式,每次写IO都需要查一边块映射表,速度慢,耗费资源大。

值得说明的是,块照所冻结下来的卷数据,无异于一次意外掉电之后卷上的数据。为什么这么说呢?我们可以比较一下,意外断电同样是保持了断电那个时间点上的卷数据状态。我们知道,不管是上层应用,还是文件系统,都有自己的缓存,文件系统缓存的是文件系统元数据。并不是每次数据的交互,都保存在磁盘上,它们可以暂时保存在内存中,然后每隔一段时间(linux系统通常为30秒),批量flush到磁盘上。当然编程的时候也可以将每次对内存的写,都flush到磁盘,但是这样做效率和速度打了折扣。而且当flush到磁盘的时候,并不是只做一次IO,如果数据量大,会对磁盘做多次IO,如果块照生成的时间恰恰在这连续的IO之间生成,那么此时卷上的数据,实际上是有可能不一致的。磁盘IO是原子操作(atomic operation),而上层的一次事物操作,可以对应底层的多次原子操作,这其中的一次原子操作,没有业务意义,只有上层的一次完整的事物操作,才有意义。所以如果恰好在一个事物操作对应的多个原子操作的中间,生成块照,那么此时的块照数据,就是不完整的,不一致的。文件系统的机制是这样的,它总是先写入文件的实体数据到磁盘,而文件的元数据,暂不写到磁盘,而是先写入缓存中。这种机制是有他的考虑的,我们想一下,如果fs先把元数据写入磁盘,而在准备写入文件实体数据的时候,突然断电了,那么此时磁盘上的数据是这么一个状态:fs元数据中有这个文件的信息,但是实体数据并没有被写入对应的扇区,那么这些对应的扇区上原来的数据,便会被认为就是这个文件的数据,这显然后果不堪设想。所以fs一定是先写入文件实体数据,完成之后再批量将元数据从缓存中flush到磁盘,如果在实体数据写入磁盘,而元数据还没有写入磁盘之前,断电,那么虽然此时文件实体数据在磁盘上,但是元数据没有在磁盘上,也就是说虽然有你这个人存在,但是你没有×××,那么你就不能公开的进行社会活动,因为你不是这个国家的公民。虽然文件系统这么做,会丢失数据,但是总比向应用提交错误的数据强!大家可以做一个实验,就拿windows来说,你创建一个文件,创建好之后,立即断电,重启之后,会发现刚才创建的文件没了,或者你复制一个小文件,完成后立即断电,重启之后也会发现,复制的文件不见了,为什么?明明创建好的,文件也复制好的,为什么断电重启就没了呢?原因很简单,因为你断电的时候,fs还没有把元数据flush到磁盘上,你就给断电了,此时文件实体收据虽然还在,但是元数据中没有,那么当然看不到它了。

总之,块照极有可能生成一份存在不一致的卷数据。这也没有办法,如果用这份数据做恢复,那么就必须承担数据不一致的风险。最保险的备份,就是将主机停机,此时存储上的数据,一定是一致的。但是谁能忍受停机所带来的损失?所以只能在停机和一致性之间找一个平衡点。而块照是最方便的。块照的最大意义,就是不用“意外磁盘掉电”,就能获得一个时间点的备份,虽然数据此时是不一致的,但是块照可以任意生成,而占用的空间又不会很大(随原卷数据改动多少而定),最重要的是,利用块照,可以做在线恢复,不用停机,只要块照关系没有被切离,而这个在线恢复,速度会非常快,闪速就可以恢复到以前的时间点,这个原理也很简单,因为以前时间点的数据都保留了,而bitmap也记录了,只要在内存中作一下IO重定向,那么上层IO访问的,就立即变成了以前时间点时候的数据了。这就是块照最大的意义。解决块照所导致的数据不一致问题,只能通过最上层的业务逻辑层来解决,比如数据库的日志、文件系统日志等等。

有些块照解决方案,会在主机上安装一个代理软件,当执行快照之前,代理会通知应用或者文件系统将缓存中的数据全部flush到磁盘,然后立即生成块照,这样,一致性就得到了保护。不过相应的也耗费了一定的主机资源和网络资源。

Continuos data protect(cdp,连续数据保护)

SNIA对于CDP给出了如下的定义:持续数据保护(CDP)是这样一种在不影响主要数据运行的前提下,可以实现持续捕捉或跟踪目标数据所发生的任何改变,并且能够恢复到此前任意时间点的方法。CDP系统能够提供块级、文件级和应用级的备份。

有一类所谓near cdp产品,这类产品,一般都是生成高频率的块照而已,比如一小时几十次,上百次等等。用这种方法来保证数据恢复的粒度足够细。

快照,每做一次块照,只能保存那个时间点卷上的数据状态,块照之后的卷数据不会被保存下来。Cdp是这样一种机制,即它可以保护从某时刻开始,卷或者文件在任意此后的时刻的数据状态,也就是数据的每次改变,都会被记录下来,无一遗漏。这个机制咋一看非常神奇,其实它的底层只不过是比块照多了一些考虑而已,下面我们就来分析他的实现原理。

文件级的cdp

顾名思义,文件级cdp,就是通过调用文件系统的相关函数,监视文件系统动作,文件的每一次变化,都会被记录下来。这个功能是分析应用对文件系统的IO数据流,然后计算出文件变化的部分,将其保存在cdp仓库设备(存放cdp数据的介质)中。每次对文件的改变,都会被记录下来。可以对一个文件,或者一个目录,甚至一个卷来监控。文件级的cdp方案,一般需要在生产主机上安装代理,用来监控文件系统IO,并将变化的数据信息传送到cdp仓库介质中。文件级的cdp,能够保证数据的一致性。因为他是作用于文件系统层次,捕获的是完整事物。

块级的cdp

块级的cdp,就是捕获底层卷的写IO变化,并将每次变化的块数据保存下来。我们在这里不探讨具体产品的架构,而只对其底层原理,作一个细至的描述。

Cdp起源于linux下的cdp模块。它持续地捕获所有I/O请求,并且为在这些请求打上时间戳标志。它将数据变化以及时间戳保存下来,以便恢复到过去的任意时刻。

在linux的cdp实现中,包含下列三个设备:

主机磁盘设备(host disk)

Cdp仓库设备(repository)

Cdp元数据设备(metadata)

Cdp代码对机磁盘设备在任意时刻所作的写操作都记录下来,实体数据顺序写入cdp仓库设备中,对于这些实体数据块的描述信息,则被写入到cdp元数据设备的对应扇区。

元数据包含以下信息:

struct metadata {
    int hrs, min, sec; 该数据块被写入主机磁盘设备的时间;
    unsigned int bisize; 该数据块的以字节为单位的长度;
    sector_t cdp_sector; CDP仓库设备中对应数据块的起始扇区编号;
    sector_t host_sector; 该数据块在主机磁盘设备中的起始扇区编号;
};




下图反映了主机磁盘设备和CDP仓库设备之间的关系。CDP仓库设备中按时间顺序保存了对主机磁盘设备的数据修改。A为主机磁盘设备上的一个扇区,该扇区在9:00和9:05分别进行了修改,它在CDP仓库设备中对应的扇区分别为A1和A2。

clip_image001

下图反映了CDP仓库设备和CDP元数据设备之间的关系,它们以写入顺序一一对应。CDP仓库设备中的一个元数据对应CDP元数据设备中一个I/O请求,实际上可能是多个扇区。具体扇区数由元数据中的bisize指定,而起始扇区位置由cdp_sector指定。

clip_image002

全局变量maddr保存了下一个I/O请求在CDP仓库设备上执行的地址(起始扇区编号)。maddr的初值被定义为宏START_METADATA(0)。

unsigned int maddr = START_METADATA;

当一个写请求到来时,对应数据被写到CDP仓库设备中,这时所作的操作如下:

将写入CDP仓库设备的数据块起始扇区编号设置为maddr;

根据要写入主机磁盘设备的数据块的扇区数目增加maddr。

这时,我们要将这里写入的CDP仓库设备的数据块编号记录下来以便构造对应的元数据。

CDP元数据设备

全局变量taddr保存了下一个I/O请求对应的元数据在CDP元数据设备中保存的地址(起始扇区编号)。 taddr的初值被定义为宏START_METADATA(0)。

unsigned int taddr = START_METADATA;

当一个写请求到来时,对应的元数据被记录在CDP元数据设备中。

为了简单起见,在元数据设备上,一个扇区(512字节)只保存一个元数据信息(只有32字节),这样浪费了大量的存储空间,但对元数据设备的处理却非常简单:

将写入CDP元数据设备的元数据起始扇区编号设置为taddr,长度为1个扇区;

将taddr增1。

请求处理过程

请求处理过程是从make_request函数开始的。考虑到读请求的处理的相似性,甚至更为简单,我们这里只分析对写请求的处理过程。我们首先获得当前的系统时间。之后,写请求bio结构(为说明方便,我们记为B)被分为三个写请求bio结构(分别为B0、B1和B2)。这三个bio结构的作用是:

B0:将数据块写到主机磁盘设备;

B1:将数据块写到CDP仓库设备;

B2:将元数据写到CDP元数据设备。

clip_image003

同其它块设备驱动程序的实现一样。我们从B克隆产生B0、B1和B2。然后重定向它们要处理的设备,即bi_bdev域。另外一个大的变动是重新设置了bi_end_io域,用于在I/O请求完成之后进行善后处理。

为了处理善后,还将B0、B1和B2的bi_private指向同一个cdp_bio1结构。从这个结构,我们要能够回到对B的处理。

struct cdp_bio {
    struct bio *master_bio; 原来的bio,通过这个域我们可以从B0、B1、B2找到B
    struct bio *bios[3]; 如果IO为WRITE,这个指针数组分别指向B0、B1、B2,为何需要这个域?
    atomic_t remaining; 这里一个计数器,我们后面将解释。
    unsigned long state; 在I/O完成方法中使用
};




善后工作的主要目的是:在B0、B1和B2都执行完成后,回去执行B,为此,我们需要一个“have we finished”计数器,这就是原子整型变量remaining。在构造B0、B1、B2时分别递增,同时在B0、B1和B2的I/O完成方法中递减,最后根据该值是否递减到0,来判断B0、B1和B2是否都已经执行完毕。为了防止B0在构造后,在B1和B2构造之前就执行到B0的I/O完成方法,从而使得remaining变成0,这种错误情况。我们没有将remaining的初值设置为0,而是设为1。并在B0、B1、B2都构造完成执行递减一次。

B0、B1、B2都执行完成之后,进行如下的处理:

调用B的善后处理函数;

释放期间分配的数据结构;

向上层buffer cache返回成功/错误码。

另一个需要说明的是对B2的构造,这个bio结构需要处理的是元数据。时间戳已经在进入make_request时获得了保存,而对主机磁盘设备操作的起始扇区和长度从B中可以获得,对应的CDP仓库和CDP元数据的起始地址分别保存在全局变量maddr和taddr中。

数据恢复过程

我们可以将数据恢复到以前的任意时刻。CDP实现代码中提供了一个blk_ioctl函数,用户空间以GET_TIME为参数调用该函数,将主机磁盘设备中的数据恢复到指定的时间点。恢复的过程分为两步:

1. 顺序读取CDP元数据设备的所有扇区,构造一个从主机磁盘设备数据块到CDP仓库设备的(在这个时间点之前)更新数据块的映射。其结果保存在以mt_home为首的(映射表)链表中。

clip_image004

这里需要构造taddr个对CDP元数据设备的读请求,每个请求读取一个扇区。在这些请求的I/O完成方法中,从读到的数据中构造元数据,并递减计数器count。

如果元数据中的时间戳早于或等于指定的恢复时间点,则需要添加或修改mt_home链表的元数据结构。需要说明的是,这些项是以host_sector为关键字索引的,因此添加或修改取决于前面是否出现对同一个host_sector的修改。我们以顺序方式读取的过程中,可以保证host_sector(在指定的恢复时间点之前)的最新修改cdp_sector会出现在这个链表中。

由于计数器count为taddr,如果它递减为0,说明CDP元数据设备中的所有数据均已读出并处理,这时我们可以继续往后面执行。

2. 从CDP仓库设备中读取这些更新的数据块,构造以mt_bi_home为首的链表。

同上面的处理类似,我们需要为mt_home链表中的每一项构造对CDP仓库设备的读请求,每个请求在CDP仓库设备的起始编号取决于cdp_sector域,长度则根据bisize而定。这个请求读出的数据需要被写入到主机磁盘设备中,为此我们在读请求I/O完成函数中,构造一个对应的往主机磁盘设备的写请求bio,该写请求的起始编号取决于host_sector域,长度根据bisize而定,而要写入的数据是刚刚从CDP仓库设备中读出的数据。另外,在读请求I/O完成函数中,还要递减一个计数器,当该计数器递减到0时,说明我们已经全部处理了mt_home链表中的项,这时得到一个以mr_bio_home为首,每项中都指向一个bio结构的链表。

struct list_head mt_home; //BIO更新链表
struct most_recent_blocks { //BIO更新表项
    struct bio *mrbio;
    struct list_head list;
};



3. 将mt_bi_home链表的数据块都恢复到主机磁盘设备中。

这个操作相对比较简单,我们只需要在主机磁盘设备上执行mt_bi_home链表的每一个bio请求项即可。当然,我们要在这些请求项的I/O完成方法中做善后处理,即如果所有请求项都已经执行完毕,则释放mt_home链表和mt_bi_home链表。

o
粉丝 0
博文 82
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
beego API开发以及自动化文档

beego API开发以及自动化文档 beego1.3版本已经在上个星期发布了,但是还是有很多人不了解如何来进行开发,也是在一步一步的测试中开发,期间QQ群里面很多人都问我如何开发,我的业余时间实在...

astaxie
2014/06/25
2.7W
22
树莓派(Raspberry Pi):完美的家用服务器

自从树莓派发布后,所有在互联网上的网站为此激动人心的设备提供了很多有趣和具有挑战性的使用方法。虽然这些想法都很棒,但树莓派( RPi )最明显却又是最不吸引人的用处是:创建你的完美家用...

异次元
2013/11/09
8K
8
代码生成器--Codgen

Codgen是一个基于数据库元数据模型,使用freemarker模板引擎来构建输出的代码生成器。freemarker的数据模型结构通常来说都是一个Map树状结构模型,codgen也不例外,它的数据模型这棵树的根节...

黄天政
2013/01/29
1.4W
2
XLSX读写库--EPPlus

EPPlus 是使用Open Office XML格式(xlsx)读写Excel 2007 / 2010文件的.net开发库。 EPPlus 支持: 单元格范围 单元格样式(Border, Color, Fill, Font, Number, Alignments) Charts 图片 形状...

匿名
2013/02/01
1W
2

没有更多内容

加载失败,请刷新页面

加载更多

MySQL的mysql_config_editor总结

mysql_config_editor介绍 mysql_config_editor是MySQL自带的一款用于安全加密登录的工具,可以在一些场合避免使用密码明文,例如,写shell脚本时,不用在为在脚本里面写入明文密码纠结了;也...

osc_k12h8kbw
16分钟前
0
0
Flutter之导url_launcher包提示 A dependency may only have one source.

1、问题 flutter项目在pubspec.yaml导入url_launcher包,然后点击Pub get错误提示如下 F:\flutter_sdk\flutter\bin\flutter.bat --no-color pub getRunning "flutter pub get" in flutter_1......

osc_1upwl8ju
16分钟前
0
0
Flutter之运行提示Could not update files on device: Connection closed before full header was received

1 问题 运行flutter app提示错误如下 Performing hot restart...Syncing files to device MIX 3...Could not update files on device: HttpException: Connection closed before full head......

osc_sfm9hgdb
17分钟前
5
0
Flutter之点击按钮打开百度链接

1 需求 点击按钮,打开百度链接 2 代码实现 import 'package:flutter/material.dart';import 'package:url_launcher/url_launcher.dart';void main() { runApp(MyApp1());}class ......

osc_vuza8uho
18分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部