Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit faeedbc

Browse files
committed
Introduce PG_IO_ALIGN_SIZE and align all I/O buffers.
In order to have the option to use O_DIRECT/FILE_FLAG_NO_BUFFERING in a later commit, we need the addresses of user space buffers to be well aligned. The exact requirements vary by OS and file system (typically sectors and/or memory pages). The address alignment size is set to 4096, which is enough for currently known systems: it matches modern sectors and common memory page size. There is no standard governing O_DIRECT's requirements so we might eventually have to reconsider this with more information from the field or future systems. Aligning I/O buffers on memory pages is also known to improve regular buffered I/O performance. Three classes of I/O buffers for regular data pages are adjusted: (1) Heap buffers are now allocated with the new palloc_aligned() or MemoryContextAllocAligned() functions introduced by commit 439f617. (2) Stack buffers now use a new struct PGIOAlignedBlock to respect PG_IO_ALIGN_SIZE, if possible with this compiler. (3) The buffer pool is also aligned in shared memory. WAL buffers were already aligned on XLOG_BLCKSZ. It's possible for XLOG_BLCKSZ to be configured smaller than PG_IO_ALIGNED_SIZE and thus for O_DIRECT WAL writes to fail to be well aligned, but that's a pre-existing condition and will be addressed by a later commit. BufFiles are not yet addressed (there's no current plan to use O_DIRECT for those, but they could potentially get some incidental speedup even in plain buffered I/O operations through better alignment). If we can't align stack objects suitably using the compiler extensions we know about, we disable the use of O_DIRECT by setting PG_O_DIRECT to 0. This avoids the need to consider systems that have O_DIRECT but can't align stack objects the way we want; such systems could in theory be supported with more work but we don't currently know of any such machines, so it's easier to pretend there is no O_DIRECT support instead. That's an existing and tested class of system. Add assertions that all buffers passed into smgrread(), smgrwrite() and smgrextend() are correctly aligned, unless PG_O_DIRECT is 0 (= stack alignment tricks may be unavailable) or the block size has been set too small to allow arrays of buffers to be all aligned. Author: Thomas Munro <thomas.munro@gmail.com> Author: Andres Freund <andres@anarazel.de> Reviewed-by: Justin Pryzby <pryzby@telsasoft.com> Discussion: https://postgr.es/m/CA+hUKGK1X532hYqJ_MzFWt0n1zt8trz980D79WbjwnT-yYLZpg@mail.gmail.com
1 parent d73c285 commit faeedbc

File tree

26 files changed

+108
-45
lines changed

26 files changed

+108
-45
lines changed

contrib/bloom/blinsert.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ blbuildempty(Relation index)
166166
Page metapage;
167167

168168
/* Construct metapage. */
169-
metapage = (Page) palloc(BLCKSZ);
169+
metapage = (Page) palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, 0);
170170
BloomFillMetapage(index, metapage);
171171

172172
/*

contrib/pg_prewarm/pg_prewarm.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ typedef enum
3636
PREWARM_BUFFER
3737
} PrewarmType;
3838

39-
static PGAlignedBlock blockbuffer;
39+
static PGIOAlignedBlock blockbuffer;
4040

4141
/*
4242
* pg_prewarm(regclass, mode text, fork text,

src/backend/access/gist/gistbuild.c

+5-4
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ gist_indexsortbuild(GISTBuildState *state)
415415
* Write an empty page as a placeholder for the root page. It will be
416416
* replaced with the real root page at the end.
417417
*/
418-
page = palloc0(BLCKSZ);
418+
page = palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, MCXT_ALLOC_ZERO);
419419
smgrextend(RelationGetSmgr(state->indexrel), MAIN_FORKNUM, GIST_ROOT_BLKNO,
420420
page, true);
421421
state->pages_allocated++;
@@ -509,7 +509,8 @@ gist_indexsortbuild_levelstate_add(GISTBuildState *state,
509509
levelstate->current_page++;
510510

511511
if (levelstate->pages[levelstate->current_page] == NULL)
512-
levelstate->pages[levelstate->current_page] = palloc(BLCKSZ);
512+
levelstate->pages[levelstate->current_page] =
513+
palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, 0);
513514

514515
newPage = levelstate->pages[levelstate->current_page];
515516
gistinitpage(newPage, old_page_flags);
@@ -579,7 +580,7 @@ gist_indexsortbuild_levelstate_flush(GISTBuildState *state,
579580

580581
/* Create page and copy data */
581582
data = (char *) (dist->list);
582-
target = palloc0(BLCKSZ);
583+
target = palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, MCXT_ALLOC_ZERO);
583584
gistinitpage(target, isleaf ? F_LEAF : 0);
584585
for (int i = 0; i < dist->block.num; i++)
585586
{
@@ -630,7 +631,7 @@ gist_indexsortbuild_levelstate_flush(GISTBuildState *state,
630631
if (parent == NULL)
631632
{
632633
parent = palloc0(sizeof(GistSortedBuildLevelState));
633-
parent->pages[0] = (Page) palloc(BLCKSZ);
634+
parent->pages[0] = (Page) palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, 0);
634635
parent->parent = NULL;
635636
gistinitpage(parent->pages[0], 0);
636637

src/backend/access/hash/hashpage.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -992,7 +992,7 @@ static bool
992992
_hash_alloc_buckets(Relation rel, BlockNumber firstblock, uint32 nblocks)
993993
{
994994
BlockNumber lastblock;
995-
PGAlignedBlock zerobuf;
995+
PGIOAlignedBlock zerobuf;
996996
Page page;
997997
HashPageOpaque ovflopaque;
998998

src/backend/access/heap/rewriteheap.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ begin_heap_rewrite(Relation old_heap, Relation new_heap, TransactionId oldest_xm
255255

256256
state->rs_old_rel = old_heap;
257257
state->rs_new_rel = new_heap;
258-
state->rs_buffer = (Page) palloc(BLCKSZ);
258+
state->rs_buffer = (Page) palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, 0);
259259
/* new_heap needn't be empty, just locked */
260260
state->rs_blockno = RelationGetNumberOfBlocks(new_heap);
261261
state->rs_buffer_valid = false;

src/backend/access/nbtree/nbtree.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ btbuildempty(Relation index)
154154
Page metapage;
155155

156156
/* Construct metapage. */
157-
metapage = (Page) palloc(BLCKSZ);
157+
metapage = (Page) palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, 0);
158158
_bt_initmetapage(metapage, P_NONE, 0, _bt_allequalimage(index, false));
159159

160160
/*

src/backend/access/nbtree/nbtsort.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ _bt_blnewpage(uint32 level)
619619
Page page;
620620
BTPageOpaque opaque;
621621

622-
page = (Page) palloc(BLCKSZ);
622+
page = (Page) palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, 0);
623623

624624
/* Zero the page and set up standard page header info */
625625
_bt_pageinit(page, BLCKSZ);
@@ -660,7 +660,9 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
660660
while (blkno > wstate->btws_pages_written)
661661
{
662662
if (!wstate->btws_zeropage)
663-
wstate->btws_zeropage = (Page) palloc0(BLCKSZ);
663+
wstate->btws_zeropage = (Page) palloc_aligned(BLCKSZ,
664+
PG_IO_ALIGN_SIZE,
665+
MCXT_ALLOC_ZERO);
664666
/* don't set checksum for all-zero page */
665667
smgrextend(RelationGetSmgr(wstate->index), MAIN_FORKNUM,
666668
wstate->btws_pages_written++,
@@ -1170,7 +1172,7 @@ _bt_uppershutdown(BTWriteState *wstate, BTPageState *state)
11701172
* set to point to "P_NONE"). This changes the index to the "valid" state
11711173
* by filling in a valid magic number in the metapage.
11721174
*/
1173-
metapage = (Page) palloc(BLCKSZ);
1175+
metapage = (Page) palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, 0);
11741176
_bt_initmetapage(metapage, rootblkno, rootlevel,
11751177
wstate->inskey->allequalimage);
11761178
_bt_blwritepage(wstate, metapage, BTREE_METAPAGE);

src/backend/access/spgist/spginsert.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ spgbuildempty(Relation index)
158158
Page page;
159159

160160
/* Construct metapage. */
161-
page = (Page) palloc(BLCKSZ);
161+
page = (Page) palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE, 0);
162162
SpGistInitMetapage(page);
163163

164164
/*

src/backend/access/transam/generic_xlog.c

+9-4
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,17 @@ typedef struct
5858
char delta[MAX_DELTA_SIZE]; /* delta between page images */
5959
} PageData;
6060

61-
/* State of generic xlog record construction */
61+
/*
62+
* State of generic xlog record construction. Must be allocated at an I/O
63+
* aligned address.
64+
*/
6265
struct GenericXLogState
6366
{
67+
/* Page images (properly aligned, must be first) */
68+
PGIOAlignedBlock images[MAX_GENERIC_XLOG_PAGES];
6469
/* Info about each page, see above */
6570
PageData pages[MAX_GENERIC_XLOG_PAGES];
6671
bool isLogged;
67-
/* Page images (properly aligned) */
68-
PGAlignedBlock images[MAX_GENERIC_XLOG_PAGES];
6972
};
7073

7174
static void writeFragment(PageData *pageData, OffsetNumber offset,
@@ -269,7 +272,9 @@ GenericXLogStart(Relation relation)
269272
GenericXLogState *state;
270273
int i;
271274

272-
state = (GenericXLogState *) palloc(sizeof(GenericXLogState));
275+
state = (GenericXLogState *) palloc_aligned(sizeof(GenericXLogState),
276+
PG_IO_ALIGN_SIZE,
277+
0);
273278
state->isLogged = RelationNeedsWAL(relation);
274279

275280
for (i = 0; i < MAX_GENERIC_XLOG_PAGES; i++)

src/backend/access/transam/xlog.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -4506,7 +4506,7 @@ XLOGShmemSize(void)
45064506
/* xlblocks array */
45074507
size = add_size(size, mul_size(sizeof(XLogRecPtr), XLOGbuffers));
45084508
/* extra alignment padding for XLOG I/O buffers */
4509-
size = add_size(size, XLOG_BLCKSZ);
4509+
size = add_size(size, Max(XLOG_BLCKSZ, PG_IO_ALIGN_SIZE));
45104510
/* and the buffers themselves */
45114511
size = add_size(size, mul_size(XLOG_BLCKSZ, XLOGbuffers));
45124512

src/backend/catalog/storage.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ void
451451
RelationCopyStorage(SMgrRelation src, SMgrRelation dst,
452452
ForkNumber forkNum, char relpersistence)
453453
{
454-
PGAlignedBlock buf;
454+
PGIOAlignedBlock buf;
455455
Page page;
456456
bool use_wal;
457457
bool copying_initfork;

src/backend/storage/buffer/buf_init.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,12 @@ InitBufferPool(void)
7878
NBuffers * sizeof(BufferDescPadded),
7979
&foundDescs);
8080

81+
/* Align buffer pool on IO page size boundary. */
8182
BufferBlocks = (char *)
82-
ShmemInitStruct("Buffer Blocks",
83-
NBuffers * (Size) BLCKSZ, &foundBufs);
83+
TYPEALIGN(PG_IO_ALIGN_SIZE,
84+
ShmemInitStruct("Buffer Blocks",
85+
NBuffers * (Size) BLCKSZ + PG_IO_ALIGN_SIZE,
86+
&foundBufs));
8487

8588
/* Align condition variables to cacheline boundary. */
8689
BufferIOCVArray = (ConditionVariableMinimallyPadded *)
@@ -163,7 +166,8 @@ BufferShmemSize(void)
163166
/* to allow aligning buffer descriptors */
164167
size = add_size(size, PG_CACHE_LINE_SIZE);
165168

166-
/* size of data pages */
169+
/* size of data pages, plus alignment padding */
170+
size = add_size(size, PG_IO_ALIGN_SIZE);
167171
size = add_size(size, mul_size(NBuffers, BLCKSZ));
168172

169173
/* size of stuff controlled by freelist.c */

src/backend/storage/buffer/bufmgr.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -4250,7 +4250,7 @@ RelationCopyStorageUsingBuffer(RelFileLocator srclocator,
42504250
bool use_wal;
42514251
BlockNumber nblocks;
42524252
BlockNumber blkno;
4253-
PGAlignedBlock buf;
4253+
PGIOAlignedBlock buf;
42544254
BufferAccessStrategy bstrategy_src;
42554255
BufferAccessStrategy bstrategy_dst;
42564256

src/backend/storage/buffer/localbuf.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,11 @@ GetLocalBufferStorage(void)
744744
/* And don't overflow MaxAllocSize, either */
745745
num_bufs = Min(num_bufs, MaxAllocSize / BLCKSZ);
746746

747-
cur_block = (char *) MemoryContextAlloc(LocalBufferContext,
748-
num_bufs * BLCKSZ);
747+
/* Buffers should be I/O aligned. */
748+
cur_block = (char *)
749+
TYPEALIGN(PG_IO_ALIGN_SIZE,
750+
MemoryContextAlloc(LocalBufferContext,
751+
num_bufs * BLCKSZ + PG_IO_ALIGN_SIZE));
749752
next_buf_in_block = 0;
750753
num_bufs_in_block = num_bufs;
751754
}

src/backend/storage/file/buffile.c

+6
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ struct BufFile
9595
off_t curOffset; /* offset part of current pos */
9696
int pos; /* next read/write position in buffer */
9797
int nbytes; /* total # of valid bytes in buffer */
98+
99+
/*
100+
* XXX Should ideally us PGIOAlignedBlock, but might need a way to avoid
101+
* wasting per-file alignment padding when some users create many
102+
* files.
103+
*/
98104
PGAlignedBlock buffer;
99105
};
100106

src/backend/storage/page/bufpage.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,10 @@ PageSetChecksumCopy(Page page, BlockNumber blkno)
15221522
* and second to avoid wasting space in processes that never call this.
15231523
*/
15241524
if (pageCopy == NULL)
1525-
pageCopy = MemoryContextAlloc(TopMemoryContext, BLCKSZ);
1525+
pageCopy = MemoryContextAllocAligned(TopMemoryContext,
1526+
BLCKSZ,
1527+
PG_IO_ALIGN_SIZE,
1528+
0);
15261529

15271530
memcpy(pageCopy, (char *) page, BLCKSZ);
15281531
((PageHeader) pageCopy)->pd_checksum = pg_checksum_page(pageCopy, blkno);

src/backend/storage/smgr/md.c

+14-1
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,10 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
453453
int nbytes;
454454
MdfdVec *v;
455455

456+
/* If this build supports direct I/O, the buffer must be I/O aligned. */
457+
if (PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ)
458+
Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));
459+
456460
/* This assert is too expensive to have on normally ... */
457461
#ifdef CHECK_WRITE_VS_EXTEND
458462
Assert(blocknum >= mdnblocks(reln, forknum));
@@ -783,6 +787,10 @@ mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
783787
int nbytes;
784788
MdfdVec *v;
785789

790+
/* If this build supports direct I/O, the buffer must be I/O aligned. */
791+
if (PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ)
792+
Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));
793+
786794
TRACE_POSTGRESQL_SMGR_MD_READ_START(forknum, blocknum,
787795
reln->smgr_rlocator.locator.spcOid,
788796
reln->smgr_rlocator.locator.dbOid,
@@ -848,6 +856,10 @@ mdwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
848856
int nbytes;
849857
MdfdVec *v;
850858

859+
/* If this build supports direct I/O, the buffer must be I/O aligned. */
860+
if (PG_O_DIRECT != 0 && PG_IO_ALIGN_SIZE <= BLCKSZ)
861+
Assert((uintptr_t) buffer == TYPEALIGN(PG_IO_ALIGN_SIZE, buffer));
862+
851863
/* This assert is too expensive to have on normally ... */
852864
#ifdef CHECK_WRITE_VS_EXTEND
853865
Assert(blocknum < mdnblocks(reln, forknum));
@@ -1429,7 +1441,8 @@ _mdfd_getseg(SMgrRelation reln, ForkNumber forknum, BlockNumber blkno,
14291441
*/
14301442
if (nblocks < ((BlockNumber) RELSEG_SIZE))
14311443
{
1432-
char *zerobuf = palloc0(BLCKSZ);
1444+
char *zerobuf = palloc_aligned(BLCKSZ, PG_IO_ALIGN_SIZE,
1445+
MCXT_ALLOC_ZERO);
14331446

14341447
mdextend(reln, forknum,
14351448
nextsegno * ((BlockNumber) RELSEG_SIZE) - 1,

src/backend/utils/sort/logtape.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ ltsWriteBlock(LogicalTapeSet *lts, long blocknum, const void *buffer)
252252
*/
253253
while (blocknum > lts->nBlocksWritten)
254254
{
255-
PGAlignedBlock zerobuf;
255+
PGIOAlignedBlock zerobuf;
256256

257257
MemSet(zerobuf.data, 0, sizeof(zerobuf));
258258

src/bin/pg_checksums/pg_checksums.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ skipfile(const char *fn)
183183
static void
184184
scan_file(const char *fn, int segmentno)
185185
{
186-
PGAlignedBlock buf;
186+
PGIOAlignedBlock buf;
187187
PageHeader header = (PageHeader) buf.data;
188188
int f;
189189
BlockNumber blockno;

src/bin/pg_rewind/local_source.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ static void
7777
local_queue_fetch_file(rewind_source *source, const char *path, size_t len)
7878
{
7979
const char *datadir = ((local_source *) source)->datadir;
80-
PGAlignedBlock buf;
80+
PGIOAlignedBlock buf;
8181
char srcpath[MAXPGPATH];
8282
int srcfd;
8383
size_t written_len;
@@ -129,7 +129,7 @@ local_queue_fetch_range(rewind_source *source, const char *path, off_t off,
129129
size_t len)
130130
{
131131
const char *datadir = ((local_source *) source)->datadir;
132-
PGAlignedBlock buf;
132+
PGIOAlignedBlock buf;
133133
char srcpath[MAXPGPATH];
134134
int srcfd;
135135
off_t begin = off;

src/bin/pg_upgrade/file.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@ rewriteVisibilityMap(const char *fromfile, const char *tofile,
178178
{
179179
int src_fd;
180180
int dst_fd;
181-
PGAlignedBlock buffer;
182-
PGAlignedBlock new_vmbuf;
181+
PGIOAlignedBlock buffer;
182+
PGIOAlignedBlock new_vmbuf;
183183
ssize_t totalBytesRead = 0;
184184
ssize_t src_filesize;
185185
int rewriteVmBytesPerPage;

src/common/file_utils.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -540,8 +540,8 @@ pg_pwritev_with_retry(int fd, const struct iovec *iov, int iovcnt, off_t offset)
540540
ssize_t
541541
pg_pwrite_zeros(int fd, size_t size, off_t offset)
542542
{
543-
static const PGAlignedBlock zbuffer = {{0}}; /* worth BLCKSZ */
544-
void *zerobuf_addr = unconstify(PGAlignedBlock *, &zbuffer)->data;
543+
static const PGIOAlignedBlock zbuffer = {{0}}; /* worth BLCKSZ */
544+
void *zerobuf_addr = unconstify(PGIOAlignedBlock *, &zbuffer)->data;
545545
struct iovec iov[PG_IOV_MAX];
546546
size_t remaining_size = size;
547547
ssize_t total_written = 0;

src/include/c.h

+26-8
Original file line numberDiff line numberDiff line change
@@ -1119,14 +1119,11 @@ extern void ExceptionalCondition(const char *conditionName,
11191119

11201120
/*
11211121
* Use this, not "char buf[BLCKSZ]", to declare a field or local variable
1122-
* holding a page buffer, if that page might be accessed as a page and not
1123-
* just a string of bytes. Otherwise the variable might be under-aligned,
1124-
* causing problems on alignment-picky hardware. (In some places, we use
1125-
* this to declare buffers even though we only pass them to read() and
1126-
* write(), because copying to/from aligned buffers is usually faster than
1127-
* using unaligned buffers.) We include both "double" and "int64" in the
1128-
* union to ensure that the compiler knows the value must be MAXALIGN'ed
1129-
* (cf. configure's computation of MAXIMUM_ALIGNOF).
1122+
* holding a page buffer, if that page might be accessed as a page. Otherwise
1123+
* the variable might be under-aligned, causing problems on alignment-picky
1124+
* hardware. We include both "double" and "int64" in the union to ensure that
1125+
* the compiler knows the value must be MAXALIGN'ed (cf. configure's
1126+
* computation of MAXIMUM_ALIGNOF).
11301127
*/
11311128
typedef union PGAlignedBlock
11321129
{
@@ -1135,9 +1132,30 @@ typedef union PGAlignedBlock
11351132
int64 force_align_i64;
11361133
} PGAlignedBlock;
11371134

1135+
/*
1136+
* Use this to declare a field or local variable holding a page buffer, if that
1137+
* page might be accessed as a page or passed to an SMgr I/O function. If
1138+
* allocating using the MemoryContext API, the aligned allocation functions
1139+
* should be used with PG_IO_ALIGN_SIZE. This alignment may be more efficient
1140+
* for I/O in general, but may be strictly required on some platforms when
1141+
* using direct I/O.
1142+
*/
1143+
typedef union PGIOAlignedBlock
1144+
{
1145+
#ifdef pg_attribute_aligned
1146+
pg_attribute_aligned(PG_IO_ALIGN_SIZE)
1147+
#endif
1148+
char data[BLCKSZ];
1149+
double force_align_d;
1150+
int64 force_align_i64;
1151+
} PGIOAlignedBlock;
1152+
11381153
/* Same, but for an XLOG_BLCKSZ-sized buffer */
11391154
typedef union PGAlignedXLogBlock
11401155
{
1156+
#ifdef pg_attribute_aligned
1157+
pg_attribute_aligned(PG_IO_ALIGN_SIZE)
1158+
#endif
11411159
char data[XLOG_BLCKSZ];
11421160
double force_align_d;
11431161
int64 force_align_i64;

0 commit comments

Comments
 (0)