~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to sql-bench/bench-init.pl.sh

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl
 
2
# Copyright (C) 2000-2003, 2005 MySQL AB
 
3
#
 
4
# This library is free software; you can redistribute it and/or
 
5
# modify it under the terms of the GNU Library General Public
 
6
# License as published by the Free Software Foundation; version 2
 
7
# of the License.
 
8
#
 
9
# This library is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
# Library General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU Library General Public
 
15
# License along with this library; if not, write to the Free
 
16
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 
17
# MA 02111-1307, USA
 
18
#
 
19
##########################################################
 
20
# this is the base file every test is using ....
 
21
# this is made for not changing every file if we want to
 
22
# add an option or just want to change something in
 
23
# code what is the same in every file ...
 
24
##########################################################
 
25
 
 
26
#
 
27
# The exported values are:
 
28
 
 
29
# $opt_...      Various options
 
30
# $date         Current date in ISO format
 
31
# $server       Object for current server
 
32
# $limits       Hash reference to limits for benchmark
 
33
 
 
34
$benchmark_version="2.15";
 
35
use Getopt::Long;
 
36
use POSIX;
 
37
 
 
38
require "$pwd/server-cfg" || die "Can't read Configuration file: $!\n";
 
39
 
 
40
$|=1;                           # Output data immediately
 
41
 
 
42
$opt_skip_test=$opt_skip_create=$opt_skip_delete=$opt_verbose=$opt_fast_insert=$opt_lock_tables=$opt_debug=$opt_skip_delete=$opt_fast=$opt_force=$opt_log=$opt_use_old_results=$opt_help=$opt_odbc=$opt_small_test=$opt_small_tables=$opt_samll_key_tables=$opt_stage=$opt_old_headers=$opt_die_on_errors=$opt_tcpip=$opt_random=$opt_only_missing_tests=0;
 
43
$opt_cmp=$opt_user=$opt_password=$opt_connect_options="";
 
44
$opt_server="mysql"; $opt_dir="output";
 
45
$opt_host="localhost";$opt_database="test";
 
46
$opt_machine=""; $opt_suffix="";
 
47
$opt_create_options=undef;
 
48
$opt_optimization="None";
 
49
$opt_hw="";
 
50
$opt_threads=-1;
 
51
 
 
52
if (!defined($opt_time_limit))
 
53
{
 
54
  $opt_time_limit=10*60;        # Don't wait more than 10 min for some tests
 
55
}
 
56
 
 
57
$log_prog_args=join(" ", skip_arguments(\@ARGV,"comments","cmp","server",
 
58
                                        "user", "host", "database", "password",
 
59
                                        "use-old-results","skip-test",
 
60
                                        "optimization","hw",
 
61
                                        "machine", "dir", "suffix", "log"));
 
62
GetOptions("skip-test=s","comments=s","cmp=s","server=s","user=s","host=s","database=s","password=s","loop-count=i","row-count=i","skip-create","skip-delete","verbose","fast-insert","lock-tables","debug","fast","force","field-count=i","regions=i","groups=i","time-limit=i","log","use-old-results","machine=s","dir=s","suffix=s","help","odbc","small-test","small-tables","small-key-tables","stage=i","threads=i","random","old-headers","die-on-errors","create-options=s","hires","tcpip","silent","optimization=s","hw=s","socket=s","connect-options=s","only-missing-tests") || usage();
 
63
 
 
64
usage() if ($opt_help);
 
65
$server=get_server($opt_server,$opt_host,$opt_database,$opt_odbc,
 
66
                   machine_part(), $opt_socket, $opt_connect_options);
 
67
$limits=merge_limits($server,$opt_cmp);
 
68
$date=date();
 
69
@estimated=(0.0,0.0,0.0);               # For estimated time support
 
70
 
 
71
if ($opt_threads != -1)
 
72
{
 
73
    print "WARNING: Option --threads is deprecated and has no effect\n"
 
74
}
 
75
 
 
76
if ($opt_hires)
 
77
{
 
78
  eval "use Time::HiRes;";
 
79
}
 
80
 
 
81
{
 
82
  my $tmp= $opt_server;
 
83
  $tmp =~ s/_odbc$//;
 
84
  if (length($opt_cmp) && index($opt_cmp,$tmp) < 0)
 
85
  {
 
86
    $opt_cmp.=",$tmp";
 
87
  }
 
88
}
 
89
$opt_cmp=lc(join(",",sort(split(',',$opt_cmp))));
 
90
 
 
91
#
 
92
# set opt_lock_tables if one uses --fast and drivers supports it
 
93
#
 
94
 
 
95
if (($opt_lock_tables || $opt_fast) && $server->{'limits'}->{'lock_tables'})
 
96
{
 
97
  $opt_lock_tables=1;
 
98
}
 
99
else
 
100
{
 
101
  $opt_lock_tables=0;
 
102
}
 
103
if ($opt_fast)
 
104
{
 
105
  $opt_fast_insert=1;
 
106
  $opt_suffix="_fast" if (!length($opt_suffix));
 
107
}
 
108
 
 
109
if ($opt_odbc)
 
110
{
 
111
   $opt_suffix="_odbc" if (!length($opt_suffix));
 
112
}
 
113
 
 
114
if (!$opt_silent)
 
115
{
 
116
  print "Testing server '" . $server->version() . "' at $date\n\n";
 
117
}
 
118
 
 
119
if ($opt_debug)
 
120
{
 
121
  print "\nCurrent limits: \n";
 
122
  foreach $key (sort keys %$limits)
 
123
  {
 
124
    print $key . " " x (30-length($key)) . $limits->{$key} . "\n";
 
125
  }
 
126
  print "\n";
 
127
}
 
128
 
 
129
#
 
130
# Some help functions
 
131
#
 
132
 
 
133
sub skip_arguments
 
134
{
 
135
  my($argv,@skip_args)=@_;
 
136
  my($skip,$arg,$name,@res);
 
137
 
 
138
  foreach $arg (@$argv)
 
139
  {
 
140
    if ($arg =~ /^\-+([^=]*)/)
 
141
    {
 
142
      $name=$1;
 
143
      foreach $skip (@skip_args)
 
144
      {
 
145
        if (index($skip,$name) == 0)
 
146
        {
 
147
          $name="";             # Don't use this parameters
 
148
          last;
 
149
        }
 
150
      }
 
151
      push (@res,$arg) if (length($name));
 
152
    }
 
153
  }
 
154
  return @res;
 
155
}
 
156
 
 
157
 
 
158
sub merge_limits
 
159
{
 
160
  my ($server,$cmp)= @_;
 
161
  my ($name,$tmp_server,$limits,$res_limits,$limit,$tmp_limits);
 
162
 
 
163
  $res_limits=$server->{'limits'};
 
164
  if ($cmp)
 
165
  {
 
166
    foreach $name (split(",",$cmp))
 
167
    {
 
168
      $tmp_server= (get_server($name,$opt_host, $opt_database,
 
169
                               $opt_odbc,machine_part())
 
170
                    || die "Unknown SQL server: $name\n");
 
171
      $limits=$tmp_server->{'limits'};
 
172
      %new_limits=();
 
173
      foreach $limit (keys(%$limits))
 
174
      {
 
175
        if (defined($res_limits->{$limit}) && defined($limits->{$limit}))
 
176
        {
 
177
          $new_limits{$limit}=min($res_limits->{$limit},$limits->{$limit});
 
178
        }
 
179
      }
 
180
      %tmp_limits=%new_limits;
 
181
      $res_limits=\%tmp_limits;
 
182
    }
 
183
  }
 
184
  return $res_limits;
 
185
}
 
186
 
 
187
sub date
 
188
{
 
189
  my ($sec, $min, $hour, $mday, $mon, $year) = localtime(time());
 
190
  sprintf("%04d-%02d-%02d %2d:%02d:%02d",
 
191
          1900+$year,$mon+1,$mday,$hour,$min,$sec);
 
192
}
 
193
 
 
194
sub min
 
195
{
 
196
  my($min)=$_[0];
 
197
  my($i);
 
198
  for ($i=1 ; $i <= $#_; $i++)
 
199
  {
 
200
    $min=$_[$i] if ($min > $_[$i]);
 
201
  }
 
202
  return $min;
 
203
}
 
204
 
 
205
sub max
 
206
{
 
207
  my($max)=$_[0];
 
208
  my($i);
 
209
  for ($i=1 ; $i <= $#_; $i++)
 
210
  {
 
211
    $max=$_[$i] if ($max < $_[$i]);
 
212
  }
 
213
  return $max;
 
214
}
 
215
 
 
216
 
 
217
#
 
218
# Execute many statements in a row
 
219
#
 
220
 
 
221
sub do_many
 
222
{
 
223
  my ($dbh,@statements)=@_;
 
224
  my ($statement,$sth);
 
225
 
 
226
  foreach $statement (@statements)
 
227
  {
 
228
    if (!($sth=$dbh->do($statement)))
 
229
    {
 
230
      die "Can't execute command '$statement'\nError: $DBI::errstr\n";
 
231
    }
 
232
  }
 
233
}
 
234
 
 
235
sub safe_do_many
 
236
{
 
237
  my ($dbh,@statements)=@_;
 
238
  my ($statement,$sth);
 
239
 
 
240
  foreach $statement (@statements)
 
241
  {
 
242
    if (!($sth=$dbh->do($statement)))
 
243
    {
 
244
      print STDERR "Can't execute command '$statement'\nError: $DBI::errstr\n";
 
245
      return 1;
 
246
    }
 
247
  }
 
248
  return 0;
 
249
}
 
250
 
 
251
 
 
252
 
 
253
#
 
254
# Do a query and fetch all rows from a statement and return the number of rows
 
255
#
 
256
 
 
257
sub fetch_all_rows
 
258
{
 
259
  my ($dbh,$query,$must_get_result)=@_;
 
260
  my ($count,$sth);
 
261
  $count=0;
 
262
 
 
263
  print "$query: " if ($opt_debug);
 
264
  if (!($sth= $dbh->prepare($query)))
 
265
  {
 
266
    print "\n" if ($opt_debug);
 
267
    die "Error occured with prepare($query)\n -> $DBI::errstr\n";
 
268
    return undef;
 
269
  }
 
270
  if (!$sth->execute)
 
271
  {
 
272
    print "\n" if ($opt_debug);
 
273
    if (defined($server->{'error_on_execute_means_zero_rows'}) &&
 
274
       !$server->abort_if_fatal_error())
 
275
    {
 
276
      if (defined($must_get_result) && $must_get_result)
 
277
      {
 
278
        die "Error: Query $query didn't return any rows\n";
 
279
      }
 
280
      $sth->finish;
 
281
      print "0\n" if ($opt_debug);
 
282
      return 0;
 
283
    }
 
284
    die "Error occured with execute($query)\n -> $DBI::errstr\n";
 
285
    $sth->finish;
 
286
    return undef;
 
287
  }
 
288
  while ($sth->fetchrow_arrayref)
 
289
  {
 
290
    $count++;
 
291
  }
 
292
  print "$count\n" if ($opt_debug);
 
293
  if (defined($must_get_result) && $must_get_result && !$count)
 
294
  {
 
295
    die "Error: Query $query didn't return any rows\n";
 
296
  }
 
297
  $sth->finish;
 
298
  undef($sth);
 
299
  return $count;
 
300
}
 
301
 
 
302
sub do_query
 
303
{
 
304
  my($dbh,$query)=@_;
 
305
  print "$query\n" if ($opt_debug);
 
306
  $dbh->do($query) or
 
307
    die "\nError executing '$query':\n$DBI::errstr\n";
 
308
}
 
309
 
 
310
#
 
311
# Run a query X times
 
312
#
 
313
 
 
314
sub time_fetch_all_rows
 
315
{
 
316
  my($test_text,$result_text,$query,$dbh,$test_count)=@_;
 
317
  my($i,$loop_time,$end_time,$count,$rows,$estimated);
 
318
 
 
319
  print $test_text . "\n"   if (defined($test_text));
 
320
  $count=$rows=0;
 
321
  $loop_time=new Benchmark;
 
322
  for ($i=1 ; $i <= $test_count ; $i++)
 
323
  {
 
324
    $count++;
 
325
    $rows+=fetch_all_rows($dbh,$query) or die $DBI::errstr;
 
326
    $end_time=new Benchmark;
 
327
    last if ($estimated=predict_query_time($loop_time,$end_time,\$count,$i,
 
328
                                           $test_count));
 
329
  }
 
330
  $end_time=new Benchmark;
 
331
  if ($estimated)
 
332
  { print "Estimated time"; }
 
333
  else
 
334
  { print "Time"; }
 
335
  print " for $result_text ($count:$rows) " .
 
336
    timestr(timediff($end_time, $loop_time),"all") . "\n\n";
 
337
}
 
338
 
 
339
 
 
340
#
 
341
# Handle estimated time of the server is too slow
 
342
# Returns 0 if one should continue as normal
 
343
#
 
344
 
 
345
sub predict_query_time
 
346
{
 
347
  my ($loop_time,$end_time,$count_ref,$loop,$loop_count)= @_;
 
348
  my ($k,$tmp);
 
349
 
 
350
  if (($end_time->[0] - $loop_time->[0]) > $opt_time_limit)
 
351
  {
 
352
    # We can't wait until the SUN dies.  Try to predict the end time
 
353
    if ($loop != $loop_count)
 
354
    {
 
355
      $tmp=($end_time->[0] - $loop_time->[0]);
 
356
      print "Note: Query took longer then time-limit: $opt_time_limit\nEstimating end time based on:\n";
 
357
      print "$$count_ref queries in $loop loops of $loop_count loops took $tmp seconds\n";
 
358
      for ($k=0; $k < 3; $k++)
 
359
      {
 
360
        $tmp=$loop_time->[$k]+($end_time->[$k]-$loop_time->[$k])/$loop*
 
361
          $loop_count;
 
362
        $estimated[$k]+=($tmp-$end_time->[$k]);
 
363
        $end_time->[$k]=$tmp;
 
364
      }
 
365
      $$count_ref= int($$count_ref/$loop*$loop_count);
 
366
      return 1;
 
367
    }
 
368
  }
 
369
  return 0;
 
370
}
 
371
 
 
372
#
 
373
# standard end of benchmark
 
374
#
 
375
 
 
376
sub end_benchmark
 
377
{
 
378
  my ($start_time)=@_;
 
379
 
 
380
  $end_time=new Benchmark;
 
381
  if ($estimated[0])
 
382
  {
 
383
    print "Estimated total time: ";
 
384
    $end_time->[0]+=$estimated[0];
 
385
    $end_time->[1]+=$estimated[1];
 
386
    $end_time->[2]+=$estimated[2];
 
387
  }
 
388
  else
 
389
  {
 
390
    print "Total time: "
 
391
    }
 
392
  print timestr(timediff($end_time, $start_time),"all") . "\n";
 
393
  exit 0;
 
394
}
 
395
 
 
396
sub print_time
 
397
{
 
398
  my ($estimated)=@_;
 
399
  if ($estimated)
 
400
  { print "Estimated time"; }
 
401
  else
 
402
  { print "Time"; }
 
403
}
 
404
 
 
405
#
 
406
# Create a filename part for the machine that can be used for log file.
 
407
#
 
408
 
 
409
sub machine_part
 
410
{
 
411
  my ($name,$orig);
 
412
  return $opt_machine if (length($opt_machine)); # Specified by user
 
413
# Specified by user
 
414
  $orig=$name=machine();
 
415
  $name="win9$1" if ($orig =~ /win.*9(\d)/i);
 
416
  $name="NT_$1" if ($orig =~ /Windows NT.*(\d+\.\d+)/i);
 
417
  $name="win2k" if ($orig =~ /Windows 2000/i);
 
418
  $name =~ s/\s+/_/g;           # Make the filenames easier to parse
 
419
  $name =~ s/-/_/g;
 
420
  $name =~ s/\//_/g;
 
421
  return $name;
 
422
}
 
423
 
 
424
sub machine
 
425
{
 
426
  my @name = POSIX::uname();
 
427
  my $name= $name[0] . " " . $name[2] . " " . $name[4];
 
428
  return $name;
 
429
}
 
430
 
 
431
#
 
432
# Usage
 
433
#
 
434
 
 
435
sub usage
 
436
{
 
437
    print <<EOF;
 
438
The MySQL benchmarks Ver $benchmark_version
 
439
 
 
440
All benchmarks takes the following options:
 
441
 
 
442
--comments
 
443
  Add a comment to the benchmark output.  Comments should contain
 
444
  extra information that 'uname -a' doesn\'t give and if the database was
 
445
  stared with some specific, non default, options.
 
446
 
 
447
--cmp=server[,server...]
 
448
  Run the test with limits from the given servers.  If you run all servers
 
449
  with the same --cmp, you will get a test that is comparable between
 
450
  the different sql servers.
 
451
 
 
452
--create-options=#
 
453
  Extra argument to all create statements.  If you for example want to
 
454
  create all MySQL tables as InnoDB tables use:
 
455
  --create-options=ENGINE=InnoDB
 
456
 
 
457
--database (Default $opt_database)
 
458
  In which database the test tables are created.
 
459
 
 
460
--debug
 
461
  This is a test specific option that is only used when debugging a test.
 
462
  Print out debugging information.
 
463
 
 
464
--dir (Default $opt_dir)
 
465
  Option to 'run-all-tests' to where the test results should be stored.
 
466
 
 
467
--fast
 
468
  Allow the database to use non standard ANSI SQL commands to make the
 
469
  test go faster.
 
470
 
 
471
--fast-insert
 
472
  Use "insert into table_name values(...)" instead of
 
473
  "insert into table_name (....) values(...)"
 
474
  If the database supports it, some tests uses multiple value lists.
 
475
 
 
476
--field-count
 
477
  This is a test specific option that is only used when debugging a test.
 
478
  This usually means how many fields there should be in the test table.
 
479
 
 
480
--force
 
481
  This is a test specific option that is only used when debugging a test.
 
482
  Continue the test even if there is some error.
 
483
  Delete tables before creating new ones.
 
484
 
 
485
--groups (Default $opt_groups)
 
486
  This is a test specific option that is only used when debugging a test.
 
487
  This usually means how many different groups there should be in the test.
 
488
 
 
489
--lock-tables
 
490
  Allow the database to use table locking to get more speed.
 
491
 
 
492
--log
 
493
  Option to 'run-all-tests' to save the result to the '--dir' directory.
 
494
 
 
495
--loop-count (Default $opt_loop_count)
 
496
  This is a test specific option that is only used when debugging a test.
 
497
  This usually means how many times times each test loop is executed.
 
498
 
 
499
--help
 
500
  Shows this help
 
501
 
 
502
--host='host name' (Default $opt_host)
 
503
  Host name where the database server is located.
 
504
 
 
505
--machine="machine or os_name"
 
506
  The machine/os name that is added to the benchmark output filename.
 
507
  The default is the OS name + version.
 
508
 
 
509
--odbc
 
510
  Use the ODBC DBI driver to connect to the database.
 
511
 
 
512
--only-missing-tests
 
513
  Only run test that don\'t have an old test result.
 
514
  This is useful when you want to do a re-run of tests that failed in last run.
 
515
 
 
516
--optimization='some comments'
 
517
 Add coments about optimization of DBMS, which was done before the test.
 
518
 
 
519
--password='password'
 
520
  Password for the current user.
 
521
 
 
522
--socket='socket'
 
523
  If the database supports connecting through a Unix socket,
 
524
  then use this socket to connect
 
525
 
 
526
--regions
 
527
  This is a test specific option that is only used when debugging a test.
 
528
  This usually means how AND levels should be tested.
 
529
 
 
530
--old-headers
 
531
  Get the old benchmark headers from the old RUN- file.
 
532
 
 
533
--server='server name'  (Default $opt_server)
 
534
  Run the test on the given SQL server.
 
535
  Known servers names are: Access, Adabas, AdabasD, Empress, Oracle,
 
536
  Informix, DB2, mSQL, MS-SQL, MySQL, Pg, Solid and Sybase
 
537
 
 
538
--silent
 
539
  Don't print info about the server when starting test.
 
540
 
 
541
--skip-delete
 
542
  This is a test specific option that is only used when debugging a test.
 
543
  This will keep the test tables after the test is run.
 
544
 
 
545
--skip-test=test1[,test2,...]
 
546
  For run-all-programs;  Don\'t execute the named tests.
 
547
 
 
548
--small-test
 
549
  This runs some tests with smaller limits to get a faster test.
 
550
  Can be used if you just want to verify that the database works, but
 
551
  don't have time to run a full test.
 
552
 
 
553
--small-tables
 
554
  This runs some tests that generate big tables with fewer rows.
 
555
  This can be used with databases that can\'t handle that many rows
 
556
  because of pre-sized partitions.
 
557
 
 
558
--suffix (Default $opt_suffix)
 
559
  The suffix that is added to the database name in the benchmark output
 
560
  filename.  This can be used to run the benchmark multiple times with
 
561
  different server options without overwritten old files.
 
562
  When using --fast the suffix is automaticly set to '_fast'.
 
563
 
 
564
--random
 
565
  Inform test suite that we are generate random inital values for sequence of
 
566
  test executions. It should be used for imitation of real conditions.
 
567
 
 
568
--threads=#  **DEPRECATED**
 
569
  This option has no effect, and will be removed in a future version.
 
570
 
 
571
--tcpip
 
572
  Inform test suite that we are using TCP/IP to connect to the server. In
 
573
  this case we can\t do many new connections in a row as we in this case may
 
574
  fill the TCP/IP stack
 
575
 
 
576
--time-limit (Default $opt_time_limit)
 
577
  How long a test loop is allowed to take, in seconds, before the end result
 
578
  is 'estimated'.
 
579
 
 
580
--use-old-results
 
581
  Option to 'run-all-tests' to use the old results from the  '--dir' directory
 
582
  instead of running the tests.
 
583
 
 
584
--user='user_name'
 
585
  User name to log into the SQL server.
 
586
 
 
587
--verbose
 
588
  This is a test specific option that is only used when debugging a test.
 
589
  Print more information about what is going on.
 
590
 
 
591
--hw='some comments'
 
592
 Add coments about hardware used for this test.
 
593
 
 
594
--connect-options='some connect options'
 
595
  Add options, which uses at DBI connect.
 
596
  For example --connect-options=mysql_read_default_file=/etc/my.cnf.
 
597
 
 
598
EOF
 
599
  exit(0);
 
600
}
 
601
 
 
602
 
 
603
 
 
604
####
 
605
#### The end of the base file ...
 
606
####
 
607
1;