1、问题描述



从4月17号下午5时起,至18号晚9点,客户单位部分通过ArcGIS Server发布的地图服务(该部分地图服务的数据源为数据库SJZX)无法加载浏览,表现为长时间无响应。同时,通过ArcMap加载数据库中的要素类时,表现为"卡死",并长久无响应。

2、问题观察

通过收集该时间段内某1小时之间的性能数据,得到其耗时排名前6的SQL如下:

Android 开发 接入ArcGIS Maps SDK 不显示地图_共享锁

Android 开发 接入ArcGIS Maps SDK 不显示地图_SQL_02

    发现SQL ID 为gj2c1wk1brmaa 和 bxqcnpc5q5330 的两个SQL,其在1个小时的跨度内,执行次数为0。这说明,在这1个小时之内,该SQL一直在执行,且没有结束。SQL ID为bxqcnpc5q5330的SQL执行时间为3624秒,接近完整的1小时(3600s);SQL ID为gj2c1wk1brmaa的SQL执行时间为271786秒,这说明有271786/3600=75个进程在执行这个操作,且持续1小时未结束。

继续观察,发现这两个SQL都与TABLE_LOCKS表有关,SQL ID为bxqcnpc5q5330的SQL在执行时需要获得该表的排它锁;SQL ID为gj2c1wk1brmaa的SQL在执行时需要获得该表的共享锁(即TM锁)。猜测,这两条SQL长时间未执行结束,其根本原因在于无法获得其所需要的锁,即TABLE_LOCKS上发生了锁的阻塞。 

 3、问题分析

SQL ID为bxqcnpc5q5330的SQL需要获得排它锁,它可能被其它的排它锁或共享锁(TM锁)阻塞。

SQL ID为gj2c1wk1brmaa的SQL对TABLE_LOCKS表中的记录进行删除操作,需要获得该表的共享锁(TM锁),它可能被排它锁阻塞。

我们作两种假设:

1)TABLE_LOCKS上已经有其它的排它锁

这时候,符合bxqcnpc5q5330、gj2c1wk1brmaa两个SQL的表现。但排名前6的SQL中,还有cffvq2hst53md、00xnu55uqdns0、3ub7rzsp3rpyh 三个SQL有成功执行的次数(这三个SQL分别是向TABLE_LOCKS表中增加记录、获得TABLE_LOCKS的共享锁、根据PID(进程ID)删除TABLE_LOCKS表中记录),如果TABLE_LOCKS上已经有其它的排它锁,这几个SQL也会被阻塞,不可能执行成功。因此TABLE_LOCKS上已经有其它的排它锁的假设不成立。

2)TABLE_LOCKS上有未释放的共享锁(TM锁)

这时侯,TABLE_LOCKS上的共享锁(TM锁)会阻塞bxqcnpc5q5330 SQL,但bxqcnpc5q5330 SQL之前的共享锁(TM锁)请求不会被阻塞(包括cffvq2hst53md、00xnu55uqdns0、3ub7rzsp3rpyh),bxqcnpc5q5330 SQL之后的共享锁(TM锁)请求会被bxqcnpc5q5330 SQL的排它锁请求阻塞(尽管bxqcnpc5q5330 SQL还没有真正获得到锁,但它在锁的队列中会阻塞发生在它之后的SQL)。因此,该假设符合目前观察到的现象。

4、现象模拟再现

根据上述问题分析结果,我们可以基于假设条件进行现象模拟再现。

1)TABLE_LOCKS上有未释放的共享锁(TM锁)

当对TABLE_LOCKS执行了新增、删除、更新操作,但未提交事务时(有可能是事务异常结束),共享锁(TM锁)将不会释放。

Android 开发 接入ArcGIS Maps SDK 不显示地图_数据库_03

2)对TABLE_LOCKS请求排它锁

当使用ARCMAP、ARCCATALOG对database connection中的对象(包括要素类、要素集、表等)进行删除操作时,会请求排它锁。

Android 开发 接入ArcGIS Maps SDK 不显示地图_SQL_04

 

Android 开发 接入ArcGIS Maps SDK 不显示地图_排它锁_05

该会话请求的锁模式为6,即排它锁。

Android 开发 接入ArcGIS Maps SDK 不显示地图_共享锁_06

已经开始出现"卡死"并长时间无影响的现象。

3)对TABLE_LOCKS请求共享锁

通过ARCMAP、ARCCATALOG加载图层时,需要向TABLE_LOCKS中增加1条记录,此时需要请求TABLE_LOCKS表上的共享锁。

Android 开发 接入ArcGIS Maps SDK 不显示地图_SQL_07

此时加载图层已被阻塞。

4)释放第1)步中的共享锁(TM锁)

Android 开发 接入ArcGIS Maps SDK 不显示地图_排它锁_08

Android 开发 接入ArcGIS Maps SDK 不显示地图_数据库_09

所有的阻塞都迎刃而解了。