@@ -6188,18 +6188,13 @@ heap_inplace_update_and_unlock(Relation relation,
6188
6188
HeapTupleHeader htup = oldtup -> t_data ;
6189
6189
uint32 oldlen ;
6190
6190
uint32 newlen ;
6191
- char * dst ;
6192
- char * src ;
6193
6191
6194
6192
Assert (ItemPointerEquals (& oldtup -> t_self ,& tuple -> t_self ));
6195
6193
oldlen = oldtup -> t_len - htup -> t_hoff ;
6196
6194
newlen = tuple -> t_len - tuple -> t_data -> t_hoff ;
6197
6195
if (oldlen != newlen || htup -> t_hoff != tuple -> t_data -> t_hoff )
6198
6196
elog (ERROR ,"wrong tuple length" );
6199
6197
6200
- dst = (char * )htup + htup -> t_hoff ;
6201
- src = (char * )tuple -> t_data + tuple -> t_data -> t_hoff ;
6202
-
6203
6198
/*
6204
6199
* Construct shared cache inval if necessary. Note that because we only
6205
6200
* pass the new version of the tuple, this mustn't be used for any
@@ -6218,15 +6213,15 @@ heap_inplace_update_and_unlock(Relation relation,
6218
6213
*/
6219
6214
PreInplace_Inval ();
6220
6215
6216
+ /* NO EREPORT(ERROR) from here till changes are logged */
6217
+ START_CRIT_SECTION ();
6218
+
6219
+ memcpy ((char * )htup + htup -> t_hoff ,
6220
+ (char * )tuple -> t_data + tuple -> t_data -> t_hoff ,
6221
+ newlen );
6222
+
6221
6223
/*----------
6222
- * NO EREPORT(ERROR) from here till changes are complete
6223
- *
6224
- * Our buffer lock won't stop a reader having already pinned and checked
6225
- * visibility for this tuple. Hence, we write WAL first, then mutate the
6226
- * buffer. Like in MarkBufferDirtyHint() or RecordTransactionCommit(),
6227
- * checkpoint delay makes that acceptable. With the usual order of
6228
- * changes, a crash after memcpy() and before XLogInsert() could allow
6229
- * datfrozenxid to overtake relfrozenxid:
6224
+ * XXX A crash here can allow datfrozenxid() to get ahead of relfrozenxid:
6230
6225
*
6231
6226
* ["D" is a VACUUM (ONLY_DATABASE_STATS)]
6232
6227
* ["R" is a VACUUM tbl]
@@ -6236,57 +6231,31 @@ heap_inplace_update_and_unlock(Relation relation,
6236
6231
* D: raise pg_database.datfrozenxid, XLogInsert(), finish
6237
6232
* [crash]
6238
6233
* [recovery restores datfrozenxid w/o relfrozenxid]
6239
- *
6240
- * Like in MarkBufferDirtyHint() subroutine XLogSaveBufferForHint(), copy
6241
- * the buffer to the stack before logging. Here, that facilitates a FPI
6242
- * of the post-mutation block before we accept other sessions seeing it.
6243
6234
*/
6244
- Assert ((MyProc -> delayChkptFlags & DELAY_CHKPT_START )== 0 );
6245
- START_CRIT_SECTION ();
6246
- MyProc -> delayChkptFlags |=DELAY_CHKPT_START ;
6235
+
6236
+ MarkBufferDirty (buffer );
6247
6237
6248
6238
/* XLOG stuff */
6249
6239
if (RelationNeedsWAL (relation ))
6250
6240
{
6251
6241
xl_heap_inplace xlrec ;
6252
- PGAlignedBlock copied_buffer ;
6253
- char * origdata = (char * )BufferGetBlock (buffer );
6254
- Page page = BufferGetPage (buffer );
6255
- uint16 lower = ((PageHeader )page )-> pd_lower ;
6256
- uint16 upper = ((PageHeader )page )-> pd_upper ;
6257
- uintptr_t dst_offset_in_block ;
6258
- RelFileLocator rlocator ;
6259
- ForkNumber forkno ;
6260
- BlockNumber blkno ;
6261
6242
XLogRecPtr recptr ;
6262
6243
6263
6244
xlrec .offnum = ItemPointerGetOffsetNumber (& tuple -> t_self );
6264
6245
6265
6246
XLogBeginInsert ();
6266
6247
XLogRegisterData ((char * )& xlrec ,SizeOfHeapInplace );
6267
6248
6268
- /* register block matching what buffer will look like after changes */
6269
- memcpy (copied_buffer .data ,origdata ,lower );
6270
- memcpy (copied_buffer .data + upper ,origdata + upper ,BLCKSZ - upper );
6271
- dst_offset_in_block = dst - origdata ;
6272
- memcpy (copied_buffer .data + dst_offset_in_block ,src ,newlen );
6273
- BufferGetTag (buffer ,& rlocator ,& forkno ,& blkno );
6274
- Assert (forkno == MAIN_FORKNUM );
6275
- XLogRegisterBlock (0 ,& rlocator ,forkno ,blkno ,copied_buffer .data ,
6276
- REGBUF_STANDARD );
6277
- XLogRegisterBufData (0 ,src ,newlen );
6249
+ XLogRegisterBuffer (0 ,buffer ,REGBUF_STANDARD );
6250
+ XLogRegisterBufData (0 , (char * )htup + htup -> t_hoff ,newlen );
6278
6251
6279
6252
/* inplace updates aren't decoded atm, don't log the origin */
6280
6253
6281
6254
recptr = XLogInsert (RM_HEAP_ID ,XLOG_HEAP_INPLACE );
6282
6255
6283
- PageSetLSN (page ,recptr );
6256
+ PageSetLSN (BufferGetPage ( buffer ) ,recptr );
6284
6257
}
6285
6258
6286
- memcpy (dst ,src ,newlen );
6287
-
6288
- MarkBufferDirty (buffer );
6289
-
6290
6259
LockBuffer (buffer ,BUFFER_LOCK_UNLOCK );
6291
6260
6292
6261
/*
@@ -6299,7 +6268,6 @@ heap_inplace_update_and_unlock(Relation relation,
6299
6268
*/
6300
6269
AtInplace_Inval ();
6301
6270
6302
- MyProc -> delayChkptFlags &= ~DELAY_CHKPT_START ;
6303
6271
END_CRIT_SECTION ();
6304
6272
UnlockTuple (relation ,& tuple -> t_self ,InplaceUpdateTupleLock );
6305
6273