From 5f765a8e4c240bf628c168e25d8805c6770554cb Mon Sep 17 00:00:00 2001 From: Asim R P Date: Tue, 15 Sep 2020 13:26:59 +0530 Subject: [PATCH] Do not read a persistent tuple after it is freed This bug was found in a production environment where vacuum on gp_persistent_relation was concurrently running with a backend performing end-of-xact filesystem operations. And the GUC debug_persistent_print was enabled. The *_ReadTuple() function was called on a persistent TID after the corresponding tuple was deleted with frozen transaction ID. The concurrent vacuum recycled the tuple and it led to a SIGSEGV when the backend tried to access values from the tuple. Fix it by avoiding the debug log message in case when the persistent tuple is freed (transitioning to FREE state). All other state transitions are logged. In absence of concurrent vacuum, things worked just fine because the *_ReadTuple() interface reads tuples from persistent tables directly using TID. --- src/backend/cdb/cdbpersistentfilesysobj.c | 37 +++++++++++------------ 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/src/backend/cdb/cdbpersistentfilesysobj.c b/src/backend/cdb/cdbpersistentfilesysobj.c index 291c4094b7..850707f1f7 100755 --- a/src/backend/cdb/cdbpersistentfilesysobj.c +++ b/src/backend/cdb/cdbpersistentfilesysobj.c @@ -1567,11 +1567,26 @@ PersistentFileSysObjStateChangeResult PersistentFileSysObj_StateChange( pfree(newValues); pfree(replaces); + + if (Debug_persistent_print) + { + heap_freetuple(tupleCopy); + + PersistentFileSysObj_ReadTuple( + fsObjType, + persistentTid, + values, + &tupleCopy); + + (*fileSysObjData->storeData.printTupleCallback)( + Persistent_DebugPrintLevel(), + "STATE CHANGE", + persistentTid, + values); + } } else { - heap_freetuple(tupleCopy); - PersistentFileSysObj_FreeTuple( fileSysObjData, fileSysObjSharedData, @@ -1580,23 +1595,7 @@ PersistentFileSysObjStateChangeResult PersistentFileSysObj_StateChange( flushToXLog); } - if (Debug_persistent_print) - { - PersistentFileSysObj_ReadTuple( - fsObjType, - persistentTid, - values, - &tupleCopy); - - (*fileSysObjData->storeData.printTupleCallback)( - Persistent_DebugPrintLevel(), - "STATE CHANGE", - persistentTid, - values); - - heap_freetuple(tupleCopy); - } - + heap_freetuple(tupleCopy); pfree(values); return PersistentFileSysObjStateChangeResult_StateChangeOk; -- GitLab