> Hi pgpool hackers,
>
> I would like to propose new directive to control failover behavior for
> 3.1.
>
> Background:
>
> Certain configration such as master/slave mode with Slony-I requires
> master node not to failover. For this purpose the master node is
> protected by HA(High Availability) software, it is desired for
> pgpool-II disregard failover event on the master node.
>
> Another use case is, D/W house like configuration with streaming
> replication. Primary node is not often updated and standby servers are
> used for load balancing. Sometimes it is not neccessary to promoto a
> standby when the primary goes down, rather waiting for the primary
> wakes up.
>
> Proposal:
> Add new directive to backend_*. to control the failover behavior.
>
> backend_hostname0 = 'example.com'
> backend_port0 = 5432
> backend_weight0 = 1
> backend_flag0 = 'flags' <--- proposed new directive
>
> "flags" can be just a "allow failover or not" for now, but I would
> like to allow to ORing several flags for the future porpose. At this
> poing the flag would be:
>
> ALLOW_TO_FAILOVER (allow to failover, default)
> or
> NEVER_FAILOVER (do not allow to failover)
>
> Comments?
Ok, I have created patches for this.
- Add new directive. If backend_flag0 = 'DISALLOW_TO_FAILOVER'(for
example) is specified, no failover (including health checking,
connection errors, pcp_detach_node) will happen. If you want to
allow failover you can specify backend_flag0 =
'ALLOW_TO_FAILOVER'. For backward compatibility sake, if
backend_flag0 directive is omitted, it is regarded as backend_flag0
= 'ALLOW_TO_FAILOVER' is specified.
- the directive can only be changed at pgpool starting up.
- No pool_status patches are included (yet).
- No documentation patches are included (yet).
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese: http://www.sraoss.co.jp
Index: main.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/main.c,v
retrieving revision 1.103
diff -c -r1.103 main.c
*** main.c 22 Jun 2011 08:40:49 -0000 1.103
--- main.c 23 Jun 2011 04:07:55 -0000
***************
*** 634,644 ****
if (!pool_config->parallel_mode)
{
! pool_log("set %d th backend down status", sts);
! Req_info->kind = NODE_DOWN_REQUEST;
! Req_info->node_id[0] = sts;
! failover();
! /* need to distribute this info to children */
}
else
{
--- 634,651 ----
if (!pool_config->parallel_mode)
{
! if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(sts).flag))
! {
! pool_log("health_check: %d failover is canceld because failover is disallowed", sts);
! }
! else
! {
! pool_log("set %d th backend down status", sts);
! Req_info->kind = NODE_DOWN_REQUEST;
! Req_info->node_id[0] = sts;
! failover();
! /* need to distribute this info to children */
! }
}
else
{
***************
*** 1274,1279 ****
--- 1281,1287 ----
{
pid_t parent = getppid();
int i;
+ bool need_signal = false;
if (pool_config->parallel_mode)
{
***************
*** 1291,1300 ****
continue;
}
pool_log("degenerate_backend_set: %d fail over request from pid %d", node_id_set[i], getpid());
Req_info->node_id[i] = node_id_set[i];
}
! kill(parent, SIGUSR1);
pool_semaphore_unlock(REQUEST_INFO_SEM);
}
--- 1299,1318 ----
continue;
}
+ if (POOL_DISALLOW_TO_FAILOVER(BACKEND_INFO(node_id_set[i]).flag))
+ {
+ pool_log("degenerate_backend_set: %d failover request from pid %d is canceld because failover is disallowed", node_id_set[i], getpid());
+ continue;
+ }
+
pool_log("degenerate_backend_set: %d fail over request from pid %d", node_id_set[i], getpid());
Req_info->node_id[i] = node_id_set[i];
+ need_signal = true;
}
!
! if (need_signal)
! kill(parent, SIGUSR1);
!
pool_semaphore_unlock(REQUEST_INFO_SEM);
}
Index: pool_config.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_config.c,v
retrieving revision 1.60
diff -c -r1.60 pool_config.c
*** pool_config.c 6 May 2011 23:43:26 -0000 1.60
--- pool_config.c 23 Jun 2011 04:07:56 -0000
***************
*** 485,491 ****
/* -*-pgsql-c-*- */
/*
*
! * $Header: /cvsroot/pgpool/pgpool-II/pool_config.c,v 1.60 2011/05/06 23:43:26 t-ishii Exp $
*
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
--- 485,491 ----
/* -*-pgsql-c-*- */
/*
*
! * $Header: /cvsroot/pgpool/pgpool-II/pool_config.l,v 1.56 2011/05/06 23:43:26 t-ishii Exp $
*
* pgpool: a language independent connection pool server for PostgreSQL
* written by Tatsuo Ishii
***************
*** 3236,3243 ****
if (context == INIT_CONFIG || context == RELOAD_CONFIG)
{
! double old_v = pool_config->backend_desc->backend_info[slot].unnormalized_weight;
! pool_config->backend_desc->backend_info[slot].unnormalized_weight = v;
/*
* Log weight change event only when context is
--- 3236,3243 ----
if (context == INIT_CONFIG || context == RELOAD_CONFIG)
{
! double old_v = BACKEND_INFO(slot).unnormalized_weight;
! BACKEND_INFO(slot).unnormalized_weight = v;
/*
* Log weight change event only when context is
***************
*** 3277,3282 ****
--- 3277,3358 ----
(context == RELOAD_CONFIG && (status == CON_UNUSED || status == CON_DOWN)))
strncpy(BACKEND_INFO(slot).backend_data_directory, str, MAX_PATH_LENGTH);
}
+ else if (!strncmp(key, "backend_flag", 12) &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
+ mypid == getpid()) /* this parameter must be modified by parent pid */
+ {
+ char *str;
+ char **flags;
+ int n;
+ int i;
+ int slot;
+ unsigned short flag = 0;
+ bool allow_to_failover_is_specified = 0;
+ bool disallow_to_failover_is_specified = 0;
+
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ pool_error("pool_config: extract_string failed: %s", yytext);
+ fclose(fd);
+ return(-1);
+ }
+
+ flags = extract_string_tokens(str, "|", &n);
+ if (!flags || n < 0)
+ {
+ pool_debug("pool_config: unable to get backend flags");
+ fclose(fd);
+ return(-1);
+ }
+
+ for (i=0;i<n;i++)
+ {
+ if (!strcmp(flags[i], "ALLOW_TO_FAILOVER"))
+ {
+ if (disallow_to_failover_is_specified)
+ {
+ pool_error("pool_config: cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time");
+ fclose(fd);
+ return(-1);
+ }
+ flag &= ~POOL_FAILOVER;
+ allow_to_failover_is_specified = true;
+ pool_debug("pool_config: allow_to_failover on");
+ }
+
+ else if (!strcmp(flags[i], "DISALLOW_TO_FAILOVER"))
+ {
+ if (allow_to_failover_is_specified)
+ {
+ pool_error("pool_config: cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time");
+ fclose(fd);
+ return(-1);
+ }
+ flag |= POOL_FAILOVER;
+ disallow_to_failover_is_specified = true;
+ pool_debug("pool_config: disallow_to_failover on");
+ }
+
+ else
+ {
+ pool_error("pool_config: invalid backend flag:%s", flags[i]);
+ }
+ }
+
+ slot = atoi(key + 12);
+ if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
+ {
+ pool_error("pool_config: slot number %s for flag out of range", key);
+ fclose(fd);
+ return(-1);
+ }
+
+ BACKEND_INFO(slot).flag = flag;
+
+ pool_debug("pool_config: slot number %d flag: %04x", slot, flag);
+ }
+
else if (!strcmp(key, "log_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
{
int v = eval_logical(yytext);
***************
*** 3508,3518 ****
print_host_entry(i);
#endif
! if (pool_config->backend_desc->backend_info[i].backend_port != 0)
{
! pool_config->backend_desc->backend_info[i].backend_weight =
! (RAND_MAX) * pool_config->backend_desc->backend_info[i].unnormalized_weight / total_weight;
! pool_debug("backend %d weight: %f", i, pool_config->backend_desc->backend_info[i].backend_weight);
}
}
--- 3584,3595 ----
print_host_entry(i);
#endif
! if (BACKEND_INFO(i).backend_port != 0)
{
! BACKEND_INFO(i).backend_weight =
! (RAND_MAX) * BACKEND_INFO(i).unnormalized_weight / total_weight;
! pool_debug("backend %d weight: %f", i, BACKEND_INFO(i).backend_weight);
! pool_debug("backend %d flag: %04x", i, BACKEND_INFO(i).flag);
}
}
Index: pool_config.h
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_config.h,v
retrieving revision 1.13
diff -c -r1.13 pool_config.h
*** pool_config.h 30 Mar 2011 02:13:07 -0000 1.13
--- pool_config.h 23 Jun 2011 04:07:56 -0000
***************
*** 46,51 ****
--- 46,57 ----
regex_t regexv;
} RegPattern;
+ /*
+ * Flags for backendN_flag
+ */
+ #define POOL_FAILOVER 0x0001 /* allow or disallow failover */
+ #define POOL_ALLOW_TO_FAILOVER(x) ((unsigned short)(x) & ~POOL_FAILOVER)
+ #define POOL_DISALLOW_TO_FAILOVER(x) ((unsigned short)(x) & POOL_FAILOVER)
/*
* configuration paramters
Index: pool_config.l
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_config.l,v
retrieving revision 1.56
diff -c -r1.56 pool_config.l
*** pool_config.l 6 May 2011 23:43:26 -0000 1.56
--- pool_config.l 23 Jun 2011 04:07:58 -0000
***************
*** 1511,1518 ****
if (context == INIT_CONFIG || context == RELOAD_CONFIG)
{
! double old_v = pool_config->backend_desc->backend_info[slot].unnormalized_weight;
! pool_config->backend_desc->backend_info[slot].unnormalized_weight = v;
/*
* Log weight change event only when context is
--- 1511,1518 ----
if (context == INIT_CONFIG || context == RELOAD_CONFIG)
{
! double old_v = BACKEND_INFO(slot).unnormalized_weight;
! BACKEND_INFO(slot).unnormalized_weight = v;
/*
* Log weight change event only when context is
***************
*** 1552,1557 ****
--- 1552,1633 ----
(context == RELOAD_CONFIG && (status == CON_UNUSED || status == CON_DOWN)))
strncpy(BACKEND_INFO(slot).backend_data_directory, str, MAX_PATH_LENGTH);
}
+ else if (!strncmp(key, "backend_flag", 12) &&
+ CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context) &&
+ mypid == getpid()) /* this parameter must be modified by parent pid */
+ {
+ char *str;
+ char **flags;
+ int n;
+ int i;
+ int slot;
+ unsigned short flag = 0;
+ bool allow_to_failover_is_specified = 0;
+ bool disallow_to_failover_is_specified = 0;
+
+ str = extract_string(yytext, token);
+ if (str == NULL)
+ {
+ pool_error("pool_config: extract_string failed: %s", yytext);
+ fclose(fd);
+ return(-1);
+ }
+
+ flags = extract_string_tokens(str, "|", &n);
+ if (!flags || n < 0)
+ {
+ pool_debug("pool_config: unable to get backend flags");
+ fclose(fd);
+ return(-1);
+ }
+
+ for (i=0;i<n;i++)
+ {
+ if (!strcmp(flags[i], "ALLOW_TO_FAILOVER"))
+ {
+ if (disallow_to_failover_is_specified)
+ {
+ pool_error("pool_config: cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time");
+ fclose(fd);
+ return(-1);
+ }
+ flag &= ~POOL_FAILOVER;
+ allow_to_failover_is_specified = true;
+ pool_debug("pool_config: allow_to_failover on");
+ }
+
+ else if (!strcmp(flags[i], "DISALLOW_TO_FAILOVER"))
+ {
+ if (allow_to_failover_is_specified)
+ {
+ pool_error("pool_config: cannot set ALLOW_TO_FAILOVER and DISALLOW_TO_FAILOVER at the same time");
+ fclose(fd);
+ return(-1);
+ }
+ flag |= POOL_FAILOVER;
+ disallow_to_failover_is_specified = true;
+ pool_debug("pool_config: disallow_to_failover on");
+ }
+
+ else
+ {
+ pool_error("pool_config: invalid backend flag:%s", flags[i]);
+ }
+ }
+
+ slot = atoi(key + 12);
+ if (slot < 0 || slot >= MAX_CONNECTION_SLOTS)
+ {
+ pool_error("pool_config: slot number %s for flag out of range", key);
+ fclose(fd);
+ return(-1);
+ }
+
+ BACKEND_INFO(slot).flag = flag;
+
+ pool_debug("pool_config: slot number %d flag: %04x", slot, flag);
+ }
+
else if (!strcmp(key, "log_statement") && CHECK_CONTEXT(INIT_CONFIG|RELOAD_CONFIG, context))
{
int v = eval_logical(yytext);
***************
*** 1783,1793 ****
print_host_entry(i);
#endif
! if (pool_config->backend_desc->backend_info[i].backend_port != 0)
{
! pool_config->backend_desc->backend_info[i].backend_weight =
! (RAND_MAX) * pool_config->backend_desc->backend_info[i].unnormalized_weight / total_weight;
! pool_debug("backend %d weight: %f", i, pool_config->backend_desc->backend_info[i].backend_weight);
}
}
--- 1859,1870 ----
print_host_entry(i);
#endif
! if (BACKEND_INFO(i).backend_port != 0)
{
! BACKEND_INFO(i).backend_weight =
! (RAND_MAX) * BACKEND_INFO(i).unnormalized_weight / total_weight;
! pool_debug("backend %d weight: %f", i, BACKEND_INFO(i).backend_weight);
! pool_debug("backend %d flag: %04x", i, BACKEND_INFO(i).flag);
}
}
Index: pcp/libpcp_ext.h
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pcp/libpcp_ext.h,v
retrieving revision 1.2
diff -c -r1.2 libpcp_ext.h
*** pcp/libpcp_ext.h 2 May 2011 13:31:25 -0000 1.2
--- pcp/libpcp_ext.h 23 Jun 2011 04:07:58 -0000
***************
*** 57,62 ****
--- 57,63 ----
double backend_weight; /* normalized backend load balance ratio */
double unnormalized_weight; /* descripted parameter */
char backend_data_directory[MAX_PATH_LENGTH];
+ unsigned short flag; /* various flags */
unsigned long long int standby_delay; /* The replication delay against the primary */
} BackendInfo;
_______________________________________________
Pgpool-hackers mailing list
[email protected]
http://pgfoundry.org/mailman/listinfo/pgpool-hackers