PG-286: Reduce calls to pgstat_fetch_stat_numbackends().

After couple CPU profiling sessions with perf, it was detected that the
function pgstat_fetch_stat_numbackends() is very expensive, reading the
implementation on PostgreSQL's backend_status.c just confirmed that.

We use that function on pg_stat_monitor to retrieve the application name
and IP address of the client, we now cache the results in order to avoid
calling it for every query being processed.
This commit is contained in:
Diego Fronza
2021-12-03 14:14:31 -03:00
parent d32dea0daa
commit 59c321ebc5

View File

@@ -104,12 +104,11 @@ PG_FUNCTION_INFO_V1(pg_stat_monitor_settings);
PG_FUNCTION_INFO_V1(get_histogram_timings);
PG_FUNCTION_INFO_V1(pg_stat_monitor_hook_stats);
static uint pg_get_client_addr(void);
static int pg_get_application_name(char* application_name);
static uint pg_get_client_addr(bool *ok);
static int pg_get_application_name(char *application_name, bool *ok);
static PgBackendStatus *pg_get_backend_status(void);
static Datum intarray_get_datum(int32 arr[], int len);
#if PG_VERSION_NUM < 140000
DECLARE_HOOK(void pgss_post_parse_analyze, ParseState *pstate, Query *query);
#else
@@ -1132,46 +1131,44 @@ pg_get_backend_status(void)
}
static int
pg_get_application_name(char *application_name)
pg_get_application_name(char *application_name, bool *ok)
{
PgBackendStatus *beentry = pg_get_backend_status();
if (!beentry)
return snprintf(application_name, APPLICATIONNAME_LEN, "%s", "postmaster");
if (!beentry)
return snprintf(application_name, APPLICATIONNAME_LEN, "%s", "unknown");
*ok = true;
return snprintf(application_name, APPLICATIONNAME_LEN, "%s", beentry->st_appname);
}
static uint
pg_get_client_addr(void)
pg_get_client_addr(bool *ok)
{
PgBackendStatus *beentry = pg_get_backend_status();
char remote_host[NI_MAXHOST];
int ret;
static uint localhost = 0;
remote_host[0] = '\0';
if (!beentry)
return ntohl(inet_addr("127.0.0.1"));
*ok = true;
ret = pg_getnameinfo_all(&beentry->st_clientaddr.addr,
beentry->st_clientaddr.salen,
remote_host, sizeof(remote_host),
NULL, 0,
NI_NUMERICHOST | NI_NUMERICSERV);
if (ret != 0)
{
if (localhost == 0)
localhost = ntohl(inet_addr("127.0.0.1"));
return localhost;
}
return ntohl(inet_addr("127.0.0.1"));
if (strcmp(remote_host, "[local]") == 0)
{
if (localhost == 0)
localhost = ntohl(inet_addr("127.0.0.1"));
return localhost;
}
return ntohl(inet_addr("127.0.0.1"));
return ntohl(inet_addr(remote_host));
}
@@ -1191,11 +1188,11 @@ pgss_update_entry(pgssEntry *entry,
BufferUsage *bufusage,
WalUsage *walusage,
bool reset,
pgssStoreKind kind)
pgssStoreKind kind,
const char *app_name,
size_t app_name_len)
{
int index;
char application_name[APPLICATIONNAME_LEN];
int application_name_len = pg_get_application_name(application_name);
double old_mean;
int message_len = error_info ? strlen (error_info->message) : 0;
int comments_len = comments ? strlen (comments) : 0;
@@ -1264,11 +1261,11 @@ pgss_update_entry(pgssEntry *entry,
e->counters.resp_calls[index]++;
}
if (plan_text_len > 0)
if (plan_text_len > 0 && !e->counters.planinfo.plan_text[0])
_snprintf(e->counters.planinfo.plan_text, plan_info->plan_text, plan_text_len + 1, PLAN_TEXT_LEN);
if (application_name_len > 0)
_snprintf(e->counters.info.application_name, application_name, application_name_len + 1, APPLICATIONNAME_LEN);
if (app_name_len > 0 && !e->counters.info.application_name[0])
_snprintf(e->counters.info.application_name, app_name, app_name_len + 1, APPLICATIONNAME_LEN);
e->counters.info.num_relations = num_relations;
_snprintf2(e->counters.info.relations, relations, num_relations, REL_LEN);
@@ -1465,8 +1462,8 @@ pgss_store(uint64 queryid,
pgssHashKey key;
pgssEntry *entry;
pgssSharedState *pgss = pgsm_get_ss();
char application_name[APPLICATIONNAME_LEN];
int application_name_len;
static char application_name[APPLICATIONNAME_LEN] = "";
static int application_name_len = 0;
bool reset = false;
uint64 bucketid;
uint64 prev_bucket_id;
@@ -1474,6 +1471,9 @@ pgss_store(uint64 queryid,
uint64 planid;
uint64 appid;
char comments[512] = "";
static bool found_app_name = false;
static bool found_client_addr = false;
static uint client_addr = 0;
/* Monitoring is disabled */
if (!PGSM_ENABLED)
@@ -1492,7 +1492,12 @@ pgss_store(uint64 queryid,
else
userid = GetUserId();
application_name_len = pg_get_application_name(application_name);
if (!found_app_name)
application_name_len = pg_get_application_name(application_name, &found_app_name);
if (!found_client_addr)
client_addr = pg_get_client_addr(&found_client_addr);
planid = plan_info ? plan_info->planid : 0;
appid = djb2_hash((unsigned char *)application_name, application_name_len);
@@ -1508,7 +1513,7 @@ pgss_store(uint64 queryid,
key.userid = userid;
key.dbid = MyDatabaseId;
key.queryid = queryid;
key.ip = pg_get_client_addr();
key.ip = client_addr;
key.planid = planid;
key.appid = appid;
#if PG_VERSION_NUM < 140000
@@ -1596,7 +1601,9 @@ pgss_store(uint64 queryid,
bufusage, /* bufusage */
walusage, /* walusage */
reset, /* reset */
kind); /* kind */
kind, /* kind */
application_name,
application_name_len);
LWLockRelease(pgss->lock);
}