On Thu, Dec 17, 2015 at 3:15 AM, Mithun Cy <[email protected]>
wrote:
> I have rebased the patch and tried to run pgbench.
> I see memory corruptions, attaching the valgrind report for the same.
Sorry forgot to add re-based patch, adding the same now.
After some analysis I saw writing to shared memory to store shared snapshot
is not protected under exclusive write lock, this leads to memory
corruptions.
I think until this is fixed measuring the performance will not be much
useful.
--
Thanks and Regards
Mithun C Y
EnterpriseDB: http://www.enterprisedb.com
*** a/src/backend/commands/cluster.c
--- b/src/backend/commands/cluster.c
***************
*** 1559,1564 **** finish_heap_swap(Oid OIDOldHeap, Oid OIDNewHeap,
--- 1559,1565 ----
elog(ERROR, "cache lookup failed for relation %u", OIDOldHeap);
relform = (Form_pg_class) GETSTRUCT(reltup);
+ Assert(TransactionIdIsNormal(frozenXid));
relform->relfrozenxid = frozenXid;
relform->relminmxid = cutoffMulti;
*** a/src/backend/storage/ipc/procarray.c
--- b/src/backend/storage/ipc/procarray.c
***************
*** 410,415 **** ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
--- 410,416 ----
if (LWLockConditionalAcquire(ProcArrayLock, LW_EXCLUSIVE))
{
ProcArrayEndTransactionInternal(proc, pgxact, latestXid);
+ ProcGlobal->cached_snapshot_valid = false;
LWLockRelease(ProcArrayLock);
}
else
***************
*** 558,563 **** ProcArrayGroupClearXid(PGPROC *proc, TransactionId latestXid)
--- 559,566 ----
nextidx = pg_atomic_read_u32(&proc->nextClearXidElem);
}
+ ProcGlobal->cached_snapshot_valid = false;
+
/* We're done with the lock now. */
LWLockRelease(ProcArrayLock);
***************
*** 1543,1548 **** GetSnapshotData(Snapshot snapshot)
--- 1546,1553 ----
errmsg("out of memory")));
}
+ snapshot->takenDuringRecovery = RecoveryInProgress();
+
/*
* It is sufficient to get shared lock on ProcArrayLock, even if we are
* going to set MyPgXact->xmin.
***************
*** 1557,1565 **** GetSnapshotData(Snapshot snapshot)
/* initialize xmin calculation with xmax */
globalxmin = xmin = xmax;
! snapshot->takenDuringRecovery = RecoveryInProgress();
! if (!snapshot->takenDuringRecovery)
{
int *pgprocnos = arrayP->pgprocnos;
int numProcs;
--- 1562,1592 ----
/* initialize xmin calculation with xmax */
globalxmin = xmin = xmax;
! if (!snapshot->takenDuringRecovery && ProcGlobal->cached_snapshot_valid)
! {
! Snapshot csnap = &ProcGlobal->cached_snapshot;
! TransactionId *saved_xip;
! TransactionId *saved_subxip;
! saved_xip = snapshot->xip;
! saved_subxip = snapshot->subxip;
!
! memcpy(snapshot, csnap, sizeof(SnapshotData));
!
! snapshot->xip = saved_xip;
! snapshot->subxip = saved_subxip;
!
! memcpy(snapshot->xip, csnap->xip,
! sizeof(TransactionId) * csnap->xcnt);
! memcpy(snapshot->subxip, csnap->subxip,
! sizeof(TransactionId) * csnap->subxcnt);
! globalxmin = ProcGlobal->cached_snapshot_globalxmin;
! xmin = csnap->xmin;
!
! Assert(TransactionIdIsValid(globalxmin));
! Assert(TransactionIdIsValid(xmin));
! }
! else if (!snapshot->takenDuringRecovery)
{
int *pgprocnos = arrayP->pgprocnos;
int numProcs;
***************
*** 1577,1591 **** GetSnapshotData(Snapshot snapshot)
TransactionId xid;
/*
! * Backend is doing logical decoding which manages xmin
! * separately, check below.
*/
! if (pgxact->vacuumFlags & PROC_IN_LOGICAL_DECODING)
! continue;
!
! /* Ignore procs running LAZY VACUUM */
! if (pgxact->vacuumFlags & PROC_IN_VACUUM)
! continue;
/* Update globalxmin to be the smallest valid xmin */
xid = pgxact->xmin; /* fetch just once */
--- 1604,1615 ----
TransactionId xid;
/*
! * Ignore procs running LAZY VACUUM (which don't need to retain
! * rows) and backends doing logical decoding (which manages xmin
! * separately, check below).
*/
! if (pgxact->vacuumFlags & (PROC_IN_LOGICAL_DECODING | PROC_IN_VACUUM))
! continue;
/* Update globalxmin to be the smallest valid xmin */
xid = pgxact->xmin; /* fetch just once */
***************
*** 1653,1658 **** GetSnapshotData(Snapshot snapshot)
--- 1677,1706 ----
}
}
}
+
+ /* upate cache */
+ {
+ Snapshot csnap = &ProcGlobal->cached_snapshot;
+ TransactionId *saved_xip;
+ TransactionId *saved_subxip;
+
+ ProcGlobal->cached_snapshot_globalxmin = globalxmin;
+
+ saved_xip = csnap->xip;
+ saved_subxip = csnap->subxip;
+ memcpy(csnap, snapshot, sizeof(SnapshotData));
+ csnap->xip = saved_xip;
+ csnap->subxip = saved_subxip;
+
+ /* not yet stored. Yuck */
+ csnap->xmin = xmin;
+
+ memcpy(csnap->xip, snapshot->xip,
+ sizeof(TransactionId) * csnap->xcnt);
+ memcpy(csnap->subxip, snapshot->subxip,
+ sizeof(TransactionId) * csnap->subxcnt);
+ ProcGlobal->cached_snapshot_valid = true;
+ }
}
else
{
*** a/src/backend/storage/lmgr/proc.c
--- b/src/backend/storage/lmgr/proc.c
***************
*** 114,119 **** ProcGlobalShmemSize(void)
--- 114,126 ----
size = add_size(size, mul_size(NUM_AUXILIARY_PROCS, sizeof(PGXACT)));
size = add_size(size, mul_size(max_prepared_xacts, sizeof(PGXACT)));
+ /* for the cached snapshot */
+ #define PROCARRAY_MAXPROCS (MaxBackends + max_prepared_xacts)
+ size = add_size(size, mul_size(sizeof(TransactionId), PROCARRAY_MAXPROCS));
+ #define TOTAL_MAX_CACHED_SUBXIDS \
+ ((PGPROC_MAX_CACHED_SUBXIDS + 1) * PROCARRAY_MAXPROCS)
+ size = add_size(size, mul_size(sizeof(TransactionId), TOTAL_MAX_CACHED_SUBXIDS));
+
return size;
}
***************
*** 275,280 **** InitProcGlobal(void)
--- 282,293 ----
/* Create ProcStructLock spinlock, too */
ProcStructLock = (slock_t *) ShmemAlloc(sizeof(slock_t));
SpinLockInit(ProcStructLock);
+
+ /* cached snapshot */
+ ProcGlobal->cached_snapshot_valid = false;
+ ProcGlobal->cached_snapshot.xip = ShmemAlloc(PROCARRAY_MAXPROCS * sizeof(TransactionId));
+ ProcGlobal->cached_snapshot.subxip = ShmemAlloc(TOTAL_MAX_CACHED_SUBXIDS * sizeof(TransactionId));
+ ProcGlobal->cached_snapshot_globalxmin = InvalidTransactionId;
}
/*
*** a/src/include/storage/proc.h
--- b/src/include/storage/proc.h
***************
*** 16,21 ****
--- 16,22 ----
#include "access/xlogdefs.h"
#include "lib/ilist.h"
+ #include "utils/snapshot.h"
#include "storage/latch.h"
#include "storage/lock.h"
#include "storage/pg_sema.h"
***************
*** 220,225 **** typedef struct PROC_HDR
--- 221,231 ----
int startupProcPid;
/* Buffer id of the buffer that Startup process waits for pin on, or -1 */
int startupBufferPinWaitBufId;
+
+ /* Cached snapshot */
+ bool cached_snapshot_valid;
+ SnapshotData cached_snapshot;
+ TransactionId cached_snapshot_globalxmin;
} PROC_HDR;
extern PROC_HDR *ProcGlobal;
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers