存档

‘大话技术’ 分类的存档

数据仓库环境,ORACLE RAC,100T数据,每日归档那个量5T(对于不需要产生备份的数据,已经采用了nologging方式,以减少归档数量),如何制定备份和恢复方案?
方案一:DataGuard
DataGuard是性价比最高的备份和容灾方案,但是当归档超过一定规模之后,DG的恢复就成为了瓶颈,每天产生的归档无法及时恢复完,我们也尝试过很多调优的方法,包括并行恢复,都无法解决,恢复的瓶颈不在存储的吞吐量,而在于standby的恢复方式,因为恢复的过程就是应用归档文件,RAC各个节点产生的归档必须在一个节点恢复,这个过程必须是遵循一定顺序的,大大限制了恢复的并发速度。
方案二:传统RMAN备份
采用传统RMAN备份,采用大吞吐量的虚拟带库设备,一周全备一次,每天备归档日志。很多时候,我们在做备份方案时,只考虑了备份,却没有考虑恢复。这个方案最大的问题就在于:恢复的代价非常高,一旦数据库出现问题,恢复可能需要数天之久,这是无法接受的。另外,还要额外购买备份设备。
方案三:存储镜像
数据库采用noarchivelog模式,采用ASM镜像两套存储。这个方案并不是备份方案,只是为了解决存储的单点问题而提出的,相当于对不同的存储做RAID 1。这个方案最大的问题是无法解决数据库逻辑错误,比如误删除数据。因为主库和备库通过存储镜像来实现,无法实现异地备份和容灾。
方案四:存储级别复制
采用存储级别的复制,各存储厂家都有解决方案,比如EMC SRDF等。Veritas也有类似的解决方案,比如卷复制(VERITAS Volume Replicator)。这种方案的基本原理都是通过捕获底层存储的IO,并通过网络同步到备份系统上。如果采用存储厂商的方案,那么主备库就必须使用同一家公司的产品,而且,能否承受每天4.5T的数据变化量,我们并没有验证过。另外,软件license费用不菲。
有人说:能用钱解决的问题不是问题。可是,问题是没钱!Alibaba虽然不缺钱,但是我们的目标就是花小钱办大事。我个人也不推荐使用存储厂商的解决方案,这不仅仅是钱的问题,而是这种方案基本上就是个黑盒,我们还是喜欢更简单开放的解决方案。
既然ORACLE DG是性价比最高的备份和容灾方案,我们还是想通过DG来解决这个问题。DG的好处在于可以随时打开备份,验证有效,standby延迟恢复还可以解决逻辑错误,防范ORACLE软件bug可能带来的损失。解决方案的核心就是要解决DG恢复速度慢的问题。
方案五:ORACLE DG+块级别增量备份/恢复+归档
从10g开始,ORACLE提供了一个功能:块改变跟踪(block change tracking),通过bitmap记录block的变化,通过这个块改变跟踪文件,就知道哪个block发生了变化,大大提高了增量备份的效率。具体方案为:首先为数据库建立一个0级备份(standby),然后将1级备份应用到0级备份上,相当于恢复的过程,这个恢复比应用归档日志要快很多,为什么?因为备份都是变化的block,只要将旧的block覆盖就可以了,所以不存在日志恢复过程中的顺序问题,所以恢复的并行度可以很大,可以充分发挥出设备的吞吐能力。另外,当一个block被重复变更多次时,增量备份只需要备份最新的block,恢复也只要覆盖旧的block即可,定期增量备份实际可以减少备份需要的空间使用量。而redo文件中记录了block变化的记录,所以应用redo恢复时需要多次变更该块,必须保留所有的归档文件才可以恢复成功。当然,应用1级备份之后,standby并不能打开,因为block并不是一致状态的(因为增量备份会持续很长的时间,在这个过程中,备份的block的时间点是不一致的),所以要利用归档文件将standby推到一致的状态才可以打开。
我们目前的方案:建立standby数据库,每周做一次增量备份,首先应用增量备份,然后应用归档日志文件将数据库推到一致状态,可以打开数据库,验证备份有效,归档日志文件循环备份到磁带库,整个过程通过脚本实现自动化。这个方案采用增量备份+archivelog恢复standby,可以打开standby验证备份有效,出现故障时可以直接standby switchover,大大节省了恢复的时间。而且,这个方案都是基于现有硬件基础,基本上没有采购额外的硬件设备和软件license,花小钱办大事。
我的技术理念:做解决方案就是搭积木,用简单的技术去解决问题,并不一定要发明新的东西,最佳实践也是很有价值的。
–EOF–
后记:这个问题,我曾经在OOW上问过ORACLE的技术专家,他们也没有很好的解决方案,建议我们买两套Exadata来解决(我并没有搞清楚为什么Exadata恢复归档的速度会变快,是设备本身的能力提高了,还是ORACLE恢复的方式发生了变化),或者放弃数据库级别的备份,由应用程序写多份数据来解决。所以说,ORACLE也没有考虑到如此大数据量环境的备份问题,ORACLE可以考虑推广我们的解决方案。

1 27th, 2011 | Filed under 大话技术
标签:

数据库HA的最基本要求是:1.应用透明切换;2.切换速度快;3.保证数据完整一致。ORACLE数据库的HA方案都要基于共享存储,即shared storage架构,不管是RAC还是Active-Standy方式。Data Guard更多是作为备份和容灾的方案,由于standby数据库在恢复的过程无法打开读写,Standby必须经过switch over之后才可以读写,即便11g提供了Active standby功能,DG并不是特别适合做HA方案,主要原因是:1.需要人工干预,应用不透明;2.切换速度慢,Standby必须经过切换才能读写;3.可能数据丢失,如果采用LGWR同步传输日志,可以保证数据不丢失,但是可能会影响性能。
MySQL在这方面比ORACLE要灵活许多,因为是类似逻辑复制的方式,复制的过程中数据库不仅可读写,而且还可以采用双向复制的模式,通过DB Proxy,可以提供非常灵活的HA方案,见下图:

于是,我们想到让ORACLE借鉴MySQL的方案,采用逻辑复制的方法,通过DB Proxy实现应用透明切换,方案的核心就是ORACLE日志解析与数据同步。采用这种方案的优点:1.应用透明切换;2.切换速度快;3.切换时可能会丢失部分数据。这种方案虽然无法完全保证数据一致性,但是只要日志文件不丢失,数据可以达到最终一致的状态(MySQL也是如此)。对于那些对于一致性要求不高的应用,只要将同步时延控制在一定的范围内,这个方案可以提供很好的灵活性,而且DG依然可以作为备份和容灾的角色存在。
这个方案的最大意义在于:ORACLE数据的HA不再依赖共享存储,存储设备通常都非常昂贵,而目前PC+SSD就可以提供非常高的处理能力,唯一的软肋就是可用性无法保证,如果这个方案可以实现,就可以用PC+SSD取代小型机+存储,真是很令人期待。
当然还需要解决很多问题:1.实时解析日志,减少时延;2.同步变更字段,减少网络传输;3.并行应用,提高应用速度。目前,我们正在努力解决,很快可以看到曙光。敢想敢为,就没有不可能!
–EOF–

1 19th, 2011 | Filed under 大话技术
标签:

当初年少无知,对残酷的社会现实缺乏了解,导致HelloDBA在国内注册域名,这几年吃尽了苦头,被迫做了域名备案也就算了,而且多次申请转移域名不成功,因为怕麻烦就选择了续费。
今年,实在忍无可忍,投诉到ICANN,注册商终于打来电话,要求提供资料,然后又很无耻的在验证身份这个环节做文章,总之就是故意阻挠域名转移,耗费精力无数,实在不愿意再和这个注册商打交道了。
宁为玉碎不为瓦全,我决定放弃HelloDBA.net这个域名,在Godaddy上新申请了一个HelloDB.net的域名,坚决不再给这个无耻的注册商一分钱,我再次强烈呼吁大家不要在国内的任何一家域名注册服务商注册域名,也不要使用他们的任何服务。
近期我将把博客迁移到新的域名下,原有的域名我会继续投诉到ICANN,抗争到底!
–EOF–
经过再三考虑,最终将新的域名修改HelloDB.net,希望大家继续支持!

1 10th, 2011 | Filed under 大话技术

12.12日参加了淘宝主办的2010互联网数据库技术论坛,我贡献了一个主题:《数据库性能模型与容量规划》,主要关注硬件性能评测,数据库性能模型和容量规划,并提出了基于响应时间的数据库优化方法。这些内容都来自于实际工作中遇到的一些问题,通过对经验的整理,总结出一些简单的计算模型,属于比较传统和实用的话题,希望对大家有所帮助。
感谢淘宝提供了一个机会,让我们有机会一起交流技术。
–EOF–
PPT:数据库性能模型与容量规划

12 14th, 2010 | Filed under 大话技术

近日参加了在北京举行的velocity 2010会议,velocity关注运维与性能,包括Facebook,Google和国内的各大互联网公司都参加了这次会议,收获颇丰。
Facebook和Google的大牛们带来了多前端优化的主题,让我这个门外汉都受益很多。相比较前端,我更关注后端的性能优化,印象比较深刻的几个主题有:腾讯的分布式文件系统TFS,通过直接操作裸设备,实现精简的单机文件系统去搭建分布式文件系统,性能非常高。网易自主开发了MySQL的存储引擎NTSE,将传统数据库的块级缓存修改为行级缓存,更强调实体原子性而不是ACID,简化了事务和锁的设计,相当于将memcache内嵌在MySQL数据库中,实现了在特定应用场景下非常高的性能。新浪首席DBA杨海朝的构建高性能MySQL主题,带来了MySQL设计开发运维方面的一些经验,非常实用非常nice!百度的MySQL在SSD上的应用,通过修改MySQL存储引擎,实现了MySQL Flashcache的功能,通过软件与硬件结合的方式,实现了SSD性能的最大化利用,在SSD应用的方面,百度走在了国内同行的前面。
这次velocity会议,阿里巴巴,淘宝和阿里云也都带来了非常好的主题。在开放和分享方面,淘宝应该是国内互联网企业中做得非常好的。我在这次会议上也贡献了一个主题,《Alibaba数据库运维最佳实践》,自我感觉还行,自己给自己打80分。
这次会议另外的一个收获是,认识了很多同行和朋友,希望以后能有机会多交流学习,只有开放和分享才能不断提高自我。
PPT:Alibaba数据库运维实践
–EOF–

12 8th, 2010 | Filed under IT江湖, 大话技术
标签:

NOR和NAND
NOR和NAND都是闪存技术的一种,NOR是Intel公司开发的,它有点类似于内存,允许通过地址直接访问任何一个内存单元,缺点是:密度低(容量小),写入和擦除的速度很慢。NAND是东芝公司开发的,它密度高(容量大),写入和擦除的速度都很快,但是必须通过特定的IO接口经过地址转换之后才可以访问,有些类似于磁盘。
我们现在广泛使用的U盘,SD卡,SSD都属于NAND类型,厂商将flash memory封装成为不同的接口,比如Intel的SSD就是采用了SATA的接口,访问与普通SATA磁盘一样,还有一些企业级的闪存卡,比如FusionIO,则封装为PCIe接口。
SLC和MLC
SLC是单极单元,MLC是多级单元,两者的差异在于每单元存储的数据量(密度),SLC每单元只存储一位,只包含0和1两个电压符,MLC每单元可以存储两位,包含四个电压符(00,01,10,11)。显然,MLC的存储容量比SLC大,但是SLC更简单可靠,SLC读取和写入的速度都比MLC更快,而且SLC比MLC更耐用,MLC每单元可擦除1w次,而SLC可擦除10w次,所以,企业级的闪存产品一般都选用SLC,这也是为什么企业级产品比家用产品贵很多的原因。
SSD的技术特点
SSD与传统磁盘相比,第一是没有机械装置,第二是由磁介质改为了电介质。在SSD内部有一个FTL(Flash Transalation Layer),它相当于磁盘中的控制器,主要功能就是作地址映射,将flash memory的物理地址映射为磁盘的LBA逻辑地址,并提供给OS作透明访问。
SSD没有传统磁盘的寻道时间和延迟时间,所以SSD可以提供非常高的随机读取能力,这是它的最大优势,SLC类型的SSD通常可以提供超过35000的IOPS,传统15k的SAS磁盘,最多也只能达到160个IOPS,这对于传统磁盘来说几乎就是个天文数字。SSD连续读的能力相比普通磁盘优势并不明显,因为连续读对于传统磁盘来说,并不需要寻道时间,15k的SAS磁盘,连续读的吞吐能力可以达到130MB,而SLC类型的SSD可以达到170-200MB,我们看到在吞吐量方面,SSD虽然比传统磁盘高一些,但优势虽然并不明显。
SSD的写操作比较特殊,SSD的最小写入单元为4KB,称为页(page),当写入空白位置时可以按照4KB的单位写入,但是如果需要改写某个单元时,则需要一个额外的擦除(erase)动作,擦除的单位一般是128个page(512KB),每个擦除单元称为块(block)。如果向一个空白的page写入信息时,可以直接写入而无需擦除,但是如果需要改写某个存储单元(page)的数据,必须首先将整个block读入缓存,然后修改数据,并擦除整个block的数据,最后将整个block写入,很显然,SSD改写数据的代价很高,SSD的这个特性,我们称之为erase-before-write。
经过测试,SLC SSD的随即写性能可以达到3000个左右的IOPS,连续写的吞吐量可以达到170-200MB,这个数据还是比传统磁盘高出不少。但是,随着SSD的不断写入,当越来越多的数据需要被改写时,写的性能就会逐步下降。经过我们的测试,SLC在这个方面要明显好于MLC,在长时间写入后,MLC随机写IO下降得非常厉害,而SLC表现则比较稳定。为了解决这个问题,各个厂商都有很多策略来防止写性能下降的问题。
wear leveling
因为SSD存在“写磨损”的问题,当某个单元长时间被反复擦写时(比如Oracle redo),不仅会造成写入的性能问题,而且会大大缩短SSD的使用寿命,所以必须设计一个均衡负载的算法来保证SSD的每个单元能够被均衡的使用,这就是wear leveling,称为损耗均衡算法。
Wear leveling也是SSD内部的FTL实现的,它通过数据迁移来达到均衡损耗的目的。Wear leveling依赖于SSD中的一部分保留空间,基本原理是在SSD中设置了两个block pool,一个是free block pool(空闲池),一个是数据池(data block pool),当需要改写某个page时(如果写入原有位置,必须先擦除整个block,然后才能写入数据),并不写入原有位置(不需要擦除的动作),而是从空闲池中取出新的block,将现有的数据和需要改写的数据合并为新的block,一起写入新的空白block,原有的block被标识为invalid状态(等待被擦除回收),新的block则进入数据池。后台任务会定时从data block中取出无效数据的block,擦除后回收到空闲池中。这样做的好处在于,一是不会反复擦写同一个block,二是写入的速度会比较快(省略了擦除的动作)。

Wear leveling分为两种:动态损耗均衡和静态损耗均衡,两者的原理一致,区别在于动态算法只会处理动态数据,比如数据改写时才会触发数据迁移的动作,对静态数据不起作用,而静态算法可以均衡静态数据,当后台任务发现损耗很低的静态数据块时,将其迁移到其他数据库块上,将这些块放入空闲池中使用。从均衡的效果来看,静态算法要好于动态算法,因为几乎所有的block都可以被均衡的使用,SSD的寿命会大大延长,但是静态算法的缺点是当数据迁移时,可能会导致写性能下降。
写入放大
因为SSD的erase-before-write的特性,所以就出现了一个写入放大的概念,比如你想改写4K的数据,必须首先将整个擦除块(512KB)中的数据读出到缓存中,改写后,将整个块一起写入,这时你实际写入了512KB的数据,写入放大系数是128。写入放大最好的情况是1,就是不存在放大的情况。
Wear leveling算法可以有效缓解写入放大的问题,但是不合理的算法依然会导致写入放大,比如用户需要写入4k数据时,发现free block pool中没有空白的block,这时就必须在data block pool中选择一个包含无效数据的block,先读入缓存中,改写后,将整个块一起写入,采用wear leveling算法依然会存在写入放大的问题。
通过为SSD预留更多空间,可以显著缓解写入放大导致的性能问题。根据我们的测试结果,MLC SSD在长时间的随机写入后,性能下降很明显(随机写IOPS甚至降低到300)。如果为wear leveling预留更多空间,就可以显著改善MLC SSD在长时间写操作之后的性能下降问题,而且保留的空间越多,性能提升就越明显。相比较而言,SLC SSD的性能要稳定很多(IOPS在长时间随机写后,随机写可以稳定在3000 IOPS),我想应该是SLC SSD的容量通常比较小(32G和64G),而用于wear leveling的空间又比较大的原因。
数据库IO特点分析
IO有四种类型:连续读,随机读,随机写和连续写,连续读写的IO size通常比较大(128KB-1MB),主要衡量吞吐量,而随机读写的IO size比较小(小于8KB),主要衡量IOPS和响应时间。数据库中的全表扫描是连续读IO,索引访问则是典型的随机读IO,日志文件是连续写IO,而数据文件则是随机写IO。
数据库系统基于传统磁盘访问特性来设计,最大特点是日志文件采用sequential logging,数据库中的日志文件,要求必须在事务提交时写入到磁盘,对响应时间的要求很高,所以设计为顺序写入的方式,可以有效降低磁盘寻道花费的时间,减少延迟时间。日志文件的顺序写入,虽然是物理位置是连续的,但是并不同于传统的连续写类型,日志文件的IO size很小(通常小于4K),每个IO之间是独立的(磁头必须抬起来重新寻道,并等待磁盘转动到相应的位置),而且间隔很短,数据库通过log buffer(缓存)和group commit的方式(批量提交)来达到提高IO size的大小,并减少IO的次数,从而得到更小的响应延迟,所以日志文件的顺序写入可以被认为是“连续位置的随机写入”,瓶颈还是在IOPS,而不是吞吐量。
数据文件采用in place update的方式,意思是数据文件的修改都是写入到原来的位置,数据文件不同于日志文件,并不会在事务commit时写入数据文件,只有当数据库发现dirty buffer过多或者需要做checkpoint动作时,才会刷新这些dirty buffer到相应的位置,这是一个异步的过程,通常情况下,数据文件的随机写入对IO的要求并不是特别高,只要满足checkpoint和dirty buffer的要求就可以了。
SSD的IO特点分析
1.随机读能力非常好,连续读性能一般,但比普通SAS磁盘好。
2.不存在磁盘寻道的延迟时间,随机写和连续写的响应延迟差异不大。
3.erase-before-write特性,造成写入放大,影响写入的性能。
4.写磨损特性,采用wear leveling算法延长寿命,但同时会影响读的性能。
5.读和写的IO响应延迟不对等(读要大大好于写),而普通磁盘读和写的IO响应延迟差异很小。
6.连续写比随机写性能好,比如1M顺序写比128个8K的随即写要好很多,因为随即写会带来大量的擦除。
基于SSD的上述特性,如果将数据库全部放在SSD上,可能会有以下的问题:
1.日志文件sequential logging会反复擦写同一位置,虽然有损耗均衡算法,但是长时间写入依然会导致性能下降。
2.数据文件in place update会产生大量的随机写入,erase-before-write会产生写入放大。
3.数据库读写混合型应用,存在大量的随机写入,同时会影响读的性能,产生大量的IO延迟。
基于SSD的数据库优化法则:
基于SSD的优化就是解决erase-before-write产生的写入放大的问题,不同类型的IO分离,减少写操作带来的性能影响。
1.将sequential logging修改为In-page logging,避免对相同位置的反复擦写。
2.通过缓存写入的方式将大量的in-place update随机写入合并为少量顺序写入。
3.利用SSD随机读写能力高的特点,减少写增加读,从而达到整体性能的提升。
In-page logging
In-page logging是基于SSD对数据库sequential logging的一种优化方法,数据库中的sequential logging对传统磁盘是非常有利的,可以大大提高响应时间,但是对于SSD就是噩梦,因为需要对同一位置反复擦写,而wear leveling算法虽然可以平衡负载,但是依然会影响性能,并产生大量的IO延迟。所以In-page [...]

10 28th, 2010 | Filed under 大话技术
标签: ,

关于SSD
去年,我们曾经使用了一批SSD的PC,用来做数据库的服务器,用来提高数据库服务器的IO能力。但是从目前的使用情况来看,如果将SSD作为主存储,存在一些问题:
首先,SSD的稳定性还不够好,我们碰到了一些SSD盘损坏和SSD与机器不兼容的情况发生。
第二,SSD的容量盘都比较小,考虑到稳定性的问题,如果做RAID会进一步损失容量,性价比不高。
第三,SSD属于NAND类型的flash,写操作不仅会产生“磨损”,而且随着碎片的不断增加,写操作的性能会不断下降。
目前看来,SSD并不太适合作为数据库的主存储,写操作并不是SSD的特长,而且作为主存储的代价过高,SSD更加适合作为内存和磁盘之间的一层cache,降低读操作的延迟时间,我们将其称为flash cache。Oracle 11g R2中就提供了这样的功能,Oracle exadata V2配置了flash卡用来做flash cache,可以提供非常高的IOPS。对于MySQL数据库,Google和Facebook都提出了基于MySQL数据库的解决方案。
将SSD和Flash卡配置在PC服务器上,与普通SAS或者SATA磁盘混插,采用数据库flash cache技术,可以达到一个非常理想的性能,代价又不是特别高,我们也在考虑采用MySQL的flash cache架构。但是,如果你采用大型的存储设备,比如EMC和HDS,存储的cache实际上已经起到了一个二级缓存的作用,就没有太多必要使用SSD或者Flash卡了。
使用SSD还可以解决写操作的响应延迟,比如Oracle数据库的redo,因为每次commit都必须物理写入到磁盘上,所以将redo放在SSD上,可以提高写的响应延迟,但是不必将数据文件放在SSD上,因为他们并不是必须被写入的。这里要注意的是,SSD可能出现随着大量的写操作性能下降的情况。在我们的测试中,SLC的写能力比较稳定,而MLC的写能力会出现下降的情况。
SSD一定有光明的未来,取代磁盘只是个时间问题,只是我们还需要等待技术更加成熟,价格更加便宜。
关于可扩展的数据库架构
数据库分片(Sharding)是最简单实用的方案之一,将一个集中式的数据库拆分为很多小的数据库,从而获取数据库横向扩展的能力。但是,Sharding也带来一些问题:第一,应用可能需要进行大幅度的修改,以适应数据库拆分的变化。我们通过数据库代理软件来解决应用透明访问的问题,比如Amoeba,让数据库对应用透明,从而降低应用修改的复杂程度。第二,Sharding带来了一些应用上的限制,比如join,复杂查询和事务,要想解决这个问题比较困难,但是我们可以选择在适当的应用场景来使用,比如:在我们实际的应用场景中,绝大部分压力来自于商品,订单,交易等这类应用,其特点是:访问简单,数据量大,查询压力大。这类应用往往占到系统85%以上的压力,他们是非常适合做数据库拆分的。还有些应用是不适合做拆分的,比如一些查询复杂,事务要求高的应用,采用集中式数据库是比较合适的。我们通过应用场景的不同,选择不同的方案,既可以降低数据库压力,又可以降低应用的复杂程度。
还有一种常见的解决方案,在数据库前端增加一层cache,比如内存数据库,搜索引擎,KV cache等等,属于读写分离架构的一种,通过cache层有效缓解数据库的读压力,提高整个系统的处理能力。在这种架构中,由cache层承载了大量的数据访问,而数据库则退化为一个单纯的数据存储。在我们的系统架构中,就大量使用了memcache作为数据库的外部cache,淘宝也开发了自己的分布式KV  cache(Tair)。
作为DBA来说,我们也常常使用数据本身的功能去解决问题,比如Partition功能,但是它依然受限于单个database的处理能力,如果我们预期到单一数据库可能产生性能瓶颈时,就需要考虑借助一些应用架构去解决问题,而不是总是局限在数据库本身的功能上。
事实上,解决方案都不是孤立存在的,这几种方案经常混合在一起使用,比如Facebook的架构中,就是利用MySQL数据库和memcache,通过Sharding和读写分离等架构,从而使整个网站具备非常高的性能和扩展能力。我们在实际解决问题时,也是如此,从数据库本身的优化,数据库内做分区,数据库拆分,利用memcache作读写分离,多数据库中心架构等等。

关于Oracle和MySQL
Oracle更适合集中式数据库架构,而MySQL数据库更适合分布式架构,在两种架构并存的环境下,我们用MySQL完全去替换Oracle是不现实的。
从公司战略的角度出发,逐步降低对Oracle的依赖,这是一个大的方向和目标,但并不意味着我们需要把所有的应用都迁移到MySQL数据库上,从纯技术的角度分析,这并不合理。
我对MySQL和Oracle的想法是:分布式架构采用MySQL数据库,集中式架构采用Oracle数据库,前者通过数据拆分(Sharding)等手段,解决海量数据处理和弹性扩展的问题,集中式Oracle数据库则用于保存核心数据,提供简单可靠的数据存储和访问服务。合理的使用Oracle和MySQL数据库,集中式架构和分布式架构共存,不仅可以控制Oracle数据库的压力和规模,而且可以降低整体开发成本和维护成本。
关于小型机和存储
虽然说近些年来PC服务器的性能得到了很大的提高,甚至已经超过了小型机,但是小型机也不是一无是处,在稳定性,管理性和维护性等方面,小型机都要比PC服务器高出不止一个档次。其缺点就是价格昂贵,容易对硬件厂商产生依赖。
长远来看,我们要控制小型机使用的规模,但并不意味着要替换掉所有的小型机,对于核心应用的Oracle数据库,我认为小型机还是有价值的,起码在可用性方面有保证。对于MySQL数据库,我们大量采用PC服务器,配合数据库拆分和高可用架构,可以充分利用单台PC服务器的处理能力,又保证整个MySQL数据库集群的可用性。
Oracle和MySQL数据库对于机器的选型也有差异,Oracle选择小型机或者比较高端的PC服务器,比如四路Intel 7500系列,最高可以配置四路六核或八核CPU,在性能上已经超过了我们使用的IBM小型机。MySQL则选择处理能力与IO能力均衡的服务器,通常会配置比较多的本地磁盘,比如双路Intel 5500或者5600系列,本地配置12-16块磁盘,甚至配置SSD或者flash卡。
对数据库而言,存储设备非常重要,通常情况下,Oracle数据库会选择中高端的存储设备,而MySQL只配置PC服务器上本地磁盘或者低端的磁盘扩展柜。因为Oracle的高可用策略通常都要基于共享的存储设备实现(比如RAC,Veritas VCS等),所以SAN存储几乎是必须的选择,而MySQL的高可用策略是基于复制的,并不需要共享的存储设备。(当然,Oracle也有data guard的方式,但是DG的切换过程复杂,需要人工干预,作为高可用策略并不适合,更多是作为一种容灾和备份的机制)。
总的来说,硬件的选择与数据库本身的特性和应用架构有密切关系。从对主机的资源利用率上看,Oracle可以充分利用机器的计算能力,而MySQL对SMP架构的支持比Oracle差很多,单台MySQL数据库可能无法完全利用主机的处理能力,所以MySQL主机配置过多的CPU也是一种资源浪费。
关于“去I/O/E”的策略(分别代表IBM,Oracle,EMC),我个人的观点是“合理使用”,而不是为了去而去。不管是数据库的选择还是硬件的选择,我们的目标应该是不依赖于某个厂商,掌握主动权和话语权,这才是最重要的。
关于NoSQL和Database
NoSQL现在非常火,我也写了一些鸡毛蒜皮的文章介绍NoSQL,NoSQL的出现并不是为了替代database,而是在某些特定的领域内解决问题,所以每个NoSQL产品都有其鲜明的特点,相比之下,Database经过这么多年的发展,已经发展成为非常成熟的商业产品,而NoSQL现在大部分还处于成长的阶段。
NoSQL产品的优势在于:扩展性,灵活的数据模型(非关系型),大规模数据处理等方面,Database的优势在于:通用解决方案,成熟度,运维成本,使用成本等方面。我始终认为他们之间不是替代的关系,而是互补的关系,未来在Alibaba的使用场景中,Database应该还是首选的数据库处理和存储方案,但是在大规模的数据处理和数据仓库计算方面,NoSQL应该可以找到大量的应用场景。
现在我们做技术方案时,往往面临很多选择,但是选择太多未必是件好事,我们在选择的过程中往往会加入个人的喜好,比如对某个技术的喜好和掌握程度,甚至为了证明某些能力,而选择一些并不熟悉的技术,虽然它非常先进,但可能并不适用。每种技术都有其存在的合理性,但是引入过多技术必然增加成本和风险,比如facebook,他们利用MySQL和memcache就解决了绝大部分的问题,而很火的cassandra,在facebook只是很小的一个应用而已。相比较而言,我们使用的技术要多得多,我建议在选择NoSQL和Database产品时,选择简单和成熟的技术方案,后期开发和运维成本都是需要考虑的。
关于DBA
DBA不应该仅仅局限于某个数据库产品,而应该更全面的了解开发架构方面的知识,甚至需要具备开发能力,比如针对MySQL数据库进行修改和优化,这也将大大提高DBA解决问题的能力。
DBA的价值不仅仅在于维护数据库本身,而应该在数据存储方案的选择上做出最专业的判断,这是DBA最大的价值所在。
关于技术发展趋势
我在公司五年多了,最初的数据库就是采用PC服务器,然后我们统一把他们整合到小型机上的集中式数据库,把MySQL换成Oracle,而现在我们又要把小型机换成PC服务器,把集中式Oracle数据库拆分成MySQL数据库集群,这不是简单的轮回,而是技术发展的结果。
虽然现在的发展趋势是分布式架构,但是说不定过几年又会出现超级计算机,从而又走向集中式的道路。我们要做的是能够看到3年内技术发展的一个方向,适应技术发展的潮流,并不断调整目标,在解决问题的过程中不断优化。问题和技术都是不断发展的,试图设计一个完美的解决方案是不现实的,在一个问题被解决后,一定会有新的问题冒出来。
选择简单但是不完美的技术解决问题,先做!然后再不断优化。如果不去尝试,我们永远也不知道下一步要做什么,总是停留在对技术方案本身优劣的讨论上,是没有意义的。
人总是在不断反思,不断否定自我的过程中进步的,技术发展也是一样。
–EOF–
本文仅代表我个人对技术一些看法,欢迎大家拍砖。

9 12th, 2010 | Filed under 大话技术
标签: , ,

Oracle中普通的表称为堆表(heap table),堆表中的数据是无序存放的,往往在使用一段时间后,数据就变得非常无序。如下图所示,索引中相同的key对应的数据存放在不同的block中,这时,如果要通过索引查询某个key的数据,就需要访问很多不同的block,代价非常高。

Oracle中有一个统计信息clustering factor,它就是用来反映索引中键值在表中的有序程度,clustering factor的值如果接近表的blocks的数量,表明数据在表中的是有序的,而如果这个值接近表的行数,则表明表中的数据是无序存放的。因为clustring factor对于索引查询的影响很大,所以在CBO计算cost时,这个值非常重要。
我们可以通过创建一个单表的hash cluster,将相同键值的数据物理存放在一起,达到提高性能的目的。创建cluster有两个最重要的参数:hashkeys和size,前者表示cluster中有多少个不同的键值,后者表示每个键值需要分配的空间。因为hash cluster的空间是预先分配的,这两个值的正确设置对cluster的性能影响非常大。hashkeys设置过大,会造成空间浪费,而如果设置过小,则会产生大量的hash碰撞,极大影响性能。size也是一样,设置过大会浪费空间,而设置过小,数据超过预先分配的空间时,会通过链接方式存放在溢出段中,影响性能。而这两个值一旦设置,就无法更改,除非重建cluster。
hash cluster简单的说就是通过预先分配空间的方式,将相同key的数据存放在一起,以提高查询性能的一种手段,所以准确的设置hashkeys和size参数是使用hash cluster的关键,使用的前提是key的数量是可以估算的,而且每个key的数据是基本平均的。但是,在实际使用的环境中,数据量的变化往往是不可预知的,这也造成hash cluster的应用场景非常有限。
Index cluster和hash cluster类似,只不过index cluster是通过索引实现数据定位,而且index cluster的空间是动态分配的,但是同样存在正确设置size参数的问题,设置过大过小都会产生性能问题。
个人观点:Oracle cluster更适合相对静态数据的存储,对于OLTP应用来说,cluster在大部分情况下都不太适用,因为我们都无法预估到数据量的变化,根本无法合理设置cluster的参数。
任何技术都要找到合适的应用场景,有利一定有弊,有些技术确实是看上去很美,但是并不实用,而有些方案看上去很土,但是可以解决问题,找到最合适的就好。
–EOF–
如果哪位兄弟有oracle cluster解决实际问题方面的案例,也请和我一起交流。

9 5th, 2010 | Filed under 大话技术

Cache和Buffer是两个不同的概念,简单的说,Cache是加速“读”,而buffer是缓冲“写”,前者解决读的问题,保存从磁盘上读出的数据,后者是解决写的问题,保存即将要写入到磁盘上的数据。在很多情况下,这两个名词并没有严格区分,常常把读写混合类型称为buffer cache,本文后续的论述中,统一称为cache。
Oracle中的log buffer是解决redo写入的问题,而data buffer cache则解决data block的读写问题。对于Oracle来说,如果IO没有在SGA中命中,都会发生物理IO,Oracle并不关心底层存储的类型,可能是一套存储系统,可能是本地磁盘,可能是RAID 10,也可能是RAID 5,可能是文件系统,也可能是裸设备,或是ASM。总之,Oracle把底层的存储系统称为存储子系统。
在存储系统中,cache几乎无处不在(在后面的论述中,我们统称为cache),文件系统有cache,存储有cache,RAID控制器上有cache,磁盘上也有cache。为了提高性能,Oracle的一个写操作,很有可能写在存储的cache上就返回了,如果这时存储系统发生问题,Oracle如何来保证数据一致性的问题。
Oracle数据库最重要的特性是:Write ahead logging,在data block在写入前,必须保证首先写入redo log,在事务commit时,同时必须保证redo log被写入。Oracle为了保证数据的一致性,对于redo log采用了direct IO,Direct IO会跳过了OS上文件系统的cache这一层。但是,OS管不了存储这一层,虽然跳过了文件系统的cache,但是依然可能写在存储的cache上。
一般的存储都有cache,为了提高性能,写操作在cache上完成就返回给OS了,我们称这种写操作为write back,为了保证掉电时cache中的内容不会丢失,存储都有电池保护,这些电池可以供存储在掉电后工作一定时间,保证cache中的数据被刷入磁盘,不会丢失。不同于UPS,电池能够支撑的时间很短,一般都在30分钟以内,只要保证cache中的数据被写入就可以了。存储可以关闭写cache,这时所有的写操作必须写入到磁盘才返回,我们称这种写操作为write throuogh,当存储发现某些部件不正常时,存储会自动关闭写cache,这时写性能会下降。
RAID卡上也有cache,一般是256M,同样是通过电池来保护的,不同于存储的是,这个电池并不保证数据可以被写入到磁盘上,而是为cache供电以保护数据不丢失,一般可以支撑几天的时间。还有些RAID卡上有flash cache,掉电后可以将cache中的内容写入到flash cache中,保证数据不丢失。如果你的数据库没有存储,而是放在普通PC机的本地硬盘之上的,一定要确认主机中的RAID卡是否有电池,很多硬件提供商默认是不配置电池的。当然,RAID卡上的cache同样可以选择关闭。
磁盘上的cache,一般是16M-64M,很多存储厂商都明确表示,存储中磁盘的cache是禁用的,这也是可以理解的,为了保证数据可靠性,而存储本身又提供了非常大的cache,相比较而言,磁盘上的cache就不再那么重要。SCSI指令中有一个FUA(Force Unit Access)的参数,设置这个参数时,写操作必须在磁盘上完成才可以返回,相当于禁用了磁盘的写cache。虽然没有查证到资料,但是我个人认为一旦磁盘被接入到RAID控制器中,写cache就会被禁用,这也是为了数据可靠性的考虑,我相信存储厂商应该会考虑这个问题。
至此,我们可以看到Oracle的一个物理IO是经历了一系列的cache之后,最终被写入到磁盘上。cache虽然可以提高性能,但是也要考虑掉电保护的问题。关于数据的一致性,是由Oracle数据库,操作系统和存储子系统共同来保证的。
–EOF–

8 28th, 2010 | Filed under 大话技术
标签: , ,

Oracle中undo的作用主要有两个:第一是回滚事务,第二是产生一致性读。同时也衍生出了一些新的 功能,比如Flashback query。传统的undo是通过undo segment来管理的,我们看下面的示例:

事务开始,必须首先在data block中分配ITL,ITL中记录了事务ID(XID),XID由三部分内容组成:XIDUSN(回滚段号),XIDSLOT(回滚段槽 号),XIDSQN(序列号),在Undo segment header中有一个事务表,记录该回滚段上的事务信息,每个事务都会占据了一个回滚槽,XID对应一个UBA(undo block address),表示该事务回滚信息的开始位置。 在上面的例子中,事务分别在T1,T2,T3时间执行了三个操作,更新了三个block中的数据,在每个data block中都存在一个ITL,指向undo segment header中的事务表。undo信息分别存放在三个undo block中,undo信息是一个链表结构,而undo segment header中的uba则指向了最后一个undo block,这也是回滚的起始位置。如果事务需要回滚,只需要在undo segment header中的事务表中找到事务回滚的起始位置,然后通过undo链表,就可以依次回滚整个事务。
细心的DBA一定会发现,在每个data block的ITL中也有一个UBA,实际上这个UBA是指向了该block对应的undo信息的起始位置,这个UBA主要的作用是提供一致性读,因为一 致性读需要通过undo信息来构造一个CR block,通过这个UBA就可以直接定位到block的回滚信息的起始位置,而不再需要通过undo segment header中的事务表。
在传统的undo管理模式中,Oracle对于undo和data block是一视同仁的,他们都需要首先读入到data buffer中进行修改,并都会产生redo信息,修改的过程大致是:产生undo的redo,更改undo block,产生data的redo,修改data block。总之redo必须要先于数据被记录下来。当数据库发生crash,可以通过redo日志,恢复data和undo block,然后再通过undo信息去回滚未提交的事务,保证数据的一致性,所以说instance recovery的过程是先前滚,再回滚的过程。
传统的undo管理有弊端,第一是undo信息如果不在data buffer中,必须首先从外部文件中读入;第二是undo的所有变化也必须同时记录redo,在事务提交时被写入到redo log中。Oracle提出了In-Memory UNDO的新特性,将undo信息都存放在内存结构中,缓解传统undo管理中带来的开销。
IMU在shared pool中分配一片内存空间(IMU pool),每个新的事务都会分配一个IMU buffer,它相当于一片事物私有的undo buffer,用来记录undo的信息。Data block中记录了IMU node的起始位置,通过IMU buffer中的信息就可以完成一致读,从而大大提升了效率。(这里要澄清一点,我在dump data block时,并没有发现指向IMU node的具体信息)。

在IMU模式下,undo信息依然会被写入到redo中,理解这点很重要!因为Instance recovery需要undo的信息去回滚未提交的事物,使数据库处于一致状态,如果redo中没有undo变化的信息,那么一旦发生Instance crash,数据库将有可能处于一个不一致的状态。
事务开始依旧会在data block中的分配ITL,并且它依然会指向undo segment header的事物表,但是undo block中的信息并不需要马上写入,这时undo信息是记录在IMU Buffer中的,这时也不会产生undo block的redo信息。在以下两种情况时,undo buffer中的信息会被写入到undo block中:1.IMU buffer空间不足;2.LGWR将redo信息被写入到redo [...]

8 2nd, 2010 | Filed under 大话技术
标签: ,