发行版标志 = 0x40000000 锁定计数 = 255 挂起计数 = 0 锁定对象名 = 22 对象类型 = 表 表空间名 = IBMDB2SAMPLEREL 方式 = Z --------------------------------- 省略 ----------------------------------- 6.4.5 其他内部锁 除了上述我们常见的一些内部锁外,DB2 数据库还存在以下几种内部锁: Inplace Reorg Lock 我们会经常对表做 REORG ,REOGR 操作会将陈旧的 RID 进行更新。负责控制并发的扫描器会持有这个锁,直到该扫描器发现没有别的应用请求这个旧的 RID 。然后扫描器就释放这个锁,这时我们就可以对这个行做在线 REORG 了。当我们的表很大的时候,如果你不厌烦阅读数据库的快照监控信息的话,你会发现 REORG 总是在等待 Inplace Reorg Lock 。同时在在线重组期间,数据库还会产生一个内部改变锁定,来对重组的表进行碎片整理。下面我们举一个 Inplace Reorg Lock 的例子,输出结果如下: C:\\>db2 +c reorg table DB2ADMIN.dept1 inplace allow read access DB20000I REORG 命令成功完成。 DB21024I 此命令为异步的,可能未能立即生效。 在另外一个窗口中使用而“ get snapshot for locks ”监控信息输出,结果如下 ( 部分 ): 锁定列表 锁定名称 = 0x0300050002000000000000006A 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 1 锁定对象名 = 2 对象类型=原地重组锁定(inplace reorg lock)表空间名 = IBMDB2SAMPLEREL 表模式 = DB2ADMIN 表名 = DEPT1 方式 = IN 锁定名称 = 0x03000500000000000000000074 -- 注:0300 代表表空间 id ; 0500 表示表 ID 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 1 锁定对象名 = 5 对象类型=内部表改变锁定 表空间名 = IBMDB2SAMPLEREL 表模式 = DB2ADMIN 表名 = DEPT1 方式 = X 锁定名称 = 0x03000500000000000000000054 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 1 锁定对象名 = 5 对象类型 = 表 表空间名 = IBMDB2SAMPLEREL 表模式 = DB2ADMIN 表名 = DEPT1 方式 = S 内部 L 锁 Internal Long/LOBLock(L-lock) 负责对大对象进行处理。 内部联机备份锁 OLB-LOCK 当我们执行数据库在线备份时,会在表空间级别获得 OLB-LOCK 锁。它主要处理在线备份期间我们对数据库的更改。 内部 O-Lock Internal-Object Table 主要负责提交 (COMMIT) 同步。 自动调整大小锁定 在 DB2 V9 中很多数据库配置参数默认都被设置为 AUTOMATIC,当我们执行某个特定操作时,DB2 会执行自动调整大小锁定。例如,当我们执行备份时,DB2 会自动调整 UTIL_HEAP_SZ 内存大小。 自动存储器锁定 在 DB2 V8.2.2 以后,如果我们建数据库时使用自动存储 (AUTOMATIC STORAGE),那么在我们做某些操作时,数据库就会有自动存储锁定。 下面我们举一个例子,这个例子中包含了内部联机备份锁、自动调整大小锁和自动存储器锁三种内部锁。输出结果如下: C:\\>db2 backup db sample online- 注:sample 数据库为自动存储,DB2 版本是 V9.5 在另外一个窗口中使用“ get snapshot for locks ”监控信息输出,结果如下 ( 部分 ): 应用程序句柄 = 1125 应用程序标识 = *LOCAL.DB2_01.081220102511 序号 = 00001 应用程序名 = db2bp.exe CONNECT 授权标识 = DB2ADMIN 应用程序状态 = 正在执行备份 状态更改时间 = 2008-12-20 18:24:55.783743 应用程序代码页 = 1208 挂起的锁定 = 18
总计等待时间 ( 毫秒 ) = 0 锁定列表
锁定名称 =0x0400000000000000000000006F- 注:表空间ID锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 0 锁定对象名 = 4
对象类型 = 内部联机备份锁定 表空间名 = SYSTOOLSPACE 方式 = X
锁定名称 = 0x0700000000000000000000005A 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 0 锁定对象名 = 7
对象类型 = 自动调整大小锁定 方式 = S
锁定名称 = 0x0000000000000000000000007A 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 0 锁定对象名 = 0
对象类型 = 自动存储器锁定 方式 = S
锁定名称 = 0x00000000000000000000000070 锁定属性 = 0x00000000 发行版标志 = 0x40000000 锁定计数 = 1 挂起计数 = 0 锁定对象名 = 0 对象类型 = 表空间
表空间名 = SYSCATSPACE 方式 = IN
上述我们给大家讲解了 DB2 的一些内部锁,其实这些内部锁是 DB2 内部的一种自我保护机制,它类似 Oracle 数据库的 LATCH( 但也不完全一样,因为 Oracle 的 LATCH 只对内存加锁,而 DB2 的内部锁有些对内存加锁,有些对数据库对象加锁 ) 。这些内部锁在通常情况下我们可以不用关注,在这里之所以给大家讲解这么多,主要想要大家了解 DB2 数据库的内部结构。更重要的是,真相知道得越多,越有信心,知其然并且知其所以然。
回页首
6.5 设置锁相关的注册变量
DB2 从版本 8 以后先后引入了三个 DB2 注册变量—— DB2_EVALUNCOMMITTED、DB2_SKIPDELETED 和 DB2_SKIPINSERTED 来提高并发。
为什么要引入这三个变量呢?在 DB2 没有这三个变量前,如果一个用户正在更改 (UPDATE)、插入 (INSERT) 或删除 (DELETE) 一行,那么 DB2 会在这一行加上排它锁 (EXCLUSIVE),别的用户不能读写,除非使用 UR 隔离级别。其实目前市场上除了 Oracle 外,Informix、SQL Server 和 Sybase 等数据库对锁的控制采用的都是这种方式。而 Oracle 数据库有回滚段 (ROLLBACK SEGMENT),在 Oracle 数据库中对于 INSERT 操作,回滚段记录插入记录的 ROWID ;对于 UPDATE 操作,回滚段记录更新字段的旧值 (BEFORE IMAGE) ;对于 DELETE 操作,回滚段记录整行的数据。由于 Oracle 有了回滚段,可以实现多版本读,所以在用 Oracle 进行数据库开发时,很少关注锁的情况,因为大部分情况下应用都是可以读的,只不过有的时候大不了读以前的“ BEFORE IMAGE ”罢了。所以很多使用 Oracle 进行开发的用户在转向 DB2 开发时,都特别郁闷。而 DB2 为了改善应用程序并发性,从 DB2 V8 以后就陆续引入了这三个变量。这三个变量也是 DB2 客户提出要求 IBM 改进的,这种需求最初是由 SAP 提出的。这三个变量并不会改变锁的本质,只不过是了解它们的工作方式和机制可以使我们根据我们的业务逻辑来合理地设置调整以提高应用程序并发。
下面我们先通过一个例子来说明没有这三个变量之前的一些锁的情况。假设 T1 表中有 5 条记录,分别为 11、22、33、44、55 。其中第 2 条记录 22 被删除了,现在有一个 Session 1 要重新插入一条新的记录 22 ;同时第二个 Session 2 执行了“ db2 select * from t1 where id >11 and id<44 ”,正常的话它应该检索到 33 这条记录,但是由于现在插入的记录 22 也包含在这个谓词限定范围内,所以这个时候 Session 2 处于 LOCKWAIT 状态,输出结果如下:
Session 1 Session 2
db2 CONNECT TO SAMPLE db2 +c INSERT INTO t1 VALUES(22)
db2 CONNECT TO SAMPLE db2 SELECT * FROM t1 WHERE id >11 and id <44
我们通过监控看到的输出结果如图 6-6 所示。
图 6-6 逻辑输出结果
从 DB2 的角度来说好像这是合理的,但是从用户角度和业务逻辑来说希望这个时候能够读取到数据,那么怎么解决这个矛盾呢?下面我们来仔细讲解这三个变量。
6.5.1 DB2_EVALUNCOMMITTED
DB2 V8.1.4 版本中首次引入了 DB2_EVALUNCOMMITTED 这个 DB2 注册表变量。当它被启用 (=TRUE | ON | YES | 1) 时,它将修改 DB2 中只读查询的行为,以减少锁冲突,使之允许在索引扫描 ( 必须是 type-2 索引,对于 type-1 索引该特性不受支持 ) 或表访问时推迟锁,直到限定语句的所有谓词都是已知的。引入这个新的注册表变量是为了可选地提高一些应用程序的并发性,其实质是允许读扫描推迟或避免行锁,只能获得那些符合某个谓词的行上的锁,而并不是获得被检查的所有行上的锁。直到适合特定查询的一个数据记录成为已知。 注意: 在 DB2 V8.1 和更高版本中,所有新索引都创建为 type-2 索引。一个例外是当您在已具有 type-1 索引的表上添加索引时,仅在这种情况下,新索引也将是 type-1 索引。要了解一个表存在什么类型的索引,执行 INSPECT CHECK 命令。要将 type-1 索引转换为 type-2 索引,执行 REORG INDEXES CONVERT 命令。 在 DB2 V8.1.4 之前 ( 并且没有设置这个注册表变量 ),DB2 将执行保守式的锁:在验证行是否满足查询的排除谓词之前,它将锁定每个被访问的行。不管数据行是否被提交,以及根据语句的谓词它是否被排除,对于索引扫描和表访问都执行这样的锁定操作。下面我们举一个简单的例子,输出结果如下: db2 create table t1(id int) db2 insert into t1 values(11) db2 commit 现在有两个 Session 分别发出了下面的 SQL 语句,输出结果如下: Session 1 Session 2 db2 CONNECT TO SAMPLE db2 +c INSERT INTO t1 VALUES(22) db2 CONNECT TO SAMPLE db2 SELECT * FROM t1
我们查看 Session 2 的状态,输出结果如图 6-7 所示。
图 6-7 查看 Session 的状态
第一条语句“ db2 +cinsert into table t1 values(22) ”阻塞所有其他 Session 的扫描,因为它持有行上的锁。如果第二个 Session 执行“ db2 select * form t1 ”那么它将被阻塞,直到事务 1 提交或回滚。但是我们假
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说教育文库DB2隔离级别和锁 - 图文(8)在线全文阅读。
相关推荐: