@ -2466,7 +2466,11 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
starting_with_empty_page = PageGetMaxOffsetNumber ( page ) = = 0 ;
if ( starting_with_empty_page & & ( options & HEAP_INSERT_FROZEN ) )
{
all_frozen_set = true ;
/* Lock the vmbuffer before entering the critical section */
LockBuffer ( vmbuffer , BUFFER_LOCK_EXCLUSIVE ) ;
}
/* NO EREPORT(ERROR) from here till changes are logged */
START_CRIT_SECTION ( ) ;
@ -2506,7 +2510,8 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
* going to add further frozen rows to it .
*
* If we ' re only adding already frozen rows to a previously empty
* page , mark it as all - visible .
* page , mark it as all - frozen and update the visibility map . We ' re
* already holding a pin on the vmbuffer .
*/
if ( PageIsAllVisible ( page ) & & ! ( options & HEAP_INSERT_FROZEN ) )
{
@ -2517,7 +2522,14 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
vmbuffer , VISIBILITYMAP_VALID_BITS ) ;
}
else if ( all_frozen_set )
{
PageSetAllVisible ( page ) ;
visibilitymap_set_vmbits ( BufferGetBlockNumber ( buffer ) ,
vmbuffer ,
VISIBILITYMAP_ALL_VISIBLE |
VISIBILITYMAP_ALL_FROZEN ,
relation - > rd_locator ) ;
}
/*
* XXX Should we set PageSetPrunable on this page ? See heap_insert ( )
@ -2565,6 +2577,12 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
xlrec - > flags = 0 ;
if ( all_visible_cleared )
xlrec - > flags = XLH_INSERT_ALL_VISIBLE_CLEARED ;
/*
* We don ' t have to worry about including a conflict xid in the
* WAL record , as HEAP_INSERT_FROZEN intentionally violates
* visibility rules .
*/
if ( all_frozen_set )
xlrec - > flags = XLH_INSERT_ALL_FROZEN_SET ;
@ -2628,6 +2646,8 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
XLogBeginInsert ( ) ;
XLogRegisterData ( xlrec , tupledata - scratch . data ) ;
XLogRegisterBuffer ( 0 , buffer , REGBUF_STANDARD | bufflags ) ;
if ( all_frozen_set )
XLogRegisterBuffer ( 1 , vmbuffer , 0 ) ;
XLogRegisterBufData ( 0 , tupledata , totaldatalen ) ;
@ -2637,26 +2657,17 @@ heap_multi_insert(Relation relation, TupleTableSlot **slots, int ntuples,
recptr = XLogInsert ( RM_HEAP2_ID , info ) ;
PageSetLSN ( page , recptr ) ;
if ( all_frozen_set )
{
Assert ( BufferIsDirty ( vmbuffer ) ) ;
PageSetLSN ( BufferGetPage ( vmbuffer ) , recptr ) ;
}
}
END_CRIT_SECTION ( ) ;
/*
* If we ' ve frozen everything on the page , update the visibilitymap .
* We ' re already holding pin on the vmbuffer .
*/
if ( all_frozen_set )
{
/*
* It ' s fine to use InvalidTransactionId here - this is only used
* when HEAP_INSERT_FROZEN is specified , which intentionally
* violates visibility rules .
*/
visibilitymap_set ( relation , BufferGetBlockNumber ( buffer ) , buffer ,
InvalidXLogRecPtr , vmbuffer ,
InvalidTransactionId ,
VISIBILITYMAP_ALL_VISIBLE | VISIBILITYMAP_ALL_FROZEN ) ;
}
LockBuffer ( vmbuffer , BUFFER_LOCK_UNLOCK ) ;
UnlockReleaseBuffer ( buffer ) ;
ndone + = nthispage ;