On Sun, 18 Feb 2001, Tom Lane wrote: > I think that there may be a performance advantage to pre-filling the > logfile even so, assuming that file allocation info is stored in a > Berkeley/McKusik-like fashion (note: I have no idea what ext2 or > reiserfs actually do). ext2 is a lot like [UF]FS. reiserfs is very different, but does have similar hole semantics. BTW, I have attached two patches which streamline log initialisation a little. The first (xlog-sendfile.diff) adds support for Linux's sendfile system call. FreeBSD and HP/UX have sendfile() too, but the prototype is different. If it's interesting, someone will have to come up with a configure test, as autoconf scares me. The second removes a further three syscalls from the log init path. There are a couple of things to note here: * I don't know why link/unlink is currently preferred over rename. POSIX offers strong guarantees on the semantics of the latter. * I have assumed that the close/rename/reopen stuff is only there for the benefit of Windows users, and ifdeffed it for everyone else. Matthew.
--- xlog.c.old Mon Feb 19 12:35:53 2001 +++ xlog.c Mon Feb 19 13:05:23 2001 @@ -24,6 +24,10 @@ #include <locale.h> #endif +#ifdef _HAVE_LINUX_SENDFILE +#include <sys/sendfile.h> +#endif + #include "access/transam.h" #include "access/xact.h" #include "catalog/catversion.h" @@ -962,6 +966,24 @@ elog(STOP, "InitCreate(logfile %u seg %u) failed: %m", logId, logSeg); +#ifdef _HAVE_LINUX_SENDFILE + { + static int zfd = -1; + ssize_t len; + + if (zfd < 0) { + zfd = BasicOpenFile("/dev/zero", O_RDONLY, 0); + if (zfd < 0) + elog(STOP, "Can't open /dev/zero: %m"); + } + len = sendfile(fd, zfd, NULL, XLogSegSize); + if (len < 0) + /* XXX - header support sendfile, but kernel doesn't? Fall +back */ + elog(STOP, "sendfile failed: %m"); + if (len < XLogSegSize) + elog(STOP, "short read on sendfile: %m"); + } +#else if (lseek(fd, XLogSegSize - 1, SEEK_SET) != (off_t) (XLogSegSize - 1)) elog(STOP, "lseek(logfile %u seg %u) failed: %m", logId, logSeg); @@ -969,6 +991,7 @@ if (write(fd, "", 1) != 1) elog(STOP, "write(logfile %u seg %u) failed: %m", logId, logSeg); +#endif if (pg_fsync(fd) != 0) elog(STOP, "fsync(logfile %u seg %u) failed: %m",
--- xlog.c.sf Mon Feb 19 13:10:38 2001 +++ xlog.c Mon Feb 19 13:13:55 2001 @@ -1001,22 +1001,20 @@ elog(STOP, "lseek(logfile %u seg %u off %u) failed: %m", log, seg, 0); +#ifndef WIN32 close(fd); +#endif -#ifndef __BEOS__ - if (link(tpath, path) < 0) -#else if (rename(tpath, path) < 0) -#endif elog(STOP, "InitRelink(logfile %u seg %u) failed: %m", logId, logSeg); - unlink(tpath); - +#ifndef WIN32 fd = BasicOpenFile(path, O_RDWR | PG_BINARY, S_IRUSR | S_IWUSR); if (fd < 0) elog(STOP, "InitReopen(logfile %u seg %u) failed: %m", logId, logSeg); +#endif return (fd); }