调整数据库以减少磁盘 I/O 争用有助于减少死锁,但死锁可能仍然比较常见,new_edit_state 存储过程调用会锁死调用应用程序并阻止对地理数据库的所有其他使用操作。
假设一个情景,其中存储过程在 STATE_LINEAGES 表上获得了大量的行锁,超出了最大锁数阈值并试图升级到排他表锁。不幸的是,调用应用程序的查询已经在 STATE_LINEAGES 表上具有了一个共享锁,这会导致死锁。大量的行锁由于具有较深的状态谱系而产生。这一点再加上锁列表大小的设置较低就会导致问题产生。如果给定锁升级的处理方式,则还可能出现其他死锁情形。
这意味着死锁在某些地方可能并不少见,具体取决于应用程序和数据库配置。再则,这一问题可能因为较深的状态谱系变得更加突出。
幸运的是,IBM Db2 提供了多个调整参数来对以下内容进行控制:锁定列表的大小 (LOCKLIST)、应用程序可保存的锁的最大百分比 (MAXLOCKS)、获取锁的请求需等待的时间量 (LOCKTIMEOUT)、死锁检测的频率间隔 (DLCHKTIME) 和死锁回滚行为 (DB2LOCK_TO_RB)。
简而言之,要增加锁列表容量和锁升级阈值,请分别修改 LOCKLIST 和 MAXLOCKS 参数。
LOCKLIST 和 MAXLOCKS 的默认值是 AUTOMATIC,可使这些参数进行自我调整。这使得 Db2 内存调谐器可以在不同的内存使用者之间动态调整内存资源的大小。仅在数据库启用了自我调整内存的情况下才会发生自动调整 (SELF_TUNING_MEM=ON)。
另外,您可以使用 Db2 锁定延迟注册表变量 DB2_EVALUNCOMMITED、DB2_SKIPDELETED 和 DB2_SKIPINSERTED 实现锁定避免,从而改善并发状况。这些注册表变量允许通过扫描方式无条件跳过未提交的删除锁定和插入锁定。
默认情况下,锁定超时会回滚请求事务。默认行为应对 Db2 中的地理数据库足够可用。
有关正确设置这些参数的详细信息,请参阅 IBM Knowledge Center 中的 Db2 文档。
下列部分提供了用于诊断死锁的一些提示。
诊断锁定问题
以下是诊断锁定问题的一些有用工具的详细信息。
- 为 ArcGIS 进程查找 db2 应用程序 ID。
SELECT appl_id FROM TABLE(SNAPSHOT_APPL_INFO('SDE',-1)) AS SNAPSHOT_APPL_INFO WHERE appl_name LIKE 'gsrvr%' SELECT appl_id,appl_name FROM TABLE(SNAPSHOT_APPL_INFO('SDE',-1))
- 为锁定和应用程序信息使用快照;例如:快速搜索感兴趣项目的快照输出会得出如下结果:
db2 get snapshot for locks on sde > all_locks.txt db2 get snapshot for locks for application applid '*LOCAL.DB2.00AB42215335' > app_locks.txt db2 get snapshot for application applid '*LOCAL.DB2.00AB42215335' > app_info.txt
Application status = Lock-wait Locks held by application = 1254 Number of SQL requests since last commit = 12 Open local cursors = 1 Most recent operation = Execute Object type = Table Tablespace name = USERSPACE1 Table schema = SDE Table name = STATE_LINEAGES Mode = X Status = Converting Current mode = IX Lock escalation = YES
- 如上所述,较深的谱系可能会导致出现大量行锁的问题。下列 SQL 语句可进行谱系深度和最大谱系深度的快速检查:
SELECT COUNT (*) FROM state_lineages GROUP BY lineage_name SELECT MAX(a.depth) FROM (SELECT COUNT (*) FROM state_lineages GROUP BY lineage_name) a(depth)