3786
3791
return $self->{hostname} || $self->{dsn_name} || 'unknown host';
3794
sub remove_duplicate_cxns {
3795
my ($self, %args) = @_;
3796
my @cxns = @{$args{cxns}};
3797
my $seen_ids = $args{seen_ids} || {};
3798
PTDEBUG && _d("Removing duplicates from ", join(" ", map { $_->name } @cxns));
3801
for my $cxn ( @cxns ) {
3802
my $dbh = $cxn->dbh();
3803
my $sql = q{SELECT @@server_id};
3804
PTDEBUG && _d($sql);
3805
my ($id) = $dbh->selectrow_array($sql);
3806
PTDEBUG && _d('Server ID for ', $cxn->name, ': ', $id);
3808
if ( ! $seen_ids->{$id}++ ) {
3809
push @trimmed_cxns, $cxn
3812
PTDEBUG && _d("Removing ", $cxn->name,
3813
", ID ", $id, ", because we've already seen it");
3817
return \@trimmed_cxns;
3790
3821
my ($self) = @_;
7505
7540
sub same_node {
7506
7541
my ($self, $cxn1, $cxn2) = @_;
7508
my $sql = "SHOW VARIABLES LIKE 'wsrep\_sst\_receive\_address'";
7509
PTDEBUG && _d($cxn1->name, $sql);
7510
my (undef, $val1) = $cxn1->dbh->selectrow_array($sql);
7511
PTDEBUG && _d($cxn2->name, $sql);
7512
my (undef, $val2) = $cxn2->dbh->selectrow_array($sql);
7514
return ($val1 || '') eq ($val2 || '');
7543
foreach my $val ('wsrep\_sst\_receive\_address', 'wsrep\_node\_name', 'wsrep\_node\_address') {
7544
my $sql = "SHOW VARIABLES LIKE '$val'";
7545
PTDEBUG && _d($cxn1->name, $cxn2->name, $sql);
7546
my (undef, $val1) = $cxn1->dbh->selectrow_array($sql);
7547
my (undef, $val2) = $cxn2->dbh->selectrow_array($sql);
7549
return unless ($val1 || '') eq ($val2 || '');
7555
sub find_cluster_nodes {
7556
my ($self, %args) = @_;
7558
my $dbh = $args{dbh};
7559
my $dsn = $args{dsn};
7560
my $dp = $args{DSNParser};
7561
my $make_cxn = $args{make_cxn};
7564
my $sql = q{SHOW STATUS LIKE 'wsrep\_incoming\_addresses'};
7565
PTDEBUG && _d($sql);
7566
my (undef, $addresses) = $dbh->selectrow_array($sql);
7567
PTDEBUG && _d("Cluster nodes found: ", $addresses);
7568
return unless $addresses;
7570
my @addresses = grep { !/\Aunspecified\z/i }
7571
split /,\s*/, $addresses;
7574
foreach my $address ( @addresses ) {
7575
my ($host, $port) = split /:/, $address;
7576
my $spec = "h=$host"
7577
. ($port ? ",P=$port" : "");
7578
my $node_dsn = $dp->parse($spec, $dsn);
7579
my $node_dbh = eval { $dp->get_dbh(
7580
$dp->get_cxn_params($node_dsn), { AutoCommit => 1 }) };
7581
if ( $EVAL_ERROR ) {
7582
print STDERR "Cannot connect to ", $dp->as_string($node_dsn),
7583
", discovered through $sql: $EVAL_ERROR\n";
7584
if ( !$port && $dsn->{P} != 3306 ) {
7585
$address .= ":3306";
7590
PTDEBUG && _d('Connected to', $dp->as_string($node_dsn));
7591
$node_dbh->disconnect();
7593
push @nodes, $make_cxn->(dsn => $node_dsn);
7599
sub remove_duplicate_cxns {
7600
my ($self, %args) = @_;
7601
my @cxns = @{$args{cxns}};
7602
my $seen_ids = $args{seen_ids};
7603
return Cxn->remove_duplicate_cxns(%args);
7517
7606
sub same_cluster {
7525
7614
return ($cluster1 || '') eq ($cluster2 || '');
7617
sub autodetect_nodes {
7618
my ($self, %args) = @_;
7619
my $ms = $args{MasterSlave};
7620
my $dp = $args{DSNParser};
7621
my $make_cxn = $args{make_cxn};
7622
my $nodes = $args{nodes};
7623
my $seen_ids = $args{seen_ids};
7627
return $new_nodes unless @$nodes;
7629
for my $node ( @$nodes ) {
7630
my $nodes_found = $self->find_cluster_nodes(
7631
dbh => $node->dbh(),
7632
dsn => $node->dsn(),
7633
make_cxn => $make_cxn,
7636
push @$new_nodes, @$nodes_found;
7639
$new_nodes = $self->remove_duplicate_cxns(
7641
seen_ids => $seen_ids
7644
my $new_slaves = [];
7645
foreach my $node (@$new_nodes) {
7646
my $node_slaves = $ms->get_slaves(
7647
dbh => $node->dbh(),
7648
dsn => $node->dsn(),
7649
make_cxn => $make_cxn,
7651
push @$new_slaves, @$node_slaves;
7654
$new_slaves = $self->remove_duplicate_cxns(
7655
cxns => $new_slaves,
7656
seen_ids => $seen_ids
7659
my @new_slave_nodes = grep { $self->is_cluster_node($_) } @$new_slaves;
7661
my $slaves_of_slaves = $self->autodetect_nodes(
7663
nodes => \@new_slave_nodes,
7666
my @autodetected_nodes = ( @$new_nodes, @$new_slaves, @$slaves_of_slaves );
7667
return \@autodetected_nodes;
7529
7671
my ($package, undef, $line) = caller 0;
7530
7672
@_ = map { (my $temp = $_) =~ s/\n/\n# /g; $temp; }