mirror of https://github.com/postgres/postgres
Add prefetching support on macOS
macOS doesn't have posix_fadvise(), but fcntl() with the F_RDADVISE command does the same thing. Some related documentation has been generalized to not mention posix_advise() specifically anymore. Reviewed-by: Thomas Munro <thomas.munro@gmail.com> Discussion: https://www.postgresql.org/message-id/flat/0827edec-1317-4917-a186-035eb1e3241d%40eisentraut.org
This commit is contained in:
parent
2e6a8047f0
commit
6654bb9204
|
@ -2679,11 +2679,9 @@ include_dir 'conf.d'
|
|||
</para>
|
||||
|
||||
<para>
|
||||
Asynchronous I/O depends on an effective <function>posix_fadvise</function>
|
||||
function, which some operating systems lack. If the function is not
|
||||
present then setting this parameter to anything but zero will result
|
||||
in an error. On some operating systems (e.g., Solaris), the function
|
||||
is present but does not actually do anything.
|
||||
Asynchronous I/O requires that the operating system supports issuing
|
||||
read-ahead advice. If there is no operating system support then
|
||||
setting this parameter to anything but zero will result in an error.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
|
@ -3852,10 +3850,8 @@ include_dir 'conf.d'
|
|||
<literal>off</literal>, <literal>on</literal> and
|
||||
<literal>try</literal> (the default). The setting
|
||||
<literal>try</literal> enables
|
||||
prefetching only if the operating system provides the
|
||||
<function>posix_fadvise</function> function, which is currently used
|
||||
to implement prefetching. Note that some operating systems provide the
|
||||
function, but it doesn't do anything.
|
||||
prefetching only if the operating system provides support for issuing
|
||||
read-ahead advice.
|
||||
</para>
|
||||
<para>
|
||||
Prefetching blocks that will soon be needed can reduce I/O wait times
|
||||
|
|
|
@ -841,8 +841,8 @@
|
|||
The <xref linkend="guc-maintenance-io-concurrency"/> and
|
||||
<xref linkend="guc-wal-decode-buffer-size"/> settings limit prefetching
|
||||
concurrency and distance, respectively. By default, it is set to
|
||||
<literal>try</literal>, which enables the feature on systems where
|
||||
<function>posix_fadvise</function> is available.
|
||||
<literal>try</literal>, which enables the feature on systems that support
|
||||
issuing read-ahead advice.
|
||||
</para>
|
||||
</sect1>
|
||||
|
||||
|
|
|
@ -1212,7 +1212,7 @@ check_effective_io_concurrency(int *newval, void **extra, GucSource source)
|
|||
#ifndef USE_PREFETCH
|
||||
if (*newval != 0)
|
||||
{
|
||||
GUC_check_errdetail("\"effective_io_concurrency\" must be set to 0 on platforms that lack posix_fadvise().");
|
||||
GUC_check_errdetail("\"effective_io_concurrency\" must be set to 0 on platforms that lack support for issuing read-ahead advice.");
|
||||
return false;
|
||||
}
|
||||
#endif /* USE_PREFETCH */
|
||||
|
@ -1225,7 +1225,7 @@ check_maintenance_io_concurrency(int *newval, void **extra, GucSource source)
|
|||
#ifndef USE_PREFETCH
|
||||
if (*newval != 0)
|
||||
{
|
||||
GUC_check_errdetail("\"maintenance_io_concurrency\" must be set to 0 on platforms that lack posix_fadvise().");
|
||||
GUC_check_errdetail("\"maintenance_io_concurrency\" must be set to 0 on platforms that lack support for issuing read-ahead advice.");
|
||||
return false;
|
||||
}
|
||||
#endif /* USE_PREFETCH */
|
||||
|
|
|
@ -2068,40 +2068,59 @@ FileClose(File file)
|
|||
/*
|
||||
* FilePrefetch - initiate asynchronous read of a given range of the file.
|
||||
*
|
||||
* Currently the only implementation of this function is using posix_fadvise
|
||||
* which is the simplest standardized interface that accomplishes this.
|
||||
* We could add an implementation using libaio in the future; but note that
|
||||
* this API is inappropriate for libaio, which wants to have a buffer provided
|
||||
* to read into.
|
||||
* Returns 0 on success, otherwise an errno error code (like posix_fadvise()).
|
||||
*
|
||||
* posix_fadvise() is the simplest standardized interface that accomplishes
|
||||
* this.
|
||||
*/
|
||||
int
|
||||
FilePrefetch(File file, off_t offset, off_t amount, uint32 wait_event_info)
|
||||
{
|
||||
#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
|
||||
int returnCode;
|
||||
|
||||
Assert(FileIsValid(file));
|
||||
|
||||
DO_DB(elog(LOG, "FilePrefetch: %d (%s) " INT64_FORMAT " " INT64_FORMAT,
|
||||
file, VfdCache[file].fileName,
|
||||
(int64) offset, (int64) amount));
|
||||
|
||||
returnCode = FileAccess(file);
|
||||
if (returnCode < 0)
|
||||
return returnCode;
|
||||
#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_WILLNEED)
|
||||
{
|
||||
int returnCode;
|
||||
|
||||
returnCode = FileAccess(file);
|
||||
if (returnCode < 0)
|
||||
return returnCode;
|
||||
|
||||
retry:
|
||||
pgstat_report_wait_start(wait_event_info);
|
||||
returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
|
||||
POSIX_FADV_WILLNEED);
|
||||
pgstat_report_wait_end();
|
||||
pgstat_report_wait_start(wait_event_info);
|
||||
returnCode = posix_fadvise(VfdCache[file].fd, offset, amount,
|
||||
POSIX_FADV_WILLNEED);
|
||||
pgstat_report_wait_end();
|
||||
|
||||
if (returnCode == EINTR)
|
||||
goto retry;
|
||||
if (returnCode == EINTR)
|
||||
goto retry;
|
||||
|
||||
return returnCode;
|
||||
return returnCode;
|
||||
}
|
||||
#elif defined(__darwin__)
|
||||
{
|
||||
struct radvisory
|
||||
{
|
||||
off_t ra_offset; /* offset into the file */
|
||||
int ra_count; /* size of the read */
|
||||
} ra;
|
||||
int returnCode;
|
||||
|
||||
ra.ra_offset = offset;
|
||||
ra.ra_count = amount;
|
||||
pgstat_report_wait_start(wait_event_info);
|
||||
returnCode = fcntl(VfdCache[file].fd, F_RDADVISE, &ra);
|
||||
pgstat_report_wait_end();
|
||||
if (returnCode != -1)
|
||||
return 0;
|
||||
else
|
||||
return errno;
|
||||
}
|
||||
#else
|
||||
Assert(FileIsValid(file));
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -139,9 +139,8 @@
|
|||
/*
|
||||
* USE_PREFETCH code should be compiled only if we have a way to implement
|
||||
* prefetching. (This is decoupled from USE_POSIX_FADVISE because there
|
||||
* might in future be support for alternative low-level prefetch APIs.
|
||||
* If you change this, you probably need to adjust the error message in
|
||||
* check_effective_io_concurrency.)
|
||||
* might in future be support for alternative low-level prefetch APIs,
|
||||
* as well as platform-specific APIs defined elsewhere.)
|
||||
*/
|
||||
#ifdef USE_POSIX_FADVISE
|
||||
#define USE_PREFETCH
|
||||
|
|
|
@ -6,3 +6,8 @@
|
|||
#define HAVE_FSYNC_WRITETHROUGH
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* macOS has a platform-specific implementation of prefetching.
|
||||
*/
|
||||
#define USE_PREFETCH
|
||||
|
|
Loading…
Reference in New Issue