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

Commitae86e46

Browse files
committed
Back-patch log_newpage_range().
Back-patch a subset of commit9155580to v11, v10, 9.6, and 9.5. Include the latest repairs to this function.Use a new XLOG_FPI_MULTI value instead of reusing XLOG_FPI. That way,if an older server reads WAL from this function, that server will PANICinstead of applying just one page of the record. The next commit adds acall to this function.Discussion:https://postgr.es/m/20200304.162919.898938381201316571.horikyota.ntt@gmail.com
1 parent4433c6e commitae86e46

File tree

6 files changed

+113
-9
lines changed

6 files changed

+113
-9
lines changed

‎src/backend/access/rmgrdesc/xlogdesc.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ xlog_desc(StringInfo buf, XLogReaderState *record)
7878

7979
appendStringInfoString(buf,xlrec->rp_name);
8080
}
81-
elseif (info==XLOG_FPI||info==XLOG_FPI_FOR_HINT)
81+
elseif (info==XLOG_FPI||info==XLOG_FPI_FOR_HINT||
82+
info==XLOG_FPI_MULTI)
8283
{
8384
/* no further information to print */
8485
}
@@ -182,6 +183,9 @@ xlog_identify(uint8 info)
182183
caseXLOG_FPI_FOR_HINT:
183184
id="FPI_FOR_HINT";
184185
break;
186+
caseXLOG_FPI_MULTI:
187+
id="FPI_MULTI";
188+
break;
185189
}
186190

187191
returnid;

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

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9754,7 +9754,7 @@ xlog_redo(XLogReaderState *record)
97549754

97559755
/* in XLOG rmgr, backup blocks are only used by XLOG_FPI records */
97569756
Assert(info==XLOG_FPI||info==XLOG_FPI_FOR_HINT||
9757-
!XLogRecHasAnyBlockRefs(record));
9757+
info==XLOG_FPI_MULTI||!XLogRecHasAnyBlockRefs(record));
97589758

97599759
if (info==XLOG_NEXTOID)
97609760
{
@@ -9957,14 +9957,16 @@ xlog_redo(XLogReaderState *record)
99579957
{
99589958
/* nothing to do here */
99599959
}
9960-
elseif (info==XLOG_FPI||info==XLOG_FPI_FOR_HINT)
9960+
elseif (info==XLOG_FPI||info==XLOG_FPI_FOR_HINT||
9961+
info==XLOG_FPI_MULTI)
99619962
{
9962-
Bufferbuffer;
9963+
uint8block_id;
99639964

99649965
/*
99659966
* Full-page image (FPI) records contain nothing else but a backup
9966-
* block. The block reference must include a full-page image -
9967-
* otherwise there would be no point in this record.
9967+
* block (or multiple backup blocks). Every block reference must
9968+
* include a full-page image - otherwise there would be no point in
9969+
* this record.
99689970
*
99699971
* No recovery conflicts are generated by these generic records - if a
99709972
* resource manager needs to generate conflicts, it has to define a
@@ -9976,9 +9978,14 @@ xlog_redo(XLogReaderState *record)
99769978
* XLOG_FPI and XLOG_FPI_FOR_HINT records, they use a different info
99779979
* code just to distinguish them for statistics purposes.
99789980
*/
9979-
if (XLogReadBufferForRedo(record,0,&buffer)!=BLK_RESTORED)
9980-
elog(ERROR,"unexpected XLogReadBufferForRedo result when restoring backup block");
9981-
UnlockReleaseBuffer(buffer);
9981+
for (block_id=0;block_id <=record->max_block_id;block_id++)
9982+
{
9983+
Bufferbuffer;
9984+
9985+
if (XLogReadBufferForRedo(record,block_id,&buffer)!=BLK_RESTORED)
9986+
elog(ERROR,"unexpected XLogReadBufferForRedo result when restoring backup block");
9987+
UnlockReleaseBuffer(buffer);
9988+
}
99829989
}
99839990
elseif (info==XLOG_BACKUP_END)
99849991
{

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

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,94 @@ log_newpage_buffer(Buffer buffer, bool page_std)
10211021
returnlog_newpage(&rnode,forkNum,blkno,page,page_std);
10221022
}
10231023

1024+
/*
1025+
* WAL-log a range of blocks in a relation.
1026+
*
1027+
* An image of all pages with block numbers 'startblk' <= X < 'endblk' is
1028+
* written to the WAL. If the range is large, this is done in multiple WAL
1029+
* records.
1030+
*
1031+
* If all page follows the standard page layout, with a PageHeader and unused
1032+
* space between pd_lower and pd_upper, set 'page_std' to true. That allows
1033+
* the unused space to be left out from the WAL records, making them smaller.
1034+
*
1035+
* NOTE: This function acquires exclusive-locks on the pages. Typically, this
1036+
* is used on a newly-built relation, and the caller is holding a
1037+
* AccessExclusiveLock on it, so no other backend can be accessing it at the
1038+
* same time. If that's not the case, you must ensure that this does not
1039+
* cause a deadlock through some other means.
1040+
*/
1041+
void
1042+
log_newpage_range(Relationrel,ForkNumberforkNum,
1043+
BlockNumberstartblk,BlockNumberendblk,
1044+
boolpage_std)
1045+
{
1046+
intflags;
1047+
BlockNumberblkno;
1048+
1049+
flags=REGBUF_FORCE_IMAGE;
1050+
if (page_std)
1051+
flags |=REGBUF_STANDARD;
1052+
1053+
/*
1054+
* Iterate over all the pages in the range. They are collected into
1055+
* batches of XLR_MAX_BLOCK_ID pages, and a single WAL-record is written
1056+
* for each batch.
1057+
*/
1058+
XLogEnsureRecordSpace(XLR_MAX_BLOCK_ID-1,0);
1059+
1060+
blkno=startblk;
1061+
while (blkno<endblk)
1062+
{
1063+
Bufferbufpack[XLR_MAX_BLOCK_ID];
1064+
XLogRecPtrrecptr;
1065+
intnbufs;
1066+
inti;
1067+
1068+
CHECK_FOR_INTERRUPTS();
1069+
1070+
/* Collect a batch of blocks. */
1071+
nbufs=0;
1072+
while (nbufs<XLR_MAX_BLOCK_ID&&blkno<endblk)
1073+
{
1074+
Bufferbuf=ReadBufferExtended(rel,forkNum,blkno,
1075+
RBM_NORMAL,NULL);
1076+
1077+
LockBuffer(buf,BUFFER_LOCK_EXCLUSIVE);
1078+
1079+
/*
1080+
* Completely empty pages are not WAL-logged. Writing a WAL record
1081+
* would change the LSN, and we don't want that. We want the page
1082+
* to stay empty.
1083+
*/
1084+
if (!PageIsNew(BufferGetPage(buf)))
1085+
bufpack[nbufs++]=buf;
1086+
else
1087+
UnlockReleaseBuffer(buf);
1088+
blkno++;
1089+
}
1090+
1091+
/* Write WAL record for this batch. */
1092+
XLogBeginInsert();
1093+
1094+
START_CRIT_SECTION();
1095+
for (i=0;i<nbufs;i++)
1096+
{
1097+
XLogRegisterBuffer(i,bufpack[i],flags);
1098+
MarkBufferDirty(bufpack[i]);
1099+
}
1100+
1101+
recptr=XLogInsert(RM_XLOG_ID,XLOG_FPI_MULTI);
1102+
1103+
for (i=0;i<nbufs;i++)
1104+
{
1105+
PageSetLSN(BufferGetPage(bufpack[i]),recptr);
1106+
UnlockReleaseBuffer(bufpack[i]);
1107+
}
1108+
END_CRIT_SECTION();
1109+
}
1110+
}
1111+
10241112
/*
10251113
* Allocate working buffers needed for WAL record construction.
10261114
*/

‎src/backend/replication/logical/decode.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ DecodeXLogOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
199199
caseXLOG_FPW_CHANGE:
200200
caseXLOG_FPI_FOR_HINT:
201201
caseXLOG_FPI:
202+
caseXLOG_FPI_MULTI:
202203
break;
203204
default:
204205
elog(ERROR,"unexpected RM_XLOG_ID record type: %u",info);

‎src/include/access/xloginsert.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include"storage/block.h"
1717
#include"storage/buf.h"
1818
#include"storage/relfilenode.h"
19+
#include"utils/relcache.h"
1920

2021
/*
2122
* The minimum size of the WAL construction working area. If you need to
@@ -54,6 +55,8 @@ extern bool XLogCheckBufferNeedsBackup(Buffer buffer);
5455
externXLogRecPtrlog_newpage(RelFileNode*rnode,ForkNumberforkNum,
5556
BlockNumberblk,char*page,boolpage_std);
5657
externXLogRecPtrlog_newpage_buffer(Bufferbuffer,boolpage_std);
58+
externvoidlog_newpage_range(Relationrel,ForkNumberforkNum,
59+
BlockNumberstartblk,BlockNumberendblk,boolpage_std);
5760
externXLogRecPtrXLogSaveBufferForHint(Bufferbuffer,boolbuffer_std);
5861

5962
externvoidInitXLogInsert(void);

‎src/include/catalog/pg_control.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ typedef struct CheckPoint
7676
#defineXLOG_END_OF_RECOVERY0x90
7777
#defineXLOG_FPI_FOR_HINT0xA0
7878
#defineXLOG_FPI0xB0
79+
#defineXLOG_FPI_MULTI0xC0
7980

8081

8182
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp