~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to lib/GenTest/Server/MySQLd.pm

More server stuff

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
16
16
# USA
17
17
 
18
 
package GenTest::Server::MySQL;
 
18
package GenTest::Server::MySQLd;
19
19
 
20
20
@ISA = qw(GenTest);
21
21
 
22
22
use DBI;
23
23
use GenTest;
 
24
use GenTest::Constants;
24
25
use if windows(), Win32::Process;
 
26
use Time::HiRes;
25
27
 
26
28
use strict;
27
29
 
29
31
use Data::Dumper;
30
32
 
31
33
use constant MYSQLD_BASEDIR => 0;
32
 
use constant MYSQLD_DATADIR => 1;
33
 
use constant MYSQLD_PORTBASE => 2;
34
 
use constant MYSQLD_MYSQLD => 3;
35
 
use constant MYSQLD_LIBMYSQL => 4;
36
 
use constant MYSQLD_BOOT_SQL => 5;
37
 
use constant MYSQLD_STDOPTS => 6;
38
 
use constant MYSQLD_MESSAGES => 7;
39
 
use constant MYSQLD_SERVER_OPTIONS => 8;
40
 
use constant MYSQLD_AUXPID => 9;
41
 
use constant MYSQLD_SERVERPID => 10;
42
 
use constant MYSQLD_WINDOWS_PROCESS => 11;
43
 
use constant MYSQLD_DBH => 12;
44
 
use constant MYSQLD_DRH => 12;
 
34
use constant MYSQLD_VARDIR => 1;
 
35
use constant MYSQLD_DATADIR => 2;
 
36
use constant MYSQLD_PORT => 3;
 
37
use constant MYSQLD_MYSQLD => 4;
 
38
use constant MYSQLD_LIBMYSQL => 5;
 
39
use constant MYSQLD_BOOT_SQL => 6;
 
40
use constant MYSQLD_STDOPTS => 7;
 
41
use constant MYSQLD_MESSAGES => 8;
 
42
use constant MYSQLD_SERVER_OPTIONS => 9;
 
43
use constant MYSQLD_AUXPID => 10;
 
44
use constant MYSQLD_SERVERPID => 11;
 
45
use constant MYSQLD_WINDOWS_PROCESS => 12;
 
46
use constant MYSQLD_DBH => 13;
45
47
 
46
48
use constant MYSQLD_PID_FILE => "mysql.pid";
47
49
use constant MYSQLD_SOCKET_FILE => "mysql.sock";
48
50
use constant MYSQLD_LOG_FILE => "mysql.err";
49
 
use constant MYSQLD_DEFAULT_PORTBASE =>  19300;
 
51
use constant MYSQLD_DEFAULT_PORT =>  19300;
50
52
use constant MYSQLD_DEFAULT_DATABASE => "test";
51
53
 
52
54
 
55
57
    my $class = shift;
56
58
 
57
59
    my $self = $class->SUPER::new({'basedir' => MYSQLD_BASEDIR,
58
 
                                   'datadir' => MYSQLD_DATADIR,
59
 
                                   'portbase' => MYSQLD_PORTBASE,
 
60
                                   'vardir' => MYSQLD_VARDIR,
 
61
                                   'port' => MYSQLD_PORT,
60
62
                                   'server_options' => MYSQLD_SERVER_OPTIONS},@_);
 
63
 
 
64
 
 
65
    if (not defined $self->[MYSQLD_VARDIR]) {
 
66
        $self->[MYSQLD_VARDIR] = "mysql-test/var";
 
67
    }
 
68
 
 
69
    if ($self->vardir =~ m/^\//) {
 
70
    } else {
 
71
        $self->[MYSQLD_VARDIR] = $self->basedir."/".$self->vardir;
 
72
    }
 
73
 
 
74
    $self->[MYSQLD_DATADIR] = $self->[MYSQLD_VARDIR]."/data";
61
75
    
62
76
    if (windows()) {
63
 
        ## Use unix-style path's since that's what Perl expects...
64
 
        $self->[MYSQLD_BASEDIR] =~ s/\\/\//g;
65
 
        $self->[MYSQLD_DATADIR] =~ s/\\/\//g;
 
77
        ## Use unix-style path's since that's what Perl expects...
 
78
        $self->[MYSQLD_BASEDIR] =~ s/\\/\//g;
 
79
        $self->[MYSQLD_VARDIR] =~ s/\\/\//g;
 
80
        $self->[MYSQLD_DATADIR] =~ s/\\/\//g;
66
81
    }
67
82
    
68
83
    $self->[MYSQLD_MYSQLD] = $self->_find($self->basedir,
69
 
                                          windows()?["sql/Debug"]:["sql","libexec"],
70
 
                                          windows()?"mysqld.exe":"mysqld");
 
84
                                          windows()?["sql/Debug"]:["sql","libexec"],
 
85
                                          windows()?"mysqld.exe":"mysqld");
71
86
    $self->[MYSQLD_BOOT_SQL] = [];
72
87
    foreach my $file ("mysql_system_tables.sql", 
73
 
                      "mysql_system_tables_data.sql", 
74
 
                      "mysql_test_data_timezone.sql",
75
 
                      "fill_help_tables.sql") {
 
88
                      "mysql_system_tables_data.sql", 
 
89
                      "mysql_test_data_timezone.sql",
 
90
                      "fill_help_tables.sql") {
76
91
        push(@{$self->[MYSQLD_BOOT_SQL]}, 
77
92
             $self->_find($self->basedir,["scripts","share/mysql"], $file));
78
93
    }
80
95
    $self->[MYSQLD_MESSAGES] = $self->_findDir($self->basedir, ["sql/share","share/mysql"], "errmsg-utf8.txt");
81
96
    
82
97
    $self->[MYSQLD_LIBMYSQL] = $self->_findDir($self->basedir, 
83
 
                                               windows()?["libmysql/Debug"]:["libmysql/.libs","lib/mysql"], 
84
 
                                               windows()?"libmysql.dll":"libmysqlclient.so");
 
98
                                               windows()?["libmysql/Debug"]:["libmysql/.libs","lib/mysql"], 
 
99
                                               windows()?"libmysql.dll":"libmysqlclient.so");
85
100
    
86
101
    $self->[MYSQLD_STDOPTS] = [join(" ",
87
102
                                    "--basedir=".$self->basedir,
88
103
                                    "--datadir=".$self->datadir,
89
104
                                    "--lc-messages-dir=".$self->[MYSQLD_MESSAGES],
90
105
                                    windows()?"":"--loose-skip-innodb",
91
 
                                    windows()?"":"--loose-skip-ndbcluster",
92
106
                                    "--default-storage-engine=myisam",
93
107
                                    "--log-warnings=0")];
94
108
 
95
 
    $self->[MYSQLD_DRH] = DBI->install_driver('mysql');
96
 
    
97
109
    $self->createMysqlBase;
98
110
 
99
111
    return $self;
107
119
    return $_[0]->[MYSQLD_DATADIR];
108
120
}
109
121
 
110
 
sub portbase {
 
122
sub vardir {
 
123
    return $_[0]->[MYSQLD_VARDIR];
 
124
}
 
125
 
 
126
sub port {
111
127
    my ($self) = @_;
112
128
    
113
 
    if (defined $self->[MYSQLD_PORTBASE]) {
114
 
        return $self->[MYSQLD_PORTBASE];
 
129
    if (defined $self->[MYSQLD_PORT]) {
 
130
        return $self->[MYSQLD_PORT];
115
131
    } else {
116
 
        return MYSQLD_DEFAULT_PORTBASE;
 
132
        return MYSQLD_DEFAULT_PORT;
117
133
    }
118
134
}
119
135
 
126
142
}
127
143
 
128
144
sub socketfile {
129
 
    return $_[0]->datadir."/".MYSQLD_SOCKET_FILE;
 
145
    return $_[0]->vardir."/".MYSQLD_SOCKET_FILE;
130
146
}
131
147
 
132
148
sub pidfile {
133
 
    return $_[0]->datadir."/".MYSQLD_PID_FILE;
 
149
    return $_[0]->vardir."/".MYSQLD_PID_FILE;
134
150
}
135
151
 
136
152
sub logfile {
137
 
    return $_[0]->datadir."/".MYSQLD_LOG_FILE;
 
153
    return $_[0]->vardir."/".MYSQLD_LOG_FILE;
138
154
}
139
155
 
140
156
sub libmysqldir {
145
161
    my ($self) = @_;
146
162
    
147
163
    ## 1. Clean old db if any
148
 
    if (-d $self->datadir) {
 
164
    if (-d $self->vardir) {
149
165
        if (windows()) {
150
 
            my $datadir = $self->datadir;
151
 
            $datadir =~ s/\//\\/g;
152
 
            system("rmdir /s /q $datadir");
 
166
            my $vardir = $self->vardir;
 
167
            $vardir =~ s/\//\\/g;
 
168
            system("rmdir /s /q $vardir");
153
169
        } else {
154
 
            system("rm -rf ".$self->datadir);
 
170
            system("rm -rf ".$self->vardir);
155
171
        }
156
172
    }
157
173
    
158
174
    ## 2. Create database directory structure
 
175
    mkdir $self->vardir;
159
176
    mkdir $self->datadir;
160
177
    mkdir $self->datadir."/mysql";
161
178
    mkdir $self->datadir."/test";
162
179
    
163
180
    ## 3. Create boot file
164
 
    my $boot = $self->datadir."/boot.sql";
 
181
    my $boot = $self->vardir."/boot.sql";
165
182
    open BOOT,">$boot";
166
183
    
167
184
    ## Set curren database
183
200
                           @{$self->[MYSQLD_STDOPTS]});
184
201
        $command =~ s/\//\\/g;
185
202
        $boot =~ s/\//\\/g;
186
 
        my $bootlog = $self->datadir."/boot.log";
 
203
        my $bootlog = $self->vardir."/boot.log";
187
204
        
188
205
        system("$command < $boot > $bootlog");
189
206
    } else {
192
209
                           "--bootstrap",
193
210
                           @{$self->[MYSQLD_STDOPTS]});
194
211
        
195
 
        my $bootlog = $self->datadir."/boot.log";
 
212
        my $bootlog = $self->vardir."/boot.log";
196
213
        
197
214
        system("cat $boot | $command > $bootlog  2>&1 ");
198
215
    }
208
225
    my $opts = join(' ',
209
226
                    "--no-defaults",
210
227
                    @{$self->[MYSQLD_STDOPTS]},
 
228
                    "--core-file",
 
229
                    "--skip-ndbcluster",
211
230
                    "--skip-grant",
212
 
                    "--port=".$self->portbase,
213
 
                    "--socket=".MYSQLD_SOCKET_FILE,
214
 
                    "--pid-file=".MYSQLD_PID_FILE);
 
231
                    "--loose-new",
 
232
                    "--relay-log=slave-relay-bin",
 
233
                    "--loose-innodb",
 
234
                    "--max-allowed-packet=16Mb",        # Allow loading bigger blobs
 
235
                    "--loose-innodb-status-file=1",
 
236
                    "--master-retry-count=65535",
 
237
                    "--port=".$self->port,
 
238
                    "--socket=".$self->socketfile,
 
239
                    "--pid-file=".$self->pidfile,
 
240
                    "--general-log-file=".$self->logfile);
215
241
    if (defined $self->[MYSQLD_SERVER_OPTIONS]) {
216
242
        $opts = $opts." ".$self->[MYSQLD_SERVER_OPTIONS]->genOpt();
217
243
    }
218
244
    
219
 
    my $serverlog = $self->datadir."/".MYSQLD_LOG_FILE;
 
245
    my $serverlog = $self->vardir."/".MYSQLD_LOG_FILE;
220
246
    
221
247
    if (windows) {
222
248
        my $proc;
223
249
        my $command = "mysqld.exe"." ".$opts;
224
250
        my $exe = $self->[MYSQLD_MYSQLD];
225
 
        my $datadir = $self->[MYSQLD_DATADIR];
 
251
        my $vardir = $self->[MYSQLD_VARDIR];
226
252
        $command =~ s/\//\\/g;
227
253
        $exe =~ s/\//\\/g;
228
 
        $datadir =~ s/\//\\/g;
229
 
        say("Starting: $exe as $command on $datadir");
 
254
        $vardir =~ s/\//\\/g;
 
255
        say("Starting: $exe as $command on $vardir");
230
256
        Win32::Process::Create($proc,
231
257
                               $exe,
232
258
                               $command,
240
266
        say("Starting: $command");
241
267
        $self->[MYSQLD_AUXPID] = fork();
242
268
        if ($self->[MYSQLD_AUXPID]) {
243
 
            sleep(1); ## Wait to be sure that the PID file is there
 
269
            ## Waht for the pid file to have been created
 
270
            my $waits = 0;
 
271
            while (!-f $self->pidfile && $waits < 100) {
 
272
                Time::HiRes::sleep(0.2);
 
273
                $waits++;
 
274
            }
244
275
            my $pidfile = $self->pidfile;
245
276
            my $pid = `cat $pidfile`;
246
277
            $pid =~ m/([0-9]+)/;
255
286
                           undef,
256
287
                           undef,
257
288
                           {PrintError => 1,
258
 
                            RaiseError => 1,
 
289
                            RaiseError => 0,
259
290
                            AutoCommit => 1});
260
 
 
261
 
    print Dumper($dbh);
262
 
 
 
291
    
263
292
    $self->[MYSQLD_DBH] = $dbh;
 
293
 
 
294
    return $dbh ? STATUS_OK : STATUS_ENVIRONMENT_FAILURE;
264
295
}
265
296
 
266
297
sub kill {
267
298
    my ($self) = @_;
268
299
 
269
300
    if (windows()) {
270
 
        $self->[MYSQLD_WINDOWS_PROCESS]->Kill(0);
 
301
        if (defined $self->[MYSQLD_WINDOWS_PROCESS]) {
 
302
            $self->[MYSQLD_WINDOWS_PROCESS]->Kill(0);
 
303
            say("Killed process ".$self->[MYSQLD_WINDOWS_PROCESS]->GetProcessId());
 
304
        }
271
305
    } else {
272
 
        kill KILL => $self->serverpid;
 
306
        if (defined $self->serverpid) {
 
307
            kill KILL => $self->serverpid;
 
308
            say("Killed process ".$self->serverpid);
 
309
        }
273
310
    }
274
311
}
275
312
 
276
313
sub stopServer {
277
314
    my ($self) = @_;
278
315
 
279
 
    my $r = $self->[MYSQLD_DRH]->func('shutdown','127.0.0.1','root',undef,'admin');
280
 
    if (!$r) {
281
 
        say("Server would not shut down properly");
 
316
    if (defined $self->[MYSQLD_DBH]) {
 
317
        say("Stopping server on port ".$self->port);
 
318
        my $r = $self->[MYSQLD_DBH]->func('shutdown','127.0.0.1','root','admin');
 
319
        if (!$r) {
 
320
            say("Server would not shut down properly");
 
321
            $self->kill;
 
322
        }
 
323
    } else {
282
324
        $self->kill;
283
325
    }
284
326
}
297
339
    my ($self,$database) = @_;
298
340
    $database = "test" if not defined MYSQLD_DEFAULT_DATABASE;
299
341
    return "dbi:mysql:host=127.0.0.1:port=".
300
 
        $self->[MYSQLD_PORTBASE].
 
342
        $self->[MYSQLD_PORT].
301
343
        ":user=root:database=".$database;
302
344
}
303
345