1. 锁资源信息的查找和监控
1.1. 系统表中关于锁的信息
1.1.1. 当前正在占用锁资源和等待锁资源信息的系统表syslocks和测试
sql
> select * from sysmaster:syslocks;
dbsname test --数据库名称
tabname test --锁发生的表名称
rowidlk 6918 --发生锁的行号
keynum 0 --有索引时索引的键值锁
type X --锁的类型,由此可以看出是排他锁
owner 54 --当前持有锁的session号
waiter 55 --等待锁的session号
--当发生锁阻塞时,一个阻塞syslocks中会有多条记录,只有waiter中有数据的才是阻塞的关键记录
锁类型的说明:
- B:byte lock字节锁
- IS:intent shared lock意向共享锁
- S:shared lock共享锁
- XS:repeatable read shared key可重复度共享锁
- U:update lock更新锁
- IX:intent exclusive lock意向独占锁
- SIX:共享意向独占锁
- X:exclusive lock独占锁
- XR:repreatable read exclusive可重复读独占锁
------------------------------关于上述测试的实验记录--------------------------------------
sql
--查看session号
> select dbinfo('sessionid') from dual;
(expression)
54
1 row(s) retrieved.
sql
--查询session号
> select dbinfo('sessionid') from dual;
(expression)
55
1 row(s) retrieved.
> set lock mode to wait;
Lockmode set.
> update test set name ='ac' where id =89627;
--此时会hang住
sql
> select * from sysmaster:syslocks where waiter is not null;
dbsname test
tabname test
rowidlk 6918
keynum 0
type X
owner 54
waiter 55
1 row(s) retrieved.
- 上述信息可以看出是test库的test表
- session55的会话在等待session44的会话
sql
> set isolation to dirty read;
Isolation level set.
> select rowid from test where id=89627;
rowid
6918
311558
597312
686618
4 row(s) retrieved.
- 设置脏读,查看本次修改数据的rowid,可以发现,第一条数据的rowid就是rowidlk
1.1.2. 从会话层次查看会话关于锁的信息
sql
> select * from sysmaster:syssesprof where sid=24;
sid 24 --会话号
lockreqs 0 --请求锁的数量
locksheld 0 --持有的锁数量
lockwts 0 --等待锁的次数
deadlks 0 --检测到死锁的次数
lktouts 0 --死锁超时的次数
logrecs 0 --写入的逻辑日志记录数
isreads 0 --读取次数
iswrites 0 --写入次数
isrewrites 0 --重写次数
isdeletes 0 --删除次数
iscommits 0 --提交次数
isrollbacks 0 --回退次数
longtxs 0 --长事务次数
bufreads 0 --缓冲读次数
bufwrites 0 --缓冲写次数
seqscans 0 --全表扫描次数
pagreads 0 --磁盘读取页面次数
pagwrites 0 --写入磁盘次数
total_sorts 0 --总排序次数
dsksorts 0 --无法放入内存的排序次数
max_sortdiskspace 0 --排序使用的最大磁盘空间
logspused 0 --当前事务使用的字节数的逻辑日志空间
maxlogsp 0 --会话开始以来任何单个事务使用的最大逻辑日志空间
--------------------------------依然以session54和session55为例
sql
> select * from sysmaster:syssesprof where sid=54 or sid=55;
--
sid 54
lockreqs 212266
locksheld 10
lockwts 0
deadlks 0
lktouts 0
logrecs 9
isreads 214
iswrites 0
isrewrites 4
isdeletes 0
iscommits 0
isrollbacks 0
longtxs 0
bufreads 5976
bufwrites 8
seqscans 2
pagreads 0
pagwrites 0
total_sorts 1
dsksorts 0
max_sortdiskspace 0
logspused 1880
maxlogsp 0
- 可以看到session54持有10个锁,没有锁等待也没有锁超时
sql
sid 55
lockreqs 6050
locksheld 2
lockwts 2
deadlks 0
lktouts 0
logrecs 0
isreads 85
iswrites 0
isrewrites 0
isdeletes 0
iscommits 0
isrollbacks 0
longtxs 0
bufreads 338
bufwrites 0
seqscans 3
pagreads 0
pagwrites 0
total_sorts 0
dsksorts 0
max_sortdiskspace 0
logspused 0
maxlogsp 0
- 从上述可以看出,持有两个锁
- 由于update执行两次都被锁住,所以等待了两次锁
1.1.3. 查看当前会话的锁模式syssqlcurses
sql
select * from sysmaster:syssqlcurses;
scs_sessionid 23 --会话id
scs_currdb test --当前数据库
scs_isolationlevel REPEATABLE READ --隔离级别
scs_lockmode 0 --锁模式
scs_executions 0 --执行次数
scs_cumtime 0.000920159285 --累计执行次数
scs_bufreads 6 --缓冲区读取次数
scs_pagereads 2 --页读取次数
scs_bufwrites 0 --缓冲区写入次数
scs_pagewrites 0 --页写入次数
scs_totsorts 0 --排序次数
scs_dsksorts 0 --磁盘排序次数
scs_sortspmax -1 --排序所需最大的磁盘空间
scs_sqerrno 0 --SQL错误号
scs_isamerr 0 --ISAM错误号
scs_fevers 9.03 --前端版本
scs_sqlstatement select * from sysmaster:syssqlcurses --SQL语句
1.2. 是否是锁资源不够的查看
1.2.1. 查看锁资源总数量sysshmvals
sql
> select * from sysmaster:sysshmvals;
sh_mode 5 --共享内存段的访问权限模式
sh_boottime 1708508793 --实例最后一次启动时间
sh_pfclrtime 1708508793 --最后一次清除页面缓存的时间戳,用来记录统计信息的时间
sh_curtime 1708675854 --查询时当前的时间戳
sh_bootstamp 527872
sh_stamp 672801 --记录和标记事件状态的时间戳
sh_mainlooptcb 1246080304
sh_sysflags 4097
sh_maxchunks 32766 --数据库能够支持的最大数据块数量
sh_maxdbspaces 2047 --数据库能支持的最大数据空间数量
sh_maxuserthreads 131068 --支持的最大用户线程数,关联到并发用户数和任务
sh_maxtrans 131068 --最大的事务
sh_maxlocks 200000 --最大的锁数量(onconfig中locks设置的大小)
sh_maxlogs 41 --逻辑日志数量
sh_nbuffs 35001 --缓冲区的个数
sh_pagesize 2048 --缓冲区的页大小
sh_nlrus 64 --所在数据库使用相应大小数据空间的缓冲区配置LRU队列的个数
sh_maxdirty 60.00000000000 --缓冲区lru_max_dirty的配置
sh_mindirty 50.00000000000 --缓冲区lru_min_dirty的配置
sh_ncleaners 32
sh_longtx 0 --出现长事务的次数
sh_optstgbsnum 0 --存储共享内存段的最佳存储器段号
sh_cpflag 0
sh_rapages 0
sh_rathreshold 0
sh_lastlogfreed 12 --最后一个可用的逻辑日志序号
sh_rmdlktout 60
sh_narchivers 0
sh_maxpdqpriority 0 --最大PDQ的优先级,值越高,并行的可能性越大。关联到了onconfig中DS_MAX_QUERIES
sh_curmaxcons 2 --实例启动以来观测到的最大并发连接数量
sh_ovlmaxcons 2 --实例安装以来观测道德最大并发连接数
1 row(s) retrieved.
--------------------------------------以session54和session55服务器为例查看最大锁资源
sql
> select sh_maxlocks from sysmaster:sysshmvals;
sh_maxlocks
900000
1 row(s) retrieved.
1.2.2. 查看页面是否在等待锁资源
数据库的锁资源是有限的,如果查看会话是否在对总体资源的需求,可以查看以下系统表
sql
> select * from sysmaster:syssessions;
sid 26 --页面id
username gbasedbt --连接用户
uid 1002 --用户id
pid 0 --客户端进程id
hostname --连接的主机名
tty --用户的标准错误文件名
connected 1701396103 --用户连接时间
feprogram --前端程序名,jdbc中应该可以配置
pooladdr 1196134464 --专有对话池指针
is_wlatch 0 --如果在等待互斥体,则为1
is_wlock 0 --等待锁资源则为1
is_wbuff 0 --等待缓冲区,则为1
is_wckpt 0 --等待检查点,则为1
is_wlogbuf 0 --等待日志缓冲区,则为1
is_wtrans 0 --等待事务,则为1
is_monitor 0 --如果是监控进程,则为1
is_incrit 0 --是否在关键段内,则为1
state 524289 --标志位
- 0x00000001:用户结构正在使用
- 0x00000002:等待latch
- 0x00000004:等待锁
- 0x00000008:等待缓冲区
- 0x00000010:等待检查点
- 0x00000020:在读调用中
- 0x00000100:写入逻辑日志文件到备份磁带
- 0x00000200:在临界区中
- 0x00000400:特殊守护进程
- 0x00000800:归档
- 0x00001000:清理死亡进程
- 0x00002000:等待写日志缓冲区
- 0x00004000:特殊缓冲刷新线程
- 0x00008000:远程数据库服务器
- 0x00010000:用于设置RS_timeout的死锁超时
- 0x00020000:常规锁超时
- 0x00040000:等待事务
- 0x00080000:会话的主线程
- 0x00100000:构建索引的线程
- 0x00200000:B树清理线程
---------------------------以session54和session55为例查看会话的对锁资源的需求
sql
> select *,hex(state) from sysmaster:syssessions;
sid 55
username gbasedbt
uid 1000
pid 1421994
hostname iZ2ze4p3q6wy4hzagubdmbZ
tty /dev/pts/4
connected 1719834825
feprogram /home/gbasedbt/gbase/bin/dbaccess
pooladdr 1396736064
is_wlatch 0
is_wlock 0
is_wbuff 0
is_wckpt 0
is_wlogbuf 0
is_wtrans 0
is_monitor 0
is_incrit 0
state 524289
(expression) 0x00080001
- 上述可以看出锁资源充足
- 且根据state可以看出其实一个主进程,且正在使用
sql
sid 54
username gbasedbt
uid 1000
pid 1421866
hostname iZ2ze4p3q6wy4hzagubdmbZ
tty /dev/pts/1
connected 1719834758
feprogram /home/gbasedbt/gbase/bin/dbaccess
pooladdr 1397104704
is_wlatch 0
is_wlock 0
is_wbuff 0
is_wckpt 0
is_wlogbuf 0
is_wtrans 0
is_monitor 0
is_incrit 0
state 524289
(expression) 0x00080001
- 上述可以看出锁资源充足
- 且根据state可以看出其实一个主进程,且正在使用
1.2.3. 整个实例锁发生锁资源不足次数的查看sysprofile
sql
----会话尝试使用超过锁最大数量的次数
ovlock 0
--锁请求等待次数
latchwts 105 7
--锁请求次数
lockreqs 1250
--锁等待次数
lockwts 0 0
--死锁次数
deadlks 0
--死锁超时次数
lktouts 0
------------------------以session54和session55的服务进行查看
sql
> select * from sysmaster:sysprofile where name in ('ovlock','latchwts','lockreqs','lockwts','deadlks','lktouts');
name value
ovlock 0
latchwts 176
lockreqs 239761
lockwts 6
deadlks 0
lktouts 0
6 row(s) retrieved.
- 上述可以看出,锁资源没有不足过
- 发生锁请求等待次数176次
- 请求锁239761次
- 发生锁等待次数6次
1.2.4. 表为单位查看发生在表上的锁的次数sysptprof
sql
> select * from sysmaster:sysptprof limit 1;
dbsname rootdbs --数据库名称或者数据空间名称
tabname TBLSpace --表名
partnum 1048577 --表的编号
lockreqs 0 --锁请求
lockwts 0 --锁等待
deadlks 0 --死锁
lktouts 0 --锁超时
isreads 0 --读次数
iswrites 0 --写次数
isrewrites 0 --更新次数
isdeletes 0 --删除次数
bufreads 693 --buffer读次数
bufwrites 0 --buffer写次数
seqscans 0 --顺序扫描次数
pagreads 1 --磁盘读
pagwrites 0 --磁盘写次数
------------------------以session54和session55的表进行查看
sql
> select * from sysmaster:sysptprof where tabname='test';
dbsname test
tabname test
partnum 6292558
lockreqs 220863
lockwts 2
deadlks 0
lktouts 0
isreads 188
iswrites 0
isrewrites 4
isdeletes 0
bufreads 9109
bufwrites 8
seqscans 8
pagreads 2845
pagwrites 5
1 row(s) retrieved.
- test表发生过2次锁等待
1.3. 工具查看锁
1.3.1. onstat -k
bash
[gbasedbt@iZ2ze4p3q6wy4hzagubdmbZ ~]$ onstat -k
Your evaluation license will expire on 2025-06-24 00:00:00
On-Line -- Up 3 days 23:45:00 -- 4275148 Kbytes
-- 锁的类型 行标识号
Locks
address wtlist owner lklist type tblsnum rowid key#/bsiz
44690028 0 4d704fa8 480f04e0 HDR+IX 60044e 0 0
480ed6a8 0 4d703568 480edb70 IX 60044e 0 0
480ed950 0 4d704fa8 480ede18 HDR+B 60044e a7a00 99
480ed9d8 0 4d704fa8 480edc80 HDR+X 60044e 91d40 0 U
480eda60 0 4d704fa8 480ed950 HDR+S 100002 201 0
480edae8 0 4d704fa8 480ed9d8 HDR+X 60044e a7a1a 0 U
480edb70 0 4d703568 0 S 100002 20b 0
480edbf8 4d7023e8 4d704fa8 44690028 HDR+X 60044e 1b06 0 U
480edc80 0 4d704fa8 480edbf8 HDR+X 60044e 4c106 0 U
480edd08 0 4d704fa8 480edae8 HDR+B 60044e 1b00 99
480edd90 0 4d704fa8 480edd08 HDR+B 60044e 4c100 99
480ede18 0 4d704fa8 480edd90 HDR+B 60044e 91d00 99
480f04e0 0 4d704fa8 0 HDR+S 100002 20b 0
13 active, 900000 total, 131072 hash buckets, 0 lock table overflows
- address:锁在共享内存中的地址(如果用户线程等待此锁,地址将会出现在onstat -u的wait字段中)
- wtlist:正在等待锁的用户线程
- owner:正持有锁的线程的共享内存地址,此地址对应onsta -u输出的address字段中的地址。当owner值显示在括号中时,它代表事务结构的共享内存地址,只有锁是为全局事务而分配时,才会出现这种情况。该地址对应onstat -G的输出的地址字段
- lklist:所有者持有的链接列表的下一个锁
- type:锁的类型
-
- HDR:头
- B:字节
- S:共享
- X:互斥
- I:意向
- U:更新
- IX:意向-互斥
- IS:意向-共享
- SIX:共享,意向-互斥
- tblsnum:锁定资源的tblspace编号,小于10000,表示enterprise replication伪锁
- rowid:行表示号
1.3.2. 查看锁会话的配合命令onstat -u
bash
[gbasedbt@iZ2ze4p3q6wy4hzagubdmbZ ~]$ onstat -u
Your evaluation license will expire on 2025-06-24 00:00:00
On-Line -- Up 3 days 23:50:53 -- 4275148 Kbytes
--线程的共享内存地址 会话状态的标志 会话唯一标识 会话用户 终端类型 锁的地址 锁等待时间 用户线程持有的锁数 用户线程的磁盘读取数 用户线程读取的写调用数
Userthreads
address flags sessid user tty wait tout locks nreads nwrites
4d7000e8 ---P--- 5 gbasedbt - 0 0 0 0 0
4d7009a8 ---P--B 6 gbasedbt - 0 0 0 0 0
4d701268 Y--P--D 7 gbasedbt - 520d4460 0 0 22830 0
4d701b28 ---P--D 8 gbasedbt - 0 0 0 0 0
4d7023e8 L---R-- 55 gbasedbt 4 480edbf8 -1 2 0 0
4d702ca8 ---P--D 12 gbasedbt - 0 0 0 0 0
4d703568 ---P--- 55 gbasedbt 4 0 0 2 0 0
4d703e28 ---P--D 13 gbasedbt - 0 0 0 2 0
4d7046e8 ---P--D 14 gbasedbt - 0 0 0 0 0
4d704fa8 Y-BP--- 54 gbasedbt 1 540a3538 0 11 17 0
4d705868 Y--P--D 25 gbasedbt - 44282c40 0 0 0 0
44 active, 256 total, 136 maximum concurrent
flags标志位
- 位置1:
-
- B:正在等待缓冲区
- C:正在等待checkpoint
- G:正在等待对逻辑日志缓冲区的写入
- L:正在等待锁
- S:正在等待互斥体,针对共享资源,同时只向一个线程授予共享资源的独占访问权,如果一个线程已经获取了互斥体,获取该互斥体的第二个线程将会被挂起
- T:正在等待事务
- Y:正在等待条件
- X:正在等待事务清除(回滚)
- 位置2
-
- *:IO故障过程中的事务是活动的
- 位置3
-
- A:Dbspace备份线程
- B:begin work has been logged
- P:
- X:XA prepared
- C:正在递交事务
- R:正在回滚或已经回滚
- H:Heuristically aborting
- 位置4
-
- P:会话主线程
- 位置5
-
- R:正在读取
- X:临界段中的线程
- 位置6
-
- R:恢复过程中使用的线程
- -:恢复过程中未使用的线程
- 位置7
-
- B:B-tree清除程序线程
- C:已终止正在等待清除的用户线程
- D:守护程序线程
- F:页清除程序线程
- M:Sepcial monitor
1.3.3. 根据onstat -k和onstat -u配合查看持有锁的会话和等待锁的会话
bash
[gbasedbt@iZ2ze4p3q6wy4hzagubdmbZ ~]$ onstat -u | awk '{print $1, $3}' | awk 'NR==FNR{a[$1]=$2; next} NR!=FNR && $2 , a[$2], $2, $1, a[$1]}' - <(onstat -k | awk '$2~ /[1-9]/ {print $2, $3}')ddr:%s 等待锁sid:%s\n",
Your evaluation license will expire on 2025-06-24 00:00:00
Your evaluation license will expire on 2025-06-24 00:00:00
持有锁sid:54 持有锁uaddr:4d704fa8 等待锁uaddr:4d7023e8 等待锁sid:55
- 从上述可以看出,持有锁的会话id是54,等待锁的会话id是55
- 可以根据会话id查看锁的sql
1.3.4. 根据会话id查看sql
bash
[gbasedbt@iZ2ze4p3q6wy4hzagubdmbZ ~]$ onstat -g sql 54
Your evaluation license will expire on 2025-06-24 00:00:00
On-Line -- Up 3 days 23:54:22 -- 4275148 Kbytes
Sess SQL Current Iso Lock SQL ISAM F.E.
Id Stmt type Database Lvl Mode ERR ERR Vers Explain
54 - test CR Not Wait 0 0 9.24 Off
Last parsed SQL statement :
update test set name ='a' where id =89627
bash
[gbasedbt@iZ2ze4p3q6wy4hzagubdmbZ ~]$ onstat -g sql 55
Your evaluation license will expire on 2025-06-24 00:00:00
On-Line -- Up 3 days 23:53:35 -- 4275148 Kbytes
Sess SQL Current Iso Lock SQL ISAM F.E.
Id Stmt type Database Lvl Mode ERR ERR Vers Explain
55 UPDATE test CR Wait 0 0 9.24 Off
Current SQL statement (6) :
update test set name ='ac' where id =89627
Last parsed SQL statement :
update test set name ='ac' where id =89627