diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2010-07-29 19:23:44 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2010-07-29 19:23:44 +0000 |
commit | 242dc3819b9667eb4a8118a779932d42dce7d849 (patch) | |
tree | 8617a8579a384f99df3180edebce2644f6a33cac /src/backend/commands/tablecmds.c | |
parent | 0378e4e73de6019353caff1cca43562d0c0e49d6 (diff) |
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.
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 4181c1a1873..14757befdff 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.242.2.6 2010/07/01 14:11:42 rhaas Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.242.2.7 2010/07/29 19:23:44 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -5960,11 +5960,11 @@ static void copy_relation_data(Relation rel, SMgrRelation dst) { SMgrRelation src; + char *buf; + Page page; bool use_wal; BlockNumber nblocks; BlockNumber blkno; - char buf[BLCKSZ]; - Page page = (Page) buf; /* * Since we copy the file directly without looking at the shared buffers, @@ -5975,6 +5975,15 @@ copy_relation_data(Relation rel, SMgrRelation dst) FlushRelationBuffers(rel); /* + * 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 * it's not a temp rel. */ @@ -6003,6 +6012,8 @@ copy_relation_data(Relation rel, SMgrRelation dst) smgrextend(dst, 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 |