Advertisement
Guest User

slony_setup

a guest
Sep 9th, 2010
1,187
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 7.95 KB | None | 0 0
  1. #!/usr/bin/perl
  2. use DBI;
  3. my $cluster;
  4.  
  5. my $m_host;
  6. my $m_username;
  7. my $m_password;
  8. my $m_conn;
  9.  
  10. my $s_host;
  11. my $s_username;
  12. my $s_password;
  13. my $s_conn;
  14.  
  15. my @bases;
  16. my @tables;
  17. my @sequences;
  18.  
  19. printf "\n STEP 1: Configuring cluster.\n\n";
  20. cluster_cfg();
  21. printf "\n STEP 2: Configuring master.\n\n";
  22. master_cfg();
  23. printf "\n STEP 3: Configuring slave.\n\n";
  24. slave_cfg();
  25. printf "\n STEP 4: Selecting databases.\n\n";
  26. bases_cfg();
  27. printf "\n STEP 5: Adding tables.\n\n";
  28. tables_cfg();
  29. printf "\n STEP 6: Adding sequences.\n\n";
  30. sequences_cfg();
  31. printf "\n STEP 7: Creating DB-structures on slave.\n\n";
  32. dump_to_slave();
  33. printf "\n STEP 8: Generating config.\n\n";
  34. generate_config();
  35. printf "\n STEP 9: Send config to slave config.\n\n";
  36. send_config();
  37. printf "\n STEP 10: Starting daemons.\n\n";
  38. start_daemons();
  39.  
  40.  
  41. #Routines
  42. sub cluster_cfg()
  43. {
  44.     do
  45.     {
  46.     printf "Enter cluster name:\n";
  47.         $cluster=<>;chomp($cluster);
  48.     } while ($cluster eq '')
  49.    
  50. }
  51.  
  52. sub master_cfg()
  53. {
  54.     printf "Master hostname:\n";
  55.     $m_host=<>;chomp($m_host);
  56.  
  57.     printf "Username for $m_host:\n";
  58.     $m_username=<>;chomp($m_username);
  59.  
  60.     printf "Password for $m_username on $m_host:\n";
  61.     $m_password=<>;chomp($m_password);
  62.  
  63.     $m_conn = DBI->connect("dbi:Pg:dbname=postgres;host=$m_host","$m_username","$m_password",
  64.         {PrintError => 0});
  65.  
  66.    if (defined($DBI::err) && $DBI::err != 0)
  67.     {
  68.     printf "Error:" . $DBI::errstr . "\nConfigure master again? (Y/n)";
  69.     if (lc(<>) eq 'n') { exit($DBI::err); }
  70.     master_cfg();
  71.     }
  72. }
  73.  
  74. sub slave_cfg()
  75. {
  76.     printf "Slave hostname:\n";
  77.     $s_host=<>;chomp($s_host);
  78.  
  79.     printf "Username for $s_host:\n";
  80.     $s_username=<>;chomp($s_username);
  81.  
  82.     printf "Password for $s_username on $s_host:\n";
  83.     $s_password=<>;chomp($s_password);
  84.  
  85.     $s_conn = DBI->connect("dbi:Pg:dbname=postgres;host=$s_host","$s_username","$s_password",
  86.         {PrintError => 0});
  87.  
  88.    if (defined($DBI::err) && $DBI::err != 0)
  89.     {
  90.     printf "Error:" . $DBI::errstr . "\nConfigure slave again? (Y/n)";
  91.     if (lc(<>) eq 'n') { exit($DBI::err); }
  92.     slave_cfg();
  93.     }
  94.     $s_conn->disconnect();
  95. }
  96.  
  97.  
  98. sub bases_cfg()
  99. {
  100.     $b=$m_conn->prepare('SELECT datname FROM pg_database;');
  101.     $res=$b->execute();
  102.     if (!defined $res) { printf "FATAL: Can`t get bases list\n";exit; }
  103.    
  104.     printf "Select base for replication(* for all, blank to continue):\n";
  105.    
  106.     for($i=0;$str = $b->fetchrow_array();$i++)    
  107.     {
  108.       $bases[0][$i]=$str;
  109.       if (!defined($bases[1][$i])) { $bases[1][$i]=''; }
  110.       printf "$i" .$bases[1][$i] . ".$str\n";
  111.     }
  112.     printf ":";
  113.  
  114.     $ch=<>;chomp($ch);
  115.     if ($ch=~m/\d{1,}/i)
  116.     {
  117.     if ($bases[1][$ch] eq '*') { $bases[1][$ch]=''; }
  118.     else { $bases[1][$ch]='*'; }
  119.     bases_cfg();return;
  120.     }
  121.     if ($ch eq "*")
  122.     {
  123.         printf "Selected all databases from $m_host\n";
  124.         for($i=0;$bases[0][$i];$i++) { $bases[1][$i]='*';}
  125.         bases_cfg();return;
  126.     }
  127.      
  128.    
  129.     $b->finish();
  130.     $m_conn->disconnect();
  131.    
  132.     $b=0;
  133.     for($i=0;$bases[0][$i];$i++)
  134.     {
  135.     if ($bases[1][$i] eq '*')
  136.     {
  137.         `su - postgres -c 'createlang plpgsql $BASES[$b]'`;
  138.         $BASES[$b]=$bases[0][$i];$b++;
  139.        
  140.     }
  141.     }
  142. }
  143.  
  144. sub tables_cfg()
  145. {
  146.     $t=0;
  147.     for($b=0;$BASES[$b];$b++)
  148.     {
  149.         $db=$BASES[$b];
  150.  
  151.         $t_conn = DBI->connect("dbi:Pg:dbname=$db;host=$m_host","$m_username","$m_password",
  152.         {PrintError => 0});
  153.  
  154.         if (defined($DBI::err) && $DBI::err != 0)
  155.         {
  156.                printf "\nError:" . $DBI::errstr . "\n";
  157.            splice(@BASES,$b,1);
  158.            redo;
  159.         }  
  160.  
  161.         $tabs=$t_conn->prepare("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public';");
  162.         $res=$tabs->execute();
  163.  
  164.         for(;$str = $tabs->fetchrow_array();$t++)
  165.         {
  166.             $tables[0][$t]=$str;
  167.         $tables[1][$t]=$b;
  168.            
  169.             if (!defined($tables[2][$t])) { $tables[2][$t]=''; }
  170.             printf "$t" .$tables[2][$t] . ".$str\n";
  171.         }
  172.        
  173.         $tabs->finish();
  174.         $t_conn->disconnect();
  175.        
  176.        
  177.        
  178.     }
  179.    
  180. }
  181.  
  182. sub sequences_cfg()
  183. {
  184.     $s=0;
  185.     for($b=0;$BASES[$b];$b++)
  186.     {
  187.         $db=$BASES[$b];
  188.  
  189.         $s_conn = DBI->connect("dbi:Pg:dbname=$db;host=$m_host","$m_username","$m_password",
  190.         {PrintError => 0});
  191.  
  192.         if (defined($DBI::err) && $DBI::err != 0)
  193.         {
  194.                printf "\nError:" . $DBI::errstr . "\n";
  195.            splice(@BASES,$b,1);
  196.            redo;
  197.  
  198.         }  
  199.  
  200.         $seqs=$s_conn->prepare("SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = 'public';");
  201.         $res=$seqs->execute();
  202.  
  203.         for(;$str = $seqs->fetchrow_array();$s++)
  204.         {
  205.             $sequences[0][$s]=$str;
  206.         $sequences[1][$s]=$b;
  207.            
  208.             if (!defined($sequences[2][$s])) { $sequences[2][$s]=''; }
  209.             printf "$s" .$sequences[2][$s] . ".$str\n";
  210.         }
  211.        
  212.         $seqs->finish();
  213.         $s_conn->disconnect();
  214.     }
  215.        
  216. }
  217.  
  218. sub dump_to_slave()
  219. {
  220.     printf "Dump selected bases to slave?(Y/n):\n";
  221.     $ch=<>;chomp($ch);
  222.     if (lc($ch) eq 'n') { return; }
  223.  
  224.     for($b=0;$BASES[$b];$b++)
  225.     {
  226.         $create= `ssh $s_host "su - postgres -c 'createdb $BASES[$b];createlang plpgsql $BASES[$b]'"`;
  227.         printf "Dumping " . $BASES[$b] . " to slave...";
  228.         $dump_out=`su - postgres -c 'pg_dump -s $BASES[$b]'|ssh $s_host "su - postgres -c 'psql $BASES[$b]'"`;
  229.         printf "done\n";
  230.     }
  231. }
  232.  
  233. sub generate_config()
  234. {
  235. $config='if ($ENV{"SLONYNODES"}) {
  236. require $ENV{"SLONYNODES"};
  237. } else {
  238. $CLUSTER_NAME = \''. $cluster . '\';
  239. $LOGDIR = \'/var/log/slony1\';
  240. $MASTERNODE = 1;
  241. $DEBUGLEVEL = 4;
  242. ';
  243. #Nodes cycle
  244.     for($b=0;$BASES[$b];$b++)
  245.     {
  246.     $config.="
  247. add_node(
  248.      node       => " . ($b*2+1) . ",
  249.      host       => '$m_host',
  250.      dbname     => '". $BASES[$b] ."',
  251.      port       => 5432,
  252.      user       => '$m_username',
  253.      password   => '$m_password');
  254.  
  255. add_node(
  256.      node       => " . ($b*2+2) . ",
  257.      host       => '$s_host',
  258.      dbname     => '".$BASES[$b]."',
  259.      port       => 5432,
  260.      user       => '$s_username',
  261.      password   => '$s_password');
  262. ";
  263.     $m_nodes.=($b*2+1) . ' ';
  264.     $s_nodes.=($b*2+2) . ' ';
  265.     }      
  266. $config.='}
  267. $SLONY_SETS = {';
  268.  
  269.     #Sets cycle
  270. for($b=0;$BASES[$b];$b++)
  271. {
  272. $config.="
  273. \"$BASES[$b]\" => {
  274. \"pkeyedtables\" => [\n";
  275.    
  276.     #Tables cycle      
  277.     for($t=0;$tables[0][$t];$t++)
  278.     {
  279.         if ($tables[1][$t] == $b)
  280.         {
  281.             $config.="'$tables[0][$t]'" . ",\n";
  282.         }
  283.     }
  284. $config.='],
  285.  
  286. "sequences" => [
  287. ';
  288.     #Sequences cycle       
  289.     for ($s=0;$sequences[0][$s];$s++)
  290.     {
  291.         if ($sequences[1][$s] == $b)
  292.         {
  293.             $config.="'$sequences[0][$s]',\n";
  294.         }
  295.            
  296.     }
  297.     $config.="]},\n";
  298.     }
  299.     $config.='};
  300. if ($ENV{"SLONYSET"}) {
  301.    require $ENV{"SLONYSET"};
  302.    }
  303. 1;';
  304.  
  305. $c_path='';
  306. chomp($iam=`whoami`);
  307. if ($iam ne 'root')
  308. {  
  309.     printf "You`re not root. Saving config to current dir...";
  310. }
  311. else
  312. {
  313.     printf "Write config to /etc/slony1/?(Y/n)";
  314.     $ch=lc(<>);chomp($ch);
  315.     if ($ch eq ''||$ch eq 'y')
  316.     {
  317.         $c_path='/etc/slony1/';
  318.     }
  319.     $m_nodes=~s/\D$//;
  320.     $s_nodes=~s/\D$//;
  321.     `echo 'SLON_TOOLS_START_NODES="$m_nodes"' > /etc/default/slony1;slonik_init_cluster|slonik`;
  322.     printf "Saving config to $c_path...";
  323. }
  324.     open OUT, ">", $c_path . 'slon_tools.conf';
  325.     printf OUT $config;
  326.     close (OUT);
  327.     printf "done\n";
  328.  
  329. }
  330.  
  331. sub send_config()
  332. {
  333.     printf "Send config to $c_path on slave?(Y/n)\n";
  334.     $ch=lc(<>);chomp($ch);
  335.     if ($ch eq ''||$ch eq 'y')
  336.     {
  337.     `scp $c_path/slon_tools.conf $s_host:$c_path`;
  338.     `ssh $s_host 'echo SLON_TOOLS_START_NODES=\\"$s_nodes\\" > /etc/default/slony1;slonik_init_cluster|slonik'`;
  339.     }
  340.  
  341. }
  342.  
  343. sub start_daemons()
  344. {
  345.     if ($iam ne 'root') {printf "You`re not root. Skipping.\n";return;}
  346.  
  347.     printf "Start daemons?(Y/n):\n";
  348.     chomp($ch=lc(<>));
  349.     if ($ch eq 'y'|| $ch eq '')
  350.     {
  351.     for($b=0;$BASES[$b];$b++)
  352.     {
  353.         printf "Starting local slon...\n";
  354.         $out=`/etc/init.d/slony1 start`;
  355.         printf "Starting slon on $s_host...\n";
  356.         $out=`ssh $s_host '/etc/init.d/slony1 start'`;
  357.     }
  358.     }
  359. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement