pgpool2.git / summary / log / commit / refs
commit 3e930d79401d4390dc6a7822fada4f692c384afa
Author: Tatsuo Ishii <ishii@postgresql.org>
Date: Sat Oct 03 09:24:04 2015 +0000
Allow to specify database for health check and streaming replication delay check.
For this purpose new directive "health_check_database" and
"sr_check_database" are added. This is useful for certain environment
in which using postgres and/or template1 database is not allowed.
doc/pgpool-en.html | 22 ++++++
doc/pgpool-ja.html | 21 ++++++
src/config/pool_config.c | 101 ++++++++++++++++++++------
src/config/pool_config.l | 54 ++++++++++++--
src/include/pool_config.h | 4 +-
src/main/pgpool_main.c | 12 ++-
src/sample/pgpool.conf.sample | 5 ++
src/sample/pgpool.conf.sample-master-slave | 4 +
src/sample/pgpool.conf.sample-replication | 4 +
src/sample/pgpool.conf.sample-stream | 4 +
src/streaming_replication/pool_worker_child.c | 2 +-
src/utils/pool_process_reporting.c | 10 +++
12 files changed, 213 insertions(+), 30 deletions(-)
diff --git a/doc/pgpool-en.html b/doc/pgpool-en.html
index dd0bdc0b0..ab6b3fb67 100644
--- a/doc/pgpool-en.html
+++ b/doc/pgpool-en.html
@@ -967,6 +967,17 @@ local0.* /var/log/pgpool.log
</p>
</dd>
+<dt><a name="HEALTH_CHECK_DATABASE"></a>health_check_database <span class="version">V3.5 -</span></dt>
+ <dd>
+ <p>The database name to perform health check. The default is '',
+ which tries "postgres" database first, then "template1" database
+ until it succeeds. This is the same behavior as 3.4 or before.
+ </p>
+ <p>
+ You need to reload pgpool.conf if you change health_check_database.
+ </p>
+ </dd>
+
<dt><a name="HEALTH_CHECK_MAX_RETRIES"></a>health_check_max_retries <span class="version">V3.2 -</span></dt>
<dd>
<p>The maximum number of times to retry a failed health check
@@ -2128,6 +2139,17 @@ The following directives can be used with this mode:
</p>
</dd>
+<dt id="SR_CHECK_DATABASE">sr_check_database <span class="version">V3.5 -</span></dt>
+ <dd>
+ <p>
+ The database to perform streaming replication delay check.
+ The default is "postgres" (which is the built-in database name in 3.4 or before).
+ </p>
+ <p>
+ You need to reload pgpool.conf if you change sr_check_database.
+ </p>
+ </dd>
+
<dt id="LOG_STANDBY_DELAY">log_standby_delay <span class="version">V3.1 -</span></dt>
<dd>
<p>
diff --git a/doc/pgpool-ja.html b/doc/pgpool-ja.html
index 8c6ff56be..72147c3dd 100644
--- a/doc/pgpool-ja.html
+++ b/doc/pgpool-ja.html
@@ -1008,6 +1008,16 @@ local0.* /var/log/pgpool.log
</p>
</dd>
+<dt><a name="HEALTH_CHECK_DATABASE"></a>health_check_database <span class="version">V3.5 -</span></dt>
+ <dd>
+ <p>ヘルスチェックを行う対象のデータベース名を指定します。
+ デフォルトは '' で、この場合最初に「postgres」データベースを試し、それに接続できない場合は「template1」データベースを試します。これはpgpool-II 3.4以前の挙動と同じです。
+ </p>
+ <p>
+ このパラメータを変更した時には設定ファイルを再読み込みしてください。
+ </p>
+ </dd>
+
<dt><a name="HEALTH_CHECK_MAX_RETRIES"></a>health_check_max_retries <span class="version">V3.2 〜</span></dt>
<dd>
<p>
@@ -2234,6 +2244,17 @@ Streaming Replicationを使う場合の雛形はpgpool.conf.sample-streamです
</p>
</dd>
+<dt id="SR_CHECK_DATABASE">sr_check_database <span class="version">V3.5 -</span></dt>
+ <dd>
+ <p>
+ ストリーミングレプリケーションの遅延チェックを行う対象のデータベース名を指定します。
+ デフォルトは「postgres」です(これは3.4以前のpgpool-IIが固定の値として使っていたデータベース名です)。
+ </p>
+ <p>
+ このパラメータは設定ファイルの再読込によって変更できます。
+ </p>
+ </dd>
+
<dt id="LOG_STANDBY_DELAY">log_standby_delay <span class="version">V3.0 〜</span></dt>
<dd>
<p>
diff --git a/src/config/pool_config.c b/src/config/pool_config.c
index 7740a5ae7..8be91870a 100644
--- a/src/config/pool_config.c
+++ b/src/config/pool_config.c
@@ -555,7 +555,7 @@ static char **extract_string_tokens(char *str, char *delim, int *n);
static void clear_host_entry(int slot);
static bool check_redirect_node_spec(char *node_spec);
-#line 560 "config/pool_config.c"
+#line 559 "config/pool_config.c"
#define INITIAL 0
@@ -740,10 +740,10 @@ YY_DECL
register char *yy_cp, *yy_bp;
register int yy_act;
-#line 91 "pool_config.l"
+#line 90 "pool_config.l"
-#line 748 "config/pool_config.c"
+#line 747 "config/pool_config.c"
if ( !(yy_init) )
{
@@ -825,12 +825,12 @@ do_action: /* This label is used only to access EOF actions. */
case 1:
/* rule 1 can match eol */
YY_RULE_SETUP
-#line 93 "pool_config.l"
+#line 92 "pool_config.l"
Lineno++; return POOL_EOL;
YY_BREAK
case 2:
YY_RULE_SETUP
-#line 94 "pool_config.l"
+#line 93 "pool_config.l"
/* eat whitespace */
YY_BREAK
case 3:
@@ -838,50 +838,50 @@ case 3:
(yy_c_buf_p) = yy_cp -= 1;
YY_DO_BEFORE_ACTION; /* set up yytext again */
YY_RULE_SETUP
-#line 95 "pool_config.l"
+#line 94 "pool_config.l"
/* eat comment */
YY_BREAK
case 4:
YY_RULE_SETUP
-#line 97 "pool_config.l"
+#line 96 "pool_config.l"
return POOL_KEY;
YY_BREAK
case 5:
YY_RULE_SETUP
-#line 98 "pool_config.l"
+#line 97 "pool_config.l"
return POOL_STRING;
YY_BREAK
case 6:
YY_RULE_SETUP
-#line 99 "pool_config.l"
+#line 98 "pool_config.l"
return POOL_UNQUOTED_STRING;
YY_BREAK
case 7:
YY_RULE_SETUP
-#line 100 "pool_config.l"
+#line 99 "pool_config.l"
return POOL_INTEGER;
YY_BREAK
case 8:
YY_RULE_SETUP
-#line 101 "pool_config.l"
+#line 100 "pool_config.l"
return POOL_REAL;
YY_BREAK
case 9:
YY_RULE_SETUP
-#line 102 "pool_config.l"
+#line 101 "pool_config.l"
return POOL_EQUALS;
YY_BREAK
case 10:
YY_RULE_SETUP
-#line 104 "pool_config.l"
+#line 103 "pool_config.l"
return POOL_PARSE_ERROR;
YY_BREAK
case 11:
YY_RULE_SETUP
-#line 106 "pool_config.l"
+#line 105 "pool_config.l"
ECHO;
YY_BREAK
-#line 886 "config/pool_config.c"
+#line 885 "config/pool_config.c"
case YY_STATE_EOF(INITIAL):
yyterminate();
@@ -1839,7 +1839,7 @@ void yyfree (void * ptr )
#define YYTABLES_NAME "yytables"
-#line 106 "pool_config.l"
+#line 105 "pool_config.l"
@@ -1880,10 +1880,10 @@ int pool_init_config(void)
pool_config->child_max_connections = 0;
pool_config->authentication_timeout = 60;
pool_config->logdir = DEFAULT_LOGDIR;
- pool_config->logsyslog = 0;
- pool_config->log_destination = "stderr";
- pool_config->syslog_facility = LOG_LOCAL0;
- pool_config->syslog_ident = "pgpool";
+ pool_config->logsyslog = 0;
+ pool_config->log_destination = "stderr";
+ pool_config->syslog_facility = LOG_LOCAL0;
+ pool_config->syslog_ident = "pgpool";
pool_config->pid_file_name = DEFAULT_PID_FILE_NAME;
pool_config->log_statement = 0;
pool_config->log_per_node_statement = 0;
@@ -1916,12 +1916,14 @@ int pool_init_config(void)
pool_config->health_check_period = 0;
pool_config->health_check_user = "nobody";
pool_config->health_check_password = "";
+ pool_config->health_check_database = "";
pool_config->health_check_max_retries = 0;
pool_config->health_check_retry_delay = 1;
pool_config->connect_timeout = 10000;
pool_config->sr_check_period = 0;
pool_config->sr_check_user = "nobody";
pool_config->sr_check_password = "";
+ pool_config->sr_check_database = "postgres";
pool_config->failover_command = "";
pool_config->follow_master_command = "";
pool_config->failback_command = "";
@@ -3154,7 +3156,28 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
pool_config->health_check_password = str;
}
- else if (!strcmp(key, "health_check_max_retries") &&
+ else if (!strcmp(key, "health_check_database") &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->health_check_database = str;
+ }
+
+
+ else if (!strcmp(key, "health_check_max_retries") &&
CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
{
int v = atoi(yytext);
@@ -3187,6 +3210,7 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
}
pool_config->health_check_retry_delay = v;
}
+
else if (!strcmp(key, "connect_timeout") &&
CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
{
@@ -3261,6 +3285,26 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
pool_config->sr_check_password = str;
}
+ else if (!strcmp(key, "sr_check_database") &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->sr_check_database = str;
+ }
+
else if (!strcmp(key, "failover_command") &&
CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
{
@@ -5009,6 +5053,21 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
}
}
+ if (strcmp(pool_config->recovery_1st_stage_command, "") ||
+ strcmp(pool_config->recovery_2nd_stage_command, ""))
+ {
+ for (i=0;i<MAX_CONNECTION_SLOTS;i++)
+ {
+ if (pool_config->backend_desc->backend_info[i].backend_port != 0 &&
+ !strcmp(pool_config->backend_desc->backend_info[i].backend_data_directory, ""))
+ {
+ ereport(ERROR,
+ (errmsg("invalid configuration, recovery_1st_stage_command and recovery_2nd_stage_command requires backend_data_directory to be set")));
+ return -1;
+ }
+ }
+ }
+
return 0;
}
diff --git a/src/config/pool_config.l b/src/config/pool_config.l
index 16d2a7a1b..f9cdd8767 100644
--- a/src/config/pool_config.l
+++ b/src/config/pool_config.l
@@ -141,10 +141,10 @@ int pool_init_config(void)
pool_config->child_max_connections = 0;
pool_config->authentication_timeout = 60;
pool_config->logdir = DEFAULT_LOGDIR;
- pool_config->logsyslog = 0;
- pool_config->log_destination = "stderr";
- pool_config->syslog_facility = LOG_LOCAL0;
- pool_config->syslog_ident = "pgpool";
+ pool_config->logsyslog = 0;
+ pool_config->log_destination = "stderr";
+ pool_config->syslog_facility = LOG_LOCAL0;
+ pool_config->syslog_ident = "pgpool";
pool_config->pid_file_name = DEFAULT_PID_FILE_NAME;
pool_config->log_statement = 0;
pool_config->log_per_node_statement = 0;
@@ -177,12 +177,14 @@ int pool_init_config(void)
pool_config->health_check_period = 0;
pool_config->health_check_user = "nobody";
pool_config->health_check_password = "";
+ pool_config->health_check_database = "";
pool_config->health_check_max_retries = 0;
pool_config->health_check_retry_delay = 1;
pool_config->connect_timeout = 10000;
pool_config->sr_check_period = 0;
pool_config->sr_check_user = "nobody";
pool_config->sr_check_password = "";
+ pool_config->sr_check_database = "postgres";
pool_config->failover_command = "";
pool_config->follow_master_command = "";
pool_config->failback_command = "";
@@ -1415,7 +1417,28 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
pool_config->health_check_password = str;
}
- else if (!strcmp(key, "health_check_max_retries") &&
+ else if (!strcmp(key, "health_check_database") &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->health_check_database = str;
+ }
+
+
+ else if (!strcmp(key, "health_check_max_retries") &&
CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
{
int v = atoi(yytext);
@@ -1448,6 +1471,7 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
}
pool_config->health_check_retry_delay = v;
}
+
else if (!strcmp(key, "connect_timeout") &&
CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
{
@@ -1522,6 +1546,26 @@ int pool_get_config(char *confpath, POOL_CONFIG_CONTEXT context)
pool_config->sr_check_password = str;
}
+ else if (!strcmp(key, "sr_check_database") &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
+ {
+ char *str;
+
+ if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY)
+ {
+ PARSE_ERROR();
+ fclose(fd);
+ return(-1);
+ }
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ fclose(fd);
+ return(-1);
+ }
+ pool_config->sr_check_database = str;
+ }
+
else if (!strcmp(key, "failover_command") &&
CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
{
diff --git a/src/include/pool_config.h b/src/include/pool_config.h
index 4b1d13b9f..6f7540a64 100644
--- a/src/include/pool_config.h
+++ b/src/include/pool_config.h
@@ -129,12 +129,14 @@ typedef struct {
int health_check_period; /* health check period */
char *health_check_user; /* PostgreSQL user name for health check */
char *health_check_password; /* password for health check username */
+ char *health_check_database; /* database name for health check username */
int health_check_max_retries; /* health check max retries */
int health_check_retry_delay; /* amount of time to wait between retries */
int connect_timeout; /* timeout value before giving up connecting to backend */
int sr_check_period; /* streaming replication check period */
- char *sr_check_user; /* PostgreSQL user name streaming replication check */
+ char *sr_check_user; /* PostgreSQL user name for streaming replication check */
char *sr_check_password; /* password for sr_check_user */
+ char *sr_check_database; /* PostgreSQL database name for streaming replication check */
char *failover_command; /* execute command when failover happens */
char *follow_master_command; /* execute command when failover is ended */
char *failback_command; /* execute command when failback happens */
diff --git a/src/main/pgpool_main.c b/src/main/pgpool_main.c
index 71cf35d51..206613ca8 100644
--- a/src/main/pgpool_main.c
+++ b/src/main/pgpool_main.c
@@ -1887,7 +1887,15 @@ do_health_check(bool use_template_db, volatile int *health_check_node_id)
if (*InRecovery)
return false;
- dbname = use_template_db ? "template1" : "postgres";
+ if (!strcmp(pool_config->health_check_database, ""))
+ dbname = use_template_db ? "template1" : "postgres";
+ else
+ dbname = pool_config->health_check_database;
+
+ ereport(DEBUG1,
+ (errmsg("doing health check against database:%s user:%s",
+ dbname, pool_config->health_check_user)));
+
/*
* Start checking the backed nodes starting from the
* previously failed node
@@ -2446,7 +2454,7 @@ static bool
s = make_persistent_db_connection_noerror(bkinfo->backend_hostname,
bkinfo->backend_port,
- "postgres",
+ pool_config->sr_check_database,
pool_config->sr_check_user,
pool_config->sr_check_password, true);
if (s)
diff --git a/src/sample/pgpool.conf.sample b/src/sample/pgpool.conf.sample
index 0eaf98ab5..e89bcf2ca 100644
--- a/src/sample/pgpool.conf.sample
+++ b/src/sample/pgpool.conf.sample
@@ -333,6 +333,8 @@ sr_check_user = 'nobody'
# sr_check_period = 0
sr_check_password = ''
# Password for streaming replication check user
+sr_check_database = 'postgres'
+ # Database name for streaming replication check
delay_threshold = 0
# Threshold before not dispatching query to standby node
# Unit is in bytes
@@ -369,6 +371,9 @@ health_check_user = 'nobody'
# Health check user
health_check_password = ''
# Password for health check user
+health_check_database = ''
+ # Database name for health check. If '', tries 'postgres' frist, then 'template1'
+
health_check_max_retries = 0
# Maximum number of times to retry a failed health check before giving up.
health_check_retry_delay = 1
diff --git a/src/sample/pgpool.conf.sample-master-slave b/src/sample/pgpool.conf.sample-master-slave
index 9ec470af4..0444f7d08 100644
--- a/src/sample/pgpool.conf.sample-master-slave
+++ b/src/sample/pgpool.conf.sample-master-slave
@@ -332,6 +332,8 @@ sr_check_user = 'nobody'
# replication delay check by sr_check_period = 0
sr_check_password = ''
# Password for streaming replication check user
+sr_check_database = 'postgres'
+ # Database name for streaming replication check
delay_threshold = 0
# Threshold before not dispatching query to standby node
# Unit is in bytes
@@ -368,6 +370,8 @@ health_check_user = 'nobody'
# Health check user
health_check_password = ''
# Password for health check user
+health_check_database = ''
+ # Database name for health check. If '', tries 'postgres' frist,
health_check_max_retries = 0
# Maximum number of times to retry a failed health check before giving up.
health_check_retry_delay = 1
diff --git a/src/sample/pgpool.conf.sample-replication b/src/sample/pgpool.conf.sample-replication
index a687ad7c6..dd582f11d 100644
--- a/src/sample/pgpool.conf.sample-replication
+++ b/src/sample/pgpool.conf.sample-replication
@@ -332,6 +332,8 @@ sr_check_user = 'nobody'
# replication delay check by sr_check_period = 0
sr_check_password = ''
# Password for streaming replication check user
+sr_check_database = 'postgres'
+ # Database name for streaming replication check
delay_threshold = 0
# Threshold before not dispatching query to standby node
# Unit is in bytes
@@ -368,6 +370,8 @@ health_check_user = 'nobody'
# Health check user
health_check_password = ''
# Password for health check user
+health_check_database = ''
+ # Database name for health check. If '', tries 'postgres' frist,
health_check_max_retries = 0
# Maximum number of times to retry a failed health check before giving up.
health_check_retry_delay = 1
diff --git a/src/sample/pgpool.conf.sample-stream b/src/sample/pgpool.conf.sample-stream
index b3304c46d..9763c607e 100644
--- a/src/sample/pgpool.conf.sample-stream
+++ b/src/sample/pgpool.conf.sample-stream
@@ -333,6 +333,8 @@ sr_check_user = 'nobody'
# replication delay check by sr_check_period = 0
sr_check_password = ''
# Password for streaming replication check user
+sr_check_database = 'postgres'
+ # Database name for streaming replication check
delay_threshold = 10000000
# Threshold before not dispatching query to standby node
# Unit is in bytes
@@ -369,6 +371,8 @@ health_check_user = 'nobody'
# Health check user
health_check_password = ''
# Password for health check user
+health_check_database = ''
+ # Database name for health check. If '', tries 'postgres' frist,
health_check_max_retries = 0
# Maximum number of times to retry a failed health check before giving up.
health_check_retry_delay = 1
diff --git a/src/streaming_replication/pool_worker_child.c b/src/streaming_replication/pool_worker_child.c
index 64f53a085..559f395d2 100644
--- a/src/streaming_replication/pool_worker_child.c
+++ b/src/streaming_replication/pool_worker_child.c
@@ -200,7 +200,7 @@ static void establish_persistent_connection(void)
bkinfo = pool_get_node_info(i);
slots[i] = make_persistent_db_connection_noerror(bkinfo->backend_hostname,
bkinfo->backend_port,
- "postgres",
+ pool_config->sr_check_database,
pool_config->sr_check_user,
pool_config->sr_check_password, true);
}
diff --git a/src/utils/pool_process_reporting.c b/src/utils/pool_process_reporting.c
index 25d49b57b..9745ba7ad 100644
--- a/src/utils/pool_process_reporting.c
+++ b/src/utils/pool_process_reporting.c
@@ -470,6 +470,11 @@ POOL_REPORT_CONFIG* get_config(int *nrows)
StrNCpy(status[i].desc, "sr check password", POOLCONFIG_MAXDESCLEN);
i++;
#endif
+ StrNCpy(status[i].name, "sr_check_database", POOLCONFIG_MAXNAMELEN);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->sr_check_database);
+ StrNCpy(status[i].desc, "sr check database", POOLCONFIG_MAXDESCLEN);
+ i++;
+
StrNCpy(status[i].name, "delay_threshold", POOLCONFIG_MAXNAMELEN);
snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%lld", pool_config->delay_threshold);
StrNCpy(status[i].desc, "standby delay threshold", POOLCONFIG_MAXDESCLEN);
@@ -518,6 +523,11 @@ POOL_REPORT_CONFIG* get_config(int *nrows)
StrNCpy(status[i].desc, "health check password", POOLCONFIG_MAXDESCLEN);
i++;
#endif
+ StrNCpy(status[i].name, "health_check_database", POOLCONFIG_MAXNAMELEN);
+ snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%s", pool_config->health_check_database);
+ StrNCpy(status[i].desc, "health check database", POOLCONFIG_MAXDESCLEN);
+ i++;
+
StrNCpy(status[i].name, "health_check_max_retries", POOLCONFIG_MAXNAMELEN);
snprintf(status[i].value, POOLCONFIG_MAXVALLEN, "%d", pool_config->health_check_max_retries);
StrNCpy(status[i].desc, "health check max retries", POOLCONFIG_MAXDESCLEN);
[parent: 5f7cd31d6bba]