IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope: Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Information Management  >

Informix 管理:Informix 性能锁和并发性

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

英文原文

英文原文


级别: 初级

Lester Knutsen, 董事长, Advanced DataTools Corp.

2009 年 6 月 15 日

改善并发性和锁,让更多用户能够更快地访问数据。
来自 IBM Database Magazine 中文版。

一个很重要但经常被忽视的性能调优步骤是:检查 Informix Dynamic Server (IDS) 如何处理锁和并发性。在由我讲授的高级 Informix 性能调优课程中,调优锁是五个改善性能的重要步骤之一。

锁的数量

当 Informix 启动时,它将读取 ONCONFIG 文件并使用 LOCK 参数创建一个内存结构(我们称之为锁表)来管理锁。在 IDS 11 之前的版本的默认设置中,包含 2,000 个锁,锁的数量非常少。在 IDS 11 中,默认的锁数量为 20,000 个 —— 锁的数量增加了,但对高容量系统而言还是欠缺。

每个打开数据库、表或读取、更新行的用户会话都会在锁表中生成锁。打开数据库会在数据库中生成一个共享锁,以避免其他人删除数据库。打开表将在表中生成一个共享锁,以避免在使用表时更改它。除了 “脏读” 之外,将在每个被读取的行上放置一个共享锁。并且当更新、删除或插入一个行时,将在该行所使用的索引上添加额外的锁。

现在给出一个例子:更新带有 3 个索引的 1,000 个行将生成 1,000 个行锁,3,000 个索引锁,以及 4,002 个数据库和表锁。锁的数量很快就会超过内存中默认的锁表结构。 Informix 能够根据需要动态地增加锁表的容量。然而,为锁表提供的额外空间位于共享内存的另一个位置,这就导致分裂的锁表。如果锁表多次溢出,就会大大降低搜索速度。

为了诊断锁表是否溢出,需要查看 onstat -k 命令的输出。在输出的末尾可以看到锁表的溢出次数。图 1 显示了一个溢出了两次的锁表。最后一行显示当前有 42,239 活动锁,锁的总数为 80,000 。在这个例子中,我将在 ONCONFIG 文件中把 LOCK 参数改为 80,000,这样就不会发生锁表溢出。在我教授的高级性能调优课程中,在执行基准测试时,我们发现在使用默认值的情况下,有时溢出的次数多达 30~40 次。这就解释了为什么修改这个设置能够列入性能调优设置的前五位。

注意:onstat -k 选项将显示所有活动锁,所以显示内容可能很长。如果在 ONCONFIG 文件中定义了大量锁,并有很多用户,那么这个命令会输出数千行内容。





回页首


锁归属

如何找出哪个用户对某个对象使用了锁?图 1 中的 “所有者” 栏列出了拥有锁的用户在共享内存中的地址。使用 onstat -u 查看所有用户,并通过与 “地址” 栏进行对比识别所有者的用户名。


图 1. onstat -k 命令显示内存中的锁表
图 1. onstat -k 命令显示内存中的锁表




回页首


锁定的表

如何找出哪个对象被锁定了?“ tblsnum ” 栏给出了锁定的表。将这个表与下面的 SQL 语句的输出进行比较,将表的 partnum 转换为十六进制,以找出哪个表被锁定了。

select tabname, hex(partnum) tblsnum from systables where tabid > 99;

这个 SQL 语句将返回一个表列表及相关的 tblsnum 。图 2 显示的例子告诉您如何识别哪个表被锁定了。


图 2. 识别哪个表被锁定了
图 2. 识别哪个表被锁定了

tblsnum 100002 有特殊的含义 —— 它表明这是一个数据库锁。每个用户在打开数据库时都将在数据库上创建一个共享锁。图 1 显示了 3 个共享锁。





回页首


锁级别

Informix 在数据库、表、页、行、字节和索引键这些级别上锁定对象。通过 onstat -k 命令查看表空间、行 ID 和键 / 字节列可以识别锁的级别。表 1 列出了锁级别,以及如何识别它们。


表 1. 锁级别说明
表 1. 锁级别说明




回页首


锁类型

onstat -k 命令输出的列 “类型”(在以前的发布版中称为 “标志”)描述了有效的锁类型。表 2 列出了锁类型。


表 2. onstat -k 输出中显示的锁类型的说明

并发性:允许更多用户共享数据

并发性主要关于如何让更多用户访问和处理相同的数据,而不通过锁彼此排斥。通过锁排斥所有用户的简单做法就是在排他模式下锁定整个数据库。但这种方法不适合在高容量、多用户的环境中使用。

Informix 提供以下五个级别的并发性,它们是通过 set isolation SQL 命令设置的:

Dirty Read 。这个并发性级别不锁定任何行,并且读取其他用户锁定或正在更改的行。它能够返回可能回滚的未提交数据。对于数据仓库环境或获取数据比读取已提交记录更重要的环境,这个并发性级别非常有用。

Committed Read 。这个级别不锁定任何行,但如果有人执行更新或在行上使用排他锁,它将失败。它仅读取已提交的行。行在读取之后可能还会变更,但它不能有可以被读取的锁。这个级别是使用日志的数据库的默认设置,并且大部分 OLTP 都采用该级别。不过,当一个用户请求被另一个用户锁定的行时,您必须提供错误处理。

Cursor Stability 。这个级别在选择的行上放置一个共享锁,因此当有用户正在读取某行时,其他用户就不能更新它。当获取到另一个行或关闭指针时,这个锁将被释放。

Repeatable Read 。这个级别创建最大数量的锁,因为它为每个读取的行或用户扫描的行放置一个共享锁,以使这些行不能再被更改,重复读取将返回同样的记录和值。在事务提交或回滚之后,就释放这些锁。这个级别是 ANSI 模式的数据库的默认设置。

Last Committed Read 。这个级别是 IDS 11 中的新特性,其工作方式与 Committed Read 非常相似;不过,当锁定以更新某个行时,IDS 将从日志中读取最近提交的记录。只有使用行级锁创建表时这个级别才有效,但它能够大大减少锁错误,并返回最近的有效数据。





回页首


性能效果

现在给出一个例子,展示并发性和隔离级别如何影响锁和性能。在图 3 中,用户使用一个更新语句锁定记录。图 4 显示了 3 个 SQL 语句试图读取那个被锁定的行时得到的结果。第一个语句使用 Committed Read,但失败了;第二个语句在更改数据时获取它。不过,在释放锁之前,该数据将再次回滚或变更。最后一个语句在该行最后一次提交时读取它,它不会放置任何锁,并且获取到有效数据。


图 3. 锁定列
图 3. 锁定列

图 4. 并发性和锁的影响
图 4. 并发性和锁的影响




回页首


以更快的速度读取更多数据

看一下您的系统使用了多少个锁,并了解新的隔离级别 Last Committed Read 。通过锁调优能够提高用户访问数据的速度;通过选择正确的隔离设置可以让更多用户访问数据。



参考资料

学习

获得产品和技术

讨论
  • 通过访问 alphaWorks,获得更多 IBM 的前瞻性技术和资源。

  • 通过访问 IBM Database Magazine 站点 community 专题,获得更多用户体验和交流信息。


关于作者

Lester Knutsen 是 Advanced DataTools Corp. 的董事长,并且是 IBM Informix 顾问和培训合作伙伴,他擅长数据仓库开发、数据库设计、性能调优和 Informix 培训和支持。他还是 Washington D.C. Area Informix User Group 的董事长,International Informix Users Group 的创始成员和 IBM 金牌顾问等等。




对本文的评价








IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款