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

Commita892234

Browse files
committed
Change the format of the VM fork to add a second bit per page.
The new bit indicates whether every tuple on the page is already frozen.It is cleared only when the all-visible bit is cleared, and it can beset only when we vacuum a page and find that every tuple on that page isboth visible to every transaction and in no need of any futurevacuuming.A future commit will use this new bit to optimize away full-table scansthat would otherwise be triggered by XID wraparound considerations. Apage which is merely all-visible must still be scanned in that case, buta page which is all-frozen need not be. This commit does not attemptthat optimization, although that optimization is the goal here. Itseems better to get the basic infrastructure in place first.Per discussion, it's very desirable for pg_upgrade to automaticallymigrate existing VM forks from the old format to the new format. That,too, will be handled in a follow-on patch.Masahiko Sawada, reviewed by Kyotaro Horiguchi, Fujii Masao, AmitKapila, Simon Riggs, Andres Freund, and others, and substantiallyrevised by me.
1 parent68c521e commita892234

File tree

14 files changed

+309
-126
lines changed

14 files changed

+309
-126
lines changed

‎contrib/pgstattuple/pgstatapprox.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ statapprox_heap(Relation rel, output_type *stat)
8787
* If the page has only visible tuples, then we can find out the free
8888
* space from the FSM and move on.
8989
*/
90-
if (visibilitymap_test(rel,blkno,&vmbuffer))
90+
if (VM_ALL_VISIBLE(rel,blkno,&vmbuffer))
9191
{
9292
freespace=GetRecordedFreeSpace(rel,blkno);
9393
stat->tuple_len+=BLCKSZ-freespace;

‎doc/src/sgml/storage.sgml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -623,7 +623,8 @@ can be used to examine the information stored in free space maps.
623623
<para>
624624
Each heap relation has a Visibility Map
625625
(VM) to keep track of which pages contain only tuples that are known to be
626-
visible to all active transactions. It's stored
626+
visible to all active transactions; it also keeps track of which pages contain
627+
only unfrozen tuples. It's stored
627628
alongside the main relation data in a separate relation fork, named after the
628629
filenode number of the relation, plus a <literal>_vm</> suffix. For example,
629630
if the filenode of a relation is 12345, the VM is stored in a file called
@@ -632,11 +633,12 @@ Note that indexes do not have VMs.
632633
</para>
633634

634635
<para>
635-
The visibility mapsimplystoresone bit per heap page.A setbit means
636-
thatall tuples onthe pageare known to be visible to all transactions.
637-
This means that the page doesnot contain any tuples that need to be vacuumed.
636+
The visibility map storestwo bits per heap page. The firstbit, if set,
637+
indicatesthat the pageis all-visible, or in other words that the page does
638+
not contain any tuples that need to be vacuumed.
638639
This information can also be used by <firstterm>index-only scans</> to answer
639640
queries using only the index tuple.
641+
The second bit, if set, means that all tuples on the page have been frozen.
640642
</para>
641643

642644
<para>

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

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6951,6 +6951,55 @@ ConditionalMultiXactIdWait(MultiXactId multi, MultiXactStatus status,
69516951
rel,NULL,XLTW_None,remaining);
69526952
}
69536953

6954+
/*
6955+
* heap_tuple_needs_eventual_freeze
6956+
*
6957+
* Check to see whether any of the XID fields of a tuple (xmin, xmax, xvac)
6958+
* will eventually require freezing. Similar to heap_tuple_needs_freeze,
6959+
* but there's no cutoff, since we're trying to figure out whether freezing
6960+
* will ever be needed, not whether it's needed now.
6961+
*/
6962+
bool
6963+
heap_tuple_needs_eventual_freeze(HeapTupleHeadertuple)
6964+
{
6965+
TransactionIdxid;
6966+
6967+
/*
6968+
* If xmin is a normal transaction ID, this tuple is definitely not
6969+
* frozen.
6970+
*/
6971+
xid=HeapTupleHeaderGetXmin(tuple);
6972+
if (TransactionIdIsNormal(xid))
6973+
return true;
6974+
6975+
/*
6976+
* If xmax is a valid xact or multixact, this tuple is also not frozen.
6977+
*/
6978+
if (tuple->t_infomask&HEAP_XMAX_IS_MULTI)
6979+
{
6980+
MultiXactIdmulti;
6981+
6982+
multi=HeapTupleHeaderGetRawXmax(tuple);
6983+
if (MultiXactIdIsValid(multi))
6984+
return true;
6985+
}
6986+
else
6987+
{
6988+
xid=HeapTupleHeaderGetRawXmax(tuple);
6989+
if (TransactionIdIsNormal(xid))
6990+
return true;
6991+
}
6992+
6993+
if (tuple->t_infomask&HEAP_MOVED)
6994+
{
6995+
xid=HeapTupleHeaderGetXvac(tuple);
6996+
if (TransactionIdIsNormal(xid))
6997+
return true;
6998+
}
6999+
7000+
return false;
7001+
}
7002+
69547003
/*
69557004
* heap_tuple_needs_freeze
69567005
*
@@ -7205,7 +7254,7 @@ log_heap_freeze(Relation reln, Buffer buffer, TransactionId cutoff_xid,
72057254
*/
72067255
XLogRecPtr
72077256
log_heap_visible(RelFileNodernode,Bufferheap_buffer,Buffervm_buffer,
7208-
TransactionIdcutoff_xid)
7257+
TransactionIdcutoff_xid,uint8vmflags)
72097258
{
72107259
xl_heap_visiblexlrec;
72117260
XLogRecPtrrecptr;
@@ -7215,6 +7264,7 @@ log_heap_visible(RelFileNode rnode, Buffer heap_buffer, Buffer vm_buffer,
72157264
Assert(BufferIsValid(vm_buffer));
72167265

72177266
xlrec.cutoff_xid=cutoff_xid;
7267+
xlrec.flags=vmflags;
72187268
XLogBeginInsert();
72197269
XLogRegisterData((char*)&xlrec,SizeOfHeapVisible);
72207270

@@ -7804,7 +7854,12 @@ heap_xlog_visible(XLogReaderState *record)
78047854
* the subsequent update won't be replayed to clear the flag.
78057855
*/
78067856
page=BufferGetPage(buffer);
7807-
PageSetAllVisible(page);
7857+
7858+
if (xlrec->flags&VISIBILITYMAP_ALL_VISIBLE)
7859+
PageSetAllVisible(page);
7860+
if (xlrec->flags&VISIBILITYMAP_ALL_FROZEN)
7861+
PageSetAllFrozen(page);
7862+
78087863
MarkBufferDirty(buffer);
78097864
}
78107865
elseif (action==BLK_RESTORED)
@@ -7856,7 +7911,7 @@ heap_xlog_visible(XLogReaderState *record)
78567911
*/
78577912
if (lsn>PageGetLSN(vmpage))
78587913
visibilitymap_set(reln,blkno,InvalidBuffer,lsn,vmbuffer,
7859-
xlrec->cutoff_xid);
7914+
xlrec->cutoff_xid,xlrec->flags);
78607915

78617916
ReleaseBuffer(vmbuffer);
78627917
FreeFakeRelcacheEntry(reln);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp