环境:数据库db2 9.7v 操作系统:linux(redhat6.0)
最近生产环境的上的一个前端导入功能客户反应说很慢,一开始客户那边反应怀疑是不是死锁和并发性导致,所以一开始就去查看db2diag.log日志找-911的错误
但是没有找到(如果一开始日志文件很大打不开,你可以重命名以下,之后数据库会生产一个新的log),于是又更改了db2数据库的注册变量环境配置,具体命令如下:
第一步:
使用命令db2 list db directory查看DB2上有那些数据库,连接数据库。
db2set -all -用于查看环境变量的配置
查看下面的三个变量是否开启,一般默认是不开启的。
第二步:
之后通过如下命令设置开启(具体语法可以使用db2set ?查看):
DBI1300N db2set 显示、设置或除去 DB2 概要文件变量。
db2set [variable=[value]]
[-g|-i instance [db-partition-number]]
[-all]
[-null]
[-r [instance] [node-number]]
[-n DAS node[-u user[-p password]]]
[-l|-lr]
[-v]
[-ul|-ur]
[-?|-h]
说明:
命令选项是:
-g 访问全局概要文件变量。
-i 指定要使用的实例概要文件,而不是当前的或缺省的实例概要文件。
-n 指定远程 DB2 管理服务器节点名。
-u 指定用于管理服务器连接的用户标识。
-ul 访问用户概要文件变量
-ur 刷新用户概要文件变量
-p 指定用于管理服务器连接的密码。
-r 复位给定实例的概要文件注册表。如果未提供任何实例,那么将使用缺
省/当前实例。
-l 列示所有实例概要文件。
-lr 列示所有受支持的注册表变量。
-v 详细方式。
-? 显示命令帮助消息。
-h 与 -? 选项相同。
-all 显示出现的所有本地环境变量,如以下各项中所定义:
* 环境,用 [e] 表示
* 用户级注册表,用 [u] 表示
* 节点级注册表,用 [n] 表示
* 实例级注册表,用 [i] 表示,和
* 全局级注册表,用 [g] 表示
-null 在指定的注册表级别将变量值设置为空(null),以防止查找在变量值
搜索顺序中定义的下一个注册表级别中的值。
注意:
* 不带变量名的 db2set 将显示定义的所有变量。
* db2set <变量> 将显示 <变量> 的值。
* db2set <变量>= (无内容) 将删除 <变量>。
* db2set <变量>=<值> 将修改 <变量> 的值。
* db2set <变量> -null 将 <变量> 的值设置为 NULL。
* db2set <变量> -all 将显示所有定义的 <变量> 的值。
* db2set -ur 将刷新当前的用户概要文件。
* db2set <变量> -ul 将显示在用户级别的定义的 <变量>。
* db2set -all 将显示所有注册表级别中的所有定义的变量。
开启命令:
db2set DB2_EVALUNCOMMITTED=ON - i 这个参数将在记录锁之前进行谓词检查,尽量减少锁的时间;
db2set DB2_SKIPINSERTED=ON - i 这个参数将新insert且没有提交的数据跳过;例如,SELECT/UPDATE语句不会发现这条记录;
db2set DB2_SKIPDELETED=ON - i 这个参数将新delete且没有提交的数据跳过;例如,SELECT/UPDATE语句不等待这条记录的提交,并且认为他已经被删除了。
关闭命令:
db2set DB2_SKIPDELETED=
如果不加-i可能会覆盖掉db2comm=tcpip导致其他客户端机器连接不上数据库,具体到java前端就会报500错误(500错误有多种,具体查看你们自己前端服务器写的启动日志)
如果发生重新设置回来即可,这些设置需要重启db2数据库,命令如下:
db2 force application all
db2stop
db2start
第三步:重启成功后发现前端导入数据还是很慢(比原先快了那么一丢丢,开启这些命令也会导致一些问题,具体要看公司业务)。
到这时候看没有死锁,跟并发性设置关系也不大,然后准备抓取数据库快照分析下。
第一步:查看开启使用数据库快照来抓取数据库的信息
通过命令db2 get monitor switches查看快照开启信息,如下命令是开启(开启会影响数据库性能,时间自定,用完之后记得关闭,on改为off即可)
第二步:
db2 update monitor switches using lock on
第三步:
db2 get snapshot for locks on dbname > /pas/log.out(可把locks改为all,这样就可以查看更多信息,locks只看锁),log.out文件部分内容
Application handle = 2888
Application ID = 199.9.39.11.5634.150915090917
Sequence number = 06373
Application name = db2jcc_application
CONNECT Authorization ID = PAS
Application status = UOW Executing--正在执行
Status change time = Not Collected
Application code page = 1208
Locks held = 9
Total wait time (ms) = 0
List Of Locks(有这个表示在上面的连接下锁了那些表)
Lock Name = 0x010031010F0054010000000052
Lock Attributes = 0x00000000
Release Flags = 0x40000000
Lock Count = 1
Hold Count = 0
Lock Object Name = 22282255
Object Type = Row --行锁
Tablespace Name = TBS_SPA --表空间名
Table Schema = SPA
Table Name = tablenam1 --表名
Mode = X --锁类型
Application handle = 434
Application ID = 199.9.39.11.377.1509141
Sequence number = 01949
Application name = db2jcc_application
CONNECT Authorization ID = PAS
Application status = UOW Waiting--在等待的连接
Status change time = Not Collected
Application code page = 1208
Locks held = 0
Total wait time (ms) = 0
之后发现了很多连接处于等待状态(锁表太久跟sql语句有直接关联??初步怀疑sql语句),而且有好些表处于行锁x以及表锁ix上,于是就想通过设置锁等待时间以及LOCKLIST和MAXLOCKS来处理。具体如下步骤:
第一步:
db2 -v update monitor switches using lock on
db2 -v terminate
第二步:
然后收集数据库快照(把信息输入到pas下面的log.out文件里):
db2 -v get snapshot for database on dbname | grep –i lock >/pas/log.out
在快照输出中,检查下列各项:
Locks held currently = 21224
Lock waits = 24683
Time database waited on locks (ms) = 32875
Lock list memory in use (Bytes) = 87224
Deadlocks detected = 89
Lock escalations = 8
Exclusive lock escalations = 12
Agents currently waiting on locks = 0
Lock Timeouts = 0
Internal rollbacks due to deadlock = 0
如果“Lock list memory in use (Bytes)”超过定义的LOCKLIST大小的50%,那么就增加LOCKLIST数据库配置参数中的4KB页的数量。
如果发生了“Lock escalations>0”或“Exclusive lock escalations>0”,
则应该或者增大LOCKLIST或者MAXLOCKS,抑或同时增大两者。
查看“Locks held currently”、“Lock waits”、“Time database waited on locks (ms)”、
“Agents currently waiting on locks”和“Deadlocks detected”中是否存在高值,如果有的话,
就可能是差于最优访问计划、事务时间较长或者应用程序并发问题的症状。
LOCKLIST和MAXLOCKS的值和设置参考下面的文档:
http://wenku.baidu.com/link?url=jw7BMdUHtcISvFq_kWhyC_GxMrsCXh8PTaZgzcL7c3X2xOXLKyU99dxxrz9OWnXT6-d8BF9jTptCdMIgHAu7Z-RbAGr4g0DnYGFv2ew0z57
走到了这一步之后发现还是行不通,导入数据依然要些时间,看来导入跟数据库设置关系不大,应该是sql语句的问题。
于是就导入一条数据,然后监视
第一步:
通过db2top -d 数据库名 -u 用户名 -p 密码 命令来监视运行的sql.
第二步:
通过db2top命令查找运行时间最长以及耗费资源最多的sql。
具体用法就不提了输入命令后上面有提示,之后找到了运行最久最耗时的sql进行了优化就快多了。
处理也就到此结束,之所以一开始没有使用db2top监视一方面是由于客户反映问题的方向,另一方面是由于这个功能其他客户也用的是一样的代码,
没曾想有人改过代码。。。。。。。
PS后记:
修改表的自增字段的起始值
db2 alter table t1 alter id restart with 11
再重组下
reorg table t1
如果表的id是自增 可以避免自增的字段是9,10的主键冲突,这个在项目中高并发经常遇到,主要是写日志的表。