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]