postgres.git / summary / log / commit / refs
commit 984d56b80f5a945db2bfa80499b5ed913848242b
Author: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu Jul 29 19:23:20 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 431b06568bd..b16232a0b52 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.336 2010/07/29 11:06:34 sriggs Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.337 2010/07/29 19:23:20 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -7230,11 +7230,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/streaming is
@@ -7263,6 +7272,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: 5b48e2ecd469]