postgres.git / summary / log / commit / refs

commit    b08fd11508a2b36e64f456d8e0345f1c66dae333
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Thu Jul 29 19:23:37 2010 +0000
First released in: 9.1.0, 8.0.26, 8.1.22, 8.2.18, 8.3.12, 8.4.5, 9.0.0

    Fix another longstanding problem in copy_relation_data: it was blithely
    assuming that a local char[] array would be aligned on at least a word
    boundary.  There are architectures on which that is pretty much guaranteed to
    NOT be the case ... and those arches also don't like non-aligned memory
    accesses, meaning that log_newpage() would crash if it ever got invoked.
    Even on Intel-ish machines there's a potential for a large performance penalty
    from doing I/O to an inadequately aligned buffer.  So palloc it instead.
    
    Backpatch to 8.0 --- 7.4 doesn't have this code.


src/backend/commands/tablecmds.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 3a899125a62..d07e51fb658 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.288.2.4 2010/07/01 14:12:04 rhaas Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.288.2.5 2010/07/29 19:23:37 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -6822,11 +6822,20 @@ static void copy_relation_data(SMgrRelation src, SMgrRelation dst, ForkNumber forkNum, bool istemp) { + char *buf; + Page page; bool use_wal; BlockNumber nblocks; BlockNumber blkno; - char buf[BLCKSZ]; - Page page = (Page) buf; + + /* + * palloc the buffer so that it's MAXALIGN'd. If it were just a local + * char[] array, the compiler might align it on any byte boundary, which + * can seriously hurt transfer speed to and from the kernel; not to + * mention possibly making log_newpage's accesses to the page header fail. + */ + buf = (char *) palloc(BLCKSZ); + page = (Page) buf; /* * We need to log the copied data in WAL iff WAL archiving is enabled AND @@ -6855,6 +6864,8 @@ copy_relation_data(SMgrRelation src, SMgrRelation dst, smgrextend(dst, forkNum, blkno, buf, true); } + pfree(buf); + /* * If the rel isn't temp, we must fsync it down to disk before it's safe * to commit the transaction. (For a temp rel we don't care since the rel [parent: 2d8346182f5c]