7 接下去看看EDI_MESSAGE_PROCESS_LOG这张表和索引BIND_PROCESS_LOG_REFNO之间有没有什么关系?
view sourceprint?
01 SQL> select index_name,table_name,index_type from user_indexes where table_name='EDI_MESSAGE_PROCESS_LOG';
02
03 INDEX_NAME TABLE_NAME INDEX_TYPE
04 ------------------------------ ------------------------------ ----------
05 PK_EDI_MESSAGE_PROCESS_LOG EDI_MESSAGE_PROCESS_LOG NORMAL
06 ID_EDI_LOG_INPUT_DATE EDI_MESSAGE_PROCESS_LOG NORMAL
07 BIND_PROCESS_LOG_REFNO EDI_MESSAGE_PROCESS_LOG BITMAP
08
09 SQL> select index_name,table_name,column_name from user_ind_columns where table_name='EDI_MESSAGE_PROCESS_LOG';
10
11 INDEX_NAME TABLE_NAME COLUMN_NAM
12 ------------------------------ ------------------------------ ----------
13 PK_EDI_MESSAGE_PROCESS_LOG EDI_MESSAGE_PROCESS_LOG LOG_ID
14 ID_EDI_LOG_INPUT_DATE EDI_MESSAGE_PROCESS_LOG INPUT_DATE
15 BIND_PROCESS_LOG_REFNO EDI_MESSAGE_PROCESS_LOG REFNO
16
17 SQL> select object_name,object_id,object_type,created from user_objects where object_name='BIND_PROCESS_LOG_REFNO';
18
19 OBJECT_NAME OBJECT_ID OBJECT_TYPE CREATED
20 ------------------------------ ---------- --------------- -------------------
21 BIND_PROCESS_LOG_REFNO 369195 INDEX 2012/11/05 10:18:28
22
23 SQL> select index_name,index_type from user_indexes where index_name='BIND_PROCESS_LOG_REFNO';
24
25 INDEX_NAME INDEX_TYPE
26 ------------------------------- -----------
27 BIND_PROCESS_LOG_REFNO BITMAP
28
29 SQL>
发现,这个索引BIND_PROCESS_LOG_REFNO是位于EDI_MESSAGE_PROCESS_LOG这张表的REFNO字段上的一个位图索引,而且是2012/11/05 10:18:28创建的,也就是说是近期才创建的1个位图索引。
问题定位到这一步基本比较清晰了,产生enq: TX – row lock contention事件的原因就是上述的第2个可能原因:位图索引同时被更新或同时并发的向位图索引字段上插入相同字段值。
8 那么,解决的办法也比较简单了,就是干掉这个位图索引,因为这个位图索引在这种应用场景下确实不太适合。事后,经过同客户方沟通确认,该索引是他们的一个DBA当初看到系统比较慢,而加上去的一个位图索引。
9 补充,从当时的ADDM报告中,也可以看到数据库给我们的建议:
view sourceprint?
01 FINDING 4: 20% impact (6013 seconds)
02 ------------------------------------
03 发现 SQL 语句正处于行锁定等待。
04
05 RECOMMENDATION 1: Application Analysis, 17% benefit (5131 seconds)
06 ACTION: 在 INDEX "SUNISCO.BIND_PROCESS_LOG_REFNO" (对象 ID 为 369195)
07 中检测到了严重的行争用。使用指定的阻塞 SQL 语句在应用程序逻辑中跟踪行争
08 用的起因。
09 RELEVANT OBJECT: database object with id 369195
10 RATIONALE: SQL_ID 为 "dr4uxu769tmmb" 的 SQL 语句在行锁上被阻塞。
11 RELEVANT OBJECT: SQL statement with SQL_ID dr4uxu769tmmb
12 INSERT INTO EDI_MESSAGE_PROCESS_LOG(LOG_ID, SERVICE_TYPE,
13 SERVICE_STATUS, LOG_DATETIME, REFNO, REF_TYPE, MSG_ID, BL_NO, BL_ID,
14 VOYAGE_ID, VESSEL_NAME, IMO_NO, VOYAGE_NO, FUNCTION_TYPE, INPUT_DATE,
15 IN_STATUS, SYSTEM_TYPE, ERROR_LOG, FILE_NAME) VALUES ( :B1 , :B2 ,
16 :B3 , :B4 , :B5 , :B6 , :B7 , :B8 , :B9 , :B10 , :B11 , :B12 , :B13 ,
17 :B14 , :B15 , :B16 , :B17 , :B18 , :B19 )
18 RATIONALE: SQL_ID 为 "dxsbgubsb6r4n" 的 SQL 语句在行锁上被阻塞。
19 RELEVANT OBJECT: SQL statement with SQL_ID dxsbgubsb6r4n
20 INSERT INTO EDI_MESSAGE_PROCESS_LOG(LOG_ID, SERVICE_TYPE,
21 SERVICE_STATUS, INFO_CODE, INFORMATION, INFO_LEVEL, LOG_DATETIME,
22 REFNO, REF_TYPE, MSG_ID, BL_NO, VOYAGE_ID, VESSEL_NAME, IMO_NO,
23 VOYAGE_NO, FUNCTION_TYPE, INPUT_DATE, IN_STATUS, SYSTEM_TYPE,
24 ERROR_LOG, FILE_NAME) VALUES ( :B1 , :B2 , :B3 , :B4 , :B5 , :B6 ,
25 :B7 , :B8 , :B9 , :B10 , :B11 , :B12 , :B13 , :B14 , :B15 , :B16 ,
26 :B17 , :B18 , :B19 , :B20 , :B21 )
27 RATIONALE: SQL_ID 为 "b38qhyzvn5bdd" 的 SQL 语句在行锁上被阻塞。
28 RELEVANT OBJECT: SQL statement with SQL_ID b38qhyzvn5bdd
29 INSERT INTO EDI_MESSAGE_PROCESS_LOG(LOG_ID, SERVICE_TYPE,
30 SERVICE_STATUS, LOG_DATETIME, REFNO, REF_TYPE, MSG_ID, BL_NO,
31 VOYAGE_ID, VESSEL_NAME, IMO_NO, VOYAGE_NO, FUNCTION_TYPE, INPUT_DATE,
32 IN_STATUS, SYSTEM_TYPE, ERROR_LOG, FILE_NAME) VALUES ( :B1 , :B2 ,
33 :B3 , :B4 , :B5 , :B6 , :B7 , :B8 , :B9 , :B10 , :B11 , :B12 , :B13 ,
34 :B14 , :B15 , :B16 , :B17 , :B18 )
35 RATIONALE: SQL_ID 为 "36k2xpx3c6wr5" 的 SQL 语句在行锁上被阻塞。
36 RELEVANT OBJECT: SQL statement with SQL_ID 36k2xpx3c6wr5
37 INSERT INTO EDI_MESSAGE_PROCESS_LOG(LOG_ID, SERVICE_TYPE,
38 SERVICE_STATUS, REFNO, REF_TYPE, MSG_ID, BL_NO, VOYAGE_ID,
39 VESSEL_NAME, IMO_NO, VOYAGE_NO, FUNCTION_TYPE, INPUT_DATE, IN_STATUS,
40 SYSTEM_TYPE, ERROR_LOG, FILE_NAME) VALUES ( :B1 , :B2 , :B3 , :B4 ,
41 :B5 , :B6 , :B7 , :B8 , :B9 , :B10 , :B11 , :B12 , :B13 , :B14 , :B15
42 , :B16 , :B17 )
43 RATIONALE: 具有 ID "268", 用户 ID "31", 程序 "FC.EdiService.Import.exe" 和
44 模块
45 "FC.EdiService.Import.exe" 的会话是构成此建议案中的优化建议的 51% 的阻
46 塞会话。
47 RATIONALE: 具有 ID "307", 用户 ID "31", 程序 "FC.EdiService.Import.exe" 和
48 模块
49 "FC.EdiService.Import.exe" 的会话是构成此建议案中的优化建议的 11% 的阻
50 塞会话。
51 RATIONALE: 具有 ID "227", 用户 ID "31", 程序 "FC.EdiService.Import.exe" 和
52 模块
53 "FC.EdiService.Import.exe" 的会话是构成此建议案中的优化建议的 11% 的阻
54 塞会话。
55 RATIONALE: 具有 ID "273", 用户 ID "31", 程序 "FC.EdiService.Import.exe" 和
56 模块
57 "FC.EdiService.Import.exe" 的会话是构成此建议案中的优化建议的 9% 的阻塞
58 会话。
10 最后,从本案例中,可以看到在日常的数据库维护中,添加或修改一些对象信息时,务必要经过严格的测试,尤其是在生产系统上做调整更应如此。同样,可以看出,数据库的一些理论基础知识对于DBA还是蛮重要的。
oracle视频教程请关注:http://u.youku.com/user_video/id_UMzAzMjkxMjE2.html