Note: The queries or commands below might produce a misleading message. When the query is run, this query might be in the dispatch phase and not all segments have started the transaction. Therefore, it's always a good idea to run the query again after two minutes ensure if the process remains the same or changed.
1. The query below might not help if the orphan process is on the master server itself. In other words, the query is still running on the master but no connection on segments. Ignore the process that is IDLE.
2. The script below uses the connections on master as a reference. In case the connection exists between the master and a few segments but not the rest, the script below might not report it.
source /usr/local/greenplum-db/greenplum_path.sh ; ORPHAN="ps auwxx|grep postgres|grep con[0-9]|`echo "egrep -v \\\"wal|con0|gpsyncagent"`|`psql -R '|' -d template1 -Atc "select 'con'||sess_id::text from pg_stat_activity"`\""; gpssh `psql -R' ' -d template1 -Atc " select distinct '-h ' || hostname from gp_segment_configuration "` $ORPHAN
Note: This works if the process is holding any lock on the table and its detected by pg_locks.
From the report below, total segments should be equal to total sessions. If this is not the case, then the session is orphan or missing one or more segments.
Greenplum 5x:
select 'con'|| a.mppsessionid AS "Session ID", b.total_seg as "Total Segments", count(a.*) AS "Total Sessions" from (select distinct mppsessionid,gp_segment_id from pg_locks where mppsessionid not in (select sess_id from pg_stat_activity where procpid!=pg_backend_pid() OR current_query!='<IDLE>' OR waiting='t') and mppsessionid != 0 ) a, (select count(*) as total_seg from gp_segment_configuration where role='p' ) b group by 1,2 having count(a.*) < b.total_seg order by 3;
Greenplum 6x:
select 'con'|| a.mppsessionid AS "Session ID", b.total_seg as "Total Segments", count(a.*) AS "Total Sessions" from (select distinct mppsessionid,gp_segment_id from pg_locks where mppsessionid not in (select sess_id from pg_stat_activity where pid!=pg_backend_pid() OR query!='<IDLE>' OR waiting='t') and mppsessionid != 0 ) a, (select count(*) as total_seg from gp_segment_configuration where role='p' ) b group by 1,2 having count(a.*) < b.total_seg order by 3;
After running the query below, note the Blockers SessionID and match it with the content <sessionID> in the query above. If it's the same then this orphan process is blocking other running queries.
Greenplum 5x + 6x:
SELECT w.relation::regclass AS "Table", w.mode AS "Waiters Mode", w.pid AS "Waiters PID", w.mppsessionid AS "Waiters SessionID", b.mode AS "Blockers Mode", b.pid AS "Blockers PID", b.mppsessionid AS "Blockers SessionID", (select 'Hostname: ' || c.hostname ||' Content: '|| c.content || ' Port: ' || port from gp_segment_configuration c where c.content=b.gp_segment_id and role='p') AS "Blocking Segment" FROM pg_catalog.pg_locks AS w, pg_catalog.pg_locks AS b Where ((w."database" = b."database" AND w.relation = b.relation) OR w.transactionid = b.transactionid) AND w.granted='f' AND b.granted='t' AND w.mppsessionid <> b.mppsessionid AND w.mppsessionid in (SELECT l.mppsessionid FROM pg_locks l WHERE l.granted = true AND relation in ( select relation from pg_locks where granted='f')) AND w.gp_segment_id = b.gp_segment_id ORDER BY 1;
For more information on the database locks, refer to the scripts discussed How to check for orphan connections in Tanzu Greenplum.
For few more scripts to check the orphan process, refer to Scripts for identifying locking session information in the database in Tanzu Greenplum.