From 65fddf256c16a9667978c58cd59a2e52a94e7711 Mon Sep 17 00:00:00 2001 From: Yuki Seino Date: Tue, 14 Feb 2023 12:09:53 +0900 Subject: [PATCH] Add CLI Excuter in SQL. --- agent/lib/library.map | 3 +- agent/lib/libstatsinfo.c | 53 +++++++++++++++++++++++++++++++++++ agent/lib/pg_statsinfo.sql.in | 7 +++++ doc/pg_statsinfo-ja.md | 14 +++++++++ doc/pg_statsinfo.md | 15 ++++++++++ 5 files changed, 91 insertions(+), 1 deletion(-) diff --git a/agent/lib/library.map b/agent/lib/library.map index 0c9af41..a628d70 100644 --- a/agent/lib/library.map +++ b/agent/lib/library.map @@ -19,7 +19,7 @@ statsinfo_meminfo; statsinfo_rusage; statsinfo_rusage_reset; - statsinfo_rusage_info; + statsinfo_rusage_info; statsinfo_sample; statsinfo_sample_wait_sampling; statsinfo_sample_wait_sampling_reset; @@ -30,5 +30,6 @@ statsinfo_tablespaces; statsinfo_wait_sampling_profile; statsinfo_wait_sampling_reset_profile; + statsinfo_cli_exec; local: *; }; diff --git a/agent/lib/libstatsinfo.c b/agent/lib/libstatsinfo.c index 84f17a5..921c467 100644 --- a/agent/lib/libstatsinfo.c +++ b/agent/lib/libstatsinfo.c @@ -58,6 +58,8 @@ #define STOP_WAIT_MIN (10) #define STOP_WAIT_MAX (300) +#define MAX_REPORT_SIZE 1048576 + /* also adjust non-critial setting parameters? */ /* #define ADJUST_NON_CRITICAL_SETTINGS */ @@ -67,6 +69,8 @@ #define PROGRAM_NAME "pg_statsinfo.exe" #endif +#define CL_PROGRAM_NAME "pg_statsinfo" + #define TAKE_HOOK(func, replace) \ prev_##func##_hook = func##_hook; \ func##_hook = replace; @@ -326,6 +330,7 @@ PG_FUNCTION_INFO_V1(statsinfo_memory); PG_FUNCTION_INFO_V1(statsinfo_profile); PG_FUNCTION_INFO_V1(statsinfo_cpuinfo); PG_FUNCTION_INFO_V1(statsinfo_meminfo); +PG_FUNCTION_INFO_V1(statsinfo_cli_exec); extern Datum PGUT_EXPORT statsinfo_sample(PG_FUNCTION_ARGS); extern Datum PGUT_EXPORT statsinfo_sample_wait_sampling(PG_FUNCTION_ARGS); @@ -347,6 +352,7 @@ extern Datum PGUT_EXPORT statsinfo_memory(PG_FUNCTION_ARGS); extern Datum PGUT_EXPORT statsinfo_profile(PG_FUNCTION_ARGS); extern Datum PGUT_EXPORT statsinfo_cpuinfo(PG_FUNCTION_ARGS); extern Datum PGUT_EXPORT statsinfo_meminfo(PG_FUNCTION_ARGS); +extern Datum PGUT_EXPORT statsinfo_cli_exec(PG_FUNCTION_ARGS); extern PGUT_EXPORT void _PG_init(void); extern PGUT_EXPORT void _PG_fini(void); @@ -2800,6 +2806,53 @@ statsinfo_meminfo(PG_FUNCTION_ARGS) PG_RETURN_INT64(mem_total); } +/* + * statsinfo_cli_exec - CLI executer + */ +Datum +statsinfo_cli_exec(PG_FUNCTION_ARGS) +{ + char bin_path[MAXPGPATH]; + char command[MAXPGPATH]; + FILE *fp; + char result[PIPE_CHUNK_SIZE]; + char report[MAX_REPORT_SIZE]; + char *params; + + /* Get function Params */ + params = text_to_cstring(PG_GETARG_TEXT_PP(0)); + + /* $PGHOME/bin */ + strlcpy(bin_path, my_exec_path, MAXPGPATH); + get_parent_directory(bin_path); + + /* Generate the command, and include stderr in stdout. */ + snprintf(command, sizeof(command), "%s/%s %s 2>&1", bin_path, CL_PROGRAM_NAME, params); + + memset(result, 0, sizeof(result)); + memset(report, 0, sizeof(report)); + + /* Execute the command with pipe and read the standard output. */ + if ((fp = popen(command, "r")) == NULL) + { + ereport(ERROR, + (errmsg("%s: could not launch shell command", command))); + return false; + } + while(fgets(result, sizeof(result), fp)) + { + snprintf(report, sizeof(report), "%s%s", report, result); + } + if (pclose(fp) < 0) + { + ereport(ERROR, + (errmsg("%s: could not close shell command", command))); + return false; + } + + PG_RETURN_CSTRING(report); +} + static bool checked_write(int fd, const void *buf, int size) { diff --git a/agent/lib/pg_statsinfo.sql.in b/agent/lib/pg_statsinfo.sql.in index e302850..1c4b146 100644 --- a/agent/lib/pg_statsinfo.sql.in +++ b/agent/lib/pg_statsinfo.sql.in @@ -336,4 +336,11 @@ CREATE FUNCTION statsinfo.meminfo AS 'MODULE_PATHNAME', 'statsinfo_meminfo' LANGUAGE C STRICT; +-- +-- statsinfo.cli_exec() +-- +CREATE FUNCTION statsinfo.cli_exec(params text) RETURNS cstring +AS '$libdir/pg_statsinfo', 'statsinfo_cli_exec' +LANGUAGE C; + COMMIT; diff --git a/doc/pg_statsinfo-ja.md b/doc/pg_statsinfo-ja.md index d0ffb5b..d2e7e88 100644 --- a/doc/pg_statsinfo-ja.md +++ b/doc/pg_statsinfo-ja.md @@ -805,6 +805,20 @@ enable_alert カラムで行います。デフォルト値はpg_statsinfo.enable +#### 関数からコマンドライン機能を実行 + + $ psql -d postgres -c "SELECT statsinfo.cli_exec('[commandline-options]')" + +PostgreSQL のサーバに pg_statsinfo がインストールされている場合、 コマンドライン機能を関数から実行できます。 +関数の引数に対して、コマンドライン機能への引数を渡します。 +以下にコマンド例を示します。 +以下のコマンド例では、ホスト名 localhost 上のポート 5432 で稼動している PostgreSQL のサーバに対して、postgres +データベースに、postgres ユーザで接続し、レポート生成のコマンドライン機能を実行します。 + + $ psql -d postgres -c "SELECT statsinfo.cli_exec('-r All -h localhost -d postgres -p 5432 -U postgres')" + + + ### 自動メンテナンス機能の使い方 自動メンテナンス機能を使用することで以下の操作を1日1回任意の時刻に行うことができます。 diff --git a/doc/pg_statsinfo.md b/doc/pg_statsinfo.md index 3ae497a..65fccfa 100644 --- a/doc/pg_statsinfo.md +++ b/doc/pg_statsinfo.md @@ -871,6 +871,21 @@ monitored database when the command tells to do something to the agent. +#### Command line operation by function. + + $ psql -d postgres -c "SELECT statsinfo.cli_exec('[commandline-options]')" + +If pg_statsinfo is installed on the PostgreSQL server, command line +operation can be run from a function.Pass the arguments of command +line operations as function arguments. +The following example is the command to tell pg_statsinfo agent to +start by connecting the PostgreSQL server via the database 'postgres' +of the user 'postgres' at localhost:5432. + + $ psql -d postgres -c "SELECT statsinfo.cli_exec('-r All -h localhost -d postgres -p 5432 -U postgres')" + + + ### Automatic maintenance Repository database will piled high with snapshots and log directory