~ubuntu-branches/ubuntu/trusty/drizzle/trusty-updates

« back to all changes in this revision

Viewing changes to tests/kewpie/randgen/lib/GenTest/Reporter/ReplicationSemiSync.pm

  • Committer: Package Import Robot
  • Author(s): Tobias Frost
  • Date: 2012-04-04 15:12:07 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20120404151207-xwsgn1xegslle4p0
Tags: 1:7.1.32-rc-1
* New upstream release.
* Plugin-filtered-replicator upstream removed and will no longer be built.
* Updating d/*install files to accommodate upstream changes from drizzle7
  to drizzle
* Added symlink in libdrizzledmessage-dev to library
* libdrizzle: soname-bump
* Rename package drizzle-plugin-performance-dictionary to shorten package name
  (due to linitan warning package-has-long-file-name)
* Debian/control: removed unused substitution variable ${shlibs:Depends} for
  -dbg and -dev packages

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2008-2009 Sun Microsystems, Inc. All rights reserved.
 
2
# Use is subject to license terms.
 
3
#
 
4
# This program is free software; you can redistribute it and/or modify
 
5
# it under the terms of the GNU General Public License as published by
 
6
# the Free Software Foundation; version 2 of the License.
 
7
#
 
8
# This program is distributed in the hope that it will be useful, but
 
9
# WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
11
# General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 
16
# USA
 
17
 
 
18
package GenTest::Reporter::ReplicationSemiSync;
 
19
 
 
20
#
 
21
# The purpose of this Reporter is to test Semi-synchronous replication as follows:
 
22
#
 
23
#  At every monitoring cycle, we issue an adverse event against the slave or the master/slave connection and then:
 
24
#
 
25
# 1. Check that the slave IO thread is up to date with the master
 
26
#
 
27
# 2A. We wait for 1/2 of the timeout period, and then we check various counters to see that no transactions
 
28
#    have committed while the slave was not available OR 
 
29
#
 
30
# 2B. We wait for more than the timeout period and then we check that some transactions have moved forward
 
31
#
 
32
# 3. We restart replication in order to allow the slave to catch up, and check that the master is back to
 
33
#    semisync replication
 
34
#
 
35
 
 
36
require Exporter;
 
37
@ISA = qw(GenTest::Reporter);
 
38
 
 
39
use strict;
 
40
use GenTest;
 
41
use GenTest::Reporter;
 
42
use GenTest::Constants;
 
43
 
 
44
my $rpl_semi_sync_master_timeout = 10;
 
45
 
 
46
sub monitor {
 
47
        my $reporter = shift;
 
48
 
 
49
        say("GenTest::Reporter::ReplicationSemiSync: Test cycle starting.");
 
50
 
 
51
        my $prng = $reporter->prng();
 
52
 
 
53
        my $slave_host = $reporter->serverInfo('slave_host');
 
54
        my $slave_port = $reporter->serverInfo('slave_port');
 
55
 
 
56
        my $master_dsn = $reporter->dsn();
 
57
        my $slave_dsn = 'dbi:mysql:host='.$slave_host.':port='.$slave_port.':user=root';
 
58
 
 
59
        my $slave_dbh = DBI->connect($slave_dsn);
 
60
        my $master_dbh = DBI->connect($master_dsn);
 
61
 
 
62
        $master_dbh->do("SET GLOBAL rpl_semi_sync_master_enabled = 1");
 
63
        $master_dbh->do("SET GLOBAL rpl_semi_sync_master_trace_level = 80");
 
64
        $slave_dbh->do("SET GLOBAL rpl_semi_sync_slave_enabled = 1");
 
65
        $slave_dbh->do("SET GLOBAL rpl_semi_sync_slave_trace_level = 80");
 
66
 
 
67
        return STATUS_REPLICATION_FAILURE if waitForSlave($master_dbh, $slave_dbh, 1);
 
68
#       sleep(1);
 
69
 
 
70
#       my ($unused2, $rpl_semi_sync_master_status_first) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_status'");
 
71
 
 
72
#       if (
 
73
#               ($rpl_semi_sync_master_status_first eq '') ||
 
74
#               ($rpl_semi_sync_master_status_first eq 'OFF')
 
75
#       ) {
 
76
#               say("GenTest::Reporter::ReplicationSemiSync: Semisync replication is not enabled: rpl_semi_sync_master_status = $rpl_semi_sync_master_status_first.");
 
77
#               return STATUS_REPLICATION_FAILURE;
 
78
#       }
 
79
 
 
80
#       $master_dbh->do("SET GLOBAL rpl_semi_sync_master_timeout = ".($rpl_semi_sync_master_timeout * 1000));
 
81
#       say("GenTest::Reporter::ReplicationSemiSync: Acquiring the global read lock.");
 
82
#       $master_dbh->do("FLUSH NO_WRITE_TO_BINLOG TABLES WITH READ LOCK");
 
83
#       say("GenTest::Reporter::ReplicationSemiSync: stopping slave IO thread.");
 
84
#       $slave_dbh->do("STOP SLAVE IO_THREAD");
 
85
#       say("GenTest::Reporter::ReplicationSemiSync: stopped slave IO thread.");
 
86
 
 
87
#       return STATUS_REPLICATION_FAILURE if isSlaveBehind($master_dbh, $slave_dbh);
 
88
 
 
89
#       $master_dbh->do("FLUSH NO_WRITE_TO_BINLOG STATUS");
 
90
#       say("GenTest::Reporter::ReplicationSemiSync: Flushed status.");
 
91
#       $master_dbh->do("UNLOCK TABLES");
 
92
#       say("GenTest::Reporter::ReplicationSemiSync: Released the global read lock.");
 
93
#       my ($unusedA, $rpl_semi_sync_master_yes_tx_atflush) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx'");
 
94
#       my ($unusedB, $rpl_semi_sync_master_no_tx_atflush) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx'");
 
95
 
 
96
        # Pick a sleep interval that is either more or less than the semisync timeout
 
97
 
 
98
        my $sleep_interval = $prng->int(0, 1) == 1 ? ($rpl_semi_sync_master_timeout * 2) : 5;
 
99
        say("GenTest::Reporter::ReplicationSemiSync: Sleeping for $sleep_interval seconds.");
 
100
        sleep($sleep_interval);
 
101
 
 
102
        my ($unused4, $rpl_semi_sync_master_yes_tx) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_yes_tx'");
 
103
        my ($unused5, $rpl_semi_sync_master_no_tx) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_no_tx'");
 
104
        my ($unused6, $rpl_semi_sync_master_status_after) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_status'");
 
105
 
 
106
        #
 
107
        # If we slept more than the semisync timeout, then we can expect that transactions have been committed
 
108
        # If we slept less, then no transactions should have committed
 
109
        #
 
110
 
 
111
        if ($sleep_interval > $rpl_semi_sync_master_timeout) {
 
112
                if ($rpl_semi_sync_master_status_after eq 'ON') {
 
113
                        say("GenTest::Reporter::ReplicationSemiSync: rpl_semi_sync_master_status = ON even after stopping for longer than the timeout.");
 
114
                        return STATUS_REPLICATION_FAILURE;
 
115
                } elsif ($rpl_semi_sync_master_no_tx == 0) {
 
116
                        say("GenTest::Reporter::ReplicationSemiSync: Transactions were not committed asynchronously while slave was stopped for longer than the timeout.");
 
117
                        say("GenTest::Reporter::ReplicationSemiSync: rpl_semi_sync_master_no_tx = $rpl_semi_sync_master_no_tx;");
 
118
                } elsif ($rpl_semi_sync_master_yes_tx > 0) {
 
119
                        say("GenTest::Reporter::ReplicationSemiSync: Transactions were committed semisynchronously while slave was stopped longer than the timeout.");
 
120
                        say("GenTest::Reporter::ReplicationSemiSync: rpl_semi_sync_master_yes_tx = $rpl_semi_sync_master_yes_tx;");
 
121
                        return STATUS_REPLICATION_FAILURE;
 
122
                }
 
123
        } else {
 
124
 
 
125
#               jasonh says that this condition is not guaranteed - if we detect a slave problem, we abort immediately and do not bother
 
126
#               to wait for the full timeout
 
127
#
 
128
                if ($rpl_semi_sync_master_status_after eq 'OFF') {
 
129
                        say("GenTest::Reporter::ReplicationSemiSync: rpl_semi_sync_master_status = OFF even after stopping for less than the timeout.");
 
130
                        return STATUS_REPLICATION_FAILURE;
 
131
                } elsif ($rpl_semi_sync_master_no_tx > 0) {
 
132
                        say("GenTest::Reporter::ReplicationSemiSync: Transactions were committed asynchronously while slave was stopped for less than the timeout.");
 
133
                        say("GenTest::Reporter::ReplicationSemiSync: rpl_semi_sync_master_no_tx = $rpl_semi_sync_master_no_tx;");
 
134
                        return STATUS_REPLICATION_FAILURE;
 
135
                } elsif ($rpl_semi_sync_master_yes_tx > 0) {
 
136
                        say("GenTest::Reporter::ReplicationSemiSync: Transactions were committed semisynchronously while slave was stopped for less than the timeout.");
 
137
                        say("GenTest::Reporter::ReplicationSemiSync: rpl_semi_sync_master_yes_tx = $rpl_semi_sync_master_yes_tx;");
 
138
                        return STATUS_REPLICATION_FAILURE;
 
139
                } else {
 
140
#                       return STATUS_REPLICATION_FAILURE if isSlaveBehind($master_dbh, $slave_dbh);
 
141
                }
 
142
        }
 
143
        
 
144
        say("GenTest::Reporter::ReplicationSemiSync: Starting slave IO thread.");
 
145
        $slave_dbh->do("START SLAVE IO_THREAD");
 
146
 
 
147
        #
 
148
        # Make sure master and slave can reconcile and semisync will be turned on again
 
149
        #
 
150
 
 
151
        return STATUS_REPLICATION_FAILURE if waitForSlave($master_dbh, $slave_dbh, 0);
 
152
#       sleep(1);
 
153
 
 
154
#       my ($unused7, $rpl_semi_sync_master_status_last) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_status'");
 
155
#       if ($rpl_semi_sync_master_status_last eq 'OFF') {
 
156
#               say("GenTest::Reporter::ReplicationSemiSync: Master has failed to return to semisync replication even after the slave has reconnected.");
 
157
#               return STATUS_REPLICATION_FAILURE;
 
158
#       }
 
159
 
 
160
#       say("GenTest::Reporter::ReplicationSemiSync: test cycle ending with Rpl_semi_sync_master_status = $rpl_semi_sync_master_status_last.");
 
161
 
 
162
        return STATUS_OK;
 
163
}
 
164
 
 
165
sub type {
 
166
        return REPORTER_TYPE_PERIODIC;
 
167
}
 
168
 
 
169
sub isSlaveBehind {
 
170
        my ($master_dbh, $slave_dbh) = @_;
 
171
 
 
172
        my $binlogs = $master_dbh->selectall_arrayref("SHOW BINARY LOGS");
 
173
        my ($last_log_name, $last_log_pos) = ($binlogs->[$#$binlogs]->[0], $binlogs->[$#$binlogs]->[1]);
 
174
        my ($last_log_id) = $last_log_name =~ m{(\d+)}sgio;
 
175
        say("Master: last_log_name = $last_log_name; last_log_pos = $last_log_pos; $last_log_id = $last_log_id.");
 
176
                        
 
177
        my $slave_status = $slave_dbh->selectrow_arrayref("SHOW SLAVE STATUS");
 
178
        my ($master_log_file, $read_master_log_pos) = ($slave_status->[5], $slave_status->[6]);
 
179
        my ($master_log_id) = $master_log_file =~ m{(\d+)}sgio;
 
180
        say("GenTest::Reporter::ReplicationSemiSync: slave: master_log_file = $master_log_file; read_master_log_pos = $read_master_log_pos; master_log_id = $master_log_id.");
 
181
        if ( 
 
182
                ($last_log_id < $master_log_id) ||
 
183
                ($last_log_id == $master_log_id) && ($last_log_pos > $read_master_log_pos)
 
184
        ) {
 
185
                my ($unused, $rpl_semi_sync_master_status) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_status'");
 
186
                say("GenTest::Reporter::ReplicationSemiSync: Slave has lagged behind while Rpl_semi_sync_master_status = $rpl_semi_sync_master_status.");
 
187
                return STATUS_REPLICATION_FAILURE;
 
188
        }
 
189
}
 
190
 
 
191
sub waitForSlave {
 
192
        my ($master_dbh, $slave_dbh, $stop_slave) = @_;
 
193
 
 
194
        say("GenTest::Reporter::ReplicationSemiSync: Flushing tables with read lock on master...");
 
195
        $master_dbh->do("FLUSH NO_WRITE_TO_BINLOG TABLES WITH READ LOCK");
 
196
        say("GenTest::Reporter::ReplicationSemiSync: ... flushed.");
 
197
 
 
198
        my ($file, $pos) = $master_dbh->selectrow_array("SHOW MASTER STATUS");
 
199
 
 
200
        if (($file eq '') || ($pos eq '')) {
 
201
                 say("GenTest::Reporter::ReplicationSemiSync: SHOW MASTER STATUS failed.");
 
202
                 return STATUS_REPLICATION_FAILURE;
 
203
        }
 
204
 
 
205
        say("GenTest::Reporter::ReplicationSemiSync: Waiting for slave...");
 
206
        #say("SHOW MASTER STATUS: " . $file . ", " . $pos);
 
207
        my $wait_status = $slave_dbh->selectrow_array("SELECT MASTER_POS_WAIT(?, ?)", undef, $file, $pos);
 
208
        say("GenTest::Reporter::ReplicationSemiSync: ... slave caught up with master.");
 
209
 
 
210
        #my ($new_file, $new_pos) = $master_dbh->selectrow_array("SHOW MASTER STATUS");
 
211
        #say("SHOW MASTER STATUS: " . $new_file . ", " . $new_pos);
 
212
 
 
213
        my ($unused2, $rpl_semi_sync_master_status) = $master_dbh->selectrow_array("SHOW STATUS LIKE 'Rpl_semi_sync_master_status'");
 
214
        if (not $rpl_semi_sync_master_status eq 'ON') {
 
215
            say("GenTest::Reporter::ReplicationSemiSync: Master has failed to return to semisync replication even after the slave has caught up.");
 
216
            return STATUS_REPLICATION_FAILURE;
 
217
        }
 
218
 
 
219
        if ($stop_slave) {
 
220
            $master_dbh->do("FLUSH NO_WRITE_TO_BINLOG STATUS");
 
221
            say("GenTest::Reporter::ReplicationSemiSync: Flushed status.");
 
222
            $master_dbh->do("SET GLOBAL rpl_semi_sync_master_timeout = ".($rpl_semi_sync_master_timeout * 1000));
 
223
            say("GenTest::Reporter::ReplicationSemiSync: stopping slave IO thread.");
 
224
            $slave_dbh->do("STOP SLAVE IO_THREAD");
 
225
            say("GenTest::Reporter::ReplicationSemiSync: stopped slave IO thread.");
 
226
        }
 
227
 
 
228
        $master_dbh->do("UNLOCK TABLES");
 
229
 
 
230
        if (not defined $wait_status) {
 
231
                say("GenTest::Reporter::ReplicationSemiSync: MASTER_POS_WAIT() has failed. Slave SQL thread has likely stopped.");
 
232
                return STATUS_REPLICATION_FAILURE;
 
233
        }
 
234
        return 0;
 
235
}
 
236
 
 
237
1;