> 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

Reply via email to