diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 06f5eb0..340e0fd 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -3408,7 +3408,9 @@ XLogFileInit(XLogSegNo logsegno, bool *use_existent, bool use_lock) ereport(ERROR, (errcode_for_file_access(), errmsg("could not create file \"%s\": %m", tmppath))); - +#if defined(HAVE_FALLOCATE) + fallocate(fd, FALLOC_FL_KEEP_SIZE, 0, XLogSegSize); +#endif /* * Zero-fill the file. We have to do this the hard way to ensure that all * the file space has really been allocated --- on platforms that allow diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index de4d902..afa3d24 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -383,6 +383,21 @@ pg_flush_data(int fd, off_t offset, off_t amount) return 0; } +/* + * pg_fallocate --- advise OS that the data pre-allocate continus file segments + * in physical disk. + * + * Not all platforms have fallocate. Some platforms only have posix_fallocate, + * but it ped zero fill to get pre-allocate file segmnets. It is not good + * peformance when extend new segmnets, so we don't use posix_fallocate. + */ +int +pg_fallocate(File file, int flags, off_t offset, off_t nbytes) +{ +#if defined(HAVE_FALLOCATE) + return fallocate(VfdCache[file].fd, flags, offset, nbytes); +#endif +} /* * fsync_fname -- fsync a file or directory, handling errors properly diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index e629181..fe6f640 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "miscadmin.h" #include "access/xlog.h" @@ -510,6 +511,10 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, * if bufmgr.c had to dump another buffer of the same file to make room * for the new page's buffer. */ + + if(forknum == 1) + pg_fallocate(v->mdfd_vfd, FALLOC_FL_KEEP_SIZE, 0, RELSEG_SIZE); + if (FileSeek(v->mdfd_vfd, seekpos, SEEK_SET) != seekpos) ereport(ERROR, (errcode_for_file_access(), diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in index 5eac52d..43d8eaf 100644 --- a/src/include/pg_config.h.in +++ b/src/include/pg_config.h.in @@ -146,6 +146,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_EDITLINE_READLINE_H +/* Define to 1 if you have the 'fallocate' function. */ +#undef HAVE_FALLOCATE + /* Define to 1 if you have the `fdatasync' function. */ #undef HAVE_FDATASYNC diff --git a/src/include/pg_config.h.win32 b/src/include/pg_config.h.win32 index 54db287..b8643fc 100644 --- a/src/include/pg_config.h.win32 +++ b/src/include/pg_config.h.win32 @@ -112,6 +112,9 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_EDITLINE_READLINE_H */ +/* Define to 1 if you have the 'fallocate' function. */ +/* #undef HAVE FALLOCATE */ + /* Define to 1 if you have the `fcvt' function. */ #define HAVE_FCVT 1 diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h index 2a60229..5ac1f6a 100644 --- a/src/include/storage/fd.h +++ b/src/include/storage/fd.h @@ -113,6 +113,7 @@ extern int pg_fsync_no_writethrough(int fd); extern int pg_fsync_writethrough(int fd); extern int pg_fdatasync(int fd); extern int pg_flush_data(int fd, off_t offset, off_t amount); +extern int pg_fallocate(File file, int flags, off_t offset, off_t amount); extern void fsync_fname(char *fname, bool isdir); /* Filename components for OpenTemporaryFile */