Oracle提供的这些特性确实是用来进行性能改善的,但我们往往忽略了对自身应用特性的分析,它们是否适合于我们.最近,通过对这方面知识的深入了解,发现我们以前存在一些错误的认识.我觉得有必要,大家一起来改变这种误解.
分析之前,先明确一下我们的应用特性.数据库应用大体可以分为OLAP和OLTP两大类,即:联机事务分析(数据仓库)和联机事务处理(事务应用)我们的应用系统,其应用特性主要是联机事务处理,又包含了少量的数据仓库特性.
1.共享服务器(MTS)
Oracle缺省用的是专用服务器模式,也就是说一个用户连接进程对应一个服务器的进程.记得某大医院刚启用的时候,我们曾经试过MTS.因为听说MTS在不增加内存和CPU的情况下连接更多的客户端,结果并不是我们预期的那样.MTS有问题吗?不是,是因为我们对MTS不了解,并不是它有问题,而是它不是用来在这种情况下做这件事的.
一般情况,只有当并发连接数超过了操作系统的支持时,才建议使用MTS,否则应该使用缺省的专用服务器模式.也就是说,在专用服务器模式下,因为多一个连接就要多消耗一个操作系统的进程,只有当并发应用需求超过操作系统的允许连接数时,才有必要考虑MTS.
如果现有系统,物理上支持100个连接的专用服务器数据库,改为使用共享服务器模式,也许支持1000个连接,但同时活动的连接可能只有100个.一般2到4个CPU的服务器,应对200到400个并发连接是足够的,如果连接增加了,可以增加CPU和内存.
MTS具有以下一些缺点:
1.共享服务器的代码路径比专用服务器长,所以它天生就比专用服务器慢.
2.存在人为死锁的可能,因为它是串行的,所有共享服务器绑定在一起(一个进程),只要一个连接阻塞,则所有用户阻塞,并且极可能死锁.
3.存在独占事务的可能,因为如果一个会话的事务运行时间过长,它独占共享资源,其它用户只能等待.(而专用服务器,每个客户端是一个会话)
4.共享服务器模式限制了某些数据库特性,例如:不能单独启动和关闭实例,不能进行介质恢复,不能使用Log Miner,不能使用,并且SQL_TRACE没有意义(因为是共享而不是当前会话的).
MTS减少的内存实际上是专用服务器模式下每个用户连接到操作系统进程所需的内存,但它却使用SGA的Large_Pool来分配UGA,拆东墙补西墙,所减少的内存是很少的.如果用户会话的连接和断开很频繁,数据库进程的创建和删除的开销会非常大,这种情况最好采用共享服务器模式(否则,应该使用连接池技术).所幸的是,我们产品的设计可能就考虑了这个因素,使用的是一次连接终身使用(会话生命周期内),避免了这种情况.
所以,综上所述,针对我们产品,建议采用缺省的专用服务器模式,连接不够时,通过增加硬件解决,而不是改用MTS.另外,实际上,Oracle可以同时支持共享服务器和专用服务器模式,可以指定一个会话使用专用服务器,另一个会话使用共享服务器.
2.集群技术(RAC)
Oracle RAC(Real Application Clusters),我们说的双机容错就是RAC的一种. 集群技术的优势在在于横向扩展性能,并提供高可用性.32位的操作系统有4G内存的限制,有些Unix系统(以及非高级版本的Windows)有CPU个数的限制.而集群技术通过集合多台机器协同工作,横向打破了这种限制.通过RAC,一台服务器一个实例,多台机器构成一个实例服务集,客户端连接到它上面.这项技术,我们有时对客户说是负载均衡,实际上这是片面的,RAC的主要针对的是CPU和内存的负载均衡,并没有实现磁盘IO的负载均衡.(当然,磁盘IO可以通过Raid或NAS来实现)
RAC还有一个好处是,提高了可用性,也就是说一台服务器坏掉了(注意:不是数据存储介质),不影响正常使用.就像负载均衡一样,它提高了数据层以上的可用性,但不是全部,因为数据坏了,它也没有办法.(数据层,那是Oracle Data Guard的事了,或者干脆说那是存储硬件的事)
但是,RAC带来好处的同时,也带来了性能的影响.因为它要全局协调数据高速缓存,保证每个实例上连接的用户看到的缓存数据是一致的,所以把以下三方面的矛盾放大:
1.高速缓存争用
2.过多的I/O
3.锁定
也就是说,如果这些方面有问题,用了RAC后问题就会更大,例如:由于SQL没有使用绑定变量导致高速缓存争用,用了RAC会更严重.
总之,如果你的服务器的CPU插满了,内存也加到极限了,而并发用户还在不断增长,或者你对故障停机时间要求非常高,RAC无疑是你应该选择的.
3.分区
Oracle的分区用途在于把大的表或索引分成小的片段,以便更容易管理.我们以前可能错误的认为分区就是fast=true,可以提高速度,也在肿瘤和儿科做过这方面的试验.实际上,在事务处理系统中,分区一般不能加快查询速度(某些情况下可能会减少对共享资源的争用).Oracle的分区特性,主要是针对数据仓库来设计的,也就是说你的某张表如果有100G的大小,最好使用分区,好处有以下三个方面:
1.提高可用性
分区的原理就是分而治之,如果一张表划分为多个分区,其中一个分区所在的介质出了问题,不影响整个表的其它分区数据的访问.
2.易于管理
在数据仓库下,表分成小的片断,更容易批量的删除,碎片整理,以及一些并行处理.
3.提高性能
这方面,通过分区来达到是最困难的,必须经过周密的计算来安排分区数据.
分区的规划是复杂的,拿我们产品应用来说,一般查询涉及到多个表,多个索引,假设我们把病人费用记录,药品收发记录,病人医嘱记录这类大表建立分区.显然,范围分区对我们提升性能用处不大,散列分区才是我们查询需求的,但大多数数据的散列又不够集中.再加上,这些表上的索引这么多,常用的ID,时间类索引就不少,很少有人能做到把它们全部进行全局分区或准确的进行范围分区(实际上可能根本无法按需求进行多个索引的范围分区).如果查询经常涉及多个索引,如何保证用到的每个索引都在一个分区上,如果不是,必然扫描多个分区,增加逻辑I/O和CPU时间,从而增加查询时间.(数据分布在不同物理存储介质的情况,在下面的并行处理中再讨论)
再来看一下,某些情况下可能会减少对共享资源的争用是指什么,是指并行修改和更新会更快.仔细分析,我们分区的原则是什么?一般最常用的可能是按时间段进行范围分区,这样,修改和更新绝大多数还是在同一个分区上进行,所以对减少共享资源的争用这方面,基本没有什么效果.(有按科室ID进行散列分区的对应的唯一应用需求吗?有基于列表分区(典型特征值)的对应的唯一应用需求吗?基本上没有.)分区主要从并行的角度来提高性能,但事务处理系统本身应用特性决定了它不适合这种技术.也就是说,针对我们产品的事务处理应用特点,根本没有必要采用分区技术.
4.并行处理
根据我们的应用特点,主要分析并行查询.一般要求配合分区特性,多CPU硬件.自Oracle 8.1.6起,增加了一个自动调节并行查询的选项:PARALLEL_AUTOMATIC_TUNING=TRUE在相应的表上设置PARALLEL参数,Oracle就会在适当的时候自动并行化该表上的操作.并行查询对事务处理系统基本上没有用.因为并行查询的设计是针对数据仓库中的单用户完全消耗100的资源而做的.而事务处理中,往往有很多并发用户,他们争用共用资源,所以你想办法让一个用户占用所有的资源是适得其反