~ubuntu-branches/ubuntu/vivid/drizzle/vivid-proposed

« back to all changes in this revision

Viewing changes to tests/randgen/lib/GenTest/Reporter/DrizzleSlavePluginCrashRecover.pm

  • Committer: Package Import Robot
  • Author(s): Tobias Frost
  • Date: 2013-08-22 20:18:31 UTC
  • mto: (20.1.1 sid)
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20130822201831-gn3ozsh7o7wmc5tk
Tags: upstream-7.2.3
ImportĀ upstreamĀ versionĀ 7.2.3

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::DrizzleSlavePluginCrashRecover;
19
 
 
20
 
require Exporter;
21
 
@ISA = qw(GenTest::Reporter);
22
 
 
23
 
use strict;
24
 
use DBI;
25
 
use GenTest;
26
 
use GenTest::Constants;
27
 
use GenTest::Reporter;
28
 
use Data::Dumper;
29
 
use IPC::Open2;
30
 
use IPC::Open3;
31
 
use File::Copy;
32
 
 
33
 
use constant SERVER1_FILE_NAME  => 0;
34
 
use constant SERVER2_FILE_NAME  => 1;
35
 
 
36
 
my $first_reporter;
37
 
 
38
 
sub monitor {
39
 
        my $reporter = shift;
40
 
 
41
 
        # In case of two servers, we will be called twice.
42
 
        # Only kill the first server and ignore the second call.
43
 
        
44
 
        $first_reporter = $reporter if not defined $first_reporter;
45
 
        return STATUS_OK if $reporter ne $first_reporter;
46
 
        
47
 
        my $dbh = DBI->connect($reporter->dsn(), undef, undef, {PrintError => 0});
48
 
       
49
 
        my $time = time();
50
 
                my $pid = $ENV{'BOT0_S0_PID'};
51
 
        my $time = time();
52
 
        my $testEnd = $reporter->testEnd();
53
 
        say("time:  $time");
54
 
        say("testEnd:  $testEnd");
55
 
        if (time() > $reporter->testEnd() - 3500) 
56
 
        {
57
 
                #my $ps_result = system("ps -al");
58
 
                #say ("$ps_result");
59
 
                say("Sending kill -9 to server pid $pid in order to force a recovery.");
60
 
                kill(9, $pid);
61
 
                #my $ps_result = system("ps -al");
62
 
                #say ("$ps_result");
63
 
                return STATUS_SERVER_KILLED;
64
 
        }
65
 
        else 
66
 
        {
67
 
                return STATUS_OK;
68
 
        }
69
 
}
70
 
 
71
 
 
72
 
sub report 
73
 
  {
74
 
        my $reporter = shift;
75
 
 
76
 
        $first_reporter = $reporter if not defined $first_reporter;
77
 
        return STATUS_OK if $reporter ne $first_reporter;
78
 
 
79
 
        # do some setup and whatnot
80
 
        my $main_port;
81
 
        my $validator_port;
82
 
        my $basedir;
83
 
 
84
 
        if (exists $ENV{'MASTER_MYPORT'})
85
 
        {
86
 
            $main_port = $ENV{'MASTER_MYPORT'};
87
 
        }
88
 
        else
89
 
        {
90
 
            $main_port = '9306';
91
 
        }
92
 
        if (exists $ENV{'BOT0_S1'})
93
 
        {
94
 
            $validator_port = $ENV{'BOT0_S1'};
95
 
        }
96
 
        else
97
 
        {
98
 
            $validator_port = '9307';
99
 
        }
100
 
        if (exists $ENV{'DRIZZLE_BASEDIR'})
101
 
        {
102
 
            $basedir = $ENV{'DRIZZLE_BASEDIR'};
103
 
        }
104
 
        else
105
 
        {
106
 
            $basedir= $reporter->serverVariable('basedir');
107
 
        }
108
 
        my $drizzledump = $basedir.'/client/drizzledump' ;
109
 
        my $drizzle_client = $basedir.'/client/drizzle' ;
110
 
        my $transaction_reader; 
111
 
        if (exists $ENV{'DRIZZLE_TRX_READER'})
112
 
        {
113
 
            $transaction_reader = $ENV{'DRIZZLE_TRX_READER'}
114
 
        } 
115
 
        elsif (-e $basedir.'/drizzled/message/transaction_reader')
116
 
        {
117
 
            $transaction_reader = $basedir.'/drizzled/message/transaction_reader';
118
 
        }
119
 
        else 
120
 
        {
121
 
            $transaction_reader = $basedir.'/plugin/transaction_log/utilities/drizzletrx' ;
122
 
        }
123
 
 
124
 
        # transaction log location can vary depending on how we start the server
125
 
        # we really only account for test-run and drizzle-automation starts
126
 
        my $transaction_log = '';
127
 
        if (-e $basedir.'/var/local/transaction.log')
128
 
        {
129
 
          $transaction_log = $basedir.'/var/local/transaction.log' ;
130
 
        }
131
 
        elsif (-e $basedir.'/tests/workdir/bot0/s0/var/master-data/local/transaction.log')
132
 
        {
133
 
          $transaction_log = $basedir.'/tests/workdir/bot0/s0/var/master-data/local/transaction.log' ;
134
 
        }
135
 
        else
136
 
        {
137
 
          $transaction_log = $basedir.'/tests/var/master-data/local/transaction.log' ;
138
 
        }
139
 
        my $transaction_log_copy = tmpdir()."/translog_".$$."_.log" ;
140
 
        copy($transaction_log, $transaction_log_copy);
141
 
 
142
 
# Server restart razzle-dazzle
143
 
        my $binary = $basedir.'/drizzled/drizzled' ;
144
 
        my $datadir = $reporter->serverVariable('datadir');
145
 
 
146
 
        
147
 
 
148
 
        my $dbh_prev = DBI->connect($reporter->dsn());
149
 
 
150
 
        if (defined $dbh_prev) {
151
 
                # Server is still running, kill it.
152
 
                $dbh_prev->disconnect();
153
 
 
154
 
                say("Sending shutdown() call to server.");
155
 
                $dbh_prev->selectrow_array('SELECT shutdown()');
156
 
                sleep(5);
157
 
        }
158
 
 
159
 
                say("Attempting database recovery using the server ...");
160
 
 
161
 
        my @drizzled_options = (
162
 
                '--no-defaults',
163
 
                '--core-file',  
164
 
                '--datadir="'.$datadir.'"',
165
 
                '--basedir="'.$basedir.'"',
166
 
                '--plugin-add=shutdown_function',
167
 
                '--innodb.replication-log',
168
 
                '--mysql-protocol.port='.$main_port,
169
 
 
170
 
        );
171
 
 
172
 
        my $drizzled_command = $binary.' '.join(' ', @drizzled_options).' 2>&1';
173
 
        say("Executing $drizzled_command .");
174
 
 
175
 
        my $drizzled_pid = open2(\*RDRFH, \*WTRFH, $drizzled_command);
176
 
        say("$drizzled_pid");
177
 
 
178
 
        #
179
 
        # Phase1 - the server is running single-threaded. We consume the error log and parse it for
180
 
        # statements that indicate failed recovery
181
 
        # 
182
 
 
183
 
        my $recovery_status = STATUS_OK;
184
 
        
185
 
        sleep(5);
186
 
        my $dbh = DBI->connect($reporter->dsn());
187
 
        $recovery_status = STATUS_DATABASE_CORRUPTION if not defined $dbh && $recovery_status == STATUS_OK;
188
 
 
189
 
        if ($recovery_status > STATUS_OK) {
190
 
                say("Recovery has failed.");
191
 
                return $recovery_status;
192
 
        }
193
 
 
194
 
        say("Waiting for slave to catch up...");
195
 
        #sleep 60;
196
 
        say("$validator_port");
197
 
        say("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^");
198
 
        my $slave_dsn="dbi:drizzle:host=localhost:port=$validator_port:user=root:password='':database=sys_replication";
199
 
        my $slave_dbh = DBI->connect($slave_dsn, undef, undef, {PrintError => 0});
200
 
        my $master_dbh = DBI->connect($reporter->dsn(), undef, undef, {PrintError => 0});
201
 
        my $not_done = 1;
202
 
        while ($not_done)
203
 
        {
204
 
            my @max_slave_id_res = $slave_dbh->selectrow_array('SELECT last_applied_commit_id from applier_state');
205
 
            my $max_slave_id = @max_slave_id_res->[0] ;
206
 
            my @max_master_id_res = $master_dbh->selectrow_arrayref("SELECT MAX(commit_id) from DATA_DICTIONARY.SYS_REPLICATION_LOG");
207
 
            my $max_master_id = @max_master_id_res->[0]->[0] ;
208
 
            if ($max_slave_id == $max_master_id)
209
 
            {
210
 
                $not_done = 0 ;
211
 
            }
212
 
            sleep 1;
213
 
            #say ("$max_slave_id");
214
 
            #say ("$max_master_id");
215
 
            #$not_done = 0;
216
 
        }
217
 
        say("Validating replication via dumpfile compare...");
218
 
        my @files;
219
 
        my @ports = ($main_port, $validator_port);
220
 
 
221
 
        foreach my $port_id (0..1) 
222
 
          {
223
 
            $files[$port_id] = tmpdir()."/translog_rpl_dump_".$$."_".$ports[$port_id].".sql";
224
 
            say("$files[$port_id]");
225
 
            say("$drizzledump --compact --skip-extended-insert --host=127.0.0.1 --port=$ports[$port_id] --user=root test >$files[$port_id]");
226
 
            my $drizzledump_result = system("$drizzledump --compact --skip-extended-insert --host=127.0.0.1 --port=$ports[$port_id] --user=root test >$files[$port_id]");
227
 
            # disable pipe to 'sort' from drizzledump call above
228
 
            #| sort > $files[$port_id]");
229
 
            return STATUS_UNKNOWN_ERROR if $drizzledump_result > 0;
230
 
          }
231
 
         say ("Executing diff --unified $files[SERVER1_FILE_NAME] $files[SERVER2_FILE_NAME]");
232
 
         my $diff_result = system("diff --unified $files[SERVER1_FILE_NAME] $files[SERVER2_FILE_NAME]");
233
 
         $diff_result = $diff_result >> 8;
234
 
       
235
 
 
236
 
         return STATUS_UNKNOWN_ERROR if $diff_result > 1;
237
 
 
238
 
         if ($diff_result == 1) 
239
 
         {
240
 
           say("Differences between the two servers were found after comparing dumpfiles");
241
 
           say("diff command:  diff --unified $files[SERVER1_FILE_NAME] $files[SERVER2_FILE_NAME]");
242
 
           say("Master dumpfile:  $files[SERVER1_FILE_NAME]");
243
 
           say("Slave dumpfile:   $files[SERVER2_FILE_NAME]");
244
 
           #say ("$max_slave_id");
245
 
           #say ("$max_master_id");
246
 
           return STATUS_REPLICATION_FAILURE;
247
 
         } 
248
 
         else 
249
 
         {
250
 
           foreach my $file (@files) 
251
 
           {
252
 
             unlink($file);
253
 
           }
254
 
           return STATUS_OK;
255
 
         }
256
 
 
257
 
   }    
258
 
        
259
 
 
260
 
 
261
 
sub type {
262
 
        return REPORTER_TYPE_ALWAYS | REPORTER_TYPE_PERIODIC;
263
 
}
264
 
 
265
 
1;