Loading Docs/manual.texi +39 −6 Original line number Diff line number Diff line Loading @@ -500,6 +500,7 @@ Examples of common queries * example-Maximum-row:: The row holding the maximum of a certain column * example-Maximum-column-group:: Maximum of column per group * example-Maximum-column-group-row:: The rows holding the group-wise maximum of a certain field * example-user-variables:: * example-Foreign keys:: Using foreign keys Creating and using a database Loading Loading @@ -948,7 +949,7 @@ Changes in release 3.19.x MySQL and the future (The TODO) * TODO MySQL 4.0:: * TODO MySQL 4.0:: Things that should be in 4.0 * TODO future:: Things that must done in the very near future * TODO sometime:: Things that have to be done sometime * TODO unplanned:: Some things we don't have any plans to do Loading Loading @@ -22657,6 +22658,7 @@ SELECT * FROM shop * example-Maximum-row:: The row holding the maximum of a certain column * example-Maximum-column-group:: Maximum of column per group * example-Maximum-column-group-row:: The rows holding the group-wise maximum of a certain field * example-user-variables:: * example-Foreign keys:: Using foreign keys @end menu Loading Loading @@ -22736,7 +22738,7 @@ GROUP BY article +---------+-------+ @end example @node example-Maximum-column-group-row, example-Foreign keys, example-Maximum-column-group, Examples @node example-Maximum-column-group-row, example-user-variables, example-Maximum-column-group, Examples @subsection The rows holding the group-wise maximum of a certain field ``For each article, find the dealer(s) with the most expensive price.'' Loading Loading @@ -22807,9 +22809,31 @@ GROUP BY article; The last example can of course be made a bit more efficient by doing the splitting of the concatenated column in the client. @node example-user-variables, example-Foreign keys, example-Maximum-column-group-row, Examples @subsection Using user variables You can use @strong{MySQL} user variables to remember results without having to store them in a temporary variables in the client. @xref{Variables}. For example to find the articles with the highest and lowest price you can do: @example select @@min_price:=min(price),@@max_price:=max(price) from shop; select * from shop where price=@@min_price or price=@@max_price; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0003 | D | 1.25 | | 0004 | D | 19.95 | +---------+--------+-------+ @end example @cindex foreign keys @cindex keys, foreign @node example-Foreign keys, , example-Maximum-column-group-row, Examples @node example-Foreign keys, , example-user-variables, Examples @subsection Using foreign keys You don't need foreign keys to join 2 tables. Loading Loading @@ -37609,6 +37633,8 @@ With source code. By Matthias Fichtner. A library to use @strong{MySQL} with Delphi} @item @uref{http://www.geocities.com/CapeCanaveral/2064/mysql.html, Delphi TDataset-component} @item @item @uref{http://www.mysql.com/Downloads/Contrib/Win32/SBMySQL50Share.exe, Delphi 5 Shareware MySQL Dataset Components} @end itemize @item @uref{http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz, mysql-ruby-2.2.0.tar.gz} Loading Loading @@ -37752,9 +37778,13 @@ An open source client for exploring databases and executing SQL. Supports A query tool for @strong{MySQL} and PostgreSQL. @item @uref{http://dbman.linux.cz/,dbMan} A query tool written in Perl. Uses DBI and Tk. @item @uref{http://www.mysql.com/Downloads/Contrib/mascon1.exe, mascon1.exe} You can get the newest one from @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon.asp}. @item @uref{http://www.mysql.com/Downloads/Win32/Msc18.exe, Mascon 2000.1.8} @item @uref{http://www.mysql.com/Downloads/Win32/FrMsc18.exe, Free Mascon 2000.1.8} Mascon is a powerful Win32 GUI for the administering MySQL server databases. Mascon's features include visual table design, connections to multiple servers, data and blob editing of tables, security setting, SQL colour coding, dump functionality and much more. @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon home page}. @item @uref{http://www.virtualbeer.net/dbui/,DBUI} DBUI is a Gtk graphical database editor. @end itemize Loading Loading @@ -38503,6 +38533,9 @@ though, so Version 3.23 is not released as a stable version yet. @item Fixed the @code{--skip-networking} works properly on NT. @item Fixed long outstanding bug in the @code{ISAM} tables when a row with a length of more than 65K was shortened by a single byte. @item Fixed bug in @code{MyISAM} when running multiple updating processes on the same table. @item client/mysql.cc +18 −9 Original line number Diff line number Diff line Loading @@ -115,9 +115,8 @@ static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, no_rehash=0,skip_updates=0,safe_updates=0,one_database=0, opt_compress=0, vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0, opt_nopager=1, opt_outfile=0, no_named_cmds=1; static uint verbose=0,opt_silent=0,opt_mysql_port=0; opt_nopager=1, opt_outfile=0, no_named_cmds=1; static uint verbose=0,opt_silent=0,opt_mysql_port=0,opt_connect_timeout=0; static my_string opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; static char *current_host,*current_db,*current_user=0,*opt_password=0, Loading Loading @@ -363,8 +362,8 @@ sig_handler mysql_end(int sig) exit(status.exit_status); } enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE} ; enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_TIMEOUT, OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE} ; static struct option long_options[] = Loading Loading @@ -412,6 +411,7 @@ static struct option long_options[] = {"socket", required_argument, 0, 'S'}, #include "sslopt-longopts.h" {"table", no_argument, 0, 't'}, {"timeout", required_argument, 0, OPT_TIMEOUT}, #ifndef DONT_ALLOW_USER_CHANGE {"user", required_argument, 0, 'u'}, #endif Loading @@ -425,7 +425,7 @@ static struct option long_options[] = CHANGEABLE_VAR changeable_vars[] = { { "max_allowed_packet", (long*) &max_allowed_packet,24*1024L*1024L,4096, { "max_allowed_packet", (long*) &max_allowed_packet,16*1024L*1024L,4096, 24*1024L*1024L, MALLOC_OVERHEAD,1024}, { "net_buffer_length",(long*) &net_buffer_length,16384,1024,24*1024*1024L, MALLOC_OVERHEAD,1024}, Loading Loading @@ -627,9 +627,12 @@ static int get_options(int argc, char **argv) case 'p': if (optarg) { char *start=optarg; my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); opt_password=my_strdup(optarg,MYF(MY_FAE)); while (*optarg) *optarg++= 'x'; // Destroy argument if (*start) start[1]=0; } else tty_password=1; Loading Loading @@ -685,6 +688,9 @@ static int get_options(int argc, char **argv) opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0)); #endif break; case OPT_TIMEOUT: opt_connect_timeout=atoi(optarg); break; case 'V': usage(1); exit(0); case 'I': case '?': Loading Loading @@ -2026,6 +2032,9 @@ sql_real_connect(char *host,char *database,char *user,char *password, connected= 0; } mysql_init(&mysql); if (opt_connect_timeout) mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT, (char*) &opt_connect_timeout); if (opt_compress) mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); #ifdef HAVE_OPENSSL Loading Loading @@ -2258,9 +2267,9 @@ void tee_fprintf(FILE *file, const char *fmt, ...) va_list args; va_start(args, fmt); VOID(vfprintf(file, fmt, args)); (void) vfprintf(file, fmt, args); if (opt_outfile) VOID(vfprintf(OUTFILE, fmt, args)); (void) vfprintf(OUTFILE, fmt, args); va_end(args); } Loading isam/_dynrec.c +6 −4 Original line number Diff line number Diff line Loading @@ -104,7 +104,8 @@ int _nisam_delete_dynamic_record(N_INFO *info) /* Write record to data-file */ static int write_dynamic_record(N_INFO *info, const byte *record, uint reclength) static int write_dynamic_record(N_INFO *info, const byte *record, uint reclength) { int flag; uint length; Loading Loading @@ -142,8 +143,9 @@ static int _nisam_find_writepos(N_INFO *info, *filepos=info->s->state.dellink; block_info.second_read=0; info->rec_cache.seek_not_done=1; if (!(_nisam_get_block_info(&block_info,info->dfile,info->s->state.dellink) & BLOCK_DELETED)) if (!(_nisam_get_block_info(&block_info,info->dfile, info->s->state.dellink) & BLOCK_DELETED)) { my_errno=HA_ERR_WRONG_IN_RECORD; DBUG_RETURN(-1); Loading Loading @@ -213,7 +215,7 @@ int _nisam_write_part_record(N_INFO *info, extra_length++; /* One empty */ } } else if (length-long_block < *reclength+5) else if (length-long_block*2 < *reclength+5) { /* To short block */ if (next_filepos == NI_POS_ERROR) next_filepos=info->s->state.dellink != NI_POS_ERROR ? Loading scripts/mysqlhotcopy.sh +110 −32 Original line number Diff line number Diff line Loading @@ -19,13 +19,24 @@ mysqlhotcopy - fast on-line hot-backup utility for local MySQL databases mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory mysqlhotcopy db_name./regex/ mysqlhotcopy db_name./^\(foo\|bar\)/ mysqlhotcopy db_name./~regex/ mysqlhotcopy db_name_1./regex_1/ db_name_1./regex_2/ ... db_name_n./regex_n/ /path/to/new_directory mysqlhotcopy --method='scp -Bq -i /usr/home/foo/.ssh/identity' --user=root --password=secretpassword \ db_1./^nice_table/ user@some.system.dom:~/path/to/new_directory WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome. =cut # Documentation continued at end of file my $VERSION = "1.7"; my $VERSION = "1.8"; my $OPTIONS = <<"_OPTIONS"; Loading @@ -39,7 +50,7 @@ Usage: $0 db_name [new_db_name | directory] --allowold don't abort if target already exists (rename it _old) --keepold don't delete previous (now renamed) target when done --noindices don't copy index files --indices include index files in copy --method=# method for copy (only "cp" currently supported) -q, --quiet be silent except for errors Loading @@ -50,6 +61,8 @@ Usage: $0 db_name [new_db_name | directory] --suffix=# suffix for names of copied databases --checkpoint=# insert checkpoint entry into specified db.table --flushlog flush logs once all tables are locked Try 'perldoc $0 for more complete documentation' _OPTIONS sub usage { Loading Loading @@ -90,6 +103,7 @@ GetOptions( \%opt, # a list of hash-refs containing: # # 'src' - name of the db to copy # 't_regex' - regex describing tables in src # 'target' - destination directory of the copy # 'tables' - array-ref to list of tables in the db # 'files' - array-ref to list of files to be copied Loading @@ -100,12 +114,14 @@ my $tgt_name = undef; if ( $opt{regexp} || $opt{suffix} || @ARGV > 2 ) { $tgt_name = pop @ARGV unless ( exists $opt{suffix} ); @db_desc = map { { 'src' => $_ } } @ARGV; @db_desc = map { s{^([^\.]+)\./(.+)/$}{$1}; { 'src' => $_, 't_regex' => ( $2 ? $2 : '.*' ) } } @ARGV; } else { usage("Database name to hotcopy not specified") unless ( @ARGV ); @db_desc = ( { 'src' => $ARGV[0] } ); $ARGV[0] =~ s{^([^\.]+)\./(.+)/$}{$1}; @db_desc = ( { 'src' => $ARGV[0], 't_regex' => ( $2 ? $2 : '.*' ) } ); if ( @ARGV == 2 ) { $tgt_name = $ARGV[1]; } Loading Loading @@ -195,15 +211,35 @@ foreach my $rdb ( @db_desc ) { die "Database '$db' not accessible: $@" if ( $@ ); my @dbh_tables = $dbh->func( '_ListTables' ); ## generate regex for tables/files my $t_regex = $rdb->{t_regex}; ## assign temporary regex my $negated = $t_regex =~ tr/~//d; ## remove and count negation operator: we don't allow ~ in table names $t_regex = qr/$t_regex/; ## make regex string from user regex ## filter (out) tables specified in t_regex print "Filtering tables with '$t_regex'\n" if $opt{debug}; @dbh_tables = ( $negated ? grep { $_ !~ $t_regex } @dbh_tables : grep { $_ =~ $t_regex } @dbh_tables ); ## get list of files to copy my $db_dir = "$datadir/$db"; opendir(DBDIR, $db_dir ) or die "Cannot open dir '$db_dir': $!"; my @db_files = grep { /.+\.\w+$/ } readdir(DBDIR) or warn "'$db' is an empty database\n"; my %db_files; map { ( /(.+)\.\w+$/ ? { $db_files{$_} = $1 } : () ) } readdir(DBDIR); unless( keys %db_files ) { warn "'$db' is an empty database\n"; } closedir( DBDIR ); ## filter (out) files specified in t_regex my @db_files = sort ( $negated ? grep { $db_files{$_} !~ $t_regex } keys %db_files : grep { $db_files{$_} =~ $t_regex } keys %db_files ); ## remove indices unless we're told to keep them unless ($opt{indices}) { @db_files = grep { not /\.(ISM|MYI)$/ } @db_files; } Loading Loading @@ -238,6 +274,12 @@ if (length $tgt_name ) { $rdb->{target} = "$tgt_dirname"; } } elsif ($opt{method} =~ /^scp\b/) { # we have to trust scp to hit the target foreach my $rdb ( @db_desc ) { $rdb->{target} = "$tgt_dirname/$rdb->{src}"; } } else { die "Last argument ($tgt_dirname) is not a directory\n" Loading Loading @@ -278,6 +320,10 @@ foreach my $rdb ( @db_desc ) { if ( $opt{dryrun} ) { print "mkdir $tgt_dirpath, 0750\n"; } elsif ($opt{method} =~ /^scp\b/) { ## assume it's there? ## ... } else { mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n"; Loading Loading @@ -410,11 +456,16 @@ sub copy_files { my ($method, $files, $target) = @_; my @cmd; print "Copying ".@$files." files...\n" unless $opt{quiet}; if ($method =~ /^s?cp\b/) { # cp or scp with optional flags @cmd = ($method); # add option to preserve mod time etc of copied files # not critical, but nice to have push @cmd, "-p" if $^O =~ m/^(solaris|linux)$/; push @cmd, "-p" if $^O =~ m/^(solaris|linux|freebsd)$/; # add recursive option for scp push @cmd, "-r" if $^O =~ /m^(solaris|linux|freebsd)$/ && $method =~ /^scp\b/; # add files to copy and the destination directory push @cmd, @$files, $target; } Loading @@ -427,10 +478,13 @@ sub copy_files { next; } ## for some reason system fails but backticks works ok for scp... print "Executing '@cmd'\n" if $opt{debug}; my $cp_status = system @cmd; if ($cp_status != 0) { die "Error: @cmd failed ($cp_status) while copying files.\n"; warn "Burp ('scuse me). Trying backtick execution...\n" if $opt{debug}; #' ## try something else `@cmd` && die "Error: @cmd failed ($cp_status) while copying files.\n"; } } Loading Loading @@ -520,7 +574,22 @@ locked, and before they are copied. =item --regexp pattern Copy all databases with names matching the pattern. Copy all databases with names matching the pattern =item db_name./pattern/ Copy only tables matching pattern. Shell metacharacters ( (, ), |, !, etc.) have to be escaped (e.g. \). For example, to select all tables in database db1 whose names begin with 'foo' or 'bar': mysqlhotcopy --indices --method=cp db1./^\(foo\|bar\)/ =item db_name./~pattern/ Copy only tables not matching pattern. For example, to copy tables that do not begin with foo nor bar: mysqlhotcopy --indices --method=cp db1./~^\(foo\|bar\)/ =item -?, --help Loading @@ -542,13 +611,25 @@ port to use when connecting to local server UNIX domain socket to use when connecting to local server =item --noindices =item --indices don't copy index files include index files in copy =item --method=# method for copy (only "cp" currently supported) method for copy (only "cp" currently supported). Alpha support for "scp" was added in November 2000. Your experience with the scp method will vary with your ability to understand how scp works. 'man scp' and 'man ssh' are your friends. The destination directory _must exist_ on the target machine using the scp method. Liberal use of the --debug option will help you figure out what's really going on when you do an scp. Note that using scp will lock your tables for a _long_ time unless your network connection is _fast_. If this is unacceptable to you, use the 'cp' method to copy the tables to some temporary area and then scp or rsync the files at your leisure. =item -q, --quiet Loading @@ -575,12 +656,8 @@ Patches adding bug fixes, documentation and new features are welcome. =head1 TO DO Allow a list of tables (or regex) to be given on the command line to enable a logically-related subset of the tables to be hot-copied rather than force the whole db to be copied in one go. Extend the above to allow multiple subsets of tables to be specified on the command line: Extend the individual table copy to allow multiple subsets of tables to be specified on the command line: mysqlhotcopy db newdb t1 t2 /^foo_/ : t3 /^bar_/ : + Loading Loading @@ -609,5 +686,6 @@ Tim Bunce Martin Waite - added checkpoint, flushlog, regexp and dryrun options Ralph Corderoy - Added synonyms for commands =cut Ralph Corderoy - added synonyms for commands Scott Wiersdorf - added table regex and scp support sql-bench/test-insert.sh +19 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,25 @@ else print " for order_by_big ($small_loop_count:$rows): " . timestr(timediff($end_time, $loop_time),"all") . "\n"; $loop_time=new Benchmark; $estimated=$rows=0; for ($i=1 ; $i <= $range_loop_count ; $i++) { $start=$opt_loop_count/$range_loop_count*$i; $end=$start+$i; $rows+=fetch_all_rows($dbh,"select dummy1 from bench1 where id>=$start and id <= $end order by id3",1); $end_time=new Benchmark; last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i, $range_loop_count)); } if ($estimated) { print "Estimated time"; } else { print "Time"; } print " for order_by_range ($range_loop_count:$rows): " . timestr(timediff($end_time, $loop_time),"all") . "\n"; $loop_time=new Benchmark; $estimated=$rows=0; for ($i=1 ; $i <= $range_loop_count ; $i++) Loading Loading
Docs/manual.texi +39 −6 Original line number Diff line number Diff line Loading @@ -500,6 +500,7 @@ Examples of common queries * example-Maximum-row:: The row holding the maximum of a certain column * example-Maximum-column-group:: Maximum of column per group * example-Maximum-column-group-row:: The rows holding the group-wise maximum of a certain field * example-user-variables:: * example-Foreign keys:: Using foreign keys Creating and using a database Loading Loading @@ -948,7 +949,7 @@ Changes in release 3.19.x MySQL and the future (The TODO) * TODO MySQL 4.0:: * TODO MySQL 4.0:: Things that should be in 4.0 * TODO future:: Things that must done in the very near future * TODO sometime:: Things that have to be done sometime * TODO unplanned:: Some things we don't have any plans to do Loading Loading @@ -22657,6 +22658,7 @@ SELECT * FROM shop * example-Maximum-row:: The row holding the maximum of a certain column * example-Maximum-column-group:: Maximum of column per group * example-Maximum-column-group-row:: The rows holding the group-wise maximum of a certain field * example-user-variables:: * example-Foreign keys:: Using foreign keys @end menu Loading Loading @@ -22736,7 +22738,7 @@ GROUP BY article +---------+-------+ @end example @node example-Maximum-column-group-row, example-Foreign keys, example-Maximum-column-group, Examples @node example-Maximum-column-group-row, example-user-variables, example-Maximum-column-group, Examples @subsection The rows holding the group-wise maximum of a certain field ``For each article, find the dealer(s) with the most expensive price.'' Loading Loading @@ -22807,9 +22809,31 @@ GROUP BY article; The last example can of course be made a bit more efficient by doing the splitting of the concatenated column in the client. @node example-user-variables, example-Foreign keys, example-Maximum-column-group-row, Examples @subsection Using user variables You can use @strong{MySQL} user variables to remember results without having to store them in a temporary variables in the client. @xref{Variables}. For example to find the articles with the highest and lowest price you can do: @example select @@min_price:=min(price),@@max_price:=max(price) from shop; select * from shop where price=@@min_price or price=@@max_price; +---------+--------+-------+ | article | dealer | price | +---------+--------+-------+ | 0003 | D | 1.25 | | 0004 | D | 19.95 | +---------+--------+-------+ @end example @cindex foreign keys @cindex keys, foreign @node example-Foreign keys, , example-Maximum-column-group-row, Examples @node example-Foreign keys, , example-user-variables, Examples @subsection Using foreign keys You don't need foreign keys to join 2 tables. Loading Loading @@ -37609,6 +37633,8 @@ With source code. By Matthias Fichtner. A library to use @strong{MySQL} with Delphi} @item @uref{http://www.geocities.com/CapeCanaveral/2064/mysql.html, Delphi TDataset-component} @item @item @uref{http://www.mysql.com/Downloads/Contrib/Win32/SBMySQL50Share.exe, Delphi 5 Shareware MySQL Dataset Components} @end itemize @item @uref{http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz, mysql-ruby-2.2.0.tar.gz} Loading Loading @@ -37752,9 +37778,13 @@ An open source client for exploring databases and executing SQL. Supports A query tool for @strong{MySQL} and PostgreSQL. @item @uref{http://dbman.linux.cz/,dbMan} A query tool written in Perl. Uses DBI and Tk. @item @uref{http://www.mysql.com/Downloads/Contrib/mascon1.exe, mascon1.exe} You can get the newest one from @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon.asp}. @item @uref{http://www.mysql.com/Downloads/Win32/Msc18.exe, Mascon 2000.1.8} @item @uref{http://www.mysql.com/Downloads/Win32/FrMsc18.exe, Free Mascon 2000.1.8} Mascon is a powerful Win32 GUI for the administering MySQL server databases. Mascon's features include visual table design, connections to multiple servers, data and blob editing of tables, security setting, SQL colour coding, dump functionality and much more. @uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon home page}. @item @uref{http://www.virtualbeer.net/dbui/,DBUI} DBUI is a Gtk graphical database editor. @end itemize Loading Loading @@ -38503,6 +38533,9 @@ though, so Version 3.23 is not released as a stable version yet. @item Fixed the @code{--skip-networking} works properly on NT. @item Fixed long outstanding bug in the @code{ISAM} tables when a row with a length of more than 65K was shortened by a single byte. @item Fixed bug in @code{MyISAM} when running multiple updating processes on the same table. @item
client/mysql.cc +18 −9 Original line number Diff line number Diff line Loading @@ -115,9 +115,8 @@ static bool info_flag=0,ignore_errors=0,wait_flag=0,quick=0, no_rehash=0,skip_updates=0,safe_updates=0,one_database=0, opt_compress=0, vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0, opt_nopager=1, opt_outfile=0, no_named_cmds=1; static uint verbose=0,opt_silent=0,opt_mysql_port=0; opt_nopager=1, opt_outfile=0, no_named_cmds=1; static uint verbose=0,opt_silent=0,opt_mysql_port=0,opt_connect_timeout=0; static my_string opt_mysql_unix_port=0; static int connect_flag=CLIENT_INTERACTIVE; static char *current_host,*current_db,*current_user=0,*opt_password=0, Loading Loading @@ -363,8 +362,8 @@ sig_handler mysql_end(int sig) exit(status.exit_status); } enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE} ; enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_TIMEOUT, OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE} ; static struct option long_options[] = Loading Loading @@ -412,6 +411,7 @@ static struct option long_options[] = {"socket", required_argument, 0, 'S'}, #include "sslopt-longopts.h" {"table", no_argument, 0, 't'}, {"timeout", required_argument, 0, OPT_TIMEOUT}, #ifndef DONT_ALLOW_USER_CHANGE {"user", required_argument, 0, 'u'}, #endif Loading @@ -425,7 +425,7 @@ static struct option long_options[] = CHANGEABLE_VAR changeable_vars[] = { { "max_allowed_packet", (long*) &max_allowed_packet,24*1024L*1024L,4096, { "max_allowed_packet", (long*) &max_allowed_packet,16*1024L*1024L,4096, 24*1024L*1024L, MALLOC_OVERHEAD,1024}, { "net_buffer_length",(long*) &net_buffer_length,16384,1024,24*1024*1024L, MALLOC_OVERHEAD,1024}, Loading Loading @@ -627,9 +627,12 @@ static int get_options(int argc, char **argv) case 'p': if (optarg) { char *start=optarg; my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR)); opt_password=my_strdup(optarg,MYF(MY_FAE)); while (*optarg) *optarg++= 'x'; // Destroy argument if (*start) start[1]=0; } else tty_password=1; Loading Loading @@ -685,6 +688,9 @@ static int get_options(int argc, char **argv) opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0)); #endif break; case OPT_TIMEOUT: opt_connect_timeout=atoi(optarg); break; case 'V': usage(1); exit(0); case 'I': case '?': Loading Loading @@ -2026,6 +2032,9 @@ sql_real_connect(char *host,char *database,char *user,char *password, connected= 0; } mysql_init(&mysql); if (opt_connect_timeout) mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT, (char*) &opt_connect_timeout); if (opt_compress) mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS); #ifdef HAVE_OPENSSL Loading Loading @@ -2258,9 +2267,9 @@ void tee_fprintf(FILE *file, const char *fmt, ...) va_list args; va_start(args, fmt); VOID(vfprintf(file, fmt, args)); (void) vfprintf(file, fmt, args); if (opt_outfile) VOID(vfprintf(OUTFILE, fmt, args)); (void) vfprintf(OUTFILE, fmt, args); va_end(args); } Loading
isam/_dynrec.c +6 −4 Original line number Diff line number Diff line Loading @@ -104,7 +104,8 @@ int _nisam_delete_dynamic_record(N_INFO *info) /* Write record to data-file */ static int write_dynamic_record(N_INFO *info, const byte *record, uint reclength) static int write_dynamic_record(N_INFO *info, const byte *record, uint reclength) { int flag; uint length; Loading Loading @@ -142,8 +143,9 @@ static int _nisam_find_writepos(N_INFO *info, *filepos=info->s->state.dellink; block_info.second_read=0; info->rec_cache.seek_not_done=1; if (!(_nisam_get_block_info(&block_info,info->dfile,info->s->state.dellink) & BLOCK_DELETED)) if (!(_nisam_get_block_info(&block_info,info->dfile, info->s->state.dellink) & BLOCK_DELETED)) { my_errno=HA_ERR_WRONG_IN_RECORD; DBUG_RETURN(-1); Loading Loading @@ -213,7 +215,7 @@ int _nisam_write_part_record(N_INFO *info, extra_length++; /* One empty */ } } else if (length-long_block < *reclength+5) else if (length-long_block*2 < *reclength+5) { /* To short block */ if (next_filepos == NI_POS_ERROR) next_filepos=info->s->state.dellink != NI_POS_ERROR ? Loading
scripts/mysqlhotcopy.sh +110 −32 Original line number Diff line number Diff line Loading @@ -19,13 +19,24 @@ mysqlhotcopy - fast on-line hot-backup utility for local MySQL databases mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory mysqlhotcopy db_name./regex/ mysqlhotcopy db_name./^\(foo\|bar\)/ mysqlhotcopy db_name./~regex/ mysqlhotcopy db_name_1./regex_1/ db_name_1./regex_2/ ... db_name_n./regex_n/ /path/to/new_directory mysqlhotcopy --method='scp -Bq -i /usr/home/foo/.ssh/identity' --user=root --password=secretpassword \ db_1./^nice_table/ user@some.system.dom:~/path/to/new_directory WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome. =cut # Documentation continued at end of file my $VERSION = "1.7"; my $VERSION = "1.8"; my $OPTIONS = <<"_OPTIONS"; Loading @@ -39,7 +50,7 @@ Usage: $0 db_name [new_db_name | directory] --allowold don't abort if target already exists (rename it _old) --keepold don't delete previous (now renamed) target when done --noindices don't copy index files --indices include index files in copy --method=# method for copy (only "cp" currently supported) -q, --quiet be silent except for errors Loading @@ -50,6 +61,8 @@ Usage: $0 db_name [new_db_name | directory] --suffix=# suffix for names of copied databases --checkpoint=# insert checkpoint entry into specified db.table --flushlog flush logs once all tables are locked Try 'perldoc $0 for more complete documentation' _OPTIONS sub usage { Loading Loading @@ -90,6 +103,7 @@ GetOptions( \%opt, # a list of hash-refs containing: # # 'src' - name of the db to copy # 't_regex' - regex describing tables in src # 'target' - destination directory of the copy # 'tables' - array-ref to list of tables in the db # 'files' - array-ref to list of files to be copied Loading @@ -100,12 +114,14 @@ my $tgt_name = undef; if ( $opt{regexp} || $opt{suffix} || @ARGV > 2 ) { $tgt_name = pop @ARGV unless ( exists $opt{suffix} ); @db_desc = map { { 'src' => $_ } } @ARGV; @db_desc = map { s{^([^\.]+)\./(.+)/$}{$1}; { 'src' => $_, 't_regex' => ( $2 ? $2 : '.*' ) } } @ARGV; } else { usage("Database name to hotcopy not specified") unless ( @ARGV ); @db_desc = ( { 'src' => $ARGV[0] } ); $ARGV[0] =~ s{^([^\.]+)\./(.+)/$}{$1}; @db_desc = ( { 'src' => $ARGV[0], 't_regex' => ( $2 ? $2 : '.*' ) } ); if ( @ARGV == 2 ) { $tgt_name = $ARGV[1]; } Loading Loading @@ -195,15 +211,35 @@ foreach my $rdb ( @db_desc ) { die "Database '$db' not accessible: $@" if ( $@ ); my @dbh_tables = $dbh->func( '_ListTables' ); ## generate regex for tables/files my $t_regex = $rdb->{t_regex}; ## assign temporary regex my $negated = $t_regex =~ tr/~//d; ## remove and count negation operator: we don't allow ~ in table names $t_regex = qr/$t_regex/; ## make regex string from user regex ## filter (out) tables specified in t_regex print "Filtering tables with '$t_regex'\n" if $opt{debug}; @dbh_tables = ( $negated ? grep { $_ !~ $t_regex } @dbh_tables : grep { $_ =~ $t_regex } @dbh_tables ); ## get list of files to copy my $db_dir = "$datadir/$db"; opendir(DBDIR, $db_dir ) or die "Cannot open dir '$db_dir': $!"; my @db_files = grep { /.+\.\w+$/ } readdir(DBDIR) or warn "'$db' is an empty database\n"; my %db_files; map { ( /(.+)\.\w+$/ ? { $db_files{$_} = $1 } : () ) } readdir(DBDIR); unless( keys %db_files ) { warn "'$db' is an empty database\n"; } closedir( DBDIR ); ## filter (out) files specified in t_regex my @db_files = sort ( $negated ? grep { $db_files{$_} !~ $t_regex } keys %db_files : grep { $db_files{$_} =~ $t_regex } keys %db_files ); ## remove indices unless we're told to keep them unless ($opt{indices}) { @db_files = grep { not /\.(ISM|MYI)$/ } @db_files; } Loading Loading @@ -238,6 +274,12 @@ if (length $tgt_name ) { $rdb->{target} = "$tgt_dirname"; } } elsif ($opt{method} =~ /^scp\b/) { # we have to trust scp to hit the target foreach my $rdb ( @db_desc ) { $rdb->{target} = "$tgt_dirname/$rdb->{src}"; } } else { die "Last argument ($tgt_dirname) is not a directory\n" Loading Loading @@ -278,6 +320,10 @@ foreach my $rdb ( @db_desc ) { if ( $opt{dryrun} ) { print "mkdir $tgt_dirpath, 0750\n"; } elsif ($opt{method} =~ /^scp\b/) { ## assume it's there? ## ... } else { mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n"; Loading Loading @@ -410,11 +456,16 @@ sub copy_files { my ($method, $files, $target) = @_; my @cmd; print "Copying ".@$files." files...\n" unless $opt{quiet}; if ($method =~ /^s?cp\b/) { # cp or scp with optional flags @cmd = ($method); # add option to preserve mod time etc of copied files # not critical, but nice to have push @cmd, "-p" if $^O =~ m/^(solaris|linux)$/; push @cmd, "-p" if $^O =~ m/^(solaris|linux|freebsd)$/; # add recursive option for scp push @cmd, "-r" if $^O =~ /m^(solaris|linux|freebsd)$/ && $method =~ /^scp\b/; # add files to copy and the destination directory push @cmd, @$files, $target; } Loading @@ -427,10 +478,13 @@ sub copy_files { next; } ## for some reason system fails but backticks works ok for scp... print "Executing '@cmd'\n" if $opt{debug}; my $cp_status = system @cmd; if ($cp_status != 0) { die "Error: @cmd failed ($cp_status) while copying files.\n"; warn "Burp ('scuse me). Trying backtick execution...\n" if $opt{debug}; #' ## try something else `@cmd` && die "Error: @cmd failed ($cp_status) while copying files.\n"; } } Loading Loading @@ -520,7 +574,22 @@ locked, and before they are copied. =item --regexp pattern Copy all databases with names matching the pattern. Copy all databases with names matching the pattern =item db_name./pattern/ Copy only tables matching pattern. Shell metacharacters ( (, ), |, !, etc.) have to be escaped (e.g. \). For example, to select all tables in database db1 whose names begin with 'foo' or 'bar': mysqlhotcopy --indices --method=cp db1./^\(foo\|bar\)/ =item db_name./~pattern/ Copy only tables not matching pattern. For example, to copy tables that do not begin with foo nor bar: mysqlhotcopy --indices --method=cp db1./~^\(foo\|bar\)/ =item -?, --help Loading @@ -542,13 +611,25 @@ port to use when connecting to local server UNIX domain socket to use when connecting to local server =item --noindices =item --indices don't copy index files include index files in copy =item --method=# method for copy (only "cp" currently supported) method for copy (only "cp" currently supported). Alpha support for "scp" was added in November 2000. Your experience with the scp method will vary with your ability to understand how scp works. 'man scp' and 'man ssh' are your friends. The destination directory _must exist_ on the target machine using the scp method. Liberal use of the --debug option will help you figure out what's really going on when you do an scp. Note that using scp will lock your tables for a _long_ time unless your network connection is _fast_. If this is unacceptable to you, use the 'cp' method to copy the tables to some temporary area and then scp or rsync the files at your leisure. =item -q, --quiet Loading @@ -575,12 +656,8 @@ Patches adding bug fixes, documentation and new features are welcome. =head1 TO DO Allow a list of tables (or regex) to be given on the command line to enable a logically-related subset of the tables to be hot-copied rather than force the whole db to be copied in one go. Extend the above to allow multiple subsets of tables to be specified on the command line: Extend the individual table copy to allow multiple subsets of tables to be specified on the command line: mysqlhotcopy db newdb t1 t2 /^foo_/ : t3 /^bar_/ : + Loading Loading @@ -609,5 +686,6 @@ Tim Bunce Martin Waite - added checkpoint, flushlog, regexp and dryrun options Ralph Corderoy - Added synonyms for commands =cut Ralph Corderoy - added synonyms for commands Scott Wiersdorf - added table regex and scp support
sql-bench/test-insert.sh +19 −0 Original line number Diff line number Diff line Loading @@ -365,6 +365,25 @@ else print " for order_by_big ($small_loop_count:$rows): " . timestr(timediff($end_time, $loop_time),"all") . "\n"; $loop_time=new Benchmark; $estimated=$rows=0; for ($i=1 ; $i <= $range_loop_count ; $i++) { $start=$opt_loop_count/$range_loop_count*$i; $end=$start+$i; $rows+=fetch_all_rows($dbh,"select dummy1 from bench1 where id>=$start and id <= $end order by id3",1); $end_time=new Benchmark; last if ($estimated=predict_query_time($loop_time,$end_time,\$i,$i, $range_loop_count)); } if ($estimated) { print "Estimated time"; } else { print "Time"; } print " for order_by_range ($range_loop_count:$rows): " . timestr(timediff($end_time, $loop_time),"all") . "\n"; $loop_time=new Benchmark; $estimated=$rows=0; for ($i=1 ; $i <= $range_loop_count ; $i++) Loading