Re: SLRUs in the main buffer pool - Page Header definitions

From: "Bagga, Rishu" <bagrishu(at)amazon(dot)com>
To: Thomas Munro <thomas(dot)munro(at)gmail(dot)com>, Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
Cc: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: SLRUs in the main buffer pool - Page Header definitions
Date: 2022-09-28 01:57:34
Message-ID: 7C4D53F1-A156-4ABC-9B89-B2C253D5FF74@amazon.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

We have been working on adding page headers to the SLRU pages, as part of the migration for SLRU to buffer cache. We’ve incorporated Thomas Munro’s patch and Heikki’s Storage manager changes[1] and have a patch for early feedback.

As part of our changes we have:

1. Added page headers to the following

*Commit_TS
*CLOG
*MultiXact
*Subtrans
*Serial (predicate.c)
*Notify (async.c)

For commit_ts, clog and MultiXact, the PageXLogRecPtr field is populated with the LSN returned during the creation of a new page; as there is no WAL record for the rest, PageXLogRecPtr is set to “InvalidXlogRecPtr”.

There is one failing assert in predicate.c for SerialPagePrecedes with the page header changes; we are looking into this issue.

The page_version is set to PG_METAPAGE_LAYOUT_VERSION (which is 1)

2. Change block number passed into ReadSlruBuffer from relative to absolute, and account for SLRU’s 256kb segment size in md.c.

The changes pass the regression tests. We are still working on handling the upgrade scenario and should have a patch out for that soon.

Attached is the patch with all changes (Heikki and Munro’s patch and page headers) consolidated

Thanks,
Rishu Bagga, Amazon Web Services (AWS)

[1] https://www.postgresql.org/message-id/128709bc-992c-b57a-7174-098433b7faa4@iki.fi

[2] https://www.postgresql.org/message-id/CA+hUKG+02ZF-vjtUG4pH8bx+2Dn=eMh8GsT6jasiXZPgVxUXLw@mail.gmail.com

On 9/27/22, 6:54 PM, "Bagga, Rishu" <bagrishu(at)amazon(dot)com> wrote:

Hi all,

PostgreSQL currently maintains several data structures in the SLRU
cache. The SLRU cache has scaling and sizing challenges because of it’s
simple implementation. The goal is to move these caches to the common
buffer cache to benefit from the stronger capabilities of the common
buffercache code. At AWS, we are building on the patch shared by Thomas
Munro [1], which treats the SLRU pages as part of a pseudo-databatabe
of ID 9. We will refer to the pages belonging to SLRU components as
BufferedObject pages going forward.

The current SLRU pages do not have any header, so there is a need to
create a new page header format for these. Our investigations revealed
that we need to:

1. track LSN to ensure durability and consistency of all pages (for redo
and full page write purposes)
2. have a checksum (for page correctness verification).
3. A flag to identify if the page is a relational or BufferedObject
4. Track version information.

We are suggesting a minimal BufferedObject page header
to be the following, overlapping with the key fields near the beginning
of the regular PageHeaderData:

typedef struct BufferedObjectPageHeaderData
{
PageXLogRecPtr pd_lsn;
uint16_t pd_checksum;
uint16_t pd_flags;
uint16_t pd_pagesize_version;
} BufferedObjectPageHeaderData;

For reference, the regular page header looks like the following:
typedef struct PageHeaderData
{
PageXLogRecPtr pd_lsn;
uint16_t pd_checksum;
uint16_t pd_flags;
LocationIndex pd_lower;
LocationIndex pd_upper;
LocationIndex pd_special;
uint16_t pd_pagesize_version;
TransactionId pd_prune_xid;
ItemIdDataCommon pd_linp[];
} PageHeaderData;

After careful review, we have trimmed out the heap and index specific
fields from the suggested header that do not add any value to SLRU
components. We plan to use pd_lsn, pd_checksum, and pd_pagesize_version
in the same way that they are in relational pages. These fields are
needed to ensure consistency, durability and page correctness.

We will use the 4th bit of pd_flags to identify a BufferedObject page.
If the bit is set then this denotes a BufferedObject page. Today, bits
1 - 3 are used for determining if there are any free line pointers, if
the page is full, and if all tuples on the page are visible to
everyone, respectively. We will use this information accordingly in the
storage manager to determine which callback functions to use for file
I/O operations. This approach allows the buffercache to have an
universal method to quickly determine what type of page it is dealing
with at any time.

Using the new BufferedObject page header will be space efficient but
introduces a significant change in the codebase to now track two types
of page header data. During upgrade, all SLRU files that exist on the
system must be converted to the new format with page header. This will
require rewriting all the SLRU pages with the page header as part of
pg_upgrade.

We believe that this is the correct approach for the long run. We would
love feedback if there are additional items of data that should be
tracked as well. Alternatively, we could re-use the existing page
header and the unused fields could be used as a padding. This feels
like an unclean approach but would avoid having two page header types
in the database.

[1] - https://www.postgresql.org/message-id/flat/CA+hUKGKAYze99B-jk9NoMp-2BDqAgiRC4oJv+bFxghNgdieq8Q(at)mail(dot)gmail(dot)com

Discussed with: Joe Conway, Nathan Bossart, Shawn Debnath

Rishu Bagga

Amazon Web Services (AWS)

Attachment Content-Type Size
0001-heikki-munro-plus-page-header.patch application/octet-stream 325.9 KB

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Peter Smith 2022-09-28 02:04:00 Re: GUC tables - use designated initializers
Previous Message Michael Paquier 2022-09-28 01:23:11 Re: [small patch] Change datatype of ParallelMessagePending from "volatile bool" to "volatile sig_atomic_t"