@ -211,7 +211,7 @@
# include "utils/snapmgr.h"
/* Uncomment the next line to test the graceful degradation code. */
/* #define TEST_OLDSERXID */
/* #define TEST_SUMMARIZE_SERIAL */
/*
* Test the most selective fields first , for performance .
@ -316,37 +316,37 @@
/*
* The SLRU buffer area through which we access the old xids .
*/
static SlruCtlData OldSerXid SlruCtlData;
static SlruCtlData Serial SlruCtlData;
# define OldSerXidSlruCtl (&OldSerXid SlruCtlData)
# define SerialSlruCtl (&Serial SlruCtlData)
# define OLDSERXID _PAGESIZE BLCKSZ
# define OLDSERXID _ENTRYSIZE sizeof(SerCommitSeqNo)
# define OLDSERXID_ENTRIESPERPAGE (OLDSERXID_PAGESIZE / OLDSERXID _ENTRYSIZE)
# define SERIAL _PAGESIZE BLCKSZ
# define SERIAL _ENTRYSIZE sizeof(SerCommitSeqNo)
# define SERIAL_ENTRIESPERPAGE (SERIAL_PAGESIZE / SERIAL _ENTRYSIZE)
/*
* Set maximum pages based on the number needed to track all transactions .
*/
# define OLDSERXID_MAX_PAGE (MaxTransactionId / OLDSERXID _ENTRIESPERPAGE)
# define SERIAL_MAX_PAGE (MaxTransactionId / SERIAL _ENTRIESPERPAGE)
# define OldSerXidNextPage(page) (((page) >= OLDSERXID _MAX_PAGE) ? 0 : (page) + 1)
# define SerialNextPage(page) (((page) >= SERIAL _MAX_PAGE) ? 0 : (page) + 1)
# define OldSerXid Value(slotno, xid) (*((SerCommitSeqNo *) \
( OldSerXid SlruCtl- > shared - > page_buffer [ slotno ] + \
( ( ( ( uint32 ) ( xid ) ) % OLDSERXID_ENTRIESPERPAGE ) * OLDSERXID _ENTRYSIZE) ) ) )
# define Serial Value(slotno, xid) (*((SerCommitSeqNo *) \
( Serial SlruCtl- > shared - > page_buffer [ slotno ] + \
( ( ( ( uint32 ) ( xid ) ) % SERIAL_ENTRIESPERPAGE ) * SERIAL _ENTRYSIZE) ) ) )
# define OldSerXidPage(xid) (((uint32) (xid)) / OLDSERXID _ENTRIESPERPAGE)
# define SerialPage(xid) (((uint32) (xid)) / SERIAL _ENTRIESPERPAGE)
typedef struct OldSerXid ControlData
typedef struct Serial ControlData
{
int headPage ; /* newest initialized page */
TransactionId headXid ; /* newest valid Xid in the SLRU */
TransactionId tailXid ; /* oldest xmin we might be interested in */
} OldSerXid ControlData;
} Serial ControlData;
typedef struct OldSerXidControlData * OldSerXid Control;
typedef struct SerialControlData * Serial Control;
static OldSerXidControl oldSerXid Control;
static SerialControl serial Control;
/*
* When the oldest committed transaction on the " finished " list is moved to
@ -438,11 +438,11 @@ static void SetPossibleUnsafeConflict(SERIALIZABLEXACT *roXact, SERIALIZABLEXACT
static void ReleaseRWConflict ( RWConflict conflict ) ;
static void FlagSxactUnsafe ( SERIALIZABLEXACT * sxact ) ;
static bool OldSerXid PagePrecedesLogically( int p , int q ) ;
static void OldSerXid Init( void ) ;
static void OldSerXid Add( TransactionId xid , SerCommitSeqNo minConflictCommitSeqNo ) ;
static SerCommitSeqNo OldSerXid GetMinConflictCommitSeqNo( TransactionId xid ) ;
static void OldSerXid SetActiveSerXmin( TransactionId xid ) ;
static bool Serial PagePrecedesLogically( int p , int q ) ;
static void Serial Init( void ) ;
static void Serial Add( TransactionId xid , SerCommitSeqNo minConflictCommitSeqNo ) ;
static SerCommitSeqNo Serial GetMinConflictCommitSeqNo( TransactionId xid ) ;
static void Serial SetActiveSerXmin( TransactionId xid ) ;
static uint32 predicatelock_hash ( const void * key , Size keysize ) ;
static void SummarizeOldestCommittedSxact ( void ) ;
@ -784,26 +784,26 @@ FlagSxactUnsafe(SERIALIZABLEXACT *sxact)
/*------------------------------------------------------------------------*/
/*
* We will work on the page range of 0. . OLDSERXID _MAX_PAGE.
* We will work on the page range of 0. . SERIAL _MAX_PAGE.
* Compares using wraparound logic , as is required by slru . c .
*/
static bool
OldSerXid PagePrecedesLogically( int p , int q )
Serial PagePrecedesLogically( int p , int q )
{
int diff ;
/*
* We have to compare modulo ( OLDSERXID _MAX_PAGE+ 1 ) / 2. Both inputs should
* be in the range 0. . OLDSERXID _MAX_PAGE.
* We have to compare modulo ( SERIAL _MAX_PAGE+ 1 ) / 2. Both inputs should be
* in the range 0. . SERIAL _MAX_PAGE.
*/
Assert ( p > = 0 & & p < = OLDSERXID _MAX_PAGE) ;
Assert ( q > = 0 & & q < = OLDSERXID _MAX_PAGE) ;
Assert ( p > = 0 & & p < = SERIAL _MAX_PAGE) ;
Assert ( q > = 0 & & q < = SERIAL _MAX_PAGE) ;
diff = p - q ;
if ( diff > = ( ( OLDSERXID _MAX_PAGE + 1 ) / 2 ) )
diff - = OLDSERXID _MAX_PAGE + 1 ;
else if ( diff < - ( ( int ) ( OLDSERXID _MAX_PAGE + 1 ) / 2 ) )
diff + = OLDSERXID _MAX_PAGE + 1 ;
if ( diff > = ( ( SERIAL _MAX_PAGE + 1 ) / 2 ) )
diff - = SERIAL _MAX_PAGE + 1 ;
else if ( diff < - ( ( int ) ( SERIAL _MAX_PAGE + 1 ) / 2 ) )
diff + = SERIAL _MAX_PAGE + 1 ;
return diff < 0 ;
}
@ -811,25 +811,25 @@ OldSerXidPagePrecedesLogically(int p, int q)
* Initialize for the tracking of old serializable committed xids .
*/
static void
OldSerXid Init( void )
Serial Init( void )
{
bool found ;
/*
* Set up SLRU management of the pg_serial data .
*/
OldSerXid SlruCtl- > PagePrecedes = OldSerXid PagePrecedesLogically;
SimpleLruInit ( OldSerXid SlruCtl, " oldserxid " ,
NUM_OLDSERXID _BUFFERS , 0 , OldSerXid Lock, " pg_serial " ,
LWTRANCHE_OLDSERXID_BUFFERS ) ;
Serial SlruCtl- > PagePrecedes = Serial PagePrecedesLogically;
SimpleLruInit ( Serial SlruCtl, " Serial " ,
NUM_SERIAL _BUFFERS , 0 , SerialSLRU Lock, " pg_serial " ,
LWTRANCHE_SERIAL_BUFFER ) ;
/* Override default assumption that writes should be fsync'd */
OldSerXid SlruCtl- > do_fsync = false ;
Serial SlruCtl- > do_fsync = false ;
/*
* Create or attach to the OldSerXid Control structure .
* Create or attach to the Serial Control structure .
*/
oldSerXidControl = ( OldSerXid Control)
ShmemInitStruct ( " OldSerXid ControlData" , sizeof ( OldSerXid ControlData) , & found ) ;
serialControl = ( Serial Control)
ShmemInitStruct ( " Serial ControlData" , sizeof ( Serial ControlData) , & found ) ;
Assert ( found = = IsUnderPostmaster ) ;
if ( ! found )
@ -837,9 +837,9 @@ OldSerXidInit(void)
/*
* Set control information to reflect empty SLRU .
*/
oldSerXid Control- > headPage = - 1 ;
oldSerXid Control- > headXid = InvalidTransactionId ;
oldSerXid Control- > tailXid = InvalidTransactionId ;
serial Control- > headPage = - 1 ;
serial Control- > headXid = InvalidTransactionId ;
serial Control- > tailXid = InvalidTransactionId ;
}
}
@ -849,7 +849,7 @@ OldSerXidInit(void)
* An invalid commitSeqNo means that there were no conflicts out from xid .
*/
static void
OldSerXid Add( TransactionId xid , SerCommitSeqNo minConflictCommitSeqNo )
Serial Add( TransactionId xid , SerCommitSeqNo minConflictCommitSeqNo )
{
TransactionId tailXid ;
int targetPage ;
@ -859,16 +859,16 @@ OldSerXidAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
Assert ( TransactionIdIsValid ( xid ) ) ;
targetPage = OldSerXid Page( xid ) ;
targetPage = Serial Page( xid ) ;
LWLockAcquire ( OldSerXid Lock, LW_EXCLUSIVE ) ;
LWLockAcquire ( SerialSLRU Lock, LW_EXCLUSIVE ) ;
/*
* If no serializable transactions are active , there shouldn ' t be anything
* to push out to the SLRU . Hitting this assert would mean there ' s
* something wrong with the earlier cleanup logic .
*/
tailXid = oldSerXid Control- > tailXid ;
tailXid = serial Control- > tailXid ;
Assert ( TransactionIdIsValid ( tailXid ) ) ;
/*
@ -877,41 +877,41 @@ OldSerXidAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
* any new pages that enter the tailXid - headXid range as we advance
* headXid .
*/
if ( oldSerXid Control- > headPage < 0 )
if ( serial Control- > headPage < 0 )
{
firstZeroPage = OldSerXid Page( tailXid ) ;
firstZeroPage = Serial Page( tailXid ) ;
isNewPage = true ;
}
else
{
firstZeroPage = OldSerXidNextPage ( oldSerXid Control- > headPage ) ;
isNewPage = OldSerXidPagePrecedesLogically ( oldSerXid Control- > headPage ,
targetPage ) ;
firstZeroPage = SerialNextPage ( serial Control- > headPage ) ;
isNewPage = SerialPagePrecedesLogically ( serial Control- > headPage ,
targetPage ) ;
}
if ( ! TransactionIdIsValid ( oldSerXid Control- > headXid )
| | TransactionIdFollows ( xid , oldSerXid Control- > headXid ) )
oldSerXid Control- > headXid = xid ;
if ( ! TransactionIdIsValid ( serial Control- > headXid )
| | TransactionIdFollows ( xid , serial Control- > headXid ) )
serial Control- > headXid = xid ;
if ( isNewPage )
oldSerXid Control- > headPage = targetPage ;
serial Control- > headPage = targetPage ;
if ( isNewPage )
{
/* Initialize intervening pages. */
while ( firstZeroPage ! = targetPage )
{
( void ) SimpleLruZeroPage ( OldSerXid SlruCtl, firstZeroPage ) ;
firstZeroPage = OldSerXid NextPage( firstZeroPage ) ;
( void ) SimpleLruZeroPage ( Serial SlruCtl, firstZeroPage ) ;
firstZeroPage = Serial NextPage( firstZeroPage ) ;
}
slotno = SimpleLruZeroPage ( OldSerXid SlruCtl, targetPage ) ;
slotno = SimpleLruZeroPage ( Serial SlruCtl, targetPage ) ;
}
else
slotno = SimpleLruReadPage ( OldSerXid SlruCtl, targetPage , true , xid ) ;
slotno = SimpleLruReadPage ( Serial SlruCtl, targetPage , true , xid ) ;
OldSerXid Value( slotno , xid ) = minConflictCommitSeqNo ;
OldSerXid SlruCtl- > shared - > page_dirty [ slotno ] = true ;
Serial Value( slotno , xid ) = minConflictCommitSeqNo ;
Serial SlruCtl- > shared - > page_dirty [ slotno ] = true ;
LWLockRelease ( OldSerXid Lock) ;
LWLockRelease ( SerialSLRU Lock) ;
}
/*
@ -920,7 +920,7 @@ OldSerXidAdd(TransactionId xid, SerCommitSeqNo minConflictCommitSeqNo)
* will be returned .
*/
static SerCommitSeqNo
OldSerXid GetMinConflictCommitSeqNo( TransactionId xid )
Serial GetMinConflictCommitSeqNo( TransactionId xid )
{
TransactionId headXid ;
TransactionId tailXid ;
@ -929,10 +929,10 @@ OldSerXidGetMinConflictCommitSeqNo(TransactionId xid)
Assert ( TransactionIdIsValid ( xid ) ) ;
LWLockAcquire ( OldSerXid Lock, LW_SHARED ) ;
headXid = oldSerXid Control- > headXid ;
tailXid = oldSerXid Control- > tailXid ;
LWLockRelease ( OldSerXid Lock) ;
LWLockAcquire ( SerialSLRU Lock, LW_SHARED ) ;
headXid = serial Control- > headXid ;
tailXid = serial Control- > tailXid ;
LWLockRelease ( SerialSLRU Lock) ;
if ( ! TransactionIdIsValid ( headXid ) )
return 0 ;
@ -944,13 +944,13 @@ OldSerXidGetMinConflictCommitSeqNo(TransactionId xid)
return 0 ;
/*
* The following function must be called without holding OldSerXid Lock,
* The following function must be called without holding SerialSLRU Lock,
* but will return with that lock held , which must then be released .
*/
slotno = SimpleLruReadPage_ReadOnly ( OldSerXid SlruCtl,
OldSerXid Page( xid ) , xid ) ;
val = OldSerXid Value( slotno , xid ) ;
LWLockRelease ( OldSerXid Lock) ;
slotno = SimpleLruReadPage_ReadOnly ( Serial SlruCtl,
Serial Page( xid ) , xid ) ;
val = Serial Value( slotno , xid ) ;
LWLockRelease ( SerialSLRU Lock) ;
return val ;
}
@ -961,9 +961,9 @@ OldSerXidGetMinConflictCommitSeqNo(TransactionId xid)
* the SLRU can be discarded .
*/
static void
OldSerXid SetActiveSerXmin( TransactionId xid )
Serial SetActiveSerXmin( TransactionId xid )
{
LWLockAcquire ( OldSerXid Lock, LW_EXCLUSIVE ) ;
LWLockAcquire ( SerialSLRU Lock, LW_EXCLUSIVE ) ;
/*
* When no sxacts are active , nothing overlaps , set the xid values to
@ -973,9 +973,9 @@ OldSerXidSetActiveSerXmin(TransactionId xid)
*/
if ( ! TransactionIdIsValid ( xid ) )
{
oldSerXid Control- > tailXid = InvalidTransactionId ;
oldSerXid Control- > headXid = InvalidTransactionId ;
LWLockRelease ( OldSerXid Lock) ;
serial Control- > tailXid = InvalidTransactionId ;
serial Control- > headXid = InvalidTransactionId ;
LWLockRelease ( SerialSLRU Lock) ;
return ;
}
@ -987,22 +987,22 @@ OldSerXidSetActiveSerXmin(TransactionId xid)
*/
if ( RecoveryInProgress ( ) )
{
Assert ( oldSerXid Control- > headPage < 0 ) ;
if ( ! TransactionIdIsValid ( oldSerXid Control- > tailXid )
| | TransactionIdPrecedes ( xid , oldSerXid Control- > tailXid ) )
Assert ( serial Control- > headPage < 0 ) ;
if ( ! TransactionIdIsValid ( serial Control- > tailXid )
| | TransactionIdPrecedes ( xid , serial Control- > tailXid ) )
{
oldSerXid Control- > tailXid = xid ;
serial Control- > tailXid = xid ;
}
LWLockRelease ( OldSerXid Lock) ;
LWLockRelease ( SerialSLRU Lock) ;
return ;
}
Assert ( ! TransactionIdIsValid ( oldSerXid Control- > tailXid )
| | TransactionIdFollows ( xid , oldSerXid Control- > tailXid ) ) ;
Assert ( ! TransactionIdIsValid ( serial Control- > tailXid )
| | TransactionIdFollows ( xid , serial Control- > tailXid ) ) ;
oldSerXid Control- > tailXid = xid ;
serial Control- > tailXid = xid ;
LWLockRelease ( OldSerXid Lock) ;
LWLockRelease ( SerialSLRU Lock) ;
}
/*
@ -1016,19 +1016,19 @@ CheckPointPredicate(void)
{
int tailPage ;
LWLockAcquire ( OldSerXid Lock, LW_EXCLUSIVE ) ;
LWLockAcquire ( SerialSLRU Lock, LW_EXCLUSIVE ) ;
/* Exit quickly if the SLRU is currently not in use. */
if ( oldSerXid Control- > headPage < 0 )
if ( serial Control- > headPage < 0 )
{
LWLockRelease ( OldSerXid Lock) ;
LWLockRelease ( SerialSLRU Lock) ;
return ;
}
if ( TransactionIdIsValid ( oldSerXid Control- > tailXid ) )
if ( TransactionIdIsValid ( serial Control- > tailXid ) )
{
/* We can truncate the SLRU up to the page containing tailXid */
tailPage = OldSerXidPage ( oldSerXid Control- > tailXid ) ;
tailPage = SerialPage ( serial Control- > tailXid ) ;
}
else
{
@ -1042,14 +1042,14 @@ CheckPointPredicate(void)
* won ' t be removed until XID horizon advances enough to make it
* current again .
*/
tailPage = oldSerXid Control- > headPage ;
oldSerXid Control- > headPage = - 1 ;
tailPage = serial Control- > headPage ;
serial Control- > headPage = - 1 ;
}
LWLockRelease ( OldSerXid Lock) ;
LWLockRelease ( SerialSLRU Lock) ;
/* Truncate away pages that are no longer required */
SimpleLruTruncate ( OldSerXid SlruCtl, tailPage ) ;
SimpleLruTruncate ( Serial SlruCtl, tailPage ) ;
/*
* Flush dirty SLRU pages to disk
@ -1061,7 +1061,7 @@ CheckPointPredicate(void)
* before deleting the file in which they sit , which would be completely
* pointless .
*/
SimpleLruFlush ( OldSerXid SlruCtl, true ) ;
SimpleLruFlush ( Serial SlruCtl, true ) ;
}
/*------------------------------------------------------------------------*/
@ -1275,7 +1275,7 @@ InitPredicateLocks(void)
* Initialize the SLRU storage for old committed serializable
* transactions .
*/
OldSerXid Init( ) ;
Serial Init( ) ;
}
/*
@ -1324,8 +1324,8 @@ PredicateLockShmemSize(void)
size = add_size ( size , sizeof ( SHM_QUEUE ) ) ;
/* Shared memory structures for SLRU tracking of old committed xids. */
size = add_size ( size , sizeof ( OldSerXid ControlData) ) ;
size = add_size ( size , SimpleLruShmemSize ( NUM_OLDSERXID _BUFFERS , 0 ) ) ;
size = add_size ( size , sizeof ( Serial ControlData) ) ;
size = add_size ( size , SimpleLruShmemSize ( NUM_SERIAL _BUFFERS , 0 ) ) ;
return size ;
}
@ -1462,8 +1462,8 @@ SummarizeOldestCommittedSxact(void)
/* Add to SLRU summary information. */
if ( TransactionIdIsValid ( sxact - > topXid ) & & ! SxactIsReadOnly ( sxact ) )
OldSerXid Add( sxact - > topXid , SxactHasConflictOut ( sxact )
? sxact - > SeqNo . earliestOutConflictCommit : InvalidSerCommitSeqNo ) ;
Serial Add( sxact - > topXid , SxactHasConflictOut ( sxact )
? sxact - > SeqNo . earliestOutConflictCommit : InvalidSerCommitSeqNo ) ;
/* Summarize and release the detail. */
ReleaseOneSerializableXact ( sxact , false , true ) ;
@ -1727,7 +1727,7 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
* ( in particular , an elog ( ERROR ) in procarray . c would cause us to leak
* the sxact ) . Consider refactoring to avoid this .
*/
# ifdef TEST_OLDSERXID
# ifdef TEST_SUMMARIZE_SERIAL
SummarizeOldestCommittedSxact ( ) ;
# endif
LWLockAcquire ( SerializableXactHashLock , LW_EXCLUSIVE ) ;
@ -1782,7 +1782,7 @@ GetSerializableTransactionSnapshotInt(Snapshot snapshot,
Assert ( PredXact - > SxactGlobalXminCount = = 0 ) ;
PredXact - > SxactGlobalXmin = snapshot - > xmin ;
PredXact - > SxactGlobalXminCount = 1 ;
OldSerXid SetActiveSerXmin( snapshot - > xmin ) ;
Serial SetActiveSerXmin( snapshot - > xmin ) ;
}
else if ( TransactionIdEquals ( snapshot - > xmin , PredXact - > SxactGlobalXmin ) )
{
@ -3231,7 +3231,7 @@ SetNewSxactGlobalXmin(void)
}
}
OldSerXid SetActiveSerXmin( PredXact - > SxactGlobalXmin ) ;
Serial SetActiveSerXmin( PredXact - > SxactGlobalXmin ) ;
}
/*
@ -4084,7 +4084,7 @@ CheckForSerializableConflictOut(Relation relation, TransactionId xid, Snapshot s
*/
SerCommitSeqNo conflictCommitSeqNo ;
conflictCommitSeqNo = OldSerXid GetMinConflictCommitSeqNo( xid ) ;
conflictCommitSeqNo = Serial GetMinConflictCommitSeqNo( xid ) ;
if ( conflictCommitSeqNo ! = 0 )
{
if ( conflictCommitSeqNo ! = InvalidSerCommitSeqNo
@ -5069,7 +5069,7 @@ predicatelock_twophase_recover(TransactionId xid, uint16 info,
{
PredXact - > SxactGlobalXmin = sxact - > xmin ;
PredXact - > SxactGlobalXminCount = 1 ;
OldSerXid SetActiveSerXmin( sxact - > xmin ) ;
Serial SetActiveSerXmin( sxact - > xmin ) ;
}
else if ( TransactionIdEquals ( sxact - > xmin , PredXact - > SxactGlobalXmin ) )
{