[Pgpool-hackers] backend weighting calculation is wrong

Yoshiyuki Asaba y-asaba at sraoss.co.jp
Mon Sep 25 05:24:05 UTC 2006


From: Jeff Davis <pgpool at j-davis.com>
Subject: [Pgpool-hackers] backend weighting calculation is wrong
Date: Wed, 13 Sep 2006 16:57:26 -0700

> This algorithm does not look correct. For instance, if you have backends
> with weights 1.0 and 2.0, the former will only receive 1/4 of the
> queries. I tested this using replication mode with load balancing and
> verified the inconsistency.

I confirmed the problem. It's a bug.


> I have attached a short patch. I am not an expert in random number
> handling, so someone else should review my code.

I review and modify your patch. Could you test the attached patch?

--
Yoshiyuki Asaba
y-asaba at sraoss.co.jp
-------------- next part --------------
Index: pool_config.l
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_config.l,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 pool_config.l
*** pool_config.l	8 Sep 2006 03:36:07 -0000	1.1.1.1
--- pool_config.l	25 Sep 2006 05:16:44 -0000
***************
*** 908,915 ****
  
  		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].backend_weight / total_weight;
  			pool_debug("backend %d weight: %f", i, pool_config->backend_desc->backend_info[i].backend_weight);
  		}
  	}
--- 908,913 ----
Index: pool_process_query.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_process_query.c,v
retrieving revision 1.3
diff -c -r1.3 pool_process_query.c
*** pool_process_query.c	14 Sep 2006 02:00:45 -0000	1.3
--- pool_process_query.c	25 Sep 2006 05:16:57 -0000
***************
*** 3266,3273 ****
   */
  static void start_load_balance(POOL_CONNECTION_POOL *backend)
  {
! 	double max_weight;
! 	int i;
  
  #ifdef NOT_USED
  	/* save backend connection slots */
--- 3266,3274 ----
   */
  static void start_load_balance(POOL_CONNECTION_POOL *backend)
  {
! 	double total_weight;
! 	int i, j, r, alive_backends = 0;
! 	double weight[NUM_BACKENDS];
  
  #ifdef NOT_USED
  	/* save backend connection slots */
***************
*** 3282,3302 ****
  
  	/* choose a backend in random manner with weight */
  	selected_slot = 0;
! 	max_weight = 0.0;
  
  	for (i=0;i<NUM_BACKENDS;i++)
  	{
  		if (VALID_BACKEND(i))
  		{
! 			double weight;
  
! 			weight = random() * BACKEND_INFO(i).backend_weight/RAND_MAX;
  
! 			if (weight > max_weight)
  			{
- 				max_weight = weight;
  				selected_slot = i;
  			}
  		}
  	}
  
--- 3283,3322 ----
  
  	/* choose a backend in random manner with weight */
  	selected_slot = 0;
! 	total_weight = 0.0;
  
  	for (i=0;i<NUM_BACKENDS;i++)
  	{
  		if (VALID_BACKEND(i))
  		{
! 			total_weight += BACKEND_INFO(i).backend_weight;
! 			alive_backends++;
! 		}
! 	}
  
! 	/* Re-compute backend weight excluding dead backends. */
! 	for (i=0;i<NUM_BACKENDS;i++)
! 	{
! 		if (VALID_BACKEND(i))
! 		{
! 			weight[i] = RAND_MAX * pool_config->backend_desc->backend_info[i].backend_weight / total_weight;
! 		}
! 	}
  
! 	r = random();
! 	total_weight = 0.0;
! 	for (i = 0, j = 0; i < NUM_BACKENDS; i++)
! 	{
! 		if (VALID_BACKEND(i))
! 		{
! 			if ((r <= total_weight + weight[i] && weight[i] != 0.0) ||
! 				j + 1 == alive_backends)
  			{
  				selected_slot = i;
+ 				break;
  			}
+ 			j++;
+ 			total_weight += weight[i];
  		}
  	}
  


More information about the Pgpool-hackers mailing list