On Thu, Mar 09, 2023 at 03:02:29PM -0500, Stephen Frost wrote: > * Justin Pryzby (pry...@telsasoft.com) wrote: > > On Thu, Mar 09, 2023 at 09:34:10AM -0500, Stephen Frost wrote: > > > * Nathan Bossart (nathandboss...@gmail.com) wrote: > > > > On Wed, Feb 15, 2023 at 10:13:17AM -0800, Nathan Bossart wrote: > > > > > On Tue, Feb 14, 2023 at 07:32:56PM -0600, Justin Pryzby wrote: > > > > >> On Mon, Feb 13, 2023 at 08:18:52PM -0800, Nathan Bossart wrote: > > > > >>> I'm curious why you chose to make this a string instead of an enum. > > > > >>> There > > > > >>> might be little practical difference, but since there are only three > > > > >>> possible values, I wonder if it'd be better form to make it an enum. > > > > >> > > > > >> It takes more code to write as an enum - see 002.txt. I'm not > > > > >> convinced > > > > >> this is better. > > > > >> > > > > >> But your comment made me fix its <type>, and reconsider the strings, > > > > >> which I changed to active={unknown/true/false} rather than > > > > >> {unk/on/off}. > > > > >> It could also be active={unknown/yes/no}... > > > > > > > > > > I think unknown/true/false is fine. I'm okay with using a string if > > > > > no one > > > > > else thinks it should be an enum (or a bool). > > > > > > > > There's been no response for this, so I guess we can proceed with a > > > > string > > > > GUC. > > > > > > Just happened to see this and I'm not really a fan of this being a > > > string when it's pretty clear that's not what it actually is. > > > > I don't understand what you mean by that. > > Why do you say it isn't a string ? > > Because it's clearly a yes/no, either the server is currently running > with huge pages, or it isn't. That's the definition of a boolean.
I originally implemented it as a boolean, and I changed it in response to the feedback that postgres -C huge_pages_active should return "unknown". > > Is there an agreement to use a function, instead ? Alvaro was -1 on using a function Andres is +0 (?) Nathan is +1 Stephen is +1 I'm -0.5, but I reimplemented it as a function. I hope that helps it to progress. Please include a suggestion if there's better place for the function or global var. -- Justin
>From cd171da2150e1ee8cfc6ca4bdee0a591df6f566b Mon Sep 17 00:00:00 2001 From: Justin Pryzby <pryz...@telsasoft.com> Date: Mon, 23 Jan 2023 18:33:51 -0600 Subject: [PATCH v5] add pg_huge_pages_active() This is useful to show the current state of huge pages when huge_pages=try. The effective status is not otherwise visible without OS level tools like gdb or /proc/N/smaps. https://www.postgresql.org/message-id/flat/tu4pr8401mb1152ebb0d271f827e2e37a01ee...@tu4pr8401mb1152.namprd84.prod.outlook.com --- doc/src/sgml/config.sgml | 3 ++- doc/src/sgml/func.sgml | 14 ++++++++++++++ src/backend/port/sysv_shmem.c | 2 ++ src/backend/port/win32_shmem.c | 2 ++ src/backend/utils/adt/misc.c | 11 +++++++++++ src/include/catalog/pg_proc.dat | 5 +++++ src/include/miscadmin.h | 3 +++ 7 files changed, 39 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index e5c41cc6c6d..d66f73a494a 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -1700,23 +1700,24 @@ include_dir 'conf.d' </indexterm> </term> <listitem> <para> Controls whether huge pages are requested for the main shared memory area. Valid values are <literal>try</literal> (the default), <literal>on</literal>, and <literal>off</literal>. With <varname>huge_pages</varname> set to <literal>try</literal>, the server will try to request huge pages, but fall back to the default if that fails. With <literal>on</literal>, failure to request huge pages will prevent the server from starting up. With <literal>off</literal>, - huge pages will not be requested. + huge pages will not be requested. The actual state of huge pages is + indicated by <function>pg_huge_pages_active()</function>. </para> <para> At present, this setting is supported only on Linux and Windows. The setting is ignored on other systems when set to <literal>try</literal>. On Linux, it is only supported when <varname>shared_memory_type</varname> is set to <literal>mmap</literal> (the default). </para> <para> diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index a5bf2f01b57..4e99d5aff5c 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -22516,22 +22516,36 @@ SELECT * FROM pg_ls_dir('.') WITH ORDINALITY AS t(ls,n); To request information about a specific log file format, supply either <literal>csvlog</literal>, <literal>jsonlog</literal> or <literal>stderr</literal> as the value of the optional parameter. The result is <literal>NULL</literal> if the log format requested is not configured in <xref linkend="guc-log-destination"/>. The result reflects the contents of the <filename>current_logfiles</filename> file. </para></entry> </row> + <row> + <entry role="func_table_entry"><para role="func_signature"> + <indexterm> + <primary>pg_huge_pages_active</primary> + </indexterm> + <function>pg_huge_pages_active</function> () + <returnvalue>bool</returnvalue> + </para> + <para> + Reports whether huge pages are in use by the current instance. + See <xref linkend="guc-huge-pages"/> for more information. + </para></entry> + </row> + <row> <entry role="func_table_entry"><para role="func_signature"> <indexterm> <primary>pg_my_temp_schema</primary> </indexterm> <function>pg_my_temp_schema</function> () <returnvalue>oid</returnvalue> </para> <para> Returns the OID of the current session's temporary schema, or zero if it has none (because it has not created any temporary tables). diff --git a/src/backend/port/sysv_shmem.c b/src/backend/port/sysv_shmem.c index eaba244bc9c..9ff2d7b3d38 100644 --- a/src/backend/port/sysv_shmem.c +++ b/src/backend/port/sysv_shmem.c @@ -619,22 +619,24 @@ CreateAnonymousSegment(Size *size) allocsize += hugepagesize - (allocsize % hugepagesize); ptr = mmap(NULL, allocsize, PROT_READ | PROT_WRITE, PG_MMAP_FLAGS | mmap_flags, -1, 0); mmap_errno = errno; if (huge_pages == HUGE_PAGES_TRY && ptr == MAP_FAILED) elog(DEBUG1, "mmap(%zu) with MAP_HUGETLB failed, huge pages disabled: %m", allocsize); } #endif + huge_pages_active = (ptr != MAP_FAILED); + if (ptr == MAP_FAILED && huge_pages != HUGE_PAGES_ON) { /* * Use the original size, not the rounded-up value, when falling back * to non-huge pages. */ allocsize = *size; ptr = mmap(NULL, allocsize, PROT_READ | PROT_WRITE, PG_MMAP_FLAGS, -1, 0); mmap_errno = errno; } diff --git a/src/backend/port/win32_shmem.c b/src/backend/port/win32_shmem.c index 62e08074770..f97971ef340 100644 --- a/src/backend/port/win32_shmem.c +++ b/src/backend/port/win32_shmem.c @@ -319,22 +319,24 @@ retry: * If the segment already existed, CreateFileMapping() will return a * handle to the existing one and set ERROR_ALREADY_EXISTS. */ if (GetLastError() == ERROR_ALREADY_EXISTS) { CloseHandle(hmap); /* Close the handle, since we got a valid one * to the previous segment. */ hmap = NULL; Sleep(1000); continue; } + + huge_pages_active = ((flProtect & SEC_LARGE_PAGES) != 0); break; } /* * If the last call in the loop still returned ERROR_ALREADY_EXISTS, this * shared memory segment exists and we assume it belongs to somebody else. */ if (!hmap) ereport(FATAL, (errmsg("pre-existing shared memory block is still in use"), errhint("Check if there are any old server processes still running, and terminate them."))); diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 5d78d6dc060..3c175d88c59 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -1070,11 +1070,22 @@ pg_get_replica_identity_index(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } /* * Transition function for the ANY_VALUE aggregate */ Datum any_value_transfn(PG_FUNCTION_ARGS) { PG_RETURN_DATUM(PG_GETARG_DATUM(0)); } + +bool huge_pages_active = false; + +/* + * Return status of huge pages. + */ +Datum +pg_huge_pages_active(PG_FUNCTION_ARGS) +{ + PG_RETURN_BOOL(huge_pages_active); +} diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index ae658e721fd..7cfa11c994c 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -1811,22 +1811,27 @@ proname => 'bpchar', prorettype => 'bpchar', proargtypes => 'char', prosrc => 'char_bpchar' }, { oid => '861', descr => 'name of the current database', proname => 'current_database', provolatile => 's', prorettype => 'name', proargtypes => '', prosrc => 'current_database' }, { oid => '817', descr => 'get the currently executing query', proname => 'current_query', proisstrict => 'f', provolatile => 'v', proparallel => 'r', prorettype => 'text', proargtypes => '', prosrc => 'current_query' }, +{ oid => '8218', descr => 'get the state of huge pages', + proname => 'pg_huge_pages_active', proisstrict => 't', provolatile => 's', + proparallel => 's', prorettype => 'bool', proargtypes => '', + prosrc => 'pg_huge_pages_active' }, + { oid => '3399', proname => 'int8_mul_cash', prorettype => 'money', proargtypes => 'int8 money', prosrc => 'int8_mul_cash' }, { oid => '862', proname => 'int4_mul_cash', prorettype => 'money', proargtypes => 'int4 money', prosrc => 'int4_mul_cash' }, { oid => '863', proname => 'int2_mul_cash', prorettype => 'money', proargtypes => 'int2 money', prosrc => 'int2_mul_cash' }, { oid => '3344', proname => 'cash_mul_int8', prorettype => 'money', diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 06a86f9ac1f..8169e5bd6dd 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -268,22 +268,25 @@ extern PGDLLIMPORT int VacuumCostPageMiss; extern PGDLLIMPORT int VacuumCostPageDirty; extern PGDLLIMPORT int VacuumCostLimit; extern PGDLLIMPORT double VacuumCostDelay; extern PGDLLIMPORT int64 VacuumPageHit; extern PGDLLIMPORT int64 VacuumPageMiss; extern PGDLLIMPORT int64 VacuumPageDirty; extern PGDLLIMPORT int VacuumCostBalance; extern PGDLLIMPORT bool VacuumCostActive; +/* in adt/misc.c */ +extern PGDLLIMPORT bool huge_pages_active; + /* in tcop/postgres.c */ typedef char *pg_stack_base_t; extern pg_stack_base_t set_stack_base(void); extern void restore_stack_base(pg_stack_base_t base); extern void check_stack_depth(void); extern bool stack_is_too_deep(void); /* in tcop/utility.c */ -- 2.34.1