赛迪网 > IT技术 技术文档 > 文章
  IT资讯搜索
 
IT产品搜索
[程序开发][网管世界][网络安全][数据库技术]
[操作系统][嘉宾聊天·在线访谈][活动集锦]
[精彩专题][Symantec专区][订阅IT技术周刊]
[开发论坛][网管论坛][安全论坛][数据库论坛]
[操作系统论坛][Sybase专区][IBM dW技术专区]
[病毒求助][病毒与漏洞播报][文档·源码下载]

ASE的锁模式及特性简介

发布时间:2007.04.13 11:43     来源:赛迪网技术社区    作者:lynn

Sybase公司关系型数据库管理系统产品----Adaptive Server® Enterprise11.9.2的版本开始,通过对行级加锁机制的创新以满足日益增长的可伸缩性的需求,并使得产品的性能和可伸缩性得到了明显的提高;特别是在商业应用中,使得更高版本的产品能够满足尽量少占用硬件和操作系统资源的用户需求。

在本篇章中,通过一些特定的实例对新的加锁机制进行了阐述,而这些实例都是使其并发性及其性能得到了很大的提高。应该注意到,为了使本文件内容更加集中,所提供的材料都是在很高层次上的。有关更详细的信息,请参看如下的文件:

·          New Functionality in Sybase Adaptive Server Enterprise 11.9.2[1]本文件是ASE 11.9.2 文档系列之一,该资料详尽介绍了本版本中所包含的全部新功能。

·          When (and When not to) Use Data-Only Locking [2] by Ian Smart),在这本由笔者撰写的资料中包含了本文献中所引用实例的详细分析、测试数据和硬件/软件配置。

  一、加锁机制

   1) 全页加锁(AllPageLock--APL)

这种类型的锁具有以下特性:

在事务活动期间,数据页和所有相关的索引叶级页加锁, 以阻止其它用户的存取。当各种类型的页面以任何方式发生改变时,对这些排它性的页面进行加锁;而且这种加锁机制一直保持到该事务终止; 当下一个所需的页面已经成功地获得,对那些已经释放的的当前访问页进行共享页面加锁(如果采用了第三层ANSI隔离,则把这种加锁机制保持到该事务终止为止) 。采用页级时间印记(timestamp)以确定是否发生改变,详细信息记录在事务日志中,以便在系统恢复时以向前或向后方式使用。

这种加锁方式常常提供性能最高的解决方案,特别是当应用设计时已经考虑了这些特性时更是如此。但是,有一些应用系统,当发生某些活动时,这种对整个页面进行加锁的方式就可能会对系统性能产生有重大意义的影响。对于那些面对诸如文件系统或其它已经支持更细小尺度加锁机制的数据库厂家产品的一般环境而设计的应用系统而言,这种情况尤其如此。

此外,还存在一系列问题,它们要围绕着更加困难的条件进行工作。它们通常要采用更加具有Sybase特性的解决方案。对于商用的应用软件制造厂商而言,对他们是一个挑战,因为这将要求他们必须跨越他们所支持的数据库平台,去完成维护其原代码的工作,而这个工作有相当工作量。在这个领域的基本问题如下:

对已经按照升序值创建的非聚簇索引的最末端叶型页面存在着争议;

对非聚簇索引的表进行插入和查询时可能发生死锁;

在按照聚簇性的索引值进行更新和对非聚簇索引的表进行查询访问之间可能发生死锁;

在没有作索引的表的最后一行可能发生冲突(尽管对最后的特定地址可以使用分区)

有可能使行数很少的表之间发生潜在的冲突(尽管对特定的地址可以使用填充因子[ fillfactors]和每页最大行数[ max_rows_per_page]这两个参数)

对每个页面两边进行加锁的需要常常被分割开来;

如果一个表特别小,以致在一个单一页面中进行驻留,那么对单一行的访问实际上将破坏对整个表的加锁机制。

 

2) 仅对数据加锁(DataOnlyLock—DOL)

仅对数据加锁机制试图去解决本文前一节所关注的主要问题(其他的议题将在其它功能领域中加以解决)。这种加锁方式支持两类不同的工作方式: 数据行加锁(Datarow)和数据页加锁(DataPage)。在这两种情况中,对于它们所支持的加锁方式,具有下列特性:

在索引页面中不会破坏事务加锁。相反,而是采用了一种称之为锁存的机制。锁存是一种类似于旋转锁(spinlocks)的同步方法,它们与事务无关并且只保留很短的周期(一般而言,当一个任务在数据库中物理上改变一小片数据时,这个周期相当于在共享存贮区中在一个2K的页面改变某些字节数据的时间)一旦完成之后,这个任务将直接打开这个锁存。当这种情况还可能临时同其它组块时 ,因为这种锁存不能对服务器任务进行有上下文的切换,也不能涉及死锁,并且只能保持主要的一小段时间,所以它们不能产生有显著意义的争用。

采用一个RID对单一行进行数据行加锁(行标识[RID----Row ID]是逻辑页号与所在页面上该行号的组合)

支持固定的行标识 RIDs, 它可以是向前的,允许不进行其RID的改变,就完成数据行的移动。当一行变大超过了它的可用空间时,采用上述结果对非聚簇索引不需要进行任何改变。

不需要进行任何争用就可以在表的尾部进行插入操作,这一功能已经增加进来。.

支持采用范围加锁、下一个关键字加锁和无限大加锁等方式对逻辑范围值进行加锁

支持由最顶层操作所导致的页面分割。这些情况直接加以提交,"系统"事务可以导致在更短一点的时间周期里保持分裂的页面处于锁定状态。

为了支持这些变化,需要对采用的存贮表结构进行一系列改善。这些改进的主要效果如下:

聚簇索引现在被存贮为象许多人所熟悉的IBM DB2产品所采用的“放置索引”("placement indexes.”)方式。这种结构类似于非聚簇性的索引,需要类似的空间总量。这种修正的结构导致了在数据初始存贮时可以按照顺序跨数据页进行存储,但是当发生插入时,它们就要尽可能紧密存放以便在正确的逻辑页面中不存在页面分割。此外,在数据页中的数据顺序在新行增加时是不进行维护整理的。这种索引的应用使每个聚簇化的索引周游增加了一次I/O操作。

行位移表已经增加到索引页和数据页中。这种增加和新的行索引行存贮格式具有使每个索引页面所存贮的索引条目个数减少的潜在能力。

固定行标识(RIDS)。当一行移动时,对于分配新行位置的向前地址被放在用于驻留该行的位置上。当这种移动需要改变非聚簇索引时,对该行的访问需要增加一次I/O操作以得到‘向前’的位置。

一般而言,索引将更小和更短,这是因为如下原因:

从每个叶级页面中采用双重键限制机制来限制双重键(Duplicate key)例如,如果值“绿”("GREEN”)在下列行标识(RIDs)值等于123-1234-2,和345-3的行中, 就分别存贮值“绿”("GREEN”),123-1234-2345-3,而不是存贮值“绿”("GREEN,”)三次。在每个索引页中每个值只存贮一次。

在非聚簇索引树的非叶型结点中将后缀实行压缩(例如,如果键值是"GREEN”"HAMILTON”,而在这两个值之间发生分裂,那么就在非页级索引页面中存储"G”"H”)

 

3) 数据页和数据行加锁

只对数据加锁机制支持两种方式:数据页加锁(DataPage)和数据行(DataRow)加锁。这些与它们的工作方式和所提供的功能相类似。这两种方式仅在对数据访问产生阻碍作用时,在加锁的尺度上有所区别。

DataPage 表是指在事务活动期间,只对数据页加锁, 所有相关的索引叶级页不加锁.当索引叶级页需要修改时,只加Latches 锁防止存取,但这个锁不会保持到事务结束。

DataRow 表是指在事务活动期间, 只对数据行加锁, 其他用户可以使用数据页的其它部分.当索引叶级页需要修改时,只加Latches 锁防止存取,但这个锁不会保持到事务结束。

在数据页加锁方式下再采用数据行加锁方式具有两种作用(一种起正向作用,另一种起反向作用)。首先,较小尺度加锁机制的使用可能导致减少争用与冲突,然而当大量数据发生变化时,就有可能对加锁产生大量阻碍的情况发生。

 

4) 特定使用的加锁类型

除非对配置参数加以特定,对所有的表都预置了隐含的全页面加锁机制。

sp_configure ‘lock scheme’,0, [allpages | datapages | datarows]

 

也可以在建立一个新表时,使用如下的句法格式单独对目标表设置加锁类型:

create table … lock [allpages | datapages | datarows]

 

为了对已经创建好的目标表改变加锁类型,可以采用如下的句法格式:

alter table lock [allpages | datapages | datarows]

 

在一个现存的表中改变加锁方式,将引起下列三种行动后果发生:

首先,如果一张表从全页加锁转变为仅对数据加锁,或者从仅对数据加锁转变为全页加锁,在这两种类型之间就要对表进行选择以允许进行存贮格式改变。如果这是一个分区表,就要同时假定必要的并行级别和工作线程已经配置好的情况下,才能执行。

其次, 对表中的聚簇索引必须重新创建。因为我们能保证数据,所以如果从全页加锁方式转换为只对数据加锁时,这种重新创建可以通过"with sorted_data"来完成。然而,当从仅对数据加锁机制转换为全页加锁方式时,就要进行并行的索引创建操作。(请注意:如果这是一个分区表时,那么并行等级和工作线程的数目必须加以配置才能允许进行这种改变,否则这种迁移将会失败)

最后,非聚簇性的索引将被重建,如果服务器已经为并行处理所加以配置,当进行本步骤时将加以采用。

由于这些活动同潜在的工作量有关,从全页加锁机制改变为仅对数据加锁或从仅对数据加锁改变为全页加锁机制都可能是耗费时间的活动。为了标注这一点,有以下一些选择:

如果可能的话,应该配置使用并行方式。这至少对执行非聚簇索引的哈斯(杂凑,即hashed)创建方法是必须的,但是如果可能的话,采用分区表和分区扫描将使系统得到更大的改进。

在选择进入和创建聚簇性的索引之后,该任务将被设置检查点(checkpointed )所以,如果有充分的硬件资源,通过允许在任何一个时间点上,检查点任务可以具有多于10个(系统缺省值)的异步I/O请求,利用dbcc进行调谐将能够带来有益的效果。(‘maxwritedes’, number)

进一步作为降低使用检查点成本的一种方法,在相关的高速缓冲池(cache pool)、大数据量的I/O操作中,采用对高淘汰程度进行标记的方法,并允许清洁程序(好象家庭主妇一样)保持特别活跃的状态,将为那些检查点需要从高速缓冲池中刷新较“脏”的页面的而增加的I/O操作次数,并因此花费了在检查点上的时间,都能够大大减少作出贡献。

如果预先进行了配置,则可以对并行的选择进入可以使用预先分配的盘区。所以,通过将sp_configure number of pre-allocated extents设置为16也将对系统性能有明显的积极的效果。

备注:在仅对数据加锁类型之间进行改变不需要对数据进行备份, 而且执行起来只需很短的一段时间。

 

二、对小量数据的多次并发访问

 

1) 在小型表中采用不同加锁方式之间的比较

对于那些被访问的数据同时(或者)仅有一张或很少数量的页面发生改变的情况,在页面级进行加锁极有可能导致表中很大比例的页面都实施了加锁机制。使用按数据行进行加锁将因为降低了加锁的尺度而明显增加了系统的吞吐量。

为了对使用按数据行进行加锁改变了原先发生的组块移动,已经设计了一系列基于TPC/B基准的测试实验。在这些实验中,使用了各种TPC/B的变量以创建略有不同的条件和可能发生的情况。在下面这些结果中,前三个执行的是直接更新。在实验45中,采用了选择、删除以及插入的组合(请注意,这些实验比其它的实验作了更多的工作)在实验67中, 由于补偿索引直至补偿列引起了数据更新的拖延。

利用已经执行的全部工作,在更新三张表的实验中,最小的表总是最后一个被更新。然后事务在历史记录表中插入一个条目。

备注:下列测试是在具有12个处理器的HP9000/891 T500的设备谁进行的。Adaptive Server Enterprise 配置为具有10个驱动核心( engines)和 1GB的内存。

  测试结果如下图所示:

  从这些数据可以看出,利用数据页加锁方式与全页加锁方式相比较而言,对于吞吐量来说几乎没有什么差别。这是由于两者之间在加锁尺度方面没有什么差别。然而,一旦使用了数据按行加锁方式,100行的数据可以单独访问时,此时在性能上的明显改进就能够达到了。

 

2) 在小型表中采用填充因子(Fillfactor)与仅对数据加锁方式之间的比较

在上文中所提及的小型表中,对表传统的工作方式是采用了诸如在每页的某一行,在聚簇索引上有效地放置了数目为1 的填充因子。我们采用100行的表重复进行了同样的一组实验,此处表都已经具有采用这类填充因子创建的聚簇索引。

下图显示了实验结果,它们分别是较早时间进行的按数据页和数据行加锁的结果,以及与之形成对照的采用1%的填充因子的全页加锁实验结果:

正如所看到的,在直接更新的情况,对吞吐量来说有一点微小的提高;而在删除/插入的测试情况中,对吞吐量却有明显的提高;而对延迟的更新实验,吞吐量则要有一些降低。

这些实验说明对这些课题来说,Sybase公司传统的响应在大多数情况下还是有效的,而且对那些已经用这种方法实现的用户来说并没有明显的缺陷。然而,对于填充因子方法来说还是有一些缺点,因而就限制了它们的用途。

 

3) 何时采用只对数据加锁或填充因子

随着引入仅对数据加锁方式,现在数据库设计者对使用更新的表中,如何解决争用冲突课题方面,有了选择。在表比较小或保持较小时,采用填充因子对于不使用延迟更新的情况将对吞吐量的提高有轻微的改善作用。

如果表比“少数”页大,那么填充因子的使用,特别是该因子为1时,就成为应该禁止和代价昂贵的一种方式了。这是由精确度所决定的,填充因子在每个页面里都留下了一些没有使用的空间。这样一来明显增加了磁盘空间需求,对大表尤其如此,这将导致更大的数据库和对更多硬件的需要。

其次,因为填充因子不是永久的,客户必须安排重构索引的程序段以对性能进行调整和维护。这样一来使争用和冲突发生在特定的区域,使之变得更加令人烦恼。事实上在过去,当用户激活逻辑分区的数据,静态数据放在另外的表里时,就把静态数据紧紧地包装在一起,在利用填充因子使之激活,这种情况对于用户并不是罕见的情况。使用这种技术已经引用了把数据放回到一个单一的结果集合中来的组合操作,这使得编写SQL程序变得格外复杂。

采用仅对数据加锁的方法可以使用户不一定需要使用填充因子来解决更好地利用可用空间的问题。这种选择使得用户可以在“两个世界之间的最佳者”选项中作出决定,以为其环境选择最优的方案。

 

三、堆栈表和热点

 

1) 在堆栈表中增加行

应用系统更新行时,如果同时使用了填充因子(fillfactor)或每页最大行数(max_rows_per_page),在这一话题是插入一行时,特别是在特定的位置(即热点--"hot spot”)插入时,这些方法就变得几乎没有价值。无论何时在一个没有聚簇索引的表(即所谓“堆”表--"heap”)中进行插入时,这种插入总是插到表的最后一页中去。在Sybase ASE 11.0之中,Sybase公司提供了允许用户在分区表中把这种插入蔓延分散到跨分区里去。然而,在采用这种方式解决问题的同时,这种方法不能处理由于空间开销而不能使用堆的情况,也不能解决那些因为查询原因要把数据按着添加的顺序存放的表的问题。

随着在Adaptive Server Enterprise 11.9.2版本中增加了“追加行”的逻辑,仅对数据加锁和锁存技术的采用,使得索引访问与空间分配得以协调,从而明显提高了性能。现在通过执行这样的任务,就能够不需要再采用依靠数据库加锁的一系列复杂的传统事务就能进行表的追加。

在下列的实验中,基于TPC/B的历史记录表被用于确定对堆表追加行时可能提高性能的级别。在每个事务的末尾插入历史记录表,作为工作性能的一条审计记录。运行TPC/B 的正常过程要采用多张已经分区化的历史记录表。(例如,在第三节中所显示的小表实验中,采用了具有100张分区化的60张历史记录表)

  这种实验的结果如下图所示:

 

备注:此处运行号分别对应于在所有直接更新和放置适当位置的小表测试中的运行号

如果分析加锁争用与冲突,可以观察到排他性的组块加锁大大减少,这是由于对于“下一行加锁”的技术已经被增加到按数据行加锁机制的一部分。但是这种功能还没有充分扩展为包括仅对数据加锁的方式,这就是在这些案例中为什么还会发生某些组块现象的原因。

 

从这些结果,可以看到需要聚簇或分区的堆表不止是一个选择,当采用仅对数据加锁方式时将给用户在明显提高其吞吐量的方面一个很实际的替换方式,特别是在数据行加锁方式的情况下,更是如此。

 

2) 追加到非聚簇索引的叶级末端

正如在4.1节中所描述的,对于堆表页链末端的热点(hot spots)可以通过使用聚簇性的索引或分区来加以解决。但是当非聚簇索引最末级(即叶级)的最后一个页面发生争用冲突时,或者在到达一个特定的点的中途,利用上述技术中的任一种方法都不能使上述问题按传统的方式加以解决。既然按照升序值建立索引是非常普通的(例如序列号、日期/时间列等),这就成为迄今为止难于克服的一个问题.

在采用仅对数据加锁的情况下,索引页不再按照传统方式进行加锁,而宁可使用锁存技术。因为锁存仅仅是一个短时期的同步技术,所以使用传统的页加锁方式时,不会加大开销或可能发生当主要的组块现象。

采用4.1节中的历史记录表,设计了一个实验,其中按照日期时间列建立了非聚簇性的索引,这个日期时间列的值是在该列插入的时刻使用getdate() 所得到的。这个按常数升序所建立的索引引起了索引叶级的最后页面的争用冲突。这个表自身被划分为1000个分区,以试着避免在任何一个数据页发生冲突。

  实验结果如下图所示:

因为在这种情况下前面所提及的议题还是有争论的,也没有考虑加锁的尺度,所以选择仅按数据行加锁或数据页加锁是没有什么实质意义的。正如所看到的,一旦完全通过锁存技术避免对索引加锁的话,那么明显可以使性能得到提高和改善。

 

四、死锁

 

1) 发生死锁的原因

以前,由于采用通过服务器访问或变更数据的技术,就存在可能发生死锁的情况。对于常常是更多地由ASE的处理特性所引起的死锁, 而不是由不恰当的事务设计所引起的死锁,就给数据库管理员(DBA)带来了特别的麻烦。通过几种增强方式,ASE 11.9.2往后的版本将这些系统所引起的死锁问题得到了解决。

随着锁存技术的引入,对于其它用户而言,索引页只是在很短的周期内不能被使用,永远不会延续到数据库事务中。所以锁存技术的特性将那些在索引页中发生死锁的情形都排除掉了。这一点对在使用仅仅是数据表时,可以使用并发技术的情况具有巨大的效果。

此外,为了进一步处理针对数据可能发生的死锁,已经认识到可以对释放共享锁的时间点加以改变,这样一来,就能够使对以前发生死锁的数据行的并发访问保持一致。在处理一个连接(join)时,以前的处理方式是将在外部表中加锁的行一直保持到检索到内部行时为止。然而在大多数情况下,一旦检索到数据就不再需要对进行访问的行继续加锁。随着引入固定的行标识(RIDs),这就意味着,外部表的扫描从这一行扫描到下一行,一旦所需要的信息已经被检索到之后,在所连接的外部表中,对行的加锁就可以释放了。这个功能被称之为“带有加锁方式的读提交”("read committed with lock”),并可用如下的命令加以配置:

sp_configure ‘read committed with lock’,0|1

 

2) 客户情形

为了证实上述情形,建立了一个实际的客户环境,以便按照一系列它们所提供的测试进行,用于验证他们所认为的最坏的并发情况下以确保不发生死锁。

在这类“最坏情况”测试中的应用负载如下:

在一台应用服务器上执行项分开的流式任务,它们包括如下任务:

大量的插入

在一个单一逻辑事务中进行5000SQL语句的更新操

SQR报告

用户执行OLTP工作(插入、更新和联机查询)

使用复杂查询的报告。向下钻取的报告:

访问一定数量的表(典型为67

引用至少包含两个子查询的SQL语句;

在光标定义中采用截然不同的光标(cursors,以引起工作表的使用。

 

3) 可能发生的死锁

采用较早版本的服务器产品,进行上述的应用实验,可能发生死锁,其主要原因如下:

 

插入与非聚簇性的索引访问

如果插入一行,服务器就会采用聚簇性的索引以访问存贮该行所在的页面,并在一种排它性的页面加锁方式下执行插入操作。接着服务器就对表的每个非聚簇索引进行访问,在一种排它性的页面级加锁方式下,在其末端(叶级)结构中插入相应的条目。如果第二个用户也通过非聚簇性的索引访问该表,他们可以按照非聚簇索引保持对该叶级页面实施共享加锁,与此同时,这些非聚簇性的索引也由这个排它性的页面加锁所阻碍并用在插入操作中。这种对由第二个用户对非聚簇索引的叶级结构所进行的加锁方式,可能阻碍插入尝试并为第一个用户增加一个条目,从而可能引起死锁。

 

更新的范围

在这个商业应用的设计中,开始首先在一张表中采用零值与一个标识符两部分组成的键值插入所有的新行。在一个单一的逻辑事务中对所有的行使用相同的标识符来进行并发更新。这些更新采用唯一键值去代替零值,就引发了索引行移动到索引的叶级结构的最后。当多个用户并发执行这个任务时,第一个用户就锁定进行处理的页面和索引所在的叶级结构的末端。这将阻碍用户试图对第二个按行范围所进行的工作。当第一个用户到达所确定的页面边缘,即该范围即将终止,下一批所组块并妨碍的页面范围即将开始之时,就可能发生死锁。

 

按照不同顺序访问表

即使访问行是不同的,对表按照任何不一致的顺序进行访问,也会意味着可能发生死锁。这是因为一个用户所访问的行可能在另一个用户访问的同一个以不同顺序排列的页面中。对于应用系统而言,当然这种设计明显是很差的,但是却还令人惊奇地普遍存在。

 

连接与更新

正如在 5.1节所叙述的有关“采用加锁机制的读提交”段的内容,当处理连接,同时对外部表的加锁方式会一直保持到内部行被检索到为止,这种情况就会发生。如果第二个用户在访问所连接的外部表中的行之前,先访问了所连接的内部表的行,这种操作可能受阻,因为加锁的顺序被连接所破坏,从而也会引起死锁。

 

4) 问题的解决方案

采用Adaptive Server Enterprise 11.9.2的产品, 应用对索引页的锁存技术以代替传统的加锁方式,以及更小尺度的按行加锁方式,导致了前三种死锁类型不再发生。采用“按照加锁进行读提交”可以处理第四种死锁情况。

 

作为进一步的测试,在前面所述及的最坏情况实验中,同时还进行了增加额外负载的运行实验。这类实验包括一个拥有7000SQL语句的单一事务,和从Microsoft Excel电子数据表中卸载数据(加入ASE服务器)。这两个版本的测试已经进行了多次,从未发生过死锁。

 

5) 一类新的死锁以及如何解决

就在Adaptive Server Enterprise产品的设计中进行修正以防止死锁和增加并发性的同时,也发生了一种情形,可能发生死锁,而这种情况在过去是不可能发生的。

当一次更新操作必须访问整个表时(例如此时不支持索引),可能会发生一种改变。在它们已经被确认为符合要求之后,将只对个别行加锁(以前是对一张表加锁)。当访问小表的时候,对于因为性能的原因而建立的任何索引,一般而言都不会很多。如果一个用户扫描这些小表之一,并对一行加以限定,这将随之带来一个排他性的行加锁。如果第二个用户也访问同一张表,这种扫描就会因为第一个用户的排他性行加锁所阻碍。如果第一个用户试图更新同一张表中的另一行,这种扫描也会被第二个用户所阻碍,所以引起死锁。

为了解决这一问题,已经采用了一种称之为“并发优化”的优化程序。这个方法指明了如果在一张表中需要进行存取行的页面数小于某个固定的数字(其缺省值为16),那么将不再考虑使用任何一个索引,而宁可对表进行直接扫描。这就意味着对于很小的表,利用索引而不是用全表扫描方式直接访问某些可能会产生直接影响的行,存在引起死锁的可能性。在考虑扫描一张表之前,需要确定在一张表中能有多少页,可采用如下的命令在页级结构中加以配置:

sp_chgattribute , “concurrency_opt_threshold”,

 

为了提高性能,也需要仅仅对表中的少数行添加索引的建立。与以前一般都忽略了索引不同,现在利用索引是为了提供最大的并发性并避免死锁的发生。

五、何时使用不同类型的加锁方法

 

为了在尽量降低资源消耗的前提下实现性能和并发性的平衡, Sybase 已经建立了集中加锁方式,它们分别具有略有不同的特性。在什么时候采用那一种加锁方式,对这一问题。可以利用下列的“大拇指原则”,基于环境和应用程序的基本情况就应该采用的适当的加锁框架,提出原则性的指导意见。

 

1) 全页加锁方式

除非有特别的理由,应尽量使用全页加锁方式,因为它消耗诸如内存和CPU之类的资源最少。

如果发生争用冲突,并不是空间的问题,而且也可以排除正在执行的工作负载是由于在特定点(例如热点(hot spot))进行插入或延迟更新所引起的,在全页加锁方式下采用填充因子(Fillfactor)或max_rows_per_page 将能够在不增加维护问题(重组)的条件下对行级加锁提供类似的性能改善。

如果一张堆(栈)表中发生了大量的插入操作,而且空间不成为问题的话,采用较大数目分区的全页加锁方式将使性能提高到一定的水平。

如果工作负载已经是同CPU紧密相关的,那么附加的仅对数据加锁方式所需要的CPU实用程序,可能也是使用与CPU较少关联的全页加锁方式的一个主要原因。这一点对于已经使用了填充因子来解决争用冲突问题的情况尤其如此。

 

2) 数据行加锁方式

对于那些发生争用冲突而且工作负载基本上是由于延迟更新所引起的情况,应该使用数据行加锁方式,而不要再考虑空间问题。

一张表占据数据库空间的总量是一个问题,如果表较小而且有争用和冲突的话,应该采用按行加锁方式。

在一列需要非聚簇索引而且该列上所有的插入操作都在这个索引的一个确定点上发生时,按行加锁方式提供了既可以不发生索引加锁争用冲突的情况,又具有所需要的索引的能力。

对于那些正在使用堆(栈)表,但空间成为问题的情况,仅对数据加锁方法提供了较高的性能。

对于死锁的发生,利用仅对数据行加锁是一个可选的解决方案,其原因是或者由于较低的加锁争用冲突,或者由于采用了加锁方式下的读提交

 

3) 数据页加锁方式

对于那些需要仅对数据加锁但加锁机制的数目是一个问题时(例如由于内存),那么采用仅对数据页加锁可能就是一种最优的选择。

当由于某个特定的或罕见的原因需要对一张表实现仅对数据加锁时,那么采用数据页加锁比数据行加锁方式占用的资源较少,而且当加锁争用冲突只是限制在索引时,会有相同或更好的性能。


[ 发表评论 ] 字体[  ] [ 打印 ] [ 进入博客 ] [ 进入论坛 ]  [ 推荐给朋友 ]
  相关文章
· ASE数据库日志的管理 (04-13) · 浅谈如何有效建立权限管理体系 (04-06)
· PB动态报表格式自由定义的实现 (04-06) · PB中dynamic调用类型的用法 (04-06)
· 安装Sybase ASE (04-06) · 关于SYBASE ASE FOR LINUX安装 (04-06)
· 常见数据库系统之比较 (04-06) · sybase 临时数据库 (04-06)
· 关于SYBASE的自动启动 (04-06) · Sybase存储过程的建立和使用 (04-06)
  客户需求反馈表