Thanks, Dave.
The sqexplain output was bizarre and I will spare the family the details. As to your explanation of duplicates:
I was beginning to suspect that my issue might have something to do with the fact that one session is often associated with multiple threads. (Try combining a parallel sort with PDQPRIORITY set high!) I don't believe this was the issue. By adding some tx-releated columns to the query, I discovered that one thread i.e. one rstcb structure - can be associated with more than one transaction structure.
What made me look down that path? I finally gave up on finding that mystery other column and added the "unique" to the query. I still got what seemed to be duplicate rows. Almost, that is. They were identical in every column but "log_span". In one case, for example, the log span was 1 but in the next record it was 5. I don't want to see the lower number.
Thus: Here's how I think I have the query right:
drop table if exists temp_sessions;
--unload to /tmp/sessions.pip
select unique
ses.sid,
ses.hostname,
ses.username,
ses.tty,
ses.pid,
( ses.is_wlatch
+ ses.is_wlock
+ ses.is_wbuff
+ ses.is_wckpt
+ ses.is_wlogbuf
+ ses.is_wtrans)::integer in_wait,
(case
when is_incrit > 0 then "in_crit"
else "no_crit"
end) critical,
prof.locksheld::integer locksheld,
prof.pagreads::integer pagreads,
prof.pagwrites::integer pagwrites,
(tx.loguniq - tx.logbeg + 1)::integer log_span,
(select count(*)
from sysrstcb tcb
where tcb.sid = ses.sid)::integer threads,
ses.feprogram
from syssessions ses,
syssesprof prof,
systxptab tx,
sysrstcb tcb
where ses.sid = prof.sid
and prof.sid = tcb.sid
and tcb.address = tx.owner
and hostname is not null
--order by locksheld desc
into temp temp_sessions
;
select * from temp_sessions t1
where log_span = (select max(log_span)
from temp_sessions t2
where t2.sid = t1.sid)
order by locksheld desc
;
That is: Select all the info I want into a temp table, which comes with some excelsior. Then filter it so that I see only the row with the largest log-span for that SID. This takes a few seconds to start spitting out data. But you need a REALLY wide terminal window with a tiny font. As a practical matter you may want to see only the top 50 or so lock-holders.
Thanks for the lead, Dave,
------------------------------
+-----------------------------------------------------------+
| I am pleased to report that I had no problems today. |
| I had only issues, opportunities, challenges and valuable |
| learning experiences. |
+------------------------------------------ Jacob S --------+
------------------------------
Original Message:
Sent: Tue April 14, 2026 06:45 PM
From: David Williams
Subject: Sessions and transactions
Hi Jacob,
Do set explain and get the query plan for your query
NOTE: syssessions is a view on both sysscblst and sysrstcb with the additional filter
bitval(b.flags, '0x80000') = 1; { primary thread } # b is sysrstcb
Whilst sid IS a unique key on sysscblst, it is NOT a unique key on sysrstcb!
[ As syssessions is view which already includes sysrstcb I would fold the view into the query and try again. ]
Just for confirmation:
select count(*) from syssessions where sid=748814 # Should be unique as only 1 sysrstcb should be marked primary
select count(*) from syssesprof where sid=748814 # Also a view on sysrstcb but WITHOUT the filter on primary thread
select count(*) from sysscblst where sid=748814 # Sid IS a unique key here
select count(*) from sysrstcb where sid=748814 # Sid IS NOT unique as without the filter on primary thread
If there is 1 row on the last one:
select address from sysrstcb where sid=748814
Then
select tx.indx,tx.address from systxptab where owner= <prev value> # Sid IS NOT unqiue on this table
Also
select tx.indx,tx.address,tcb.indx,tcb.address from systxptab tx,sysrstcb tcb
where tcb.sid=748814
and tcb.address = tx.owner
with query plan
Regards,
David.
------------------------------
David Williams
Senior Database Platform Engineer
Flutter
London
------------------------------