tqual_xid_cache_v3_1.patch

application/octet-stream

Filename: tqual_xid_cache_v3_1.patch
Type: application/octet-stream
Part: 0
Message: Re: WIP patch for hint bit i/o mitigation

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: context
Series: patch v3
File+
tqual.c 50 13
*** tqual--unchanged.c	2012-09-20 03:17:58.000000000 +0530
--- tqual.c	2012-11-14 23:27:30.470499857 +0530
***************
*** 75,80 ****
--- 75,88 ----
  /* local functions */
  static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
  
+ /*
+  * Single-item cache for results of clog visibility check.  It's worth having
+  * such a cache to help reduce the amount of hint bit traffic when
+  * many sequentially touched tuples have the same XID.
+  */
+ static TransactionId 	cachedVisibilityXid;  
+ /* Visibility status cache stores the commit status of the XID in cachedVisibilityXid */
+ static uint16 		cachedVisibilityXidStatus;  
  
  /*
   * SetHintBits()
***************
*** 117,122 ****
--- 125,133 ----
  
  		if (XLogNeedsFlush(commitLSN) && BufferIsPermanent(buffer))
  			return;				/* not flushed yet, so don't set hint */
+ 
+ 		cachedVisibilityXid = xid;
+ 		cachedVisibilityXidStatus = infomask;
  	}
  
  	tuple->t_infomask |= infomask;
***************
*** 164,170 ****
  bool
  HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
--- 175,183 ----
  bool
  HeapTupleSatisfiesSelf(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmin(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
***************
*** 247,253 ****
  	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */
  		return true;
  
! 	if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
  	{
  		if (tuple->t_infomask & HEAP_IS_LOCKED)
  			return true;
--- 260,268 ----
  	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */
  		return true;
  
! 	if ((tuple->t_infomask & HEAP_XMAX_COMMITTED)
! 		|| (cachedVisibilityXid == HeapTupleHeaderGetXmax(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMAX_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_IS_LOCKED)
  			return true;
***************
*** 327,333 ****
  bool
  HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
--- 342,350 ----
  bool
  HeapTupleSatisfiesNow(HeapTupleHeader tuple, Snapshot snapshot, Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmin(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
***************
*** 416,422 ****
  	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */
  		return true;
  
! 	if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
  	{
  		if (tuple->t_infomask & HEAP_IS_LOCKED)
  			return true;
--- 433,441 ----
  	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */
  		return true;
  
! 	if ((tuple->t_infomask & HEAP_XMAX_COMMITTED)
! 		|| (cachedVisibilityXid == HeapTupleHeaderGetXmax(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMAX_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_IS_LOCKED)
  			return true;
***************
*** 493,499 ****
  HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
  						Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
--- 512,520 ----
  HeapTupleSatisfiesToast(HeapTupleHeader tuple, Snapshot snapshot,
  						Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmin(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
***************
*** 574,580 ****
  HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
  						 Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return HeapTupleInvisible;
--- 595,603 ----
  HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
  						 Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmin(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return HeapTupleInvisible;
***************
*** 663,669 ****
  	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */
  		return HeapTupleMayBeUpdated;
  
! 	if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
  	{
  		if (tuple->t_infomask & HEAP_IS_LOCKED)
  			return HeapTupleMayBeUpdated;
--- 686,694 ----
  	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */
  		return HeapTupleMayBeUpdated;
  
! 	if ((tuple->t_infomask & HEAP_XMAX_COMMITTED)
! 		|| (cachedVisibilityXid == HeapTupleHeaderGetXmax(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMAX_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_IS_LOCKED)
  			return HeapTupleMayBeUpdated;
***************
*** 743,749 ****
  {
  	snapshot->xmin = snapshot->xmax = InvalidTransactionId;
  
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
--- 768,776 ----
  {
  	snapshot->xmin = snapshot->xmax = InvalidTransactionId;
  
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmin(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
***************
*** 830,836 ****
  	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */
  		return true;
  
! 	if (tuple->t_infomask & HEAP_XMAX_COMMITTED)
  	{
  		if (tuple->t_infomask & HEAP_IS_LOCKED)
  			return true;
--- 857,865 ----
  	if (tuple->t_infomask & HEAP_XMAX_INVALID)	/* xid invalid or aborted */
  		return true;
  
! 	if ((tuple->t_infomask & HEAP_XMAX_COMMITTED)
! 		|| (cachedVisibilityXid == HeapTupleHeaderGetXmax(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMAX_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_IS_LOCKED)
  			return true;
***************
*** 904,910 ****
  HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
  					   Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
--- 933,941 ----
  HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
  					   Buffer buffer)
  {
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmin(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMIN_COMMITTED))
  	{
  		if (tuple->t_infomask & HEAP_XMIN_INVALID)
  			return false;
***************
*** 1008,1014 ****
  		return true;
  	}
  
! 	if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
  	{
  		if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))
  		{
--- 1039,1047 ----
  		return true;
  	}
  
! 	if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmax(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMAX_COMMITTED))
  	{
  		if (TransactionIdIsCurrentTransactionId(HeapTupleHeaderGetXmax(tuple)))
  		{
***************
*** 1240,1246 ****
  	 * invalid, then we assume it's still alive (since the presumption is that
  	 * all relevant hint bits were just set moments ago).
  	 */
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED))
  		return (tuple->t_infomask & HEAP_XMIN_INVALID) != 0 ? true : false;
  
  	/*
--- 1273,1281 ----
  	 * invalid, then we assume it's still alive (since the presumption is that
  	 * all relevant hint bits were just set moments ago).
  	 */
! 	if (!(tuple->t_infomask & HEAP_XMIN_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmin(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMIN_COMMITTED))
  		return (tuple->t_infomask & HEAP_XMIN_INVALID) != 0 ? true : false;
  
  	/*
***************
*** 1253,1259 ****
  		return false;
  
  	/* If deleter isn't known to have committed, assume it's still running. */
! 	if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED))
  		return false;
  
  	/* Deleter committed, so tuple is dead if the XID is old enough. */
--- 1288,1296 ----
  		return false;
  
  	/* If deleter isn't known to have committed, assume it's still running. */
! 	if (!(tuple->t_infomask & HEAP_XMAX_COMMITTED)
! 		&& !(cachedVisibilityXid == HeapTupleHeaderGetXmax(tuple) 
! 		&& cachedVisibilityXidStatus == HEAP_XMAX_COMMITTED))
  		return false;
  
  	/* Deleter committed, so tuple is dead if the XID is old enough. */