`
evoleht
  • 浏览: 98485 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于DB2 数据库并发性(2)

    博客分类:
  • DB2
阅读更多

DB2 V8以后陆续引入了三个注册表变量:DB2_EVALUNCOMMITTED、DB2_SKIPDELETED、DB2_SKIPINSERTED,为什么要引入这三个变量呢?在DB2没有这三个变量前,如果一个用户正在更改一行数据,那么DB2会在这一行加上排他锁,别的用户不能访问,除非使用UR隔离级别。

DB2为了改善应用程序并发性,从DB2 V8以后就陆续引入了这三个变量。这三个变量并不会改变锁的本质,只不过通过了解它们的工作方式和机制可以使我们根据我们的业务逻辑来合理的设置调整以提高应用程序并发性。这三个变量改变加锁的时机 , 减少锁冲突 ( 这样其行上的 insert/update/delete 操作不会锁住未命中的 select 操作 )

  db2set DB2_EVALUNCOMMITTED=ON

   db2set DB2_SKIPDELETED=ON    db2set DB2_SKIPINSERTED=ON

 

注解:

  1. db2set DB2_EVALUNCOMMITTED=ON - 这个参数将在记录锁之前进行谓词检查,尽量减少锁的时间
  2. db2set DB2_SKIPINSERTED=ON - 这个参数将新 insert 且没有提交的数据跳过;例如,SELECT/UPDATE 语句不会发现这条记录
  3. db2set DB2_SKIPDELETED=ON - 这个参数将新 delete 且没有提交的数据跳过;例如,SELECT/UPDATE 语句不等待这条记录的提交,并且认为他已经被删除了

下面我们通过实验来演示这三个变量是如何影响SQL语句的行为的:


表 4. 实验使用的数据模型

表名 表结构 数据
TEST 表结构 包含如下 10 行数据:
'1', '1'、'2', '2'、'3', '3'、'4', '4'、'5','5'、'6','6'、'7','7'、'8', '8'、'9','9'、'10','10'

 

在 session1 中插入一条记录 ('11','11') 到 TEST 表中,见图 30:


图 30. 执行 INSERT 事务的 session1 窗口
图 30. 执行 INSERT 事务的 session1 窗口

在 session2 中根据条件 a= ’ 1 ’ or a= ’ 11 ’查询 TEST 表,session2 被锁住,为什么呢?这是因为 session1 中 INSERT 事务还没有 COMMIT,所以这个时候 session 2 处于锁定等待 状态,见图 31、图 32:


图 31. 执行查询事务的 session2 窗口
图 31. 执行查询事务的 session2 窗口

图 32. 快照监控窗口
图 32. 快照监控窗口

正常情况下上述事务的加锁机制就是这样的,但是有时候用户希望这个时候能够查询到数据,那么怎么解决这个矛盾呢?下面我们来仔细讲解这三个变量。

设置 DB2_EVALUNCOMMITTED

DB2 V8.1.4 版本中首次引入了 DB2_EVALUNCOMMITTED 这个 DB2 注册表变量。当它被启用(=TRUE | ON | YES | 1)时,它将修改 DB2 中只读查询的行为,使之允许在索引扫描(必须是 Type 2 索引)或表访问时推迟锁,直到限定语句的所有谓词都是已知的。引入这个新的注册表变量是为了可选地提高一些应用程序的并发性,其实质是允许读扫描推迟或避免行锁,直到适合特定查询的一个数据记录成为已知。

在 DB2 V8.1.4 之前(并且没有设置这个注册表变量),DB2 将执行保守式的锁:在验证行是否满足查询的排除谓词之前,它将锁定每个被访问的行,不管数据行是否被提交落实,以及根据语句的谓词它是否被排除,对于索引扫描和表访问都执行这样的锁定操作。

下面我们举一个简单的例子来演示:


表 5. 实验使用的数据模型

表名 表结构 数据 备注
TEST 表结构 包含如下 10 行数据:
'1', '1'、'2', '2'、'3', '3'、'4', '4'、'5','5'、'6','6'、'7','7'、'8', '8'、'9','9'、'10','10'
暂时未建索引

 

现在有两个session发出了下面的SQL语句,见图33、图34:


图 33. 执行 INSERT 事务的 session1 窗口
图 33. 执行 INSERT 事务的 session1 窗口

图 34. 执行查询事务的 session2 窗口
图 34. 执行查询事务的 session2 窗口

我们查看session 2的状态,可以看见session2处于锁定等待 状态,见图 35:


图 35. 快照监控窗口
图 35. 快照监控窗口

session1 执行 DB2 INSERT INTO TABLE TEST VALUES ('11', '11') 将阻塞所有其他的扫描器扫描它,因为它持有行上的 X 锁,所以 session2 执行 DB2 SELECT * FROM TEST 将被阻塞,直到 session1 提交或回滚。但是我们假设 session2 执行的语句是 DB2 SELECT * FROM TEST WHERE id='10' ,在此情况下,即使 session2 中事务 与 session1 中事务未提交的任何值没有关系,它也仍将被阻塞,处于锁定等待 状态。在 DB2 中,默认情况下将发生这一系列的事件,因为默认的隔离级别是 CS,这种隔离级别表明,一个查询访问的任何一行在游标定位到该行时都必须被锁定。在 session1 释放它用于更新(INSERT)表 TEST 的锁之前,session2 不能包含表 TEST 第一行上的锁。如果 DB2 事先能够知道值 A='11' 不是 session2 的数据请求的一部分(换句话说,它在锁行之前计算了谓词),就可以避免阻塞,这是合情合理的,现在 DB2 数据库已经支持这种行为,通过启用 DB2_EVALUNCOMMITTED 注册变量实现,该实例变量设置后需要重启实例,见图 36:


图 36. 设置实例注册表变量 DB2_EVALUNCOMMITTED
图 36. 设置实例注册表变量 DB2_EVALUNCOMMITTED

DB2_EVALUNCOMMITTED 变量影响 DB2 在游标稳定性(CS)和读稳定性(RS)隔离级别下的行锁机制。当你启用该功能时,DB2 可以对于未提交的更新数据(INSERT/UPDATE)事先进行谓词判断,如果未提交数据不符合该条语句的谓词判断条件,DB2 将不对未提交数据加锁,这样就避免了因为要对未提交数据加锁而引起的锁等待状态,提高了应用程序访问的并发性,同时 DB2 在进行表扫描时,会无条件地忽略被删除的行数据(不管是否满足谓词判断条件,不管是否提交)。这样一定程度上缓解了锁的问题,不会因为 INSERT/UPDATE/DELETE 一条记录而可能造成整个表被锁住。

下面我们通过一个实验来演示:

实验使用的数据模型见表 5:

现在有 6 个 session 窗口按照下面的命令序列做实验:

session1 窗口:db2 delete from test where a='1' session2 窗口:db2 select * from test session1 窗口:db2 rollback session2 窗口:db2 rollback session3 窗口:db2 insert into test values('11', '11') session4 窗口:db2 select * from test where a='10' session3 窗口:db2 rollback session4 窗口:db2 rollback session5 窗口:db2 update test set a='100' where a='1' session6 窗口:db2 select * from test where a='10' session5 窗口:db2 rollback session6 窗口:db2 rollback

 

在未设置DB2_EVALUNCOMMITTED=ON时,session2/session4/session6肯定都将处于锁等待 状态的,现在我们设置了DB2_EVALUNCOMMITTED=ON后,我们来看看session2/session4/session6能否检索到数据,通过这个实验我们发现当启用 DB2_EVALUNCOMMITTED=ON 时,对于delete/insert/update操作的处理,DB2 在进行表扫描时会无条件地忽略被删除的记录(不管是否满足谓词判断条件,不管是否提交),见图 37、图 38,而对于未提交的更新数据(INSERT/UPDATE)会事先进行谓词判断,如果未提交的记录不符合该条语句的谓词判断条件,DB2 将不对未提交记录加锁,这样就避免了因为要对未提交记录加锁而引起的查询事务锁等待状态,见图 39、图 40、图 41、图 42:


图 37. 执行 DELETE 事务的 session1 窗口
图 37. 执行 DELETE 事务的 session1 窗口

图 38. 执行查询事务的 session2 窗口
图 38. 执行查询事务的 session2 窗口

在 session1/session2 窗口使用 db2 rollback 命令将实验场景恢复原状。


图 39. 执行 INSERT 事务的 session3 窗口
图 39. 执行 INSERT 事务的 session3 窗口

图 40. 执行查询事务的 session4 窗口
图 40. 执行查询事务的 session4 窗口

在 session3/session4 窗口使用 db2 rollback 命令将实验场景恢复原状。


图 41. 执行 UPDATE 事务的 session5 窗口
图 41. 执行 UPDATE 事务的 session5 窗口

图 42. 执行查询事务的 session6 窗口
图 42. 执行查询事务的 session6 窗口

在 session5/session6 窗口使用 db2 rollback 命令将实验场景恢复原状。

现在在TEST表上创建一个type-2的索引(在字段A上创建索引),然后再来做刚才的那个实验:

我们发现session2处于锁等待状态(见图 44),为什么呢?

当您的DB2环境中启用了evaluate uncommitted行为时,您应该清楚,谓词计算可能发生在未提交的数据上。我们知道在表扫描访问中,被删除行被无条件忽略,而对于使用type-2索引进行扫描,被删除的键不会被忽略(除非您还设置了DB2_SKIPDELETED注册表变量,DB2_SKIPDELETED变量我们稍后介绍),实验见图43、图44、图45;如果您要在环境中单独设置DB2_SKIPDELETED注册表变量,DB2将也允许在表扫描访问时无条件地忽略被删除行,并忽略通过type-2索引扫描访问的伪删除索引键。


图 43. 执行 DELETE 事务的 session1 窗口
图 43. 执行 DELETE 事务的 session1 窗口

图 44. 执行查询事务的 session2 窗口
图 44. 执行查询事务的 session2 窗口

图 45. 快照监控窗口
图 45. 快照监控窗口

设置 DB2_SKIPDELETED

DB2_SKIPDELETED=ON 该变量被启用时,将允许使用 CS 或 RS 隔离级别的语句在索引扫描期间无条件地跳过被删除的键,而在表访问期间则无条件地跳过被删除的行。当 DB2_EVALUNCOMMITTED 被启用时,被删除的行会被自动跳过,但是除非同时启用了 DB2_SKIPDELETED,否则 type-2 索引中未提交的伪删除键不会被跳过。

在上面的实验中,我们发现当我们仅仅设置了 DB2_EVALUNCOMMITTED 变量时,如果表上有 type-2 索引,那么在我们通过索引读取数据时,被删除的索引键不会被忽略。这种情况下如果你希望跳过被删除的键,可以通过设置 DB2_SKIPDELETED=ON 来实现。

下面我们做个实验来演示一下:

首先打开实例注册表变量 DB2_SKIPDELETED,见图 46:


图 46. 设置实例注册表变量 DB2_SKIPDELETED=ON
图 46. 设置实例注册表变量 DB2_SKIPDELETED=ON

重新做刚才的实验,我们可以看到在设置DB2_SKIPDELETED=ON后,即使test表上有type-2的索引,那么在扫描type-2索引的时候仍然忽略这个被删除的行。见图47、图48:


图 47. 执行 DELETE 事务的 session1 窗口
图 47. 执行 DELETE 事务的 session1 窗口

图 48. 执行查询事务的 session2 窗口
图 48. 执行查询事务的 session2 窗口

设置 DB2_SKIPINSERTED

虽然当 SELECT 语句由于一个未提交的 INSERT 操作而被锁住的这种行为是正确的 —— 但是有些特殊情况下希望 DB2 忽略正在等待提交的被插入的行,就好像它没有发生一样,这可以通过设置 DB2_SKIPINSERTED 注册表变量来达到这种目的。 DB2_SKIPINSERTED=OFF 是默认设置,这使得 DB2 的行为和预期的一样:SELECT 事务一直等到 INSERT 事务提交或回滚,然后返回数据;如果设置 DB2_SKIPINSERTED=ON,那么 SELECT 事务将忽略尚未提交的 INSERT 事务(只对于 CS 和 RS 隔离级别),不论表上是否存在索引。该特性增加了并发性,同时又不牺牲隔离语义。

下面我们来看设置DB2_SKIPINSERTED变量前后的例子:


表 6. 实验使用的数据模型

表名 表结构 数据 备注
TEST 查询结果 包含如下 10 行数据:
'1', '1'、'2', '2'、'3', '3'、'4', '4'、'5','5'、'6','6'、'7','7'、'8', '8'、'9','9'、'10','10'
未建索引

 

虽然之前已经打开了 DB2_EVALUNCOMMITTED 注册表变量,但是在打开 DB2_SKIPINSERTED 注册表变量前,下面的 session2 查询事务将处于 锁定等待 状态,为什么呢?因为 session1 中的 INSERT 事务插入了 1 条记录 '11', '11',而 session2 查询事务事先根据谓词条件判断 session1 中插入的记录在条件范围之内,所以 session2 被锁住;然而 session3 查询事务却可以正常执行(也是通过全表扫描,因为未建索引),因为 session3 查询事务事先根据谓词条件判断 session1 中插入的记录不在条件范围之内(因为已经打开了DB2_EVALUNCOMMITTED变量,所以可以提前判断未提交的INSERT/UPDATE事务所涉及到的记录是否在谓词条件范围之内,如果不在条件范围之内的话,DB2将不对未提交的记录加锁,这样就避免了因为要对未提交记录加锁而引起的查询事务锁等待状态),所以 session3 查询事务可以正常执行,见图 49、图 50、图 51、图 52:


图 49. 执行 INSERT 事务的 session1 窗口
图 49. 执行 INSERT 事务的 session1 窗口

图 50. 执行查询事务的 session2 窗口
图 50. 执行查询事务的 session2 窗口

图 51. 快照监控窗口
图 51. 快照监控窗口

图 52. 执行查询事务的 session3 窗口
图 52. 执行查询事务的 session3 窗口

如果这种情况下 session2 希望能够跳过未提交 的 insert 操作而得到数据,那么可以打开 DB2_SKIPINSERTED 注册表变量,见图 53:


图 53. 设置实例注册表变量 DB2_SKIPINSERTED=ON
图 53. 设置实例注册表变量 DB2_SKIPINSERTED=ON

然后再重复刚才的实验,我们发现这个时候,session2 已经可以查询到数据了,见图 54、图 55

图 54. 执行 INSERT 事务的 session1 窗口
图 54. 执行 INSERT 事务的 session1 窗口

图 55. 执行查询事务的 session2 窗口
图 55. 执行查询事务的 session2 窗口

可见session1中插入的记录被忽略掉了。

总结

总的来说这 3 个注册表变量会影响到并发性。通过合理设置这些变量可以改善并发性,但是也会影响到应用程序的行为,所以建议综合考虑业务的需求和结合自己的业务逻辑,来考量是否适合启用相应的注册表变量。

分享到:
评论

相关推荐

    DB2数据库性能调整和优化 牛新庄 PDF

    DB2数据库性能调整和优化(第2版)侧重于介绍DB2数据库的性能调优。性能调优是一个系统工程:全面监控分析操作系统、I/O性能、内存、应用及数据库才能快速找到问题根源;深刻理解DB2的锁及并发机制、索引原理、数据库...

    DB2的并发性 DB2的并发性

    ### DB2并发性的深入解析 #### 一、并发性概述 在多用户环境中,数据库管理系统(DBMS)必须处理多个用户同时访问和修改同一数据库的情况。这种情况被称为“并发性”。DB2作为一款强大的企业级数据库管理系统,提供...

    一个关于DB2数据库学习文档集

    DB2数据库是一款由IBM开发的关系型数据库管理系统,广泛应用于企业级的数据存储和管理。这个文档集是针对DB2的学习资源,包含了多个方面的内容,对于深入理解和掌握DB2有着极高的价值。 首先,DB2函数文档详细列出...

    DB2数据库基础学习

    ### DB2数据库基础学习 #### 一、DB2数据库概览 DB2是IBM公司开发的一款关系型数据库管理系统,自1983年发布以来,不断进化,支持多种平台,包括Windows、Linux、Unix和z/OS等。DB2不仅提供高性能的数据存储和检索...

    db2数据库面试问题

    根据给定文件中的标题、描述、标签以及部分内容,我们可以从中提炼出与DB2数据库相关的多个重要知识点。以下是对这些知识点的详细阐述: ### DB2数据库面试问题概览 #### 1. E-R图中的关系类型及其特点 E-R图...

    db2数据库性能优化小技巧

    锁机制是数据库并发控制的重要手段之一,不合理的锁设置可能会导致性能瓶颈。 #### 3.1 锁列表配置 - **Lock List Memory**:锁列表内存,用于存储锁定信息。如果锁列表内存不足,可能会导致锁等待时间延长,影响...

    DB2数据库程序开发试验

    DB2数据库程序开发试验是一个深度探索数据库管理系统的实践性学习项目,主要针对吉林大学软件学院的学生。这个试验涉及使用IBM的DB2_ESC_97_x64版本,这是一个64位的企业级数据库管理系统,适合大规模数据存储和处理...

    db2数据库驱动9.7jar包(全) db2jcc.jar+db2jcc_license_cu.jar

    DB2数据库支持多种特性,如事务处理、并发控制、备份恢复、安全性、性能调优等。9.7版本的改进可能包括更快的查询速度、更高的并发能力、更好的内存管理以及对Java EE 5和6的支持。在开发和部署Java应用程序时,理解...

    IBM内部关于DB2数据库的中文翻译版资料

    从给定的文件信息来看,这是一份关于IBM DB2数据库管理与开发的GUI界面操作指南,名为“db2atc80管理和开发GUI.pdf”。这份文档提供了详细的指导,涵盖了DB2数据库的各种功能和操作流程,是IBM为DB2用户提供的专业...

    DB2数据库管理最佳实践pdf

    这份PDF文档很可能是对DB2数据库在实际操作中的优化策略、配置技巧和故障排查方法的深入探讨,旨在帮助管理员提升DB2的性能、稳定性和安全性。 在DB2数据库管理中,有几个关键的知识点是所有管理员都需要掌握的: ...

    DB2数据库性能调整和优化

    DB2数据库是IBM公司开发的一款关系型数据库管理系统,广泛应用于企业级数据存储和管理。数据库性能调整和优化是确保系统高效运行的关键环节,涉及到多个层面的技术和策略。本篇文章将深入探讨DB2数据库性能调整与...

    db2数据库错误解决代码sqlcode

    DB2数据库是IBM开发的一款企业级关系型数据库管理系统,广泛应用于大型企业和机构。在使用过程中,用户可能会遇到各种错误,其中“SQLCODE”是DB2返回的一种错误代码,用于指示查询或操作失败的具体原因。本篇文章将...

    牛新庄-db2数据库性能调整优化

    合理设置事务隔离级别可以平衡并发性和数据一致性,避免死锁的发生。同时,优化事务处理逻辑,减少不必要的回滚和重试,可以显著提升系统吞吐量。 数据库的物理存储布局同样影响性能。通过合理分配表空间、分区和段...

    用JMeter测量性能测试您的DB2数据库

    标题和描述均聚焦于“用JMeter测量性能测试您的DB2数据库”,这表明文章的核心议题是探讨如何利用Apache JMeter这一开源工具,对IBM DB2数据库进行性能测试,以评估和优化其处理能力和响应时间。以下是对这一主题的...

    db2数据库驱动jar包

    它支持SQL语言,提供事务处理、并发控制、数据恢复等核心功能,并具有高度的安全性和稳定性。 该驱动jar包的使用主要包括以下几个步骤: 1. **添加依赖**:将下载的db2数据库驱动jar包添加到项目的类路径中,对于...

    DB2 for zOS DB2 数据库设计取得最佳性能的准则

    在IBM的大型主机系统z/OS上,DB2数据库的性能优化是关键任务,因为早期的设计决策会显著影响应用程序和数据库的性能。本文主要针对DB2 for z/OS环境,提供一些数据库设计的通用准则和建议,以提升整体性能。 首先,...

    【原创】Loadrunner监控DB2数据库

    监控 DB2 数据库是性能测试中的重要环节,它可以帮助我们了解系统在高负载下的表现,找出瓶颈,优化数据库配置,以提升整体系统的稳定性和效率。正确配置 LoadRunner 以监控 DB2,可以提供有价值的数据,支持我们...

    企业级DB2数据库学习与认证

    "企业级DB2数据库学习与认证"的主题意味着我们将深入探讨DB2的基础知识、高级特性和如何准备IBM的DB2资格认证。 首先,我们要理解DB2的基本概念,包括数据模型、SQL语言以及数据库管理系统的核心功能。DB2遵循标准...

    DB2数据库基础与应用开发

    - **第6部分:数据并发性** - 讲解数据一致性的重要性及其在单用户和多用户环境中的维护机制。 - 探讨事务处理和锁机制等主题。 - **第7部分:XQuery简介** - 介绍XQuery的基础概念。 - 学习如何编写简单的...

Global site tag (gtag.js) - Google Analytics