diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2014-04-04 13:12:38 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2014-04-04 13:35:44 +0300 |
commit | 877b088785b178c50e7976d86c82dfafa4031792 (patch) | |
tree | 985c0b79a92c0c329cb8e798441946311dc0fa08 /src/backend/access/transam/xlog.c | |
parent | c7b353959931ae8e95177fe0a138b8119db9b802 (diff) | |
download | postgresql-877b088785b178c50e7976d86c82dfafa4031792.tar.gz postgresql-877b088785b178c50e7976d86c82dfafa4031792.zip |
Avoid allocations in critical sections.
If a palloc in a critical section fails, it becomes a PANIC.
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 22 |
1 files changed, 8 insertions, 14 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index f9d6609d44f..e2a14de7212 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -859,9 +859,8 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata) if (rechdr == NULL) { - rechdr = malloc(SizeOfXLogRecord); - if (rechdr == NULL) - elog(ERROR, "out of memory"); + static char rechdrbuf[SizeOfXLogRecord + MAXIMUM_ALIGNOF]; + rechdr = (XLogRecord *) MAXALIGN(&rechdrbuf); MemSet(rechdr, 0, SizeOfXLogRecord); } @@ -3080,6 +3079,7 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) { char path[MAXPGPATH]; char tmppath[MAXPGPATH]; + char zbuffer_raw[BLCKSZ + MAXIMUM_ALIGNOF]; char *zbuffer; XLogSegNo installed_segno; int max_advance; @@ -3118,16 +3118,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) unlink(tmppath); - /* - * Allocate a buffer full of zeros. This is done before opening the file - * so that we don't leak the file descriptor if palloc fails. - * - * Note: palloc zbuffer, instead of just using a local char array, to - * ensure it is reasonably well-aligned; this may save a few cycles - * transferring data to the kernel. - */ - zbuffer = (char *) palloc0(XLOG_BLCKSZ); - /* do not use get_sync_bit() here --- want to fsync only at end of fill */ fd = BasicOpenFile(tmppath, O_RDWR | O_CREAT | O_EXCL | PG_BINARY, S_IRUSR | S_IWUSR); @@ -3144,7 +3134,12 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) * fsync below) that all the indirect blocks are down on disk. Therefore, * fdatasync(2) or O_DSYNC will be sufficient to sync future writes to the * log file. + * + * Note: ensure the buffer is reasonably well-aligned; this may save a few + * cycles transferring data to the kernel. */ + zbuffer = (char *) MAXALIGN(zbuffer_raw); + memset(zbuffer, 0, BLCKSZ); for (nbytes = 0; nbytes < XLogSegSize; nbytes += XLOG_BLCKSZ) { errno = 0; @@ -3167,7 +3162,6 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) errmsg("could not write to file \"%s\": %m", tmppath))); } } - pfree(zbuffer); if (pg_fsync(fd) != 0) { |