Henri Asseily wrote:
Take the example of the pod:

$DATABASE::conf{'test'} = {
 max_retries => 2,
 db_stack => [
  [ 'dbi:Sybase:server=prod1;database=test', 'user1', 'pass1', $attrib ],
  [ 'dbi:Sybase:server=prod2;database=test', 'user2', 'pass2', $attrib ],
  [ 'dbi:Sybase:server=prod3;database=test', 'user3', 'pass3', $attrib ],
 ], ...

Assume his 'test' handle is a read-only handle.
The stack definition shows that you have 3 read-only servers: prod1, prod2 and prod3. The particular process that uses this stack will start with prod1, and if it fails max_retries times, it will switch to the next one in the stack, prod2, and so on. If you want to have your application to be load-balanced across all the read-only databases, you can do it in many ways, but ultimately it boils down to having your children processes hitting different databases, and having stacks that are as unique as possible (so that if a db server fails, all its dependents don't fail over to the same secondary).

Here's a complex example:
In the case above, say you have 20 children for those 3 databases.
The different stack permutations are:

1: prod1,prod2,prod3
2: prod1,prod3,prod2
3: prod2,prod1,prod3
4: prod2,prod3,prod1
5: prod3,prod1,prod2
6: prod3,prod2,prod1

Either dynamically or statically create these 6 permutations and put them in @all_db_stacks: Then when one of your 20 children starts up, it will take a stack. Either have each take the next stack down, or randomly take a stack. One example under Apache if you don't want to have a shared global is to grab the child's process id and get its modulus by the size of @all_db_stack:
$stack_number = $$ % scalar(@all_db_stacks)

And so in the example config above:
db_stack => $all_db_stacks[$stack_number]

Couldn't an option be added as an alternative to db_stack that indicates a desire for random ordering, thereby eliminating the need to precreate all possible permutations? I'm imaging something like this (modified version of your example):

$DATABASE::conf{'test'} = {
  max_retries => 2,
  db_pool => [
   [ 'dbi:Sybase:server=prod1;database=test', 'user1', 'pass1', $attrib ],
   [ 'dbi:Sybase:server=prod2;database=test', 'user2', 'pass2', $attrib ],
   [ 'dbi:Sybase:server=prod3;database=test', 'user3', 'pass3', $attrib ],
  ], ...

So, db_stack maintains ordering, while db_pool tells DBIx::HA to randomize the list of servers.

-ofer

Reply via email to