Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbe74b94

Browse files
committed
Revert "WAL-log inplace update before revealing it to other sessions."
This reverts commitbfd5c6e (v17) andcounterparts in each other non-master branch. This unblocks reverting acommit on which it depends.Discussion:https://postgr.es/m/10ec0bc3-5933-1189-6bb8-5dec4114558e@gmail.com
1 parentf9b4464 commitbe74b94

File tree

3 files changed

+18
-46
lines changed

3 files changed

+18
-46
lines changed

‎src/backend/access/heap/README.tuplock

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,6 @@ Inplace updates create an exception to the rule that tuple data won't change
203203
under a reader holding a pin. A reader of a heap_fetch() result tuple may
204204
witness a torn read. Current inplace-updated fields are aligned and are no
205205
wider than four bytes, and current readers don't need consistency across
206-
fields. Hence, they get by with just fetching each field once.
206+
fields. Hence, they get by with just fetching each field once. XXX such a
207+
caller may also read a value that has not reached WAL; see
208+
systable_inplace_update_finish().

‎src/backend/access/heap/heapam.c

Lines changed: 13 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6108,18 +6108,13 @@ heap_inplace_update_and_unlock(Relation relation,
61086108
HeapTupleHeaderhtup=oldtup->t_data;
61096109
uint32oldlen;
61106110
uint32newlen;
6111-
char*dst;
6112-
char*src;
61136111

61146112
Assert(ItemPointerEquals(&oldtup->t_self,&tuple->t_self));
61156113
oldlen=oldtup->t_len-htup->t_hoff;
61166114
newlen=tuple->t_len-tuple->t_data->t_hoff;
61176115
if (oldlen!=newlen||htup->t_hoff!=tuple->t_data->t_hoff)
61186116
elog(ERROR,"wrong tuple length");
61196117

6120-
dst= (char*)htup+htup->t_hoff;
6121-
src= (char*)tuple->t_data+tuple->t_data->t_hoff;
6122-
61236118
/*
61246119
* Construct shared cache inval if necessary. Note that because we only
61256120
* pass the new version of the tuple, this mustn't be used for any
@@ -6138,15 +6133,15 @@ heap_inplace_update_and_unlock(Relation relation,
61386133
*/
61396134
PreInplace_Inval();
61406135

6136+
/* NO EREPORT(ERROR) from here till changes are logged */
6137+
START_CRIT_SECTION();
6138+
6139+
memcpy((char*)htup+htup->t_hoff,
6140+
(char*)tuple->t_data+tuple->t_data->t_hoff,
6141+
newlen);
6142+
61416143
/*----------
6142-
* NO EREPORT(ERROR) from here till changes are complete
6143-
*
6144-
* Our buffer lock won't stop a reader having already pinned and checked
6145-
* visibility for this tuple. Hence, we write WAL first, then mutate the
6146-
* buffer. Like in MarkBufferDirtyHint() or RecordTransactionCommit(),
6147-
* checkpoint delay makes that acceptable. With the usual order of
6148-
* changes, a crash after memcpy() and before XLogInsert() could allow
6149-
* datfrozenxid to overtake relfrozenxid:
6144+
* XXX A crash here can allow datfrozenxid() to get ahead of relfrozenxid:
61506145
*
61516146
* ["D" is a VACUUM (ONLY_DATABASE_STATS)]
61526147
* ["R" is a VACUUM tbl]
@@ -6156,57 +6151,31 @@ heap_inplace_update_and_unlock(Relation relation,
61566151
* D: raise pg_database.datfrozenxid, XLogInsert(), finish
61576152
* [crash]
61586153
* [recovery restores datfrozenxid w/o relfrozenxid]
6159-
*
6160-
* Like in MarkBufferDirtyHint() subroutine XLogSaveBufferForHint(), copy
6161-
* the buffer to the stack before logging. Here, that facilitates a FPI
6162-
* of the post-mutation block before we accept other sessions seeing it.
61636154
*/
6164-
Assert(!MyProc->delayChkpt);
6165-
START_CRIT_SECTION();
6166-
MyProc->delayChkpt= true;
6155+
6156+
MarkBufferDirty(buffer);
61676157

61686158
/* XLOG stuff */
61696159
if (RelationNeedsWAL(relation))
61706160
{
61716161
xl_heap_inplacexlrec;
6172-
PGAlignedBlockcopied_buffer;
6173-
char*origdata= (char*)BufferGetBlock(buffer);
6174-
Pagepage=BufferGetPage(buffer);
6175-
uint16lower= ((PageHeader)page)->pd_lower;
6176-
uint16upper= ((PageHeader)page)->pd_upper;
6177-
uintptr_tdst_offset_in_block;
6178-
RelFileNodernode;
6179-
ForkNumberforkno;
6180-
BlockNumberblkno;
61816162
XLogRecPtrrecptr;
61826163

61836164
xlrec.offnum=ItemPointerGetOffsetNumber(&tuple->t_self);
61846165

61856166
XLogBeginInsert();
61866167
XLogRegisterData((char*)&xlrec,SizeOfHeapInplace);
61876168

6188-
/* register block matching what buffer will look like after changes */
6189-
memcpy(copied_buffer.data,origdata,lower);
6190-
memcpy(copied_buffer.data+upper,origdata+upper,BLCKSZ-upper);
6191-
dst_offset_in_block=dst-origdata;
6192-
memcpy(copied_buffer.data+dst_offset_in_block,src,newlen);
6193-
BufferGetTag(buffer,&rnode,&forkno,&blkno);
6194-
Assert(forkno==MAIN_FORKNUM);
6195-
XLogRegisterBlock(0,&rnode,forkno,blkno,copied_buffer.data,
6196-
REGBUF_STANDARD);
6197-
XLogRegisterBufData(0,src,newlen);
6169+
XLogRegisterBuffer(0,buffer,REGBUF_STANDARD);
6170+
XLogRegisterBufData(0, (char*)htup+htup->t_hoff,newlen);
61986171

61996172
/* inplace updates aren't decoded atm, don't log the origin */
62006173

62016174
recptr=XLogInsert(RM_HEAP_ID,XLOG_HEAP_INPLACE);
62026175

6203-
PageSetLSN(page,recptr);
6176+
PageSetLSN(BufferGetPage(buffer),recptr);
62046177
}
62056178

6206-
memcpy(dst,src,newlen);
6207-
6208-
MarkBufferDirty(buffer);
6209-
62106179
LockBuffer(buffer,BUFFER_LOCK_UNLOCK);
62116180

62126181
/*
@@ -6219,7 +6188,6 @@ heap_inplace_update_and_unlock(Relation relation,
62196188
*/
62206189
AtInplace_Inval();
62216190

6222-
MyProc->delayChkpt= false;
62236191
END_CRIT_SECTION();
62246192
UnlockTuple(relation,&tuple->t_self,InplaceUpdateTupleLock);
62256193

‎src/backend/access/transam/xloginsert.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ XLogRegisterBlock(uint8 block_id, RelFileNode *rnode, ForkNumber forknum,
269269
{
270270
registered_buffer*regbuf;
271271

272+
/* This is currently only used to WAL-log a full-page image of a page */
273+
Assert(flags&REGBUF_FORCE_IMAGE);
272274
Assert(begininsert_called);
273275

274276
if (block_id >=max_registered_block_id)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp