summaryrefslogtreecommitdiff
path: root/scripts/bucardo_rrd
blob: 35ed37cc15f42f8f0e0c5e58a25880572072bbc2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/env perl
# -*-mode:cperl; indent-tabs-mode: nil-*-

## Grab a bunch of Bucardo stats for cacti
##
## Copyright 2007 Greg Sabino Mullane <greg@endpoint.com>

use strict;
use warnings;
use DBI;

our $VERSION = '1.0.1'; 

my $DBUSER = 'bucardo_readonly';
my $DBOPT = {AutoCommit=>0,RaiseError=>1,PrintError=>0};
my $verbose = 0;

my $dbh =
  {
   dbname1 => DBI->connect('dbi:Pg:dbname=dbname1', $DBUSER, '', $DBOPT),
   bucardo => DBI->connect('dbi:Pg:dbname=bucardo', $DBUSER, '', $DBOPT),
  };

## Specialized due to constraint exclusion funkiness:
my $minutesback = 5;
my $SQL = "SELECT now()-'$minutesback minutes'::interval";
my $ARG =
  {
   TS => $dbh->{bucardo}->selectall_arrayref($SQL)->[0][0],
};
$dbh->{bucardo}->do('SET constraint_exclusion = true');

my $info = {};
my $query;
my $db;
my @q;
while (<DATA>) {
  next if /^\s*#/ or /^\s*$/;
  if (/^DB:(\w+)/) {
    my $newdb = $1;
    push @q, [$db,$query] if defined $query;
    $db = $newdb;
    $query = '';
  }
  else {
    $query .= $_;
  }
}
push @q, [$db,$query] if defined $query and length $query;

for (@q) {
  my ($db,$sql) = @$_;
  chomp $sql;
  $sql =~ s/ARG{(\w+)}/$ARG->{$1}/ge;
  $verbose and warn "SQL: -->$sql<--\n";
  my $sth = $dbh->{$db}->prepare($sql);
  $sth->execute();
  for my $row (@{$sth->fetchall_arrayref({})}) {
    for my $key (keys %$row) {
      $info->{$key} = $row->{$key};
    }
    last;
  }
}

## Aggregate some info
$info->{swap_rows} = $info->{swap_inserts} + $info->{swap_updates} + $info->{swap_deletes};

$info->{total_rows} = $info->{swap_rows} + $info->{fullcopy_rows} + $info->{pushdelta_rows};

$info->{total_syncs} = $info->{swap_syncs} + $info->{fullcopy_syncs} + $info->{pushdelta_syncs};

## Track each type of abort error
$query = qq{
SELECT whydie
FROM   bucardo.q
WHERE  cdate >= '$ARG->{TS}'
AND    aborted IS NOT NULL
UNION ALL
SELECT whydie
FROM   freezer.master_q
WHERE  cdate >= '$ARG->{TS}'
AND    aborted IS NOT NULL
};
my %abort;
for (qw/ deadlock serialize route killed unknown/) {
  $abort{$_} = 0;
}
$info->{aborts} = 0;
for my $row (@{$dbh->{bucardo}->selectall_arrayref($query)}) {
  my $reason = $row->[0];
  $info->{aborts}++;
  $reason ||= '';
  if ($reason =~ /deadlock/) {
    $abort{deadlock}++;
  }
  elsif ($reason =~ /could not serialize/) {
    $abort{serialize}++;
  }
  elsif ($reason =~ /route to host/) {
    $abort{route}++;
  }
  elsif ($reason =~ /unexpectedly/) {
    $abort{killed}++;
  }
  else {
    $abort{unknown}++;
  }
}

for (keys %abort) {
  $info->{"abort_$_"} = $abort{$_};
}


for (values %$dbh) { $_->disconnect(); }

my $string = join ' ' => map { "$_:$info->{$_}" } sort keys %$info;
print "$string\n";

exit;

__DATA__
## Format: DB:database\ncommand
## Order is important

## Number of delta rows awaitin'
DB:bcs
SELECT count(*) AS deltarows FROM bucardo.bucardo_delta

## Number of track rows awaitin'
DB:bcs
SELECT count(*) AS trackrows FROM bucardo.bucardo_track

## Number of transactions yet to be synced
DB:bcs
SELECT count(distinct txntime) AS deltatxns FROM bucardo.bucardo_delta

## Number of swap inserts, updates, deletes in the last 5 minutes
DB:bucardo
SELECT coalesce(qi,0)+coalesce(fi,0) AS swap_inserts,
       coalesce(qd,0)+coalesce(fd,0) AS swap_deletes,
       coalesce(qu,0)+coalesce(fu,0) AS swap_updates
FROM 
  (SELECT sum(inserts) AS qi, sum(updates) AS qu, sum(deletes) AS qd FROM bucardo.q
   WHERE cdate >= 'ARG{TS}' AND synctype = 'swap') AS a,
  (SELECT sum(inserts) AS fi, sum(updates) AS fu, sum(deletes) AS fd FROM freezer.master_q 
   WHERE cdate >= 'ARG{TS}' AND synctype = 'swap') AS b;

## Number of fullcopy rows (always inserts) in last 5 minutes
DB:bucardo
SELECT coalesce(x,0)+coalesce(y,0) AS fullcopy_rows
FROM 
  (SELECT sum(inserts) AS x FROM bucardo.q
   WHERE cdate >= 'ARG{TS}' AND synctype = 'fullcopy') AS a,
  (SELECT sum(inserts) AS y FROM freezer.master_q 
   WHERE cdate >= 'ARG{TS}' AND synctype = 'fullcopy') AS b;

## Number of pushdelta rows (always inserts) in last 5 minutes
DB:bucardo
SELECT coalesce(x,0)+coalesce(y,0) AS pushdelta_rows
FROM 
  (SELECT sum(inserts) AS x FROM bucardo.q
   WHERE cdate >= 'ARG{TS}' AND synctype = 'pushdelta') AS a,
  (SELECT sum(inserts) AS y FROM freezer.master_q 
   WHERE cdate >= 'ARG{TS}' AND synctype = 'pushdelta') AS b;

## Number of swap syncs run in the last 5 minutes
DB:bucardo
SELECT x+y AS swap_syncs
FROM
  (SELECT count(*) AS x
   FROM   bucardo.q
   WHERE  cdate >= 'ARG{TS}'
   AND    synctype = 'swap'
   AND    ended IS NOT NULL) AS a,
  (SELECT count(*) AS y
   FROM   freezer.master_q
   WHERE  cdate >= 'ARG{TS}'
   AND    synctype = 'swap'
   AND    ended IS NOT NULL) AS b

## Number of fullcopy syncs run in the last 5 minutes
DB:bucardo
SELECT x+y AS fullcopy_syncs
FROM
  (SELECT count(*) AS x
   FROM   bucardo.q
   WHERE  cdate >= 'ARG{TS}'
   AND    synctype = 'fullcopy'
   AND    ended IS NOT NULL) AS a,
  (SELECT count(*) AS y
   FROM   freezer.master_q
   WHERE  cdate >= 'ARG{TS}'
   AND    synctype = 'fullcopy'
   AND    ended IS NOT NULL) AS b


## Number of swap sync run in the last 5 minutes
DB:bucardo
SELECT x+y AS pushdelta_syncs
FROM
  (SELECT count(*) AS x
   FROM   bucardo.q
   WHERE  cdate >= 'ARG{TS}'
   AND    synctype = 'pushdelta'
   AND    ended IS NOT NULL) AS a,
  (SELECT count(*) AS y
   FROM   freezer.master_q
   WHERE  cdate >= 'ARG{TS}'
   AND    synctype = 'pushdelta'
   AND    ended IS NOT NULL) AS b

## Number of PIDs created in last 5 minutes
DB:bucardo
SELECT count(*) AS pids
FROM bucardo.audit_pid WHERE birthdate >= 'ARG{TS}'