Oracle如何避免partial write

来源:互联网  责任编辑:小易  时间:2017/1/11 20:43:03
用户提出问题:Oracle如何避免partial write,具体如下:

通过互联网整理获得以下解决方法:

=================1楼=====================

恢复.所以如果想要恢复split block,是要有该split block的整个前镜像的吧.

不懂 MySQL的原理,你说的这个,应该是 Oracle 的 UNDO ,你先百度了解一下;

=================2楼=====================

split block是指:一个 Oracle block 由多个 OS block 组成,写入必定有先后。那么外部工具备份是以 OS block 为单位备份,就可能发生一个 Oracle block 下的多个 OS block 版本不一致的情况。
而rman是把这一组 OS block 作为一个整体单位来处理的,全部读进来,如果版本一致可以写入备份,如果不一致全部重读。
所以读脏块没关系,只要有办法检测出不一致,直接把不一致的数据丢弃重读就行。

=================3楼=====================

引用 1 楼 wmxcn2000 的回复:
恢复.所以如果想要恢复split block,是要有该split block的整个前镜像的吧.

不懂 MySQL的原理,你说的这个,应该是 Oracle 的 UNDO ,你先百度了解一下;

跟undo没关系吧

引用一段<<MySQL技术内幕:InnoDB存储引擎>>书中对double write的描述内容:
如果说Insert Buffer带给InnoDB存储引擎的是性能上的提升,那么doublewrite(两次写)带给InnoDB存储引擎的是数据页的可靠性。

当发生数据库宕机时,可能InnoDB存储引擎正在写入某个页到表中,而这个页只写了一部分,比如16KB的页,只写了前4KB,之后就发生了宕机,这种情况被称为部分写失效(partial page write)。在InnoDB存储引擎未使用doublewrite技术前,曾经出现过因为部分写失效而导致数据丢失的情况。

有经验的DBA也许会想,如果发生写失效,可以通过重做日志进行恢复。这是一个办法。但是必须清楚地认识到,重做日志中记录的是对页的物理操作,如偏移量800,写'aaaa'记录。如果这个页本身已经发生了损坏,再对其进行重做是没有意义的。这就是说,在应用(apply)重做日志前,用户需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是doublewrite。

=================4楼=====================

引用 2 楼 Tiger_Zhao 的回复:
split block是指:一个 Oracle block 由多个 OS block 组成,写入必定有先后。那么外部工具备份是以 OS block 为单位备份,就可能发生一个 Oracle block 下的多个 OS block 版本不一致的情况。
而rman是把这一组 OS block 作为一个整体单位来处理的,全部读进来,如果版本一致可以写入备份,如果不一致全部重读。
所以读脏块没关系,只要有办法检测出不一致,直接把不一致的数据丢弃重读就行。


令我产生疑问的不是脏读,是Oracle block和OS block大小不一样.Oracle写一个oracle block到磁盘,加设8K,而一个OS block可能是4K,那么有可能产生这两个4K的块不一致,oracle如何保证不会产生这种不一致?

=================5楼=====================

引用 3 楼 ashic 的回复:
Quote: 引用 1 楼 wmxcn2000 的回复:

恢复.所以如果想要恢复split block,是要有该split block的整个前镜像的吧.

不懂 MySQL的原理,你说的这个,应该是 Oracle 的 UNDO ,你先百度了解一下;

跟undo没关系吧

引用一段<<MySQL技术内幕:InnoDB存储引擎>>书中对double write的描述内容:
如果说Insert Buffer带给InnoDB存储引擎的是性能上的提升,那么doublewrite(两次写)带给InnoDB存储引擎的是数据页的可靠性。

当发生数据库宕机时,可能InnoDB存储引擎正在写入某个页到表中,而这个页只写了一部分,比如16KB的页,只写了前4KB,之后就发生了宕机,这种情况被称为部分写失效(partial page write)。在InnoDB存储引擎未使用doublewrite技术前,曾经出现过因为部分写失效而导致数据丢失的情况。

有经验的DBA也许会想,如果发生写失效,可以通过重做日志进行恢复。这是一个办法。但是必须清楚地认识到,重做日志中记录的是对页的物理操作,如偏移量800,写'aaaa'记录。如果这个页本身已经发生了损坏,再对其进行重做是没有意义的。这就是说,在应用(apply)重做日志前,用户需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是doublewrite。


嗯。 

=================6楼=====================

引用 1 楼 wmxcn2000 的回复:
恢复.所以如果想要恢复split block,是要有该split block的整个前镜像的吧.

不懂 MySQL的原理,你说的这个,应该是 Oracle 的 UNDO ,你先百度了解一下;

您说的对,我也感觉需要split block的前镜像,但是正常dbwr写脏块到磁盘时.
加上oracle block 大小为8K, OS block大小为4K,那么此时一个oracle blokc= 2* OS block
加入dbwr在写脏块,写了前4K,此时发生crash,比如电源挂了,那么这个oracle block的前4k和后4k就不一致了,对于这种不一致的oracle block,通过redo没法恢复吧. 那么oracle如果保证不会产生我假设的这种情况呢?

MySQL通过double write避免这种问题
在对缓冲池的脏页进行刷新时,并不直接写磁盘,而是会通过memcpy函数将脏页先复制到内存中的doublewrite buffer,之后通过doublewrite buffer再分两次,每次1MB顺序地写入共享表空间的物理磁盘上,然后马上调用fsync函数,将更改真正的写入目标对应得数据文件中

在数据写失败时会有一下2种情况。
-如果是写doublewrite buffer本身失败,那么这些数据不会被写到磁盘,也就是真正的page没有损坏,innodb此时会从磁盘载入原始的数据,然后通过innodb的事务日志来计算出正确的数据,重新 写入到doublewrite buffer

-如果 doublewrite buffer写成功的话,但是写磁盘失败(通过对比checksum判断),innodb就不用通过事务日志来计算了,而是直接用double write buffer的数据再写一遍.

=================7楼=====================

引用 4 楼 ashic 的回复:
令我产生疑问的不是脏读,是Oracle block和OS block大小不一样.Oracle写一个oracle block到磁盘,加设8K,而一个OS block可能是4K,那么有可能产生这两个4K的块不一致,oracle如何保证不会产生这种不一致? 

这2个4k本身就在Oracle的缓存中,要取数据直接从缓存中取,总是一致的。
只有Oracle之外的程序才从硬盘读,从而发生读到4k旧、4k新数据的可能。

=================8楼=====================

引用 7 楼 Tiger_Zhao 的回复:
[Quote=引用 4 楼 ashic 的回复:]令我产生疑问的不是脏读,是Oracle block和OS block大小不一样.Oracle写一个oracle block到磁盘,加设8K,而一个OS block可能是4K,那么有可能产生这两个4K的块不一致,oracle如何保证不会产生这种不一致? 

这2个4k本身就在Oracle的缓存中,要取数据直接从缓存中取,总是一致的。
只有Oracle之外的程序才从硬盘读,从而发生读到4k旧、4k新数据的可能。

这两个4K的os block对应一个Oracle block,写入过程中写了第一个4K,然后服务器断电了.现在就很有可能前4K和后4K checksum不一致. 和在缓存中有啥关系?服务器都挂了,硬盘中的oracle block已经被修改了一部分了,后面那4K没改成功

=================9楼=====================

引用 8 楼 ashic 的回复:
这两个4K的os block对应一个Oracle block,写入过程中写了第一个4K,然后服务器断电了.现在就很有可能前4K和后4K checksum不一致. 和在缓存中有啥关系?服务器都挂了,硬盘中的oracle block已经被修改了一部分了,后面那4K没改成功 

中间断电,日志中该操作没完成,重启后会回滚(恢复上个版本数据)。
总之数据库是以8k作为一个原子来操作的,对数据库而言,并不存在(需要)4k成功4k不成功的这样的状态,只有(只需要)8k不成功状态就行。

=================10楼=====================

引用 9 楼 Tiger_Zhao 的回复:
[Quote=引用 8 楼 ashic 的回复:]这两个4K的os block对应一个Oracle block,写入过程中写了第一个4K,然后服务器断电了.现在就很有可能前4K和后4K checksum不一致. 和在缓存中有啥关系?服务器都挂了,硬盘中的oracle block已经被修改了一部分了,后面那4K没改成功 

中间断电,日志中该操作没完成,重启后会回滚(恢复上个版本数据)。
总之数据库是以8k作为一个原子来操作的,对数据库而言,并不存在(需要)4k成功4k不成功的这样的状态,只有(只需要)8k不成功状态就行。
redo肯定是在dbwr写脏块前就把日志写入磁盘了,而dbwr写脏块是在之后发生,如果出现写数据块不一致,redo中也不会记录该操作是否完成吧
第二句还靠谱,我再ITPUB上也看有人这么说,你们的意思就是Oracle写脏块时以Oracle block为最小IO单位吗?oracle直接去写数据文件,不经过操作系统?如果Oracle可以控制以自身Oracle block为原子进行写数据,那么到时可以避免partial write.但是我又产生了疑问,如果oracle可以做到为什么mysql不这么做呢,有没有能证实您说法的文档?

=================11楼=====================

引用 9 楼 Tiger_Zhao 的回复:
[Quote=引用 8 楼 ashic 的回复:]这两个4K的os block对应一个Oracle block,写入过程中写了第一个4K,然后服务器断电了.现在就很有可能前4K和后4K checksum不一致. 和在缓存中有啥关系?服务器都挂了,硬盘中的oracle block已经被修改了一部分了,后面那4K没改成功 

中间断电,日志中该操作没完成,重启后会回滚(恢复上个版本数据)。
总之数据库是以8k作为一个原子来操作的,对数据库而言,并不存在(需要)4k成功4k不成功的这样的状态,只有(只需要)8k不成功状态就行。

您说的"数据库是以8k作为一个原子来操作的"有没有官方文档,或者其他文献资料可以证实?或者您通过实验证实?我觉得MySQL通过double write也只是避免了自身crash导致的数据损坏,没法保证操作系统再写page的过程中断电是否会造成os block损坏,至于OS有什么机制避免,我还不清楚
但是假设oracle以oracle block为最小IO单位写数据,它怎么保证自己再写了8K中的一部分时,数据库崩溃不会造成partial write,除非他先写到一个临时文件,写成功了在去写真正的数据块

"中间断电,日志中该操作没完成,重启后会回滚(恢复上个版本数据)。" 您的意思是说,dbwr写脏块的过程还要记录在redo中?,写完了在redo中标记写成功?恐怕不是这样吧

=================12楼=====================

写脏块会记录在控制文件中

原子操作的概念是事务层面的吧?

=================13楼=====================

[http://blog.163.com/bihonggang_anshan/blog/static/13171564320118143472780/]oracle 写入数据的过程[/url]
Oracle中SGA与PGA的异同点是什么
对于任何一个完善的数据库,这是封装好的底层基本功能,属于无需关心的部分。
想了解自己找文档看,远比你想象的/平时简要描述的要复杂的多。

=================14楼=====================

引用 13 楼 Tiger_Zhao 的回复:
[http://blog.163.com/bihonggang_anshan/blog/static/13171564320118143472780/]oracle 写入数据的过程[/url]
Oracle中SGA与PGA的异同点是什么
对于任何一个完善的数据库,这是封装好的底层基本功能,属于无需关心的部分。
想了解自己找文档看,远比你想象的/平时简要描述的要复杂的多。


我现在觉得你根本不知道我再问什么,而你对体系结构也很混乱

=================15楼=====================

引用 13 楼 Tiger_Zhao 的回复:
[http://blog.163.com/bihonggang_anshan/blog/static/13171564320118143472780/]oracle 写入数据的过程[/url]
Oracle中SGA与PGA的异同点是什么
对于任何一个完善的数据库,这是封装好的底层基本功能,属于无需关心的部分。
想了解自己找文档看,远比你想象的/平时简要描述的要复杂的多。

我在这里要讨论的就是你说的底层,我发文也是翻过oracle官方文档,MOS,ITPUB得不到答案才来提问的.从你一开始说什么"在Oracle的缓存中","中间断电,日志中该操作没完成,重启后会回滚".这都不是我要讨论的问题.
不管什么数据库,对操作系统来说都是是一个软件,是软件就要协同操作系统完成任务.MySQL知道以自己的page进行写,要调用系统方法实现,而系统块大小与MySQL page不符,所以才有了double write.而Oracle如果解决官方文档中并没有体现.
我要再次引用<<MySQL技术内幕:InnoDB存储引擎>>中的描述
当发生数据库宕机时,可能InnoDB存储引擎正在写入某个页到表中,而这个页只写了一部分,比如16KB的页,只写了前4KB,之后就发生了宕机,这种情况被称为部分写失效(partial page write)。在InnoDB存储引擎未使用doublewrite技术前,曾经出现过因为部分写失效而导致数据丢失的情况。

有经验的DBA也许会想,如果发生写失效,可以通过重做日志进行恢复。这是一个办法。但是必须清楚地认识到,重做日志中记录的是对页的物理操作,如偏移量800,写'aaaa'记录。如果这个页本身已经发生了损坏,再对其进行重做是没有意义的。这就是说,在应用(apply)重做日志前,用户需要一个页的副本,当写入失效发生时,先通过页的副本来还原该页,再进行重做,这就是doublewrite。


实例恢复是以健康的数据块为基础,应用日志,前滚回滚,完成实例恢复,构造buffer中的数据块.而如果块本身已经corrupt,是不能以此作为基础再通过日志进行恢复的,至少MySQL不能,所以有了double write.而我在这里问的就是Oracle如何解决,这是对比学习的方法

恕我直言,没有文档,文献,实验支持的结论都是耍流氓.不能说"任何一个完善的数据库,这是封装好的底层基本功能,属于无需关心的部分"就相当然的认为别人是这样的做的,这不是做技术的学习方法.

网上涉及的文章,都没有详细说明.
http://www.vmcd.org/2014/09/1748/comment-page-1/#comment-343836
https://community.oracle.com/thread/1087650?start=0&tstart=0
http://www.ixora.com.au/tips/use_raw_log_files.htm

=================16楼=====================

你问: Oracle 避免 split block 的方式。
其实一句话就可以回答:把属于同一个 oracle block 的 OS block 作为一个原子进行控制就行。
其余的就是你在不停地追加细节问题了。

如果仅仅是学会使用数据库,你把它看成一个黑箱功能,反正数据库保证做到,能用就行。
如果你想学着编写一个数据库系统,先从大概原理来,可以看看我的回复。
如果你就追究Oracle是怎么做的,请忽略我的回复,去看文档。

=================17楼=====================

引用 12 楼 sych888 的回复:
写脏块会记录在控制文件中

原子操作的概念是事务层面的吧?


写脏块完成后会记录检查点.以便实例恢复时能够找到开始恢复的"点"
我觉得也是事物层

引用 16 楼 Tiger_Zhao 的回复:
你问: Oracle 避免 split block 的方式。
其实一句话就可以回答:把属于同一个 oracle block 的 OS block 作为一个原子进行控制就行。
其余的就是你在不停地追加细节问题了。

如果仅仅是学会使用数据库,你把它看成一个黑箱功能,反正数据库保证做到,能用就行。
如果你想学着编写一个数据库系统,先从大概原理来,可以看看我的回复。
如果你就追究Oracle是怎么做的,请忽略我的回复,去看文档。


无论如何还是谢谢您了

=================18楼=====================

继续求答案!

如果您还有更好的解决方法,请在最下面评论中留下您的解决方法


  • 本文相关:
  • 站长必读,如何真正写好一篇原创文章
  • 互联网之路细嗅蔷薇 资深站长分享掘金之道
  • 企业站的站长的工作重心究竟有哪些
  • 浅析:行业门户网站的一些盈利模式
  • 3000IP的企业网站每天订单不到30个的苦恼
  • 网站想内外兼修?先学习提高网站可用性的6大原则
  • 浅谈网页设计中的简约之美
  • 网页改版实战:日本设计师如何彻底优化旅游网站?
  • 网页改版实战!日本设计师如何彻底优化招聘网站?
  • 2015年值得关注的21个网页设计趋势
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2015 www.zgxue.com All Rights Reserved