mirror of https://github.com/sysown/proxysql
parent
db00c9a904
commit
4b4e1234a1
@ -0,0 +1,99 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use vars;
|
||||
use DBI;
|
||||
use DBD::mysql;
|
||||
|
||||
|
||||
## CUSTOMIZE THESE CONSTANTS
|
||||
use constant {
|
||||
HOST => "127.0.0.1",
|
||||
PORT => "6032",
|
||||
USER => "admin",
|
||||
PASS => "admin",
|
||||
VERB => 1
|
||||
};
|
||||
|
||||
our $dbn;
|
||||
our $dbh;
|
||||
|
||||
sub main {
|
||||
@ARGV = @_;
|
||||
my $nargs=$#ARGV + 1;
|
||||
if ($nargs != 3) {
|
||||
print STDERR "Incorrect number of arguments\n";
|
||||
return 1;
|
||||
}
|
||||
my $writerHG=$ARGV[0];
|
||||
my $readerHG=$ARGV[1];
|
||||
my $maxwriters=$ARGV[2];
|
||||
if (VERB) {
|
||||
print STDERR "Writer hostgroup: $writerHG\n";
|
||||
print STDERR "Reader hostgroup: $readerHG\n";
|
||||
print STDERR "Max num writers: $maxwriters\n";
|
||||
}
|
||||
# connect to Admin interface and retrieve the current ative masters
|
||||
$dbn="dbi:mysql:main:".HOST.":".PORT;
|
||||
$dbh=DBI->connect($dbn, USER, PASS) or die "Unable to connect: $DBI::errstr\n";
|
||||
my $selh=$dbh->prepare("SELECT hostname,port FROM runtime_mysql_servers WHERE status='ONLINE' AND hostgroup_id=$writerHG") or die "Unable to prepare: $DBI::errstr\n";
|
||||
$selh->execute() or die "Unable to execute: $DBI::errstr\n";
|
||||
my @data;
|
||||
while (my $res=$selh->fetchrow_hashref) {
|
||||
push (@data, $res);
|
||||
}
|
||||
my $active_writers= scalar @data;
|
||||
if (VERB) {
|
||||
print STDERR "Active writers found: $active_writers\n";
|
||||
foreach (@data) {
|
||||
my $s=$_;
|
||||
print " $s->{'hostname'} $s->{'port'}\n";
|
||||
}
|
||||
}
|
||||
if ($active_writers==$maxwriters) {
|
||||
if (VERB) {
|
||||
print STDERR "Active writers match max number of writers: exit with no action\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
# if the execution of the script reaches here, some action is required
|
||||
if (VERB) {
|
||||
print STDERR "$active_writers active writers found do not match $maxwriters writers expected\n";
|
||||
}
|
||||
# although we run the check on runtime_mysql_servers , we will perform all the operations on mysql_servers
|
||||
# be aware that in ProxySQL Admin doesn't support locking or transactions, so, even if unlikely,
|
||||
# it is possible that race conditions can happen if two scripts update mysql_servers at the same
|
||||
|
||||
# first, set to OFFLINE_SOFT all nodes in the writer hostgroup
|
||||
# OFFLINE_SOFT doesn't terminate current transactions, therefore it is a graceful "shutdown"
|
||||
print STDERR "Disabling old $active_writers write(s)\n";
|
||||
$dbh->do("UPDATE mysql_servers SET status='OFFLINE_SOFT' WHERE hostgroup_id=$writerHG") or die "Unable to set writes offline: $DBI::errstr\n";
|
||||
|
||||
# here we define the new masters
|
||||
# the algorithm used to determine the new masters is customizable: define the algorithm you prefer
|
||||
# CUSTOMIZE IT!
|
||||
print STDERR "Adding new $maxwriters write(s)\n";
|
||||
|
||||
# in this example, the algorithm is that are promoted as master(s) the first N hosts order by ORDER BY weight DESC, hostname, port
|
||||
$dbh->do("REPLACE INTO mysql_servers (hostgroup_id, hostname, port, status, weight, max_connections, use_ssl) SELECT $writerHG , hostname, port, status, weight, max_connections, use_ssl FROM mysql_servers WHERE hostgroup_id=$readerHG AND status='ONLINE' ORDER BY weight DESC, hostname, port LIMIT $maxwriters") or die "Unable to set new writer: $DBI::errstr\n";
|
||||
|
||||
# now we load at RUNTIME
|
||||
print STDERR "Loading to runtime...";
|
||||
$dbh->do("LOAD MYSQL SERVERS TO RUNTIME") or die "Unable to LOAD MYSQL SERVERS TO RUNTIME: $DBI::errstr\n";
|
||||
print STDERR " Done!\n";
|
||||
# as last step, we display the current masters
|
||||
print STDERR "Reporting new writer(s) :\n";
|
||||
$selh->execute() or die "Unable to execute: $DBI::errstr\n";
|
||||
my @newhosts;
|
||||
while (my $res=$selh->fetchrow_hashref) {
|
||||
push (@newhosts, $res);
|
||||
}
|
||||
foreach (@newhosts) {
|
||||
my $s=$_;
|
||||
print " $s->{'hostname'} $s->{'port'}\n";
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if(!caller) { exit(main(@ARGV)); }
|
||||
Loading…
Reference in new issue