Informix Dynamic Server 1150 基础考试 555 认证准备第 6 部分 数据并发性.docx
- 文档编号:10008463
- 上传时间:2023-02-07
- 格式:DOCX
- 页数:28
- 大小:28.45KB
Informix Dynamic Server 1150 基础考试 555 认证准备第 6 部分 数据并发性.docx
《Informix Dynamic Server 1150 基础考试 555 认证准备第 6 部分 数据并发性.docx》由会员分享,可在线阅读,更多相关《Informix Dynamic Server 1150 基础考试 555 认证准备第 6 部分 数据并发性.docx(28页珍藏版)》请在冰豆网上搜索。
InformixDynamicServer1150基础考试555认证准备第6部分数据并发性
InformixDynamicServer11.50基础考试555认证准备,第6部分:
数据并发性
开始之前
关于本系列
这个共包含9个部分的免费系列将帮助您准备IBMInformixDynamicServer11.50基础认证考试555。
这个认证将考察关于IDS11.50管理的入门级知识,包括基础SQL、如何安装IDS11.50、如何创建数据库和数据库对象、安全性、事务隔离、备份和恢复流程,以及数据复制技术。
这些教程为考试的每部分打下了坚实的基础。
不过,您不能仅使用这些教程作为唯一的考试准备材料。
回页首
关于本教程
本教程描述IBMInformixDynamicServer11.50中的锁机制。
它讨论了隔离级别及其作用,并且介绍隔离级别和锁的监控。
回页首
目标
阅读本教程之后,您应该能够:
∙理解IDS中的锁机制
∙识别隔离级别及其作用
回页首
先决条件
本教程面向具备SQL基础知识的用户。
回页首
系统需求
要理解和测试本教程中的概念,您需要一个可用的IDS11.50实例。
理解锁
什么是锁?
锁是一种软件机制,用于控制对数据库中的数据的访问。
在出现同时读取和更新数据的多用户环境中,锁能够确保每个事务的原子性、隔离、一致性和持续性(ACID)不受到威胁,并且维护数据的完整性。
锁的粒度
Informix提供各种粒度的锁。
它们是:
∙数据库锁:
针对整个数据库的锁
∙表锁:
针对整个表的锁
∙页锁:
针对整页数据的锁
∙行锁:
针对一个数据行的锁
∙字节锁:
在包含VARCHAR的行上的锁
∙键锁:
在索引中的一个键值上的锁
锁的粒度越粗,它就能锁住越多的数据库对象。
例如,对于能够在一个磁盘页上包含4行的表,在该页放置一个锁将锁住其中包含的所有4个行。
相反,如果使用行锁,那么将仅锁住一个行。
因此,锁的粒度越粗,并发性就越低,从而影响到性能,尤其是应用程序试图访问相同的行集时。
不过,粗粒度也意味着在某些情况下锁住相同数量的行需要的锁数量更少。
例如,锁住整个表仅需要一个表锁。
回页首
表的锁模式
创建一个表时,它的默认锁粒度是页锁。
可以在创建表的过程中使用LOCKMODE子句覆盖默认值。
例如:
CREATETABLEt1(c1int)LOCKMODEROW;
这个上下文中的锁模式表明访问表时需要使用的锁的粒度。
如果从CREATESQL语句省略掉这个LOCKMODE子句,那么就使用默认的锁模式。
如果表已经创建,那么可以使用ALTERTABLE语句更改锁模式。
对于以上提到的表t1例子,您可以使用下面的ALTER语句将锁模式从行锁更改页锁:
dbaccessdb1-
ALTERTABLEt1LOCKMODE(PAGE);
可以使用配置参数DEF_TABLE_LOCKMODE更改已创建的表的默认锁模式。
该参数的值可以是ROW或PAGE。
例如,如果DEF_TABLE_LOCKMODE设置为ROW,那么数据库服务器重启之后创建的表的默认锁模式将为ROW。
类似地,可以使用环境变量IFX_DEF_TABLE_LOCKMODE实现相同的效果。
注意:
如果从运行oninit以启动服务器的窗口设置环境变量,那么通过环境变量指定的默认锁模式将对所有会话有效。
然而,如果仅在特定客户端会话环境中设置锁模式,那么它仅对特定会话有效。
清单1-4显示了检查表的锁模式的不同方法(表名为t1;数据库名为db1):
清单1.使用dbschema
dbschema-ddb1-tt1-ss
清单2.输出
createtable"informix".t1
(
c1integer
)extentsize16nextsize16lockmoderow;
清单3.使用oncheck
oncheck-ptdb1:
t1
Output:
TBLspaceReportfordb1:
informix.t1
PhysicalAddress1:
64070
Creationdate07/14/200904:
51:
27
TBLspaceFlags802RowLocking
TBLspaceuse4bitbit-maps
Maximumrowsize4
Numberofspecialcolumns0
Numberofkeys0
Numberofextents1
Currentserialvalue1
CurrentSERIAL8value1
CurrentBIGSERIALvalue1
CurrentREFIDvalue1
Pagesize(k)2
Firstextentsize8
Nextextentsize8
Numberofpagesallocated8
Numberofpagesused1
Numberofdatapages0
Numberofrows0
Partitionpartnum1049067
Partitionlockid1049067
Extents
LogicalPagePhysicalPageSizePhysicalPages
01:
6499988
清单4.使用dbaccess从数据库的系统目录表查询系统表
dbaccessdb1-
>select*fromsystableswheretabname='t1';
tabnamet1
ownerinformix
partnum1049067
tabid100
rowsize4
ncols1
nindexes0
nrows0.00
created07/14/2009
version6553601
tabtypeT
locklevelR
npused0.00
fextsize16
nextsize16
flags0
site
dbname
type_xid0
am_id0
pagesize2048
ustlowts
secpolicyid0
protgranularity
字段“locklevel”为R,表明这是一个行锁。
另外,使用onstat-k来监控锁模式。
这将在“使用onstat实用程序监控锁”小节进行介绍。
回页首
锁的类型
数据库、表、页和行(在这个小节中统称为对象)通过不同类型的锁来控制对自身的访问。
IDS使用以下类型的锁:
共享锁
当需要读取数据并且不允许更改行时,那么就可以在该对象(比如表、页或行)上设置一个共享锁。
一个对象可以由不同的会话设置多个共享锁。
因此,可以在需要时在一个对象上设置多个共享锁。
更新/提升锁
可以在需要更新的对象上设置更新锁。
如果一个对象已经设置了共享锁,另一个会话还可以在其上设置一个更新锁。
如果需要更改对象,那么更新锁必须提升为独占锁。
不过,为了实现独占锁,在提升过程中该对象不能包含共享锁或更新锁。
独占锁
当一个会话请求单独使用某个对象时,可以在该对象上放置一个独占锁。
如果一个对象上已经放置了独占锁,那么其他会话就不能再在该对象上放置其他类型的锁。
INSERT、UPDATE和DELETE语句在它们所更改的行上使用这个锁。
在事务完成之后将释放该锁。
onstat实用程序和syslocks表使用以下符号表示锁的类型:
∙共享锁-S
∙更新锁-U
∙独占锁-X
在某些情况下,可以通过放置一个意向锁(intentlock)来表明要放置特定锁的意向。
例如,意向共享锁的表示符号为IS。
在使用SELECT语句期间通常可以在表上看到IS锁。
在使用INSERT、UPDATE或DELETE语句期间通常可以在表上看到意向独占锁。
表1使用这些符号列出了一个兼容性矩阵,显示当一个会话已经在某个对象上放置了特定的锁时,另一个会话可以在该对象上请求的锁。
表1.锁兼容性矩阵
持有X锁
持有U锁
持有S锁
持有IS锁
持有SIX锁
持有IX锁
请求X锁
No
No
No
No
No
No
请求U锁
No
No
Yes
Yes
No
No
请求S锁
No
Yes
Yes
Yes
No
No
请求IS锁
No
Yes
Yes
Yes
Yes
Yes
请求SIX锁
No
No
No
Yes
No
No
请求IX锁
No
No
No
Yes
No
Yes
回页首
锁请求失败
当会话请求锁失败时,数据库服务器的默认行为是返回一个错误。
要让该会话等待拥有锁的会话释放锁,请在运行预定语句之前运行以下SQL语句:
SETLOCKMODETOWAIT;
这将让会话一直等到锁释放。
如果要设置固定的等待期限(例如,5秒),则使用以下语句:
SETLOCKMODETOWAIT5;
回到默认行为:
SETLOCKMODETONOTWAIT;
SETLOCKMODE语句仅在会话级别有效。
我们通过以下例子查看锁模式的行为:
清单5.开始会话
dbaccess--
DROPDATABASEdb1;
CREATEDATABASEdb1WITHBUFFEREDLOG;
CREATETABLEt1(c1int);
INSERTINTOt1VALUES
(1);
清单6.会话A
dbaccessdb1-
BEGINWORK;
UPDATEt1SETc1=5;
清单7.会话B
dbaccessdb1-
SELECT*FROMt1;
清单8.收到的错误
244:
Couldnotdoaphysical-orderreadtofetchnextrow.
107:
ISAMerror:
recordislocked.
清单9.onstat-gsql输出
$onstat-gsql
IBMInformixDynamicServerVersion11.50.FC4--On-Line--Up1days06:
16:
34
--149504Kbytes
SessSQLCurrentIsoLockSQLISAMF.E.
IdStmttypeDatabaseLvlModeERRERRVersExplain
30-db1CRNotWait009.24Off
输出结果显示db1的隔离级别为“CommittedRead”(后面将讨论隔离级别)。
因为表t1上有一个未提交的更新,错误提示需要使用锁定的记录。
让我们在会话B中尝试使用SETLOCKMODEWAIT语句:
SETLOCKMODETOWAIT;
SELECT*FROMt1;
这个会话并没有立即返回错误,而是等待锁释放。
现在,在会话A中,完成事务:
COMMITWORK;
在会话B中,现在是等待提交结束之后才返回查询结果。
死锁
当两个会话都持有它们需要使用的锁时就会导致死锁。
结果是两个会话都等待对方释放锁。
不过,数据库服务器可以检测到这种情况并阻止它发生。
例如:
T1:
读取行A并在其上放置一个锁。
T2:
读取行B并在其上放置一个锁。
T1:
在行B上请求一个锁。
T2:
在行A上请求一个锁。
IDS维护一个内部锁表。
为了防止出现死锁,IDS将检查内部锁表,查看在会话等待锁期间是否会导致死锁。
发生的情况如下所示:
T1:
将锁模式设置为等待。
T2:
将锁模式设置为等待。
T1:
读取行A并在其上放置一个锁。
T2:
读取行B并在其上放置一个锁。
T1:
在行B上请求一个锁;必须等待T2在行B上释放该锁。
T2:
在行A上请求一个锁,但被拒绝了,因为等待该锁的释放会导致死锁。
IDS从内部锁表检测到:
∙T1持有行A上的锁
∙T2持有行B上的锁
∙T1等待T2持有的行B上的锁
如果允许T2等待T1在行A上持有的锁,那么将出现死锁。
因此,锁请求被拒绝,并返回错误(-143ISAMerror:
deadlockdetected)。
检查onstat-p的输出看看是否有死锁:
清单10.检查onstat-p输出中的死锁
$onstat-p
IBMInformixDynamicServerVersion11.50.FC4--On-Line--Up2days22:
34:
37
--157696Kbytes
Profile
dskreadspagreadsbufreads%cacheddskwritspagwritsbufwrits%cached
1385144301189439499.27226044115942931194.73
isamtotopenstartreadwriterewritedeletecommitrollbk
11788846449588313413795467235845056571783316
gp_readgp_writegp_rewrtgp_delgp_allocgp_freegp_curs
0000000
ovlockovuserthreadovbuffusercpusyscpunumckptsflushes
00089.2313.3236670849
bufwaitslokwaitslockreqsdeadlksdltoutsckpwaitscompressseqscans
191075018350640106770
ixda-RAidx-RAda-RARA-pgsusedlchwaits
231230803313254
查看“deadlks”字段,您可以看到在数据库服务器上线至今发生了5个死锁事件。
如果频繁发生死锁,请检查应用程序并交错使用频繁更改的行。
通过减少锁等待时间可以降低出现死锁的几率。
对于分布式事务,会话在返回错误之前使用DEADLOCK_TIMEOUT配置参数等待来自远程数据库的响应。
在onstat-p输出中的“dlouts”字段显示分布式死锁超时的统计数据。
日志和非日志数据库
在日志数据库中,数据库服务器记录其事务以及在事务期间持有的锁。
一般都能够识别到事务持有的锁,除非事务没有提交或被回滚。
非日志数据库中没有事务,但仍然使用锁。
尽管很容易错过,但是服务器在执行DataManipulationLanguage时使用锁,并且在该语句完成之后快速释放锁。
监控锁
onstat实用程序监控锁
数据库服务器使用的锁保持在一个内部锁表中。
使用onstat-k命令可以监控数据库服务器持有的锁的类型和粒度。
onstat-k命令的输出包含以下字段:
表2.onstat-k命令输出包含的字段
字段
说明
address
锁表中的锁的位置。
如果用户线程正在等待这个锁,那么该锁的地址就会出现在onstat-u(用户)输出的wait字段中。
wtlist
等待锁的用户线程列表的第一项,如果存在的话。
owner
持有锁的线程的共享内存地址。
这个地址与onstat-u(用户)输出中的address字段中的地址对应。
当持有者值显示在圆括号中时,它表示事务结构的共享内存地址。
仅当为全局事务分配锁时才会发生这种情况。
这个地址与onstat-G输出的address字段对应。
lklist
刚才列出的持有者持有的链接锁列表中的下一个锁。
type
使用以下符号表示锁的类型:
∙HDR-头部
∙B-字节
∙S-共享
∙X-独占
∙I-意向
∙U-更新
∙IX-意向独占
∙IS-意向共享
∙SIX-共享意向独占
tblsnum
行标识号码。
rowid提供以下锁信息:
∙如果rowid为0,那么这个锁是一个表锁。
∙如果rowid以两个0结尾,那么这个锁是一个页锁。
∙如果rowid小于等于6位数并且不以0结尾,那么这个锁可能是一个行锁。
∙如果rowid大于6位数,那么该锁可能是一个索引键-值锁。
key#/bsiz
索引键值号,或为VARCHAR锁锁定的字节数。
如果这个字段包含“K-”并且其后接一个值,那么这是一个键锁。
该值标识要锁住的索引。
例如,K-1表示为表定义的第一个索引包含一个锁。
回页首
onstat-k命令的示例输出
这个例子使用不遵从ANSI的日志数据库和两个表:
CREATEDATABASEdb1WITHLOG;
CREATETABLEt1(c1int);
CREATETABLEt2(c1int)LOCKMODEROW;
以下值被插入到这两个表中:
INSERTINTOt1VALUES
(1);
INSERTINTOt2VALUES
(1);
INSERTINTOt2VALUES
(2);
执行以下语句:
BEGINWORK;
UPDATEt1SETc1=5;
UPDATEt2SETc1=5;
onstat-k的输出:
清单11.onstat-k的输出
$onstat-k
IBMInformixDynamicServerVersion11.50.FC4--On-Line--Up2days21:
39:
44
--157696Kbytes
Locks
addresswtlistownerlklisttypetblsnumrowidkey#/bsiz
10a3134d80111535cd80HDR+S1000022040
10a44bcd801115354880S1000022040
10a44bd5801115365280S1000022040
10a44c4d80111537e180HDR+S1000022020
11348b0280111537e1810a44c4d8HDR+IX1001ef00
11348b0a80111537e1811348b028HDR+X1001ef1000
11348b1280111537e1811348b0a8HDR+IX1001f000
11348b2a80111537e1811348b128HDR+X1001f01010U
11348b3280111537e1811348b2a8HDR+X1001f01020U
9active,80000total,16384hashbuckets,2locktableoverflows
该输出包含以下信息:
∙表锁:
o查看地址为11348b028的行,其rowid为0,表明这个锁是表锁。
IX表明其类型为意向独占。
∙页锁:
o查看地址为11348b0a8的行,其rowid的最后两位为00,表明这个锁是页锁。
类型X表明它是独占锁。
这是针对t1的,它使用页级锁模式。
∙行锁:
o查看地址为11348b328的行,其rowid为0x102,表明这个锁是行锁,在这里为独占锁。
这是针对t2的,它使用行级锁模式。
∙数据库锁:
o查看地址为10a3134d8的行,表上有一个行锁。
不过,tblsnum0x100002是一个数据库tblspace,它是在服务器中保持数据库列表的特殊表。
因此,它行上的锁相当于锁定数据库。
类型S表明该锁是一个共享锁。
要在onstat-k,中找出tblsnum的表名,需要对systables表使用以下语句:
清单12.识别tbslnum的表名
SELECT*FROMsystablesWHEREpartnum=1049072;
Output:
tabnamet2
ownerinformix
partnum1049072
tabid101
rowsize4
ncols1
nindexes0
nrows0.00
created07/20/2009
version6619137
tabtypeT
locklevelR
npused0.00
fextsize16
nextsize16
flags0
site
dbname
type_xid0
am_id0
pagesize2048
ustlowts
secpolicyid0
protgranularity
回页首
在sysmaster数据库中使用syslocks表监控锁
您还可以通过在sysmaster数据库中使用syslocks表来监控锁。
表3列出了该表中的列并附带上说明:
表3.syslock表的字段
列
描述
dbsname
持有锁的数据库
tabname
持有锁的表的名称
rowidlk
持有锁的行的ID(0表明该锁是一个表锁)
keynum
行的键号
Type
锁的类型
owner
锁持有者的会话ID
waiter
锁的第一个等待者的会话ID
在db1中运行以下查询:
清单13.db1上的查询
CREATEDATABASEdb1WITHLOG;
CREATETABLEt3(c1int);
CREATEINDEXidx1ONt3(c1)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Informix Dynamic Server 1150 基础考试 555 认证准备第 部分 数据并发性 基础 考试 认证 准备 数据 并发
链接地址:https://www.bdocx.com/doc/10008463.html