Portability fixes
Docs/manual.texi: Updated links and added more examples client/mysql.cc: Added --timeout + merge of Jani:s changes isam/_dynrec.c: Fixed bug when making big rows 1 byte smaller scripts/mysqlhotcopy.sh: Added regexp handling of filenames sql-bench/test-insert.sh: More order by tests sql/mf_iocache.cc: Cleanup sql/mysqld.cc: Moved my_delete() to before master thread died sql/sql_parse.cc: Fixed wrong comparison
This commit is contained in:
parent
19fc413aa2
commit
0ffa94682e
@ -500,6 +500,7 @@ Examples of common queries
|
|||||||
* example-Maximum-row:: The row holding the maximum of a certain column
|
* 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:: Maximum of column per group
|
||||||
* example-Maximum-column-group-row:: The rows holding the group-wise maximum of a certain field
|
* 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
|
* example-Foreign keys:: Using foreign keys
|
||||||
|
|
||||||
Creating and using a database
|
Creating and using a database
|
||||||
@ -948,7 +949,7 @@ Changes in release 3.19.x
|
|||||||
|
|
||||||
MySQL and the future (The TODO)
|
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 future:: Things that must done in the very near future
|
||||||
* TODO sometime:: Things that have to be done sometime
|
* TODO sometime:: Things that have to be done sometime
|
||||||
* TODO unplanned:: Some things we don't have any plans to do
|
* TODO unplanned:: Some things we don't have any plans to do
|
||||||
@ -22657,6 +22658,7 @@ SELECT * FROM shop
|
|||||||
* example-Maximum-row:: The row holding the maximum of a certain column
|
* 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:: Maximum of column per group
|
||||||
* example-Maximum-column-group-row:: The rows holding the group-wise maximum of a certain field
|
* 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
|
* example-Foreign keys:: Using foreign keys
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@ -22736,7 +22738,7 @@ GROUP BY article
|
|||||||
+---------+-------+
|
+---------+-------+
|
||||||
@end example
|
@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
|
@subsection The rows holding the group-wise maximum of a certain field
|
||||||
|
|
||||||
``For each article, find the dealer(s) with the most expensive price.''
|
``For each article, find the dealer(s) with the most expensive price.''
|
||||||
@ -22807,9 +22809,31 @@ GROUP BY article;
|
|||||||
The last example can of course be made a bit more efficient by doing the
|
The last example can of course be made a bit more efficient by doing the
|
||||||
splitting of the concatenated column in the client.
|
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 foreign keys
|
||||||
@cindex keys, foreign
|
@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
|
@subsection Using foreign keys
|
||||||
|
|
||||||
You don't need foreign keys to join 2 tables.
|
You don't need foreign keys to join 2 tables.
|
||||||
@ -37609,6 +37633,8 @@ With source code. By Matthias Fichtner.
|
|||||||
A library to use @strong{MySQL} with Delphi}
|
A library to use @strong{MySQL} with Delphi}
|
||||||
|
|
||||||
@item @uref{http://www.geocities.com/CapeCanaveral/2064/mysql.html, Delphi TDataset-component}
|
@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
|
@end itemize
|
||||||
|
|
||||||
@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz, mysql-ruby-2.2.0.tar.gz}
|
@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz, mysql-ruby-2.2.0.tar.gz}
|
||||||
@ -37752,9 +37778,13 @@ An open source client for exploring databases and executing SQL. Supports
|
|||||||
A query tool for @strong{MySQL} and PostgreSQL.
|
A query tool for @strong{MySQL} and PostgreSQL.
|
||||||
@item @uref{http://dbman.linux.cz/,dbMan}
|
@item @uref{http://dbman.linux.cz/,dbMan}
|
||||||
A query tool written in Perl. Uses DBI and Tk.
|
A query tool written in Perl. Uses DBI and Tk.
|
||||||
@item @uref{http://www.mysql.com/Downloads/Contrib/mascon1.exe, mascon1.exe}
|
@item @uref{http://www.mysql.com/Downloads/Win32/Msc18.exe, Mascon 2000.1.8}
|
||||||
You can get the newest one from
|
@item @uref{http://www.mysql.com/Downloads/Win32/FrMsc18.exe, Free Mascon 2000.1.8}
|
||||||
@uref{http://www.scibit.com/Products/Software/Utils/Mascon.asp,Mascon.asp}.
|
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}
|
@item @uref{http://www.virtualbeer.net/dbui/,DBUI}
|
||||||
DBUI is a Gtk graphical database editor.
|
DBUI is a Gtk graphical database editor.
|
||||||
@end itemize
|
@end itemize
|
||||||
@ -38503,6 +38533,9 @@ though, so Version 3.23 is not released as a stable version yet.
|
|||||||
@item
|
@item
|
||||||
Fixed the @code{--skip-networking} works properly on NT.
|
Fixed the @code{--skip-networking} works properly on NT.
|
||||||
@item
|
@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
|
Fixed bug in @code{MyISAM} when running multiple updating processes on
|
||||||
the same table.
|
the same table.
|
||||||
@item
|
@item
|
||||||
|
@ -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,
|
no_rehash=0,skip_updates=0,safe_updates=0,one_database=0,
|
||||||
opt_compress=0,
|
opt_compress=0,
|
||||||
vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0,
|
vertical=0,skip_line_numbers=0,skip_column_names=0,opt_html=0,
|
||||||
opt_nopager=1, opt_outfile=0,
|
opt_nopager=1, opt_outfile=0, no_named_cmds=1;
|
||||||
no_named_cmds=1;
|
static uint verbose=0,opt_silent=0,opt_mysql_port=0,opt_connect_timeout=0;
|
||||||
static uint verbose=0,opt_silent=0,opt_mysql_port=0;
|
|
||||||
static my_string opt_mysql_unix_port=0;
|
static my_string opt_mysql_unix_port=0;
|
||||||
static int connect_flag=CLIENT_INTERACTIVE;
|
static int connect_flag=CLIENT_INTERACTIVE;
|
||||||
static char *current_host,*current_db,*current_user=0,*opt_password=0,
|
static char *current_host,*current_db,*current_user=0,*opt_password=0,
|
||||||
@ -363,8 +362,8 @@ sig_handler mysql_end(int sig)
|
|||||||
exit(status.exit_status);
|
exit(status.exit_status);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_PAGER,
|
enum options {OPT_CHARSETS_DIR=256, OPT_DEFAULT_CHARSET, OPT_TIMEOUT,
|
||||||
OPT_NOPAGER, OPT_TEE, OPT_NOTEE} ;
|
OPT_PAGER, OPT_NOPAGER, OPT_TEE, OPT_NOTEE} ;
|
||||||
|
|
||||||
|
|
||||||
static struct option long_options[] =
|
static struct option long_options[] =
|
||||||
@ -378,7 +377,7 @@ static struct option long_options[] =
|
|||||||
#endif
|
#endif
|
||||||
{"database", required_argument, 0, 'D'},
|
{"database", required_argument, 0, 'D'},
|
||||||
{"debug-info", no_argument, 0, 'T'},
|
{"debug-info", no_argument, 0, 'T'},
|
||||||
{"default-character-set", required_argument, 0, OPT_DEFAULT_CHARSET},
|
{"default-character-set", required_argument,0, OPT_DEFAULT_CHARSET},
|
||||||
{"enable-named-commands", no_argument, 0, 'G'},
|
{"enable-named-commands", no_argument, 0, 'G'},
|
||||||
{"execute", required_argument, 0, 'e'},
|
{"execute", required_argument, 0, 'e'},
|
||||||
{"force", no_argument, 0, 'f'},
|
{"force", no_argument, 0, 'f'},
|
||||||
@ -412,6 +411,7 @@ static struct option long_options[] =
|
|||||||
{"socket", required_argument, 0, 'S'},
|
{"socket", required_argument, 0, 'S'},
|
||||||
#include "sslopt-longopts.h"
|
#include "sslopt-longopts.h"
|
||||||
{"table", no_argument, 0, 't'},
|
{"table", no_argument, 0, 't'},
|
||||||
|
{"timeout", required_argument, 0, OPT_TIMEOUT},
|
||||||
#ifndef DONT_ALLOW_USER_CHANGE
|
#ifndef DONT_ALLOW_USER_CHANGE
|
||||||
{"user", required_argument, 0, 'u'},
|
{"user", required_argument, 0, 'u'},
|
||||||
#endif
|
#endif
|
||||||
@ -425,7 +425,7 @@ static struct option long_options[] =
|
|||||||
|
|
||||||
|
|
||||||
CHANGEABLE_VAR changeable_vars[] = {
|
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},
|
24*1024L*1024L, MALLOC_OVERHEAD,1024},
|
||||||
{ "net_buffer_length",(long*) &net_buffer_length,16384,1024,24*1024*1024L,
|
{ "net_buffer_length",(long*) &net_buffer_length,16384,1024,24*1024*1024L,
|
||||||
MALLOC_OVERHEAD,1024},
|
MALLOC_OVERHEAD,1024},
|
||||||
@ -627,9 +627,12 @@ static int get_options(int argc, char **argv)
|
|||||||
case 'p':
|
case 'p':
|
||||||
if (optarg)
|
if (optarg)
|
||||||
{
|
{
|
||||||
|
char *start=optarg;
|
||||||
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
|
my_free(opt_password,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
opt_password=my_strdup(optarg,MYF(MY_FAE));
|
opt_password=my_strdup(optarg,MYF(MY_FAE));
|
||||||
while (*optarg) *optarg++= 'x'; // Destroy argument
|
while (*optarg) *optarg++= 'x'; // Destroy argument
|
||||||
|
if (*start)
|
||||||
|
start[1]=0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
tty_password=1;
|
tty_password=1;
|
||||||
@ -685,6 +688,9 @@ static int get_options(int argc, char **argv)
|
|||||||
opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0));
|
opt_mysql_unix_port=my_strdup(MYSQL_NAMEDPIPE,MYF(0));
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
case OPT_TIMEOUT:
|
||||||
|
opt_connect_timeout=atoi(optarg);
|
||||||
|
break;
|
||||||
case 'V': usage(1); exit(0);
|
case 'V': usage(1); exit(0);
|
||||||
case 'I':
|
case 'I':
|
||||||
case '?':
|
case '?':
|
||||||
@ -2026,6 +2032,9 @@ sql_real_connect(char *host,char *database,char *user,char *password,
|
|||||||
connected= 0;
|
connected= 0;
|
||||||
}
|
}
|
||||||
mysql_init(&mysql);
|
mysql_init(&mysql);
|
||||||
|
if (opt_connect_timeout)
|
||||||
|
mysql_options(&mysql,MYSQL_OPT_CONNECT_TIMEOUT,
|
||||||
|
(char*) &opt_connect_timeout);
|
||||||
if (opt_compress)
|
if (opt_compress)
|
||||||
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
|
mysql_options(&mysql,MYSQL_OPT_COMPRESS,NullS);
|
||||||
#ifdef HAVE_OPENSSL
|
#ifdef HAVE_OPENSSL
|
||||||
@ -2258,9 +2267,9 @@ void tee_fprintf(FILE *file, const char *fmt, ...)
|
|||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
VOID(vfprintf(file, fmt, args));
|
(void) vfprintf(file, fmt, args);
|
||||||
if (opt_outfile)
|
if (opt_outfile)
|
||||||
VOID(vfprintf(OUTFILE, fmt, args));
|
(void) vfprintf(OUTFILE, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,7 +104,8 @@ int _nisam_delete_dynamic_record(N_INFO *info)
|
|||||||
|
|
||||||
/* Write record to data-file */
|
/* 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;
|
int flag;
|
||||||
uint length;
|
uint length;
|
||||||
@ -142,8 +143,9 @@ static int _nisam_find_writepos(N_INFO *info,
|
|||||||
*filepos=info->s->state.dellink;
|
*filepos=info->s->state.dellink;
|
||||||
block_info.second_read=0;
|
block_info.second_read=0;
|
||||||
info->rec_cache.seek_not_done=1;
|
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;
|
my_errno=HA_ERR_WRONG_IN_RECORD;
|
||||||
DBUG_RETURN(-1);
|
DBUG_RETURN(-1);
|
||||||
@ -213,7 +215,7 @@ int _nisam_write_part_record(N_INFO *info,
|
|||||||
extra_length++; /* One empty */
|
extra_length++; /* One empty */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (length-long_block < *reclength+5)
|
else if (length-long_block*2 < *reclength+5)
|
||||||
{ /* To short block */
|
{ /* To short block */
|
||||||
if (next_filepos == NI_POS_ERROR)
|
if (next_filepos == NI_POS_ERROR)
|
||||||
next_filepos=info->s->state.dellink != NI_POS_ERROR ?
|
next_filepos=info->s->state.dellink != NI_POS_ERROR ?
|
||||||
|
@ -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_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.
|
WARNING: THIS IS VERY MUCH A FIRST-CUT ALPHA. Comments/patches welcome.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
# Documentation continued at end of file
|
# Documentation continued at end of file
|
||||||
|
|
||||||
my $VERSION = "1.7";
|
my $VERSION = "1.8";
|
||||||
|
|
||||||
my $OPTIONS = <<"_OPTIONS";
|
my $OPTIONS = <<"_OPTIONS";
|
||||||
|
|
||||||
@ -39,7 +50,7 @@ Usage: $0 db_name [new_db_name | directory]
|
|||||||
|
|
||||||
--allowold don't abort if target already exists (rename it _old)
|
--allowold don't abort if target already exists (rename it _old)
|
||||||
--keepold don't delete previous (now renamed) target when done
|
--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)
|
--method=# method for copy (only "cp" currently supported)
|
||||||
|
|
||||||
-q, --quiet be silent except for errors
|
-q, --quiet be silent except for errors
|
||||||
@ -50,6 +61,8 @@ Usage: $0 db_name [new_db_name | directory]
|
|||||||
--suffix=# suffix for names of copied databases
|
--suffix=# suffix for names of copied databases
|
||||||
--checkpoint=# insert checkpoint entry into specified db.table
|
--checkpoint=# insert checkpoint entry into specified db.table
|
||||||
--flushlog flush logs once all tables are locked
|
--flushlog flush logs once all tables are locked
|
||||||
|
|
||||||
|
Try 'perldoc $0 for more complete documentation'
|
||||||
_OPTIONS
|
_OPTIONS
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
@ -89,23 +102,26 @@ GetOptions( \%opt,
|
|||||||
# ==========
|
# ==========
|
||||||
# a list of hash-refs containing:
|
# a list of hash-refs containing:
|
||||||
#
|
#
|
||||||
# 'src' - name of the db to copy
|
# 'src' - name of the db to copy
|
||||||
# 'target' - destination directory of the copy
|
# 't_regex' - regex describing tables in src
|
||||||
# 'tables' - array-ref to list of tables in the db
|
# 'target' - destination directory of the copy
|
||||||
# 'files' - array-ref to list of files to be copied
|
# 'tables' - array-ref to list of tables in the db
|
||||||
|
# 'files' - array-ref to list of files to be copied
|
||||||
#
|
#
|
||||||
|
|
||||||
my @db_desc = ();
|
my @db_desc = ();
|
||||||
my $tgt_name = undef;
|
my $tgt_name = undef;
|
||||||
|
|
||||||
if ( $opt{regexp} || $opt{suffix} || @ARGV > 2 ) {
|
if ( $opt{regexp} || $opt{suffix} || @ARGV > 2 ) {
|
||||||
$tgt_name = pop @ARGV unless ( exists $opt{suffix} );
|
$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 {
|
else {
|
||||||
usage("Database name to hotcopy not specified") unless ( @ARGV );
|
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 ) {
|
if ( @ARGV == 2 ) {
|
||||||
$tgt_name = $ARGV[1];
|
$tgt_name = $ARGV[1];
|
||||||
}
|
}
|
||||||
@ -195,15 +211,35 @@ foreach my $rdb ( @db_desc ) {
|
|||||||
die "Database '$db' not accessible: $@" if ( $@ );
|
die "Database '$db' not accessible: $@" if ( $@ );
|
||||||
my @dbh_tables = $dbh->func( '_ListTables' );
|
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";
|
my $db_dir = "$datadir/$db";
|
||||||
opendir(DBDIR, $db_dir )
|
opendir(DBDIR, $db_dir )
|
||||||
or die "Cannot open dir '$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 );
|
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}) {
|
unless ($opt{indices}) {
|
||||||
@db_files = grep { not /\.(ISM|MYI)$/ } @db_files;
|
@db_files = grep { not /\.(ISM|MYI)$/ } @db_files;
|
||||||
}
|
}
|
||||||
@ -238,6 +274,12 @@ if (length $tgt_name ) {
|
|||||||
$rdb->{target} = "$tgt_dirname";
|
$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
|
else
|
||||||
{
|
{
|
||||||
die "Last argument ($tgt_dirname) is not a directory\n"
|
die "Last argument ($tgt_dirname) is not a directory\n"
|
||||||
@ -249,7 +291,7 @@ if (length $tgt_name ) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
die "Error: expected \$opt{suffix} to exist" unless ( exists $opt{suffix} );
|
die "Error: expected \$opt{suffix} to exist" unless ( exists $opt{suffix} );
|
||||||
|
|
||||||
foreach my $rdb ( @db_desc ) {
|
foreach my $rdb ( @db_desc ) {
|
||||||
$rdb->{target} = "$datadir/$rdb->{src}$opt{suffix}";
|
$rdb->{target} = "$datadir/$rdb->{src}$opt{suffix}";
|
||||||
}
|
}
|
||||||
@ -278,6 +320,10 @@ foreach my $rdb ( @db_desc ) {
|
|||||||
if ( $opt{dryrun} ) {
|
if ( $opt{dryrun} ) {
|
||||||
print "mkdir $tgt_dirpath, 0750\n";
|
print "mkdir $tgt_dirpath, 0750\n";
|
||||||
}
|
}
|
||||||
|
elsif ($opt{method} =~ /^scp\b/) {
|
||||||
|
## assume it's there?
|
||||||
|
## ...
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
mkdir($tgt_dirpath, 0750)
|
mkdir($tgt_dirpath, 0750)
|
||||||
or die "Can't create '$tgt_dirpath': $!\n";
|
or die "Can't create '$tgt_dirpath': $!\n";
|
||||||
@ -320,26 +366,26 @@ else {
|
|||||||
printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet};
|
printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet};
|
||||||
$dbh->do( "FLUSH LOGS" ) if ( $opt{flushlog} );
|
$dbh->do( "FLUSH LOGS" ) if ( $opt{flushlog} );
|
||||||
}
|
}
|
||||||
|
|
||||||
my @failed = ();
|
my @failed = ();
|
||||||
|
|
||||||
foreach my $rdb ( @db_desc ) {
|
foreach my $rdb ( @db_desc ) {
|
||||||
my @files = map { "$datadir/$rdb->{src}/$_" } @{$rdb->{files}};
|
my @files = map { "$datadir/$rdb->{src}/$_" } @{$rdb->{files}};
|
||||||
next unless @files;
|
next unless @files;
|
||||||
eval { copy_files($opt{method}, \@files, $rdb->{target} ); };
|
eval { copy_files($opt{method}, \@files, $rdb->{target} ); };
|
||||||
|
|
||||||
push @failed, "$rdb->{src} -> $rdb->{target} failed: $@"
|
push @failed, "$rdb->{src} -> $rdb->{target} failed: $@"
|
||||||
if ( $@ );
|
if ( $@ );
|
||||||
|
|
||||||
if ( $opt{checkpoint} ) {
|
if ( $opt{checkpoint} ) {
|
||||||
my $msg = ( $@ ) ? "Failed: $@" : "Succeeded";
|
my $msg = ( $@ ) ? "Failed: $@" : "Succeeded";
|
||||||
|
|
||||||
eval {
|
eval {
|
||||||
$dbh->do( qq{ insert into $opt{checkpoint} (src, dest, msg)
|
$dbh->do( qq{ insert into $opt{checkpoint} (src, dest, msg)
|
||||||
VALUES ( '$rdb->{src}', '$rdb->{target}', '$msg' )
|
VALUES ( '$rdb->{src}', '$rdb->{target}', '$msg' )
|
||||||
} );
|
} );
|
||||||
};
|
};
|
||||||
|
|
||||||
if ( $@ ) {
|
if ( $@ ) {
|
||||||
warn "Failed to update checkpoint table: $@\n";
|
warn "Failed to update checkpoint table: $@\n";
|
||||||
}
|
}
|
||||||
@ -410,11 +456,16 @@ sub copy_files {
|
|||||||
my ($method, $files, $target) = @_;
|
my ($method, $files, $target) = @_;
|
||||||
my @cmd;
|
my @cmd;
|
||||||
print "Copying ".@$files." files...\n" unless $opt{quiet};
|
print "Copying ".@$files." files...\n" unless $opt{quiet};
|
||||||
|
|
||||||
if ($method =~ /^s?cp\b/) { # cp or scp with optional flags
|
if ($method =~ /^s?cp\b/) { # cp or scp with optional flags
|
||||||
@cmd = ($method);
|
@cmd = ($method);
|
||||||
# add option to preserve mod time etc of copied files
|
# add option to preserve mod time etc of copied files
|
||||||
# not critical, but nice to have
|
# 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
|
# add files to copy and the destination directory
|
||||||
push @cmd, @$files, $target;
|
push @cmd, @$files, $target;
|
||||||
}
|
}
|
||||||
@ -427,10 +478,13 @@ sub copy_files {
|
|||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## for some reason system fails but backticks works ok for scp...
|
||||||
print "Executing '@cmd'\n" if $opt{debug};
|
print "Executing '@cmd'\n" if $opt{debug};
|
||||||
my $cp_status = system @cmd;
|
my $cp_status = system @cmd;
|
||||||
if ($cp_status != 0) {
|
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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,7 +574,22 @@ locked, and before they are copied.
|
|||||||
|
|
||||||
=item --regexp pattern
|
=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
|
=item -?, --help
|
||||||
|
|
||||||
@ -542,13 +611,25 @@ port to use when connecting to local server
|
|||||||
|
|
||||||
UNIX domain socket 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=#
|
=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
|
=item -q, --quiet
|
||||||
|
|
||||||
@ -575,12 +656,8 @@ Patches adding bug fixes, documentation and new features are welcome.
|
|||||||
|
|
||||||
=head1 TO DO
|
=head1 TO DO
|
||||||
|
|
||||||
Allow a list of tables (or regex) to be given on the command line to
|
Extend the individual table copy to allow multiple subsets of tables
|
||||||
enable a logically-related subset of the tables to be hot-copied
|
to be specified on the command line:
|
||||||
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:
|
|
||||||
|
|
||||||
mysqlhotcopy db newdb t1 t2 /^foo_/ : t3 /^bar_/ : +
|
mysqlhotcopy db newdb t1 t2 /^foo_/ : t3 /^bar_/ : +
|
||||||
|
|
||||||
@ -609,5 +686,6 @@ Tim Bunce
|
|||||||
|
|
||||||
Martin Waite - added checkpoint, flushlog, regexp and dryrun options
|
Martin Waite - added checkpoint, flushlog, regexp and dryrun options
|
||||||
|
|
||||||
Ralph Corderoy - Added synonyms for commands
|
Ralph Corderoy - added synonyms for commands
|
||||||
=cut
|
|
||||||
|
Scott Wiersdorf - added table regex and scp support
|
||||||
|
@ -365,6 +365,25 @@ else
|
|||||||
print " for order_by_big ($small_loop_count:$rows): " .
|
print " for order_by_big ($small_loop_count:$rows): " .
|
||||||
timestr(timediff($end_time, $loop_time),"all") . "\n";
|
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;
|
$loop_time=new Benchmark;
|
||||||
$estimated=$rows=0;
|
$estimated=$rows=0;
|
||||||
for ($i=1 ; $i <= $range_loop_count ; $i++)
|
for ($i=1 ; $i <= $range_loop_count ; $i++)
|
||||||
|
33
sql/log.cc
33
sql/log.cc
@ -171,7 +171,7 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
|||||||
sprintf(buff, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port);
|
sprintf(buff, "%s, Version: %s, started with:\nTcp port: %d Unix socket: %s\n", my_progname,server_version,mysql_port,mysql_unix_port);
|
||||||
#endif
|
#endif
|
||||||
end=strmov(strend(buff),"Time Id Command Argument\n");
|
end=strmov(strend(buff),"Time Id Command Argument\n");
|
||||||
if (my_b_write(&log_file,buff,(uint) (end-buff)) ||
|
if (my_b_write(&log_file, (byte*) buff,(uint) (end-buff)) ||
|
||||||
flush_io_cache(&log_file))
|
flush_io_cache(&log_file))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -188,7 +188,7 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
|||||||
tm_tmp.tm_hour,
|
tm_tmp.tm_hour,
|
||||||
tm_tmp.tm_min,
|
tm_tmp.tm_min,
|
||||||
tm_tmp.tm_sec);
|
tm_tmp.tm_sec);
|
||||||
if (my_b_write(&log_file,buff,(uint) strlen(buff)) ||
|
if (my_b_write(&log_file, (byte*) buff,(uint) strlen(buff)) ||
|
||||||
flush_io_cache(&log_file))
|
flush_io_cache(&log_file))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -212,9 +212,9 @@ void MYSQL_LOG::open(const char *log_name, enum_log_type log_type_arg,
|
|||||||
s.write(&log_file);
|
s.write(&log_file);
|
||||||
flush_io_cache(&log_file);
|
flush_io_cache(&log_file);
|
||||||
pthread_mutex_lock(&LOCK_index);
|
pthread_mutex_lock(&LOCK_index);
|
||||||
error=(my_write(index_file, log_file_name,strlen(log_file_name),
|
error=(my_write(index_file, (byte*) log_file_name, strlen(log_file_name),
|
||||||
MYF(MY_NABP | MY_WME)) ||
|
MYF(MY_NABP | MY_WME)) ||
|
||||||
my_write(index_file, "\n", 1, MYF(MY_NABP | MY_WME)));
|
my_write(index_file, (byte*) "\n", 1, MYF(MY_NABP | MY_WME)));
|
||||||
pthread_mutex_unlock(&LOCK_index);
|
pthread_mutex_unlock(&LOCK_index);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
@ -444,8 +444,8 @@ during log purge for write");
|
|||||||
{
|
{
|
||||||
char* l;
|
char* l;
|
||||||
get_dynamic(&logs_to_keep, (gptr)&l, i);
|
get_dynamic(&logs_to_keep, (gptr)&l, i);
|
||||||
if (my_write(index_file, l, strlen(l), MYF(MY_WME|MY_NABP)) ||
|
if (my_write(index_file, (byte*) l, strlen(l), MYF(MY_WME|MY_NABP)) ||
|
||||||
my_write(index_file, "\n", 1, MYF(MY_WME|MY_NABP)))
|
my_write(index_file, (byte*) "\n", 1, MYF(MY_WME|MY_NABP)))
|
||||||
{
|
{
|
||||||
error = LOG_INFO_FATAL;
|
error = LOG_INFO_FATAL;
|
||||||
goto err;
|
goto err;
|
||||||
@ -571,21 +571,21 @@ void MYSQL_LOG::write(THD *thd,enum enum_server_command command,
|
|||||||
start->tm_hour,
|
start->tm_hour,
|
||||||
start->tm_min,
|
start->tm_min,
|
||||||
start->tm_sec);
|
start->tm_sec);
|
||||||
if (my_b_write(&log_file,buff,16))
|
if (my_b_write(&log_file, (byte*) buff,16))
|
||||||
error=errno;
|
error=errno;
|
||||||
}
|
}
|
||||||
else if (my_b_write(&log_file,"\t\t",2) < 0)
|
else if (my_b_write(&log_file, (byte*) "\t\t",2) < 0)
|
||||||
error=errno;
|
error=errno;
|
||||||
sprintf(buff,"%7ld %-10.10s", id,command_name[(uint) command]);
|
sprintf(buff,"%7ld %-10.10s", id,command_name[(uint) command]);
|
||||||
if (my_b_write(&log_file,buff,strlen(buff)))
|
if (my_b_write(&log_file, (byte*) buff,strlen(buff)))
|
||||||
error=errno;
|
error=errno;
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
if (my_b_write(&log_file," ",1) ||
|
if (my_b_write(&log_file, (byte*) " ",1) ||
|
||||||
my_b_vprintf(&log_file,format,args) == (uint) -1)
|
my_b_vprintf(&log_file,format,args) == (uint) -1)
|
||||||
error=errno;
|
error=errno;
|
||||||
}
|
}
|
||||||
if (my_b_write(&log_file,"\n",1) ||
|
if (my_b_write(&log_file, (byte*) "\n",1) ||
|
||||||
flush_io_cache(&log_file))
|
flush_io_cache(&log_file))
|
||||||
error=errno;
|
error=errno;
|
||||||
if (error && ! write_error)
|
if (error && ! write_error)
|
||||||
@ -711,7 +711,6 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
|||||||
last_time=current_time;
|
last_time=current_time;
|
||||||
struct tm tm_tmp;
|
struct tm tm_tmp;
|
||||||
struct tm *start;
|
struct tm *start;
|
||||||
char buff[32];
|
|
||||||
localtime_r(¤t_time,&tm_tmp);
|
localtime_r(¤t_time,&tm_tmp);
|
||||||
start=&tm_tmp;
|
start=&tm_tmp;
|
||||||
/* Note that my_b_write() assumes it knows the length for this */
|
/* Note that my_b_write() assumes it knows the length for this */
|
||||||
@ -722,7 +721,7 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
|||||||
start->tm_hour,
|
start->tm_hour,
|
||||||
start->tm_min,
|
start->tm_min,
|
||||||
start->tm_sec);
|
start->tm_sec);
|
||||||
if (my_b_write(&log_file,buff,24))
|
if (my_b_write(&log_file, (byte*) buff,24))
|
||||||
error=errno;
|
error=errno;
|
||||||
}
|
}
|
||||||
if (my_b_printf(&log_file, "# User@Host: %s [%s] @ %s [%s]\n",
|
if (my_b_printf(&log_file, "# User@Host: %s [%s] @ %s [%s]\n",
|
||||||
@ -778,8 +777,8 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
|||||||
*end++=';';
|
*end++=';';
|
||||||
*end++='\n';
|
*end++='\n';
|
||||||
*end=0;
|
*end=0;
|
||||||
if (my_b_write(&log_file,"SET ",4) ||
|
if (my_b_write(&log_file, (byte*) "SET ",4) ||
|
||||||
my_b_write(&log_file,buff+1,(uint) (end-buff)-1))
|
my_b_write(&log_file, (byte*) buff+1,(uint) (end-buff)-1))
|
||||||
error=errno;
|
error=errno;
|
||||||
}
|
}
|
||||||
if (!query)
|
if (!query)
|
||||||
@ -787,8 +786,8 @@ void MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
|
|||||||
query="#adminstrator command";
|
query="#adminstrator command";
|
||||||
query_length=21;
|
query_length=21;
|
||||||
}
|
}
|
||||||
if (my_b_write(&log_file,(byte*) query,query_length) ||
|
if (my_b_write(&log_file, (byte*) query,query_length) ||
|
||||||
my_b_write(&log_file,";\n",2) ||
|
my_b_write(&log_file, (byte*) ";\n",2) ||
|
||||||
flush_io_cache(&log_file))
|
flush_io_cache(&log_file))
|
||||||
error=errno;
|
error=errno;
|
||||||
if (error && ! write_error)
|
if (error && ! write_error)
|
||||||
|
@ -363,7 +363,7 @@ public:
|
|||||||
Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id):
|
Stop_log_event(IO_CACHE* file, time_t when_arg, uint32 server_id):
|
||||||
Log_event(when_arg,0,0,server_id)
|
Log_event(when_arg,0,0,server_id)
|
||||||
{
|
{
|
||||||
char skip[4];
|
byte skip[4];
|
||||||
my_b_read(file, skip, sizeof(skip)); // skip the event length
|
my_b_read(file, skip, sizeof(skip)); // skip the event length
|
||||||
}
|
}
|
||||||
Stop_log_event(const char* buf):Log_event(buf)
|
Stop_log_event(const char* buf):Log_event(buf)
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
static void my_aiowait(my_aio_result *result);
|
static void my_aiowait(my_aio_result *result);
|
||||||
#endif
|
#endif
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
@ -233,24 +234,28 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Read buffered. Returns 1 if can't read requested characters */
|
/*
|
||||||
/* Returns 0 if record read */
|
Read buffered. Returns 1 if can't read requested characters
|
||||||
|
This function is only called from the my_b_read() macro
|
||||||
|
when there isn't enough characters in the buffer to
|
||||||
|
satisfy the request.
|
||||||
|
Returns 0 we succeeded in reading all data
|
||||||
|
*/
|
||||||
|
|
||||||
int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
|
int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count)
|
||||||
{
|
{
|
||||||
uint length,diff_length,left_length;
|
uint length,diff_length,left_length;
|
||||||
my_off_t max_length, pos_in_file;
|
my_off_t max_length, pos_in_file;
|
||||||
|
|
||||||
if((left_length=(uint) (info->rc_end-info->rc_pos)))
|
if ((left_length=(uint) (info->rc_end-info->rc_pos)))
|
||||||
{
|
{
|
||||||
if(Count < left_length)
|
dbug_assert(Count >= left_length); /* User is not using my_b_read() */
|
||||||
left_length = Count;
|
memcpy(Buffer,info->rc_pos, (size_t) (left_length));
|
||||||
memcpy(Buffer,info->rc_pos,
|
|
||||||
(size_t) (left_length));
|
|
||||||
Buffer+=left_length;
|
Buffer+=left_length;
|
||||||
Count-=left_length;
|
Count-=left_length;
|
||||||
}
|
}
|
||||||
pos_in_file=info->pos_in_file+ left_length;
|
/* pos_in_file always point on where info->buffer was read */
|
||||||
|
pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
|
||||||
if (info->seek_not_done)
|
if (info->seek_not_done)
|
||||||
{ /* File touched, do seek */
|
{ /* File touched, do seek */
|
||||||
VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
|
VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)));
|
||||||
|
@ -330,12 +330,12 @@ static void dump_local_log_entries(const char* logname)
|
|||||||
if (position)
|
if (position)
|
||||||
{
|
{
|
||||||
/* skip 'position' characters from stdout */
|
/* skip 'position' characters from stdout */
|
||||||
char buff[IO_SIZE];
|
byte buff[IO_SIZE];
|
||||||
my_off_t length,tmp;
|
my_off_t length,tmp;
|
||||||
for (length=position ; length > 0 ; length-=tmp)
|
for (length=position ; length > 0 ; length-=tmp)
|
||||||
{
|
{
|
||||||
tmp=min(length,sizeof(buff));
|
tmp=min(length,sizeof(buff));
|
||||||
if (my_b_read(file,buff,tmp))
|
if (my_b_read(file,buff, (uint) tmp))
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -569,7 +569,6 @@ static sig_handler print_signal_warning(int sig)
|
|||||||
|
|
||||||
void unireg_end(int signal_number __attribute__((unused)))
|
void unireg_end(int signal_number __attribute__((unused)))
|
||||||
{
|
{
|
||||||
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
|
|
||||||
clean_up();
|
clean_up();
|
||||||
pthread_exit(0); // Exit is in main thread
|
pthread_exit(0); // Exit is in main thread
|
||||||
}
|
}
|
||||||
@ -580,7 +579,6 @@ void unireg_abort(int exit_code)
|
|||||||
if (exit_code)
|
if (exit_code)
|
||||||
sql_print_error("Aborting\n");
|
sql_print_error("Aborting\n");
|
||||||
clean_up(); /* purecov: inspected */
|
clean_up(); /* purecov: inspected */
|
||||||
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
|
|
||||||
exit(exit_code); /* purecov: inspected */
|
exit(exit_code); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -610,6 +608,7 @@ void clean_up(void)
|
|||||||
free_defaults(defaults_argv);
|
free_defaults(defaults_argv);
|
||||||
my_free(mysql_tmpdir,MYF(0));
|
my_free(mysql_tmpdir,MYF(0));
|
||||||
x_free(opt_bin_logname);
|
x_free(opt_bin_logname);
|
||||||
|
(void) my_delete(pidfile_name,MYF(0)); // This may not always exist
|
||||||
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
|
||||||
|
|
||||||
/* Tell main we are ready */
|
/* Tell main we are ready */
|
||||||
@ -1520,7 +1519,7 @@ int main(int argc, char **argv)
|
|||||||
sql_print_error("Can't init databases");
|
sql_print_error("Can't init databases");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_MLOCKALL
|
#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
|
||||||
if (locked_in_memory && !geteuid())
|
if (locked_in_memory && !geteuid())
|
||||||
{
|
{
|
||||||
ha_key_cache();
|
ha_key_cache();
|
||||||
|
@ -42,7 +42,7 @@ static int create_table_from_dump(THD* thd, NET* net, const char* db,
|
|||||||
static inline char* rewrite_db(char* db);
|
static inline char* rewrite_db(char* db);
|
||||||
static void free_table_ent(TABLE_RULE_ENT* e)
|
static void free_table_ent(TABLE_RULE_ENT* e)
|
||||||
{
|
{
|
||||||
my_free((byte*)e, MYF(0));
|
my_free((gptr) e, MYF(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
static byte* get_table_key(TABLE_RULE_ENT* e, uint* len,
|
static byte* get_table_key(TABLE_RULE_ENT* e, uint* len,
|
||||||
@ -74,12 +74,12 @@ int tables_ok(THD* thd, TABLE_LIST* tables)
|
|||||||
uint len = strmov(p, tables->real_name) - hash_key ;
|
uint len = strmov(p, tables->real_name) - hash_key ;
|
||||||
if(do_table_inited) // if there are any do's
|
if(do_table_inited) // if there are any do's
|
||||||
{
|
{
|
||||||
if(hash_search(&replicate_do_table, hash_key, len))
|
if(hash_search(&replicate_do_table, (byte*) hash_key, len))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(ignore_table_inited) // if there are any do's
|
if(ignore_table_inited) // if there are any do's
|
||||||
{
|
{
|
||||||
if(hash_search(&replicate_ignore_table, hash_key, len))
|
if(hash_search(&replicate_ignore_table, (byte*) hash_key, len))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1559,7 +1559,7 @@ mysql_execute_command(void)
|
|||||||
/* Check if auto_commit mode changed */
|
/* Check if auto_commit mode changed */
|
||||||
if ((org_options ^ lex->options) & OPTION_AUTO_COMMIT)
|
if ((org_options ^ lex->options) & OPTION_AUTO_COMMIT)
|
||||||
{
|
{
|
||||||
if (!org_options & OPTION_AUTO_COMMIT)
|
if (!(org_options & OPTION_AUTO_COMMIT))
|
||||||
{
|
{
|
||||||
/* We changed to auto_commit mode */
|
/* We changed to auto_commit mode */
|
||||||
thd->options&= ~(ulong) (OPTION_BEGIN);
|
thd->options&= ~(ulong) (OPTION_BEGIN);
|
||||||
|
@ -48,6 +48,7 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
|
|||||||
bool some_tables_deleted=0;
|
bool some_tables_deleted=0;
|
||||||
uint error;
|
uint error;
|
||||||
db_type table_type;
|
db_type table_type;
|
||||||
|
TABLE_LIST *table;
|
||||||
DBUG_ENTER("mysql_rm_table");
|
DBUG_ENTER("mysql_rm_table");
|
||||||
|
|
||||||
/* mark for close and remove all cached entries */
|
/* mark for close and remove all cached entries */
|
||||||
@ -59,22 +60,22 @@ int mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists)
|
|||||||
pthread_mutex_unlock(&thd->mysys_var->mutex);
|
pthread_mutex_unlock(&thd->mysys_var->mutex);
|
||||||
|
|
||||||
if(global_read_lock)
|
if(global_read_lock)
|
||||||
|
{
|
||||||
|
if(thd->global_read_lock)
|
||||||
{
|
{
|
||||||
if(thd->global_read_lock)
|
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
|
||||||
{
|
tables->real_name);
|
||||||
my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE,MYF(0),
|
error = 1;
|
||||||
tables->real_name);
|
goto err;
|
||||||
error = 1;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
while (global_read_lock && ! thd->killed)
|
|
||||||
{
|
|
||||||
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
while (global_read_lock && ! thd->killed)
|
||||||
|
{
|
||||||
|
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (TABLE_LIST *table=tables ; table ; table=table->next)
|
for (table=tables ; table ; table=table->next)
|
||||||
{
|
{
|
||||||
char *db=table->db ? table->db : thd->db;
|
char *db=table->db ? table->db : thd->db;
|
||||||
if (!close_temporary_table(thd, db, table->real_name))
|
if (!close_temporary_table(thd, db, table->real_name))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user