-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathenqwaits.sql
466 lines (465 loc) · 13 KB
/
enqwaits.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
/**********************************************************************
* File: enqwaits.sql
* Type: SQL*Plus script
* Author: Tim Gorman (Evergreen Database Technologies, Inc.)
* Date: 15jan01
*
* Description:
*
* This report is intended to provide a complete picture of the
* dependencies that ensue when session-based enqueues cause other
* sessions to "wait" (or be "blocked").
*
* Modifications:
* TGorman 15jan01 written
*********************************************************************/
REM
REM If your installation is running Oracle Apps R11+, then leave the following
REM two substitution variables containing blank values.
REM
REM If your database is not running Oracle Apps, then assign the string "/*"
REM (i.e. start comment) to the substitution variable START_ORACLE_APPS_CODE and
REM the string "*/" (i.e. end comment) to the substitution variables
REM END_ORACLE_APPS_CODE.
REM
define START_ORACLE_APPS_CODE=""
define END_ORACLE_APPS_CODE=""
spool enqwaits
set echo on feedback on timing on termout off
create or replace procedure enqwaits
(b_GetRelatedSessions in boolean default FALSE)
is
--
cursor get_sqltext(in_address in raw)
is
select SQL_TEXT
from SYS.V_$SQLTEXT
where ADDRESS = in_address
order by PIECE;
--
cursor get_waiters
is
select SID,
TYPE,
DECODE(TYPE,
'BL','Buffer hash table',
'CF','Control File Transaction',
'CI','Cross Instance Call',
'CS','Control File Schema',
'CU','Bind Enqueue',
'DF','Data File',
'DL','Direct-loader index-creation',
'DM','Mount/startup db primary/secondary instance',
'DR','Distributed Recovery Process',
'DX','Distributed Transaction Entry',
'FI','SGA Open-File Information',
'FS','File Set',
'IN','Instance Number',
'IR','Instance Recovery Serialization',
'IS','Instance State',
'IV','Library Cache InValidation',
'JQ','Job Queue',
'KK','Redo Log "Kick"',
'LS','Log Start/Log Switch',
'MB','Master Buffer hash table',
'MM','Mount Definition',
'MR','Media Recovery',
'PF','Password File',
'PI','Parallel Slaves',
'PR','Process Startup',
'PS','Parallel Slaves Synchronization',
'RE','USE_ROW_ENQUEUE Enforcement',
'RT','Redo Thread',
'RW','Row Wait',
'SC','System Commit Number',
'SH','System Commit Number HWM',
'SM','SMON',
'SQ','Sequence Number',
'SR','Synchronized Replication',
'SS','Sort Segment',
'ST','Space Transaction',
'SV','Sequence Number Value',
'TA','Transaction Recovery',
'TD','DDL enqueue',
'TE','Extend-segment enqueue',
'TM','DML enqueue',
'TS','Temporary Segment',
'TT','Temporary Table',
'TX','Transaction',
'UL','User-defined Lock',
'UN','User Name',
'US','Undo Segment Serialization',
'WL','Being-written redo log instance',
'WS','Write-atomic-log-switch global enqueue',
'XA','Instance Attribute',
'XI','Instance Registration',
decode(substr(TYPE,1,1),
'L','Library Cache ('||substr(TYPE,2,1)||')',
'N','Library Cache Pin ('||substr(TYPE,2,1)||')',
'Q','Row Cache ('||substr(TYPE,2,1)||')',
'????')) LOCK_TYPE,
REQUEST,
DECODE(REQUEST,
0, '',
1, 'Null',
2, 'Sub-Share',
3, 'Sub-Exclusive',
4, 'Share',
5, 'Share/Sub-Excl',
6, 'Exclusive',
'<Unknown>') MODE_REQUESTED,
ID1,
ID2
from SYS.V_$LOCK
where REQUEST > 0
and LMODE = 0;
--
cursor get_blockers(in_type in varchar2,
in_id1 in number,
in_id2 in number,
in_sid in number)
is
select SID,
TYPE,
DECODE(TYPE,
'BL','Buffer hash table',
'CF','Control File Transaction',
'CI','Cross Instance Call',
'CS','Control File Schema',
'CU','Bind Enqueue',
'DF','Data File',
'DL','Direct-loader index-creation',
'DM','Mount/startup db primary/secondary instance',
'DR','Distributed Recovery Process',
'DX','Distributed Transaction Entry',
'FI','SGA Open-File Information',
'FS','File Set',
'IN','Instance Number',
'IR','Instance Recovery Serialization',
'IS','Instance State',
'IV','Library Cache InValidation',
'JQ','Job Queue',
'KK','Redo Log "Kick"',
'LS','Log Start/Log Switch',
'MB','Master Buffer hash table',
'MM','Mount Definition',
'MR','Media Recovery',
'PF','Password File',
'PI','Parallel Slaves',
'PR','Process Startup',
'PS','Parallel Slaves Synchronization',
'RE','USE_ROW_ENQUEUE Enforcement',
'RT','Redo Thread',
'RW','Row Wait',
'SC','System Commit Number',
'SH','System Commit Number HWM',
'SM','SMON',
'SQ','Sequence Number',
'SR','Synchronized Replication',
'SS','Sort Segment',
'ST','Space Transaction',
'SV','Sequence Number Value',
'TA','Transaction Recovery',
'TD','DDL enqueue',
'TE','Extend-segment enqueue',
'TM','DML enqueue',
'TS','Temporary Segment',
'TT','Temporary Table',
'TX','Transaction',
'UL','User-defined Lock',
'UN','User Name',
'US','Undo Segment Serialization',
'WL','Being-written redo log instance',
'WS','Write-atomic-log-switch global enqueue',
'XA','Instance Attribute',
'XI','Instance Registration',
decode(substr(TYPE,1,1),
'L','Library Cache ('||substr(TYPE,2,1)||')',
'N','Library Cache Pin ('||substr(TYPE,2,1)||')',
'Q','Row Cache ('||substr(TYPE,2,1)||')',
'????')) LOCK_TYPE,
LMODE,
DECODE(LMODE,
0, '--Waiting--',
1, 'Null',
2, 'Sub-Share',
3, 'Sub-Exclusive',
4, 'Share',
5, 'Share/Sub-Excl',
6, 'Exclusive',
'<Unknown>') MODE_HELD,
ID1,
ID2
from SYS.V_$LOCK
where TYPE = in_type
and ID1 = in_id1
and ID2 = in_id2
and SID <> in_sid
and LMODE > 0
and REQUEST = 0;
--
cursor get_related_sessions(in_sid in number)
is
select S.SID,
S.SERIAL# SNBR,
S.LOGON_TIME,
S.USERNAME,
S.SQL_ADDRESS,
S.STATUS,
S.OSUSER,
P.SPID,
T.XIDUSN || '.' || T.XIDSLOT || '.' || T.XIDSQN TXN_ID,
T.STATUS TXN_STATUS,
T.START_TIME TXN_START_TIME,
T.USED_UBLK,
T.USED_UREC
from SYS.V_$SESSION S1,
SYS.V_$SESSION S,
SYS.V_$PROCESS P,
SYS.V_$TRANSACTION T
where S1.SID = in_sid
and S.PADDR = S1.PADDR
and P.ADDR = S1.PADDR
and T.ADDR (+) = S1.TADDR
order by decode(S.SID, in_sid, 0, S.SID);
--
cursor get_dml_locks(in_sid in number)
is
select o.OWNER,
o.OBJECT_TYPE type,
o.OBJECT_NAME name,
decode(l.LMODE,
0, 'REQUESTED=' ||
DECODE(l.REQUEST,
0, '--Waiting--',
1, 'Null',
2, 'Sub-Share',
3, 'Sub-Exclusive',
4, 'Share',
5, 'Share/Sub-Excl',
6, 'Exclusive',
'<Unknown>'),
'HELD=' ||
DECODE(l.LMODE,
0, '--Waiting--',
1, 'Null',
2, 'Sub-Share',
3, 'Sub-Exclusive',
4, 'Share',
5, 'Share/Sub-Excl',
6, 'Exclusive',
'<Unknown>')) lmode
from sys.V_$LOCK l,
sys.DBA_OBJECTS o
where l.sid = in_sid
and l.type = 'TM'
and o.object_id = l.id1;
--
v_waiter_username varchar2(30);
v_blocker_username varchar2(30);
v_errcontext varchar2(80);
v_errmsg varchar2(300);
--
begin
--
v_errcontext := 'open/fetch get_waiters';
for w in get_waiters loop
--
dbms_output.put_line('.');
v_errcontext := 'open/fetch get_related_sessions (waiters)';
for rw in get_related_sessions(w.sid) loop
--
if w.sid = rw.sid then
--
v_waiter_username := rw.username;
--
&&START_ORACLE_APPS_CODE
v_errcontext := 'query waiters OraApps user info';
begin
select u.user_name
into v_waiter_username
from apps.fnd_logins l,
apps.fnd_user u
where l.spid = rw.spid
and l.login_name = rw.osuser
and l.end_time is null
and l.start_time =
(select max(ll.start_time)
from apps.fnd_logins ll
where ll.spid = l.spid
and ll.end_time is null)
and u.user_id = l.user_id;
exception
when no_data_found then
v_waiter_username := '';
when too_many_rows then
null;
end;
&&END_ORACLE_APPS_CODE
--
v_errcontext := 'PUT_LINE waiters session/lock info';
dbms_output.put_line(substr('Waiter: SID=' || rw.sid ||
' (' || rw.status || '), Logged on at ' ||
to_char(rw.logon_time,'DD-MON HH24:MI'),1,78));
dbms_output.put_line('....... REQUESTED LOCK|MODE=' ||
w.type || ' (' || w.lock_type ||
') | ' || w.mode_requested ||
' (' || w.id1 || ',' || w.id2 || ')');
dbms_output.put_line('....... AppsUser=' || v_waiter_username);
dbms_output.put_line('....... OS PID=' || rw.spid);
--
else
--
if b_GetRelatedSessions = FALSE then
--
exit; -- ...exit from "get_related_sessions" cursor loop
--
end if;
--
v_errcontext := 'PUT_LINE related waiters session info';
dbms_output.put_line(substr('... Related waiting SID=' ||
rw.sid || ' (' || rw.status ||
'), Logged on at ' ||
to_char(rw.logon_time,'DD-MON HH24:MI'),1,78));
--
end if;
--
dbms_output.put_line('.... TXN ID=' || rw.txn_id ||
' (' || rw.txn_status || ') started=' ||
rw.txn_start_time || ' undo=' || rw.used_ublk || 'b/' ||
rw.used_urec || 'r');
--
v_errcontext := 'open/fetch get_dml_locks (waiters)';
for d in get_dml_locks(rw.sid) loop
--
dbms_output.put_line(substr('....... DML Lock: ' ||
d.owner || '.' || d.name || ' (' || d.type || ') - LOCK ' ||
d.lmode,1,78));
--
v_errcontext := 'fetch/close get_dml_locks (waiters)';
--
end loop; /* end of "get_dml_locks (waiters)" cursor loop */
--
dbms_output.put_line('.... SQL Statement currently executing:');
v_errcontext := 'open/fetch waiters get_sqltext';
for t in get_sqltext(rw.sql_address) loop
--
dbms_output.put_line('....... ' || t.sql_text);
--
v_errcontext := 'fetch/close waiters get_sqltext';
--
end loop; /* end of "get_sqltext" cursor loop */
--
v_errcontext := 'fetch/close get_related_sessions (waiters)';
--
end loop; /* end of "get_related_sessions (waiters)" cursor loop */
--
v_errcontext := 'open/fetch get_blockers';
for b in get_blockers(w.type, w.id1, w.id2, w.sid) loop
--
v_errcontext := 'open/fetch get_related_sessions (blockers)';
for rb in get_related_sessions(b.sid) loop
--
if b.sid = rb.sid then
--
v_blocker_username := rb.username;
--
&&START_ORACLE_APPS_CODE
v_errcontext := 'query blockers OraApps user info';
begin
select u.user_name
into v_blocker_username
from apps.fnd_logins l,
apps.fnd_user u
where l.spid = rb.spid
and l.login_name = rb.osuser
and l.end_time is null
and l.start_time =
(select max(ll.start_time)
from apps.fnd_logins ll
where ll.spid = l.spid
and ll.end_time is null)
and u.user_id = l.user_id;
exception
when no_data_found then
v_blocker_username := '';
when too_many_rows then
null;
end;
&&END_ORACLE_APPS_CODE
--
v_errcontext := 'PUT_LINE blockers session/lock info';
dbms_output.put_line(substr('==>BLOCKER: SID=' || rb.sid ||
',' || rb.snbr ||
' (' || rb.status || '), Logged on at ' ||
to_char(rb.logon_time,'DD-MON HH24:MI'),1,78));
dbms_output.put_line('........... HELD LOCK|MODE=' ||
b.type || ' (' || b.lock_type ||
') | ' || b.mode_held);
dbms_output.put_line('........... AppsUser=' ||
v_blocker_username);
dbms_output.put_line('........... OS PID=' || rb.spid);
--
else
--
if b_GetRelatedSessions = FALSE then
--
exit; -- ...exit from "get_related_sessions" cursor loop
--
end if;
--
v_errcontext := 'PUT_LINE related blockers session info';
dbms_output.put_line(substr('...... Related BLOCKER: SID='
|| rb.sid || ' (' || rb.status ||
'), Logged on at ' ||
to_char(rb.logon_time,'DD-MON HH24:MI'),1,78));
--
end if;
--
dbms_output.put_line('....... TXN ID=' || rb.txn_id ||
' (' || rb.txn_status || ') started=' ||
rb.txn_start_time || ' undo=' || rb.used_ublk || 'b/' ||
rb.used_urec || 'r');
--
v_errcontext := 'open/fetch get_dml_locks (blockers)';
for d in get_dml_locks(rb.sid) loop
--
dbms_output.put_line(substr('........... DML Lock: ' ||
d.owner || '.' || d.name || ' (' || d.type || ') - LOCK ' ||
d.lmode,1,78));
--
v_errcontext := 'fetch/close get_dml_locks (blockers)';
--
end loop; /* end of "get_dml_locks (blockers)" cursor loop */
--
dbms_output.put_line('....... SQL currently executing (not necessarily the blocking SQL):');
v_errcontext := 'open/fetch get_sqltext (blockers)';
for t in get_sqltext(rb.sql_address) loop
--
dbms_output.put_line('........... ' || t.sql_text);
--
v_errcontext := 'fetch/close get_sqltext (blockers)';
--
end loop; /* end of "get_sqltext (blockers)" cursor loop */
--
v_errcontext := 'fetch/close get_related_sessions (blockers)';
--
end loop; /* end of "get_related_sessions (blockers)" cursor loop */
--
v_errcontext := 'fetch/close get_blockers';
--
end loop; /* end of "get_blockers" cursor loop */
--
v_errcontext := 'fetch/close get_waiters';
--
end loop; /* end of "get_waiters" cursor loop */
--
exception
when others then
v_errmsg := substr(sqlerrm, 1, 300);
raise_application_error(-20001, v_errcontext||': '||v_errmsg);
end enqwaits;
/
set termout on
show errors
spool off