Merge with 4.0

BitKeeper/etc/logging_ok:
  auto-union
BitKeeper/deleted/.del-apply-patch:
  Delete: netware/BUILD/apply-patch
BitKeeper/deleted/.del-save-patch:
  Delete: netware/BUILD/save-patch
BitKeeper/deleted/.del-mini_client.cc~8677895ec8169183:
  Auto merged
BitKeeper/triggers/post-commit:
  Auto merged
VC++Files/mysys/mysys.dsp:
  Auto merged
client/mysqlbinlog.cc:
  Auto merged
extra/resolveip.c:
  Auto merged
include/config-win.h:
  Auto merged
include/my_global.h:
  Auto merged
include/my_sys.h:
  Auto merged
include/mysql_com.h:
  Auto merged
innobase/include/os0thread.h:
  Auto merged
innobase/os/os0file.c:
  Auto merged
innobase/srv/srv0start.c:
  Auto merged
innobase/thr/thr0loc.c:
  Auto merged
libmysql/manager.c:
  Auto merged
libmysqld/Makefile.am:
  Auto merged
libmysqld/lib_sql.cc:
  Auto merged
myisam/ft_boolean_search.c:
  Auto merged
myisam/mi_extra.c:
  Auto merged
myisam/mi_locking.c:
  Auto merged
mysql-test/mysql-test-run.sh:
  Auto merged
mysql-test/r/fulltext.result:
  Auto merged
mysql-test/r/myisam.result:
  Auto merged
mysql-test/r/select.result:
  Auto merged
mysql-test/t/fulltext.test:
  Auto merged
mysql-test/t/myisam.test:
  Auto merged
mysql-test/t/rpl_reset_slave.test:
  Auto merged
mysql-test/t/rpl_trunc_binlog.test:
  Auto merged
mysys/Makefile.am:
  Auto merged
mysys/errors.c:
  Auto merged
mysys/my_symlink.c:
  Auto merged
mysys/my_thr_init.c:
  Auto merged
scripts/mysql_install_db.sh:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/log_event.h:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/slave.cc:
  Auto merged
sql/sql_cache.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_repl.cc:
  Auto merged
sql/sql_test.cc:
  Auto merged
sql/unireg.h:
  Auto merged
client/mysqldump.c:
  merge with 4.0 (quoted names)
configure.in:
  use local file
include/my_pthread.h:
  Use local file
innobase/include/srv0srv.h:
  Use local file
innobase/row/row0sel.c:
  Use local file
innobase/srv/srv0srv.c:
  Use local file
libmysql/libmysql.c:
  Use local file
myisam/myisamchk.c:
  merge fixes
mysql-test/r/func_crypt.result:
  update results
mysql-test/r/order_by.result:
  update results
mysql-test/r/query_cache.result:
  update results
mysql-test/r/range.result:
  update results
mysql-test/r/rpl_reset_slave.result:
  update results
mysql-test/r/rpl_trunc_binlog.result:
  update results
mysql-test/t/func_crypt.test:
  Added disable_warnings/enable warnings
mysql-test/t/query_cache.test:
  merge tests
mysql-test/t/range.test:
  merge tests
mysys/charset.c:
  use local file (will merge patch separately)
sql/ha_innodb.cc:
  use local file
sql/log_event.cc:
  new slave_proxy_id handling
sql/slave.h:
  merge
sql/sql_base.cc:
  merge
sql/sql_parse.cc:
  Fixes for counting user connect resourses
  Added function comments for involved functions
sql/sql_select.cc:
  Fix for not doing sort with LIMIT when OPTION_FOUND_ROWS is used
sql/unireg.cc:
  merge fixes
support-files/mysql.server.sh:
  merge fixes
This commit is contained in:
unknown 2003-11-04 09:40:36 +02:00
commit f97f48acaf
67 changed files with 882 additions and 199 deletions

View File

@ -19,7 +19,7 @@ BK_STATUS=$BK_STATUS$BK_COMMIT
if [ "$BK_STATUS" = OK ]
then
CHANGESET=`bk -R prs -r+ -h -d':I:' ChangeSet`
CHANGESET=`bk -R prs -r+ -h -d':P:::I:' ChangeSet`
#++
# dev-public@

View File

@ -430,6 +430,10 @@ SOURCE=.\my_symlink2.c
# End Source File
# Begin Source File
SOURCE=.\my_sync.c
# End Source File
# Begin Source File
SOURCE=.\my_tempnam.c
# End Source File
# Begin Source File

View File

@ -52,7 +52,7 @@ static const char* host = 0;
static int port = MYSQL_PORT;
static const char* sock= 0;
static const char* user = 0;
static const char* pass = "";
static char* pass = 0;
static ulonglong position = 0;
static short binlog_flags = 0;
static MYSQL* mysql = NULL;
@ -226,7 +226,7 @@ static struct my_option my_long_options[] =
{"offset", 'o', "Skip the first N entries.", (gptr*) &offset, (gptr*) &offset,
0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"password", 'p', "Password to connect to remote server.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
{"port", 'P', "Use port to connect to the remote server.",
(gptr*) &port, (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0,
0, 0, 0},
@ -266,6 +266,11 @@ void sql_print_error(const char *format,...)
va_end(args);
}
static void cleanup()
{
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
}
static void die(const char* fmt, ...)
{
va_list args;
@ -274,6 +279,7 @@ static void die(const char* fmt, ...)
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);
cleanup();
exit(1);
}
@ -333,6 +339,7 @@ extern "C" my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
char *argument)
{
bool tty_password=0;
switch (optid) {
#ifndef DBUG_OFF
case '#':
@ -343,7 +350,17 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
one_database = 1;
break;
case 'p':
pass = my_strdup(argument, MYF(0));
if (argument)
{
my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
char *start=argument;
pass= my_strdup(argument,MYF(MY_FAE));
while (*argument) *argument++= 'x'; /* Destroy argument */
if (*start)
start[1]=0; /* Cut length of argument */
}
else
tty_password=1;
break;
case 'r':
if (!(result_file = my_fopen(argument, O_WRONLY | O_BINARY, MYF(MY_WME))))
@ -359,6 +376,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
usage();
exit(0);
}
if (tty_password)
pass= get_tty_password(NullS);
return 0;
}
@ -707,6 +727,7 @@ int main(int argc, char** argv)
my_fclose(result_file, MYF(0));
if (remote_opt)
mysql_close(mysql);
cleanup();
free_defaults(defaults_argv);
my_end(0);
return 0;

View File

@ -632,6 +632,7 @@ static my_bool test_if_special_chars(const char *str)
} /* test_if_special_chars */
static char *quote_name(const char *name, char *buff, my_bool force)
{
char *to= buff;
@ -789,7 +790,8 @@ static uint getTableStructure(char *table, char* db)
if (verbose)
fprintf(stderr, "-- Retrieving table structure for table %s...\n", table);
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", (opt_quoted || opt_keywords));
sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d",
(opt_quoted || opt_keywords));
result_table= quote_name(table, table_buff, 1);
opt_quoted_table= quote_name(table, table_buff2, 0);
if (!opt_xml && !mysql_query(sock,insert_pat))
@ -1041,7 +1043,8 @@ static uint getTableStructure(char *table, char* db)
else if (keynr == primary_key)
fputs(",\n PRIMARY KEY (",sql_file); /* First UNIQUE is primary */
else
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,0));
fprintf(sql_file, ",\n UNIQUE %s (",quote_name(row[2],name_buff,
0));
}
else
putc(',', sql_file);
@ -1520,23 +1523,28 @@ static int init_dumping(char *database)
{
if (opt_databases || opt_alldbs)
{
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", database);
/*
length of table name * 2 (if name contain quotas), 2 quotas and 0
*/
char quoted_database_buf[64*2+3];
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
fprintf(md_result_file,"\n--\n-- Current Database: %s\n--\n", qdatabase);
if (!opt_create_db)
{
char qbuf[128];
char qbuf[256];
MYSQL_ROW row;
MYSQL_RES *dbinfo;
sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s",database);
sprintf(qbuf,"SHOW CREATE DATABASE WITH IF NOT EXISTS %s",
qdatabase);
if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock)))
{
/* Old server version, dump generic CREATE DATABASE */
fprintf(md_result_file,
"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s%s%s;\n",
(opt_quoted ? "`" : ""),
database,
(opt_quoted ? "`" : ""));
"\nCREATE DATABASE /*!32312 IF NOT EXISTS*/ %s;\n",
qdatabase);
}
else
{
@ -1547,18 +1555,16 @@ static int init_dumping(char *database)
}
}
}
fprintf(md_result_file,"\nUSE %s%s%s;\n", (opt_quoted ? "`" : ""),
database,
(opt_quoted ? "`" : ""));
fprintf(md_result_file,"\nUSE %s;\n", qdatabase);
}
}
if (extended_insert)
if (init_dynamic_string(&extended_row, "", 1024, 1024))
exit(EX_EOM);
if (extended_insert && init_dynamic_string(&extended_row, "", 1024, 1024))
exit(EX_EOM);
return 0;
} /* init_dumping */
static int dump_all_tables_in_db(char *database)
{
char *table;

View File

@ -731,7 +731,7 @@ AC_CHECK_HEADERS(fcntl.h float.h floatingpoint.h ieeefp.h limits.h \
strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \
sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \
unistd.h utime.h sys/utime.h termio.h termios.h sched.h crypt.h alloca.h \
sys/ioctl.h)
sys/ioctl.h malloc.h sys/malloc.h)
#--------------------------------------------------------------------
# Check for system libraries. Adds the library to $LIBS
@ -1832,7 +1832,7 @@ AC_CHECK_FUNCS(alarm bmove \
pthread_attr_create pthread_getsequence_np pthread_attr_setstacksize \
pthread_attr_getstacksize \
pthread_condattr_create rwlock_init pthread_rwlock_rdlock \
fchmod getpass getpassphrase initgroups mlockall)
fsync fdatasync fchmod getpass getpassphrase initgroups mlockall)
CFLAGS="$ORG_CFLAGS"

View File

@ -36,10 +36,6 @@
extern int h_errno;
#endif
#ifndef HAVE_IN_ADDR_T
#define in_addr_t ulong
#endif
static my_bool silent;
static struct my_option my_long_options[] =

View File

@ -183,8 +183,8 @@ inline double rint(double nr)
}
#ifdef _WIN64
#define ulonglong2double(A) ((double) (A))
#define my_off_t2double(A) ((double) (A))
#define ulonglong2double(A) ((double) (ulonglong) (A))
#define my_off_t2double(A) ((double) (my_off_t) (A))
#else
inline double ulonglong2double(ulonglong value)

View File

@ -594,8 +594,8 @@ extern double my_atof(const char*);
#define closesocket(A) close(A)
#endif
#ifndef ulonglong2double
#define ulonglong2double(A) ((double) (A))
#define my_off_t2double(A) ((double) (A))
#define ulonglong2double(A) ((double) (ulonglong) (A))
#define my_off_t2double(A) ((double) (my_off_t) (A))
#endif
#endif

View File

@ -63,6 +63,15 @@ C_MODE_START
#define O_NONBLOCK 1 /* For emulation of fcntl() */
#endif
/*
On OSes which don't have the in_addr_t, we guess that using uint32 is the best
possible choice. We guess this from the fact that on HP-UX64bit & FreeBSD64bit
& Solaris64bit, in_addr_t is equivalent to uint32. And on Linux32bit too.
*/
#ifndef HAVE_IN_ADDR_T
#define in_addr_t uint32
#endif
/* Thread safe or portable version of some functions */
void my_inet_ntoa(struct in_addr in, char *buf);

View File

@ -645,6 +645,7 @@ struct st_my_thread_var
long id;
int cmp_length;
int volatile abort;
my_bool init;
struct st_my_thread_var *next,**prev;
void *opt_info;
#ifndef DBUG_OFF

View File

@ -614,6 +614,7 @@ extern FILE *my_fopen(const char *FileName,int Flags,myf MyFlags);
extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
extern int my_fclose(FILE *fd,myf MyFlags);
extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
extern int my_sync(File fd, myf my_flags);
extern int my_error _VARARGS((int nr,myf MyFlags, ...));
extern int my_printf_error _VARARGS((uint my_err, const char *format,
myf MyFlags, ...)

View File

@ -33,7 +33,7 @@
#if defined(__WIN__) && !defined( _CUSTOMCONFIG_)
#define MYSQL_NAMEDPIPE "MySQL"
#define MYSQL_SERVICENAME "MySql"
#define MYSQL_SERVICENAME "MySQL"
#endif /* __WIN__ */
enum enum_server_command

View File

@ -21,7 +21,7 @@ extern "C" {
#endif
#define GLOB 0 /* Error maps */
#define GLOBERRS 27 /* Max number of error messages in map's */
#define GLOBERRS 28 /* Max number of error messages in map's */
#define EE(X) globerrs[ X ] /* Defines to add error to right map */
extern const char * NEAR globerrs[]; /* my_error_messages is here */
@ -53,6 +53,7 @@ extern const char * NEAR globerrs[]; /* my_error_messages is here */
#define EE_CANT_READLINK 24
#define EE_CANT_SYMLINK 25
#define EE_REALPATH 26
#define EE_SYNC 27
/* exit codes for all MySQL programs */

View File

@ -3095,7 +3095,15 @@ consecutive_loop:
/* Do the i/o with ordinary, synchronous i/o functions: */
if (slot->type == OS_FILE_WRITE) {
if (array == os_aio_write_array) {
if ((total_len % UNIV_PAGE_SIZE != 0)
|| (slot->offset % UNIV_PAGE_SIZE != 0)) {
fprintf(stderr,
"InnoDB: Error: trying a displaced write to %s %lu %lu, len %lu\n",
slot->name, slot->offset_high,
slot->offset, total_len);
ut_a(0);
}
/* Do a 'last millisecond' check that the page end
is sensible; reported page checksum errors from
Linux seem to wipe over the page end */

View File

@ -3287,14 +3287,14 @@ rec_loop:
latest version of the record */
} else if (index == clust_index) {
/* Fetch a previous version of the row if the current
one is not visible in the snapshot; if we have a very
high force recovery level set, we try to avoid crashes
by skipping this lookup */
if (srv_force_recovery < 5
&& !lock_clust_rec_cons_read_sees(rec, index,
&& !lock_clust_rec_cons_read_sees(rec, index,
trx->read_view)) {
err = row_sel_build_prev_vers_for_mysql(

View File

@ -1717,7 +1717,7 @@ srv_init(void)
os_fast_mutex_init(&srv_conc_mutex);
UT_LIST_INIT(srv_conc_queue);
srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
for (i = 0; i < OS_THREAD_MAX_N; i++) {

View File

@ -1164,6 +1164,28 @@ NetWare. */
/* Note that the call srv_boot() also changes the values of
srv_pool_size etc. to the units used by InnoDB internally */
/* Set the maximum number of threads which can wait for a semaphore
inside InnoDB */
#if defined(__WIN__) || defined(__NETWARE__)
/* Create less event semaphores because Win 98/ME had difficulty creating
40000 event semaphores.
Comment from Novell, Inc.: also, these just take a lot of memory on
NetWare. */
srv_max_n_threads = 1000;
#else
if (srv_pool_size >= 8 * 1024 * 1024) {
/* Here we still have srv_pool_size counted
in bytes, srv_boot converts the value to
pages; if buffer pool is less than 8 MB,
assume fewer threads. */
srv_max_n_threads = 10000;
} else {
srv_max_n_threads = 1000; /* saves several MB of memory,
especially in 64-bit
computers */
}
#endif
err = srv_boot();
if (err != DB_SUCCESS) {

View File

@ -250,17 +250,15 @@ int nisam_extra(N_INFO *info, enum ha_extra_function function)
pthread_mutex_unlock(&THR_LOCK_isam);
break;
case HA_EXTRA_FLUSH:
#ifdef __WIN__
if (info->s->not_flushed)
{
info->s->not_flushed=0;
if (_commit(info->s->kfile))
error=errno;
if (_commit(info->dfile))
error=errno;
if (my_sync(info->s->kfile, MYF(0)))
error= my_errno;
if (my_sync(info->dfile, MYF(0)))
error= my_errno;
}
break;
#endif
case HA_EXTRA_NORMAL: /* Theese isn't in use */
case HA_EXTRA_QUICK:
case HA_EXTRA_KEY_CACHE:

View File

@ -90,7 +90,7 @@ MYSQL_MANAGER* STDCALL mysql_manager_connect(MYSQL_MANAGER* con,
{
my_socket sock;
struct sockaddr_in sock_addr;
uint32 ip_addr;
in_addr_t ip_addr;
char msg_buf[MAX_MYSQL_MANAGER_MSG];
int msg_len;
Vio* vio;

View File

@ -92,10 +92,10 @@ libmysqld.a: libmysqld_int.a $(INC_LIB)
ar x $$file; \
for obj in *.o ; do mv $$obj $${bfile}_$$obj ; done ; \
ar q ../libmysqld_int2.a *.o ; \
rm *.o ; \
rm -f *.o ; \
done
mv libmysqld_int2.a libmysqld.a
rm tmp/*
rm -f tmp/*
$(RANLIB) libmysqld.a
## XXX: any time the client interface changes, we'll need to bump

View File

@ -362,7 +362,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
Hack: instead of init_queue, we'll use reinit queue to be able
to alloc queue with alloc_root()
*/
res=ftb->queue.max_elements=1+query_len/(ft_min_word_len+1);
res=ftb->queue.max_elements=1+query_len/(min(ft_min_word_len,2)+1);
ftb->queue.root=(byte **)alloc_root(&ftb->mem_root, (res+1)*sizeof(void*));
reinit_queue(& ftb->queue, res, 0, 0,
(int (*)(void*,byte*,byte*))FTB_WORD_cmp, 0);

View File

@ -336,22 +336,10 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg)
if (share->not_flushed)
{
share->not_flushed=0;
#if defined(__WIN__)
if (_commit(share->kfile))
error=errno;
if (_commit(info->dfile))
error=errno;
#elif defined(HAVE_FDATASYNC)
if (fdatasync(share->kfile))
error=errno;
if (fdatasync(share->dfile))
error=errno;
#elif defined(HAVE_FSYNC)
if ( fsync(share->kfile))
error=errno;
if (fsync(share->dfile))
error=errno;
#endif
if (my_sync(share->kfile, MYF(0)))
error= my_errno;
if (my_sync(info->dfile, MYF(0)))
error= my_errno;
if (error)
{
share->changed=1;

View File

@ -98,22 +98,10 @@ int mi_lock_database(MI_INFO *info, int lock_type)
share->changed=0;
if (myisam_flush)
{
#if defined(__WIN__)
if (_commit(share->kfile))
error=errno;
if (_commit(info->dfile))
error=errno;
#elif defined(HAVE_FDATASYNC)
if (fdatasync(share->kfile))
error=errno;
if (fdatasync(share->dfile))
error=errno;
#elif defined(HAVE_FSYNC)
if (fsync(share->kfile))
error=errno;
if (fsync(share->dfile))
error=errno;
#endif
if (my_sync(share->kfile, MYF(0)))
error= my_errno;
if (my_sync(info->dfile, MYF(0)))
error= my_errno;
}
else
share->not_flushed=1;

View File

@ -411,6 +411,8 @@ static void usage(void)
-q, --quick Faster repair by not modifying the data file.\n\
One can give a second '-q' to force myisamchk to\n\
modify the original datafile in case of duplicate keys.\n\
NOTE: Tables where the data file is currupted can't be\n\
fixed with this option.\n\
-u, --unpack Unpack file packed with myisampack.\n\
");
@ -1109,7 +1111,7 @@ end2:
filename));
if (param->testflag & T_REP_ANY)
VOID(fprintf(stderr,
"Try fixing it by using the --safe-recover (-o) or the --force (-f) option\n"));
"Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag\n"));
}
else if (!(param->error_printed & 2) &&
!(param->testflag & T_FORCE_CREATE))

View File

@ -338,7 +338,13 @@ while test $# -gt 0; do
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb"
;;
--valgrind)
VALGRIND="valgrind --alignment=8 --leak-check=yes --num-callers=16"
VALGRIND=`which valgrind` # this will print an error if not found
# Give good warning to the user and stop
if [ -z "$VALGRIND" ] ; then
$ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://developer.kde.org/~sewardj ."
exit 1
fi
VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16"
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb"
SLEEP_TIME_AFTER_RESTART=10
@ -349,6 +355,9 @@ while test $# -gt 0; do
TMP=`$ECHO "$1" | $SED -e "s;--valgrind-options=;;"`
VALGRIND="$VALGRIND $TMP"
;;
--valgrind-all)
VALGRIND="$VALGRIND -v --show-reachable=yes"
;;
--skip-*)
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT $1"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT $1"
@ -1163,7 +1172,7 @@ run_testcase ()
echo $tname > $CURRENT_TEST
SKIP_SLAVE=`$EXPR \( $tname : rpl \) = 0`
if [ $USE_MANAGER = 1 ] ; then
many_slaves=`$EXPR \( $tname : rpl_failsafe \) != 0`
many_slaves=`$EXPR \( \( $tname : rpl_failsafe \) != 0 \) \| \( \( $tname : rpl_chain_temp_table \) != 0 \)`
fi
if [ -n "$SKIP_TEST" ] ; then

View File

@ -297,6 +297,8 @@ insert into t2 values (3, 1, 'xxbuz');
select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
t1_id name t2_id t1_id name
1 data1 1 1 xxfoo
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
t2_id t1_id name
drop table t1,t2;
SET NAMES latin1;
CREATE TABLE t1 (t text character set utf8 not null, fulltext(t));

View File

@ -1,6 +1,16 @@
drop table if exists t1;
select length(encrypt('foo', 'ff')) <> 0;
length(encrypt('foo', 'ff')) <> 0
1
create table t1 (name varchar(50), pw varchar(16));
insert into t1 values ('tom', password('my_pass'));
set @pass='my_pass';
select name from t1 where name='tom' and pw=password(@pass);
name
tom
select name from t1 where name='tom' and pw=password(@undefined);
name
drop table t1;
select password('abc');
password('abc')
*0D3CED9BEC10A777AEC23CCC353A8C08A633045E

View File

@ -306,17 +306,17 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 9 NULL 8 Using where; Using index
explain select * from t1 where a = 2 and b >0 order by a desc,b desc;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index
1 SIMPLE t1 range a a 9 NULL 4 Using where; Using index
explain select * from t1 where a = 2 and b is null order by a desc,b desc;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 9 const,const 1 Using where; Using index; Using filesort
explain select * from t1 where a = 2 and (b is null or b > 0) order by a
desc,b desc;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 9 NULL 6 Using where; Using index
1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index
explain select * from t1 where a = 2 and b > 0 order by a desc,b desc;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index
1 SIMPLE t1 range a a 9 NULL 4 Using where; Using index
explain select * from t1 where a = 2 and b < 2 order by a desc,b desc;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 9 NULL 2 Using where; Using index

View File

@ -1,8 +1,9 @@
set GLOBAL query_cache_size=1355776;
flush query cache;
flush query cache;
reset query cache;
flush status;
drop table if exists t1,t2,t3;
drop table if exists t1,t2,t3,t4,t11,t21;
drop database if exists mysqltest;
create table t1 (a int not null);
insert into t1 values (1),(2),(3);
@ -722,6 +723,46 @@ Variable_name Value
Qcache_queries_in_cache 2
SET OPTION SQL_SELECT_LIMIT=DEFAULT;
drop table t1;
flush query cache;
reset query cache;
flush status;
set GLOBAL query_cache_size=1048576;
create table t1 (a int not null);
insert into t1 values (1),(2),(3);
create table t2 (a text not null);
create table t3 (a text not null);
insert into t3 values("1111111111111111111111111111111111111111111111111111");
insert into t2 select * from t3;
insert into t3 select * from t2;
insert into t2 select * from t3;
insert into t3 select * from t2;
insert into t2 select * from t3;
insert into t3 select * from t2;
insert into t2 select * from t3;
insert into t3 select * from t2;
insert into t2 select * from t3;
insert into t3 select * from t2;
drop table t2;
create table t2 (a int not null);
insert into t2 values (1),(2),(3);
create table t4 (a int not null);
insert into t4 values (1),(2),(3);
select * from t4;
select * from t2;
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
select * from t2;
select * from t4;
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
select * from t2;
select * from t4;
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
delete from t2 where a=1;
flush query cache;
select * from t3;
delete from t4 where a=1;
flush query cache;
drop table t1,t2,t3,t4;
set GLOBAL query_cache_size=0;
SET NAMES koi8r;
CREATE TABLE t1 (a char(1) character set koi8r);
INSERT INTO t1 VALUES (_koi8r'á'),(_koi8r'Á');

View File

@ -262,6 +262,23 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index
1 SIMPLE t1 ALL i2 NULL NULL NULL 4 Range checked for each record (index map: 0x2)
DROP TABLE t1,t2;
CREATE TABLE t1 (
a int(11) default NULL,
b int(11) default NULL,
KEY a (a),
KEY b (b)
) TYPE=MyISAM;
INSERT INTO t1 VALUES
(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(10,2),
(13,2),(14,2),(15,2),(16,2),(17,3),(17,3),(16,3),(17,3),(19,3),(20,3),
(21,4),(22,5),(23,5),(24,5),(25,5),(26,5),(30,5),(31,5),(32,5),(33,5),
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
table type possible_keys key key_len ref rows Extra
t1 range a,b a 5 NULL 2 Using where
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
a b
DROP TABLE t1;
create table t1 (id int(10) primary key);
insert into t1 values (1),(2),(3),(4),(5),(6),(7),(8),(9);
select id from t1 where id in (2,5,9) ;

View File

@ -0,0 +1,30 @@
slave stop;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
reset master;
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
slave start;
reset master;
change master to master_host='127.0.0.1',master_port=9307, master_user='root';
start slave;
create temporary table t1 (a int);
create temporary table t1 (a int);
show status like 'slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 2
create temporary table t1 (a int);
create temporary table t1 (a int);
show status like 'slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 4
stop slave;
insert into t1 values(1);
create table t2 as select * from t1;
start slave;
show status like 'slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 4
select * from t2;
a
1
drop table t2;

View File

@ -20,3 +20,13 @@ start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 79 slave-relay-bin.000002 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No #
stop slave;
reset slave;
start slave;
create temporary table t1 (a int);
stop slave;
reset slave;
start slave;
show status like 'slave_open_temp_tables';
Variable_name Value
Slave_open_temp_tables 1

View File

@ -8,7 +8,8 @@ stop slave;
flush logs;
reset slave;
start slave;
show slave status;
Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master
# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 4 slave-relay-bin.000002 123 master-bin.000001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 326 None 0 No #
reset master;
show slave status;
Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space
127.0.0.1 root MASTER_PORT 1 master-bin.002 4 slave-relay-bin.002 161 master-bin.001 Yes No 0 Rolling back unfinished transaction (no COMMIT or ROLLBACK) from relay log. Probably cause is that the master died while writing the transaction to it's binary log. 0 79 317

View File

@ -2150,10 +2150,10 @@ a a a
select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1;
a a a
1 1 2
2 2 2
3 3 2
1 1 3
2 2 2
2 2 3
3 3 2
3 3 3
select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
a a a

View File

@ -228,6 +228,12 @@ insert into t2 values (1, 1, 'xxfoo');
insert into t2 values (2, 1, 'xxbar');
insert into t2 values (3, 1, 'xxbuz');
select * from t1 join t2 using(`t1_id`) where match (t1.name, t2.name) against('xxfoo' in boolean mode);
#
# bug with many short (< ft_min_word_len) words in boolean search
#
select * from t2 where match name against ('a* b* c* d* e* f*' in boolean mode);
drop table t1,t2;
#

View File

@ -1,9 +1,21 @@
-- source include/have_crypt.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
select length(encrypt('foo', 'ff')) <> 0;
--replace_result $1$aa$4OSUA5cjdx0RUQ08opV27/ aaqPiZY5xR5l.
create table t1 (name varchar(50), pw varchar(16));
insert into t1 values ('tom', password('my_pass'));
set @pass='my_pass';
select name from t1 where name='tom' and pw=password(@pass);
select name from t1 where name='tom' and pw=password(@undefined);
drop table t1;
# Test new and old password handling functions
select password('abc');
select password('');
select old_password('abc');

View File

@ -1 +0,0 @@
--set-variable=query_cache_size=1355776

View File

@ -3,6 +3,7 @@
#
# Tests with query cache
#
set GLOBAL query_cache_size=1355776;
# Reset query cache variables.
@ -11,7 +12,7 @@ flush query cache; # This crashed in some versions
reset query cache;
flush status;
--disable_warnings
drop table if exists t1,t2,t3;
drop table if exists t1,t2,t3,t4,t11,t21;
drop database if exists mysqltest;
--enable_warnings
@ -489,6 +490,55 @@ show status like "Qcache_queries_in_cache";
SET OPTION SQL_SELECT_LIMIT=DEFAULT;
drop table t1;
#
# query cache crash on using same table twice in one query test
#
flush query cache;
reset query cache;
flush status;
set GLOBAL query_cache_size=1048576;
create table t1 (a int not null);
insert into t1 values (1),(2),(3);
create table t2 (a text not null);
create table t3 (a text not null);
insert into t3 values("1111111111111111111111111111111111111111111111111111");
insert into t2 select * from t3;
insert into t3 select * from t2;
insert into t2 select * from t3;
insert into t3 select * from t2;
insert into t2 select * from t3;
insert into t3 select * from t2;
insert into t2 select * from t3;
insert into t3 select * from t2;
insert into t2 select * from t3;
insert into t3 select * from t2;
drop table t2;
create table t2 (a int not null);
insert into t2 values (1),(2),(3);
create table t4 (a int not null);
insert into t4 values (1),(2),(3);
disable_result_log;
select * from t4;
select * from t2;
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
select * from t2;
select * from t4;
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
select * from t2;
select * from t4;
select * from t1 as tt, t1 as ttt where tt.a=1 and ttt.a=2;
delete from t2 where a=1;
flush query cache;
select * from t3;
enable_result_log;
delete from t4 where a=1;
flush query cache;
drop table t1,t2,t3,t4;
#
# Test character set related variables:
# character_set_result
@ -535,3 +585,4 @@ show status like "Qcache_queries_in_cache";
# Keep things tidy
#
DROP TABLE t1;
SET GLOBAL query_cache_size=0;

View File

@ -306,3 +306,28 @@ select * from t1, t2 where t1.uid=t2.uid AND t1.uid > 0;
select * from t1, t2 where t1.uid=t2.uid AND t1.uid != 0;
drop table t1,t2;
#
# bug #1724: use RANGE on more selective column instead of REF on less
# selective
CREATE TABLE t1 (
a int(11) default NULL,
b int(11) default NULL,
KEY a (a),
KEY b (b)
) TYPE=MyISAM;
INSERT INTO t1 VALUES
(1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,2),(10,2),
(13,2),(14,2),(15,2),(16,2),(17,3),(17,3),(16,3),(17,3),(19,3),(20,3),
(21,4),(22,5),(23,5),(24,5),(25,5),(26,5),(30,5),(31,5),(32,5),(33,5),
(33,5),(33,5),(33,5),(33,5),(34,5),(35,5);
EXPLAIN SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
SELECT * FROM t1 WHERE a IN(1,2) AND b=5;
DROP TABLE t1;
# we expect that optimizer will choose key on A

View File

@ -0,0 +1,99 @@
# This test makes some assumptions about values of thread ids, which should be
# true if the servers have been restarted for this test. So we want to
# stop/restart servers. Note that if assumptions are wrong, the test will not
# fail; it will just fail to test the error-prone scenario.
# Using the manager is the only way to have more than one slave server.
# So you must run this test with --manager.
require_manager;
server_stop master;
server_start master;
server_stop slave;
server_start slave;
# no need for slave_sec (no assumptions on thread ids for this server).
source include/master-slave.inc;
connect (slave_sec,localhost,root,,test,0,slave.sock-1);
connection master;
save_master_pos;
connection slave;
sync_with_master;
reset master;
save_master_pos;
connection slave_sec;
eval change master to master_host='127.0.0.1',master_port=$SLAVE_MYPORT, master_user='root';
start slave;
sync_with_master;
# :P now we have a chain ready-to-test.
connection master;
create temporary table t1 (a int);
save_master_pos;
connection slave;
sync_with_master;
connection master1;
create temporary table t1 (a int);
save_master_pos;
connection slave;
sync_with_master;
save_master_pos;
# First test:
connection slave_sec;
# Before BUG#1686 ("If 2 master threads with same-name temp table, slave makes
# bad binlog") was fixed, sync_with_master failed
sync_with_master;
show status like 'slave_open_temp_tables';
# 'master' and 'master1' usually have thread id 2-3 or 3-4.
# 'slave' and 'slave1' usually have thread id 2-3.
connection slave;
create temporary table t1 (a int);
connection slave1;
create temporary table t1 (a int);
# So it's likely that in the binlog of slave we get
# server_id=of_master thread_id=3 create temp...
# server_id=of_slave thread_id=3 create temp...
# which would confuse slave-sec unless slave-sec uses server id to distinguish
# between temp tables (here thread id is obviously not enough to distinguish).
save_master_pos;
# Second test:
connection slave_sec;
# If we did not use the server id to distinguish between temp tables,
# sync_with_master would fail
sync_with_master;
show status like 'slave_open_temp_tables';
# Third test (BUG#1240 "slave of slave breaks when STOP SLAVE was issud on
# parent slave and temp tables").
stop slave;
connection slave;
insert into t1 values(1);
create table t2 as select * from t1;
save_master_pos;
connection slave_sec;
start slave;
sync_with_master;
show status like 'slave_open_temp_tables';
select * from t2;
# clean up
connection slave;
drop table t2;
save_master_pos;
connection slave_sec;
sync_with_master;
# On purpose, we don't delete the temporary tables explicitely.
# So temp tables remain on slave (remember they are not deleted when the slave
# SQL thread terminates). If you run this test with
# --valgrind --valgrind-options=--show-reachable=yes
# you will see if they get cleaned up at slave's shutdown (that is, if the
# memory they use is freed (it should) by mysqld before it terminates).
# If they wouldn't be cleaned up, you would see some "still reachable" blocks in
# Valgrind.

View File

@ -2,6 +2,8 @@
# --master-* options from mysqld, as this is what is going to be used next time
# slave threads will be started). In bug 985, it displayed old values (of before
# RESET SLAVE).
# See if slave crashes when doing a CREATE TEMPORARY TABLE twice, separated by
# RESET SLAVE.
source include/master-slave.inc;
connection master;
@ -28,3 +30,19 @@ sync_with_master;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 33 #
show slave status;
# test of crash with temp tables & RESET SLAVE
# (test to see if RESET SLAVE clears temp tables in memory and disk)
stop slave;
reset slave;
start slave;
connection master;
create temporary table t1 (a int);
save_master_pos;
connection slave;
sync_with_master;
stop slave;
reset slave;
start slave;
sync_with_master;
show status like 'slave_open_temp_tables';

View File

@ -23,5 +23,3 @@ sleep 3;
--replace_result $MASTER_MYPORT MASTER_PORT
--replace_column 1 # 33 #
show slave status;
connection master;
reset master;

View File

@ -47,7 +47,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c\
my_delete.c my_rename.c my_redel.c my_tempnam.c \
my_chsize.c my_lread.c my_lwrite.c my_clock.c \
my_quick.c my_lockmem.c my_static.c \
my_getopt.c my_mkdir.c \
my_sync.c my_getopt.c my_mkdir.c \
default.c my_compress.c checksum.c raid.cc \
my_net.c my_semaphore.c my_port.c my_sleep.c \
charset.c charset-def.c my_bitmap.c my_bit.c md5.c \

View File

@ -48,6 +48,7 @@ const char * NEAR globerrs[GLOBERRS]=
"Can't read value for symlink '%s' (Error %d)",
"Can't create symlink '%s' pointing at '%s' (Error %d)",
"Error on realpath() on '%s' (Error %d)",
"Can't sync file '%s' to disk (Errcode: %d)",
};
void init_glob_errs(void)
@ -84,8 +85,9 @@ void init_glob_errs()
EE(EE_CANT_MKDIR) ="Can't create directory '%s' (Errcode: %d)";
EE(EE_UNKNOWN_CHARSET)= "Character set '%s' is not a compiled character set and is not specified in the %s file";
EE(EE_OUT_OF_FILERESOURCES)="Out of resources when opening file '%s' (Errcode: %d)";
EE(EE_CANT_READLINK)="Can't read value for symlink '%s' (Error %d)";
EE(EE_CANT_SYMLINK)="Can't create symlink '%s' pointing at '%s' (Error %d)";
EE(EE_REALPATH)="Error on realpath() on '%s' (Error %d)";
EE(EE_CANT_READLINK)= "Can't read value for symlink '%s' (Error %d)";
EE(EE_CANT_SYMLINK)= "Can't create symlink '%s' pointing at '%s' (Error %d)";
EE(EE_REALPATH)= "Error on realpath() on '%s' (Error %d)";
EE(EE_SYNC)= "Can't sync file '%s' to disk (Errcode: %d)";
}
#endif

View File

@ -25,12 +25,12 @@
void *operator new (size_t sz)
{
return (void *) malloc (sz ? sz+1 : sz);
return (void *) malloc (sz ? sz : 1);
}
void *operator new[] (size_t sz)
{
return (void *) malloc (sz ? sz+1 : sz);
return (void *) malloc (sz ? sz : 1);
}
void operator delete (void *ptr)

60
mysys/my_sync.c Normal file
View File

@ -0,0 +1,60 @@
/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysys_priv.h"
#include "mysys_err.h"
#include <errno.h>
/*
Sync data in file to disk
SYNOPSIS
my_sync()
fd File descritor to sync
my_flags Flags (now only MY_WME is supported)
NOTE
If file system supports its, only file data is synced, not inode date
RETURN
0 ok
-1 error
*/
int my_sync(File fd, myf my_flags)
{
int res;
DBUG_ENTER("my_sync");
DBUG_PRINT("my",("Fd: %d my_flags: %d", fd, my_flags));
#if defined(HAVE_FDATASYNC)
res= fdatasync(fd);
#elif defined(HAVE_FSYNC)
res=fsync(fd);
#elif defined(__WIN__)
res= _commit(fd);
#else
res= 0; /* No sync (strange OS) */
#endif
if (res)
{
if (!(my_errno= errno))
my_errno= -1; /* Unknown error */
if (my_flags & MY_WME)
my_error(EE_SYNC, MYF(ME_BELL+ME_WAITTANG), my_filename(fd), my_errno);
}
DBUG_RETURN(res);
} /* my_read */

View File

@ -159,6 +159,7 @@ my_bool my_thread_init(void)
tmp->id= ++thread_id;
pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST);
pthread_cond_init(&tmp->suspend, NULL);
tmp->init= 1;
end:
#if !defined(__WIN__) || defined(USE_TLS) || ! defined(SAFE_MUTEX)
@ -170,12 +171,14 @@ end:
void my_thread_end(void)
{
struct st_my_thread_var *tmp=my_thread_var;
struct st_my_thread_var *tmp;
tmp= my_pthread_getspecific(struct st_my_thread_var*,THR_KEY_mysys);
#ifdef EXTRA_DEBUG_THREADS
fprintf(stderr,"my_thread_end(): tmp=%p,thread_id=%ld\n",
tmp,pthread_self());
#endif
if (tmp)
if (tmp && tmp->init)
{
#if !defined(DBUG_OFF)
/* tmp->dbug is allocated inside DBUG library */
@ -191,6 +194,8 @@ void my_thread_end(void)
pthread_mutex_destroy(&tmp->mutex);
#if (!defined(__WIN__) && !defined(OS2)) || defined(USE_TLS)
free(tmp);
#else
tmp->init= 0;
#endif
}
/* The following free has to be done, even if my_thread_var() is 0 */

View File

@ -714,6 +714,9 @@ void thr_alarm_info(ALARM_INFO *info)
bzero((char*) info, sizeof(*info));
}
void resize_thr_alarm(uint max_alarms)
{
}
/*****************************************************************************
thr_alarm for win95
@ -793,6 +796,10 @@ void thr_alarm_info(ALARM_INFO *info)
bzero((char*) info, sizeof(*info));
}
void resize_thr_alarm(uint max_alarms)
{
}
#endif /* __WIN__ */
#endif /* THREAD */

View File

@ -167,7 +167,7 @@ then
fi
fi
if test "$ip_only" ="1"
if test "$ip_only" = "1"
then
ip=`echo "$resolved" | awk '/ /{print $6}'`
hostname=$ip

View File

@ -85,9 +85,13 @@ set_root_password() {
return 1
fi
do_query "SET PASSWORD FOR root=PASSWORD('$password1');"
do_query "UPDATE mysql.user SET Password=PASSWORD('$password1') WHERE User='root';"
if [ $? -eq 0 ]; then
echo "Password updated successfully!"
echo "Reloading privilege tables.."
if ! reload_privilege_tables; then
exit 1
fi
echo
rootpass=$password1
make_config
@ -144,11 +148,11 @@ reload_privilege_tables() {
do_query "FLUSH PRIVILEGES;"
if [ $? -eq 0 ]; then
echo " ... Success!"
return 0
else
echo " ... Failed!"
return 1
fi
return 0
}
interrupt() {

View File

@ -37,7 +37,7 @@ WARNING: THIS PROGRAM IS STILL IN BETA. Comments/patches welcome.
# Documentation continued at end of file
my $VERSION = "1.19";
my $VERSION = "1.20";
my $opt_tmpdir = $ENV{TMPDIR} || "/tmp";
@ -235,10 +235,15 @@ else
# --- resolve database names from regexp ---
if ( defined $opt{regexp} ) {
my $t_regex = '.*';
if ( $opt{regexp} =~ s{^/(.+)/\./(.+)/$}{$1} ) {
$t_regex = $2;
}
my $sth_dbs = $dbh->prepare("show databases");
$sth_dbs->execute;
while ( my ($db_name) = $sth_dbs->fetchrow_array ) {
push @db_desc, { 'src' => $db_name } if ( $db_name =~ m/$opt{regexp}/o );
push @db_desc, { 'src' => $db_name, 't_regex' => $t_regex } if ( $db_name =~ m/$opt{regexp}/o );
}
}
@ -413,6 +418,8 @@ foreach my $rdb ( @db_desc ) {
else {
mkdir($tgt_dirpath, 0750) or die "Can't create '$tgt_dirpath': $!\n"
unless -d $tgt_dirpath;
my @f_info= stat "$datadir/$rdb->{src}";
chown $f_info[4], $f_info[5], $tgt_dirpath;
}
}
}
@ -938,6 +945,14 @@ server in a mutual replication setup.
Copy all databases with names matching the pattern
=item --regexp /pattern1/./pattern2/
Copy all tables with names matching pattern2 from all databases with
names matching pattern1. For example, to select all tables which
names begin with 'bar' from all databases which names end with 'foo':
mysqlhotcopy --indices --method=cp --regexp /foo$/./^bar/
=item db_name./pattern/
Copy only tables matching pattern. Shell metacharacters ( (, ), |, !,

View File

@ -2571,7 +2571,7 @@ err:
bool Item_func_get_user_var::const_item() const
{
return var_entry && current_thd->query_id != var_entry->update_query_id;
return (!var_entry || current_thd->query_id != var_entry->update_query_id);
}

View File

@ -768,11 +768,49 @@ int Query_log_event::write(IO_CACHE* file)
int Query_log_event::write_data(IO_CACHE* file)
{
char buf[QUERY_HEADER_LEN];
if (!query)
return -1;
char buf[QUERY_HEADER_LEN];
int4store(buf + Q_THREAD_ID_OFFSET, thread_id);
/*
We want to store the thread id:
(- as an information for the user when he reads the binlog)
- if the query uses temporary table: for the slave SQL thread to know to
which master connection the temp table belongs.
Now imagine we (write_data()) are called by the slave SQL thread (we are
logging a query executed by this thread; the slave runs with
--log-slave-updates). Then this query will be logged with
thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
the same name were created simultaneously on the master (in the master
binlog you have
CREATE TEMPORARY TABLE t; (thread 1)
CREATE TEMPORARY TABLE t; (thread 2)
...)
then in the slave's binlog there will be
CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
which is bad (same thread id!).
To avoid this, we log the thread's thread id EXCEPT for the SQL
slave thread for which we log the original (master's) thread id.
Now this moves the bug: what happens if the thread id on the
master was 10 and when the slave replicates the query, a
connection number 10 is opened by a normal client on the slave,
and updates a temp table of the same name? We get a problem
again. To avoid this, in the handling of temp tables (sql_base.cc)
we use thread_id AND server_id. TODO when this is merged into
4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
and is a session variable: that's to make mysqlbinlog work with
temp tables. We probably need to introduce
SET PSEUDO_SERVER_ID
for mysqlbinlog in 4.1. mysqlbinlog would print:
SET PSEUDO_SERVER_ID=
SET PSEUDO_THREAD_ID=
for each query using temp tables.
*/
int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
buf[Q_DB_LEN_OFFSET] = (char) db_len;
int2store(buf + Q_ERR_CODE_OFFSET, error_code);
@ -790,12 +828,14 @@ int Query_log_event::write_data(IO_CACHE* file)
#ifndef MYSQL_CLIENT
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
ulong query_length, bool using_trans)
:Log_event(thd_arg, !thd_arg->tmp_table_used ?
0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans),
:Log_event(thd_arg, !thd_arg->tmp_table_used ?
0 : LOG_EVENT_THREAD_SPECIFIC_F, using_trans),
data_buf(0), query(query_arg),
db(thd_arg->db), q_len((uint32) query_length),
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
thread_id(thd_arg->thread_id)
error_code(thd_arg->killed ? ER_SERVER_SHUTDOWN: thd_arg->net.last_errno),
thread_id(thd_arg->thread_id),
/* save the original thread id; we already know the server id */
slave_proxy_id(thd_arg->slave_proxy_id)
{
time_t end_time;
time(&end_time);
@ -836,7 +876,7 @@ Query_log_event::Query_log_event(const char* buf, int event_len,
return;
memcpy(data_buf, buf + Q_DATA_OFFSET, data_len);
thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
slave_proxy_id= thread_id= uint4korr(buf + Q_THREAD_ID_OFFSET);
db = data_buf;
db_len = (uint)buf[Q_DB_LEN_OFFSET];
query=data_buf + db_len + 1;
@ -907,8 +947,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli)
{
thd->set_time((time_t)when);
thd->query_length= q_len;
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = (char*)query;
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id = query_id++;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thd->query_error= 0; // clear error
@ -1276,7 +1316,7 @@ void Load_log_event::pack_info(Protocol *protocol)
int Load_log_event::write_data_header(IO_CACHE* file)
{
char buf[LOAD_HEADER_LEN];
int4store(buf + L_THREAD_ID_OFFSET, thread_id);
int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
@ -1317,7 +1357,9 @@ Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
enum enum_duplicates handle_dup,
bool using_trans)
:Log_event(thd_arg, 0, using_trans), thread_id(thd_arg->thread_id),
num_fields(0), fields(0), field_lens(0),field_block_len(0),
slave_proxy_id(thd_arg->slave_proxy_id),
num_fields(0),fields(0),
field_lens(0),field_block_len(0),
table_name(table_name_arg ? table_name_arg : ""),
db(db_arg), fname(ex->file_name)
{
@ -1422,7 +1464,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
char* buf_end = (char*)buf + event_len;
uint header_len= old_format ? OLD_HEADER_LEN : LOG_EVENT_HEADER_LEN;
const char* data_head = buf + header_len;
thread_id = uint4korr(data_head + L_THREAD_ID_OFFSET);
slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];

View File

@ -455,6 +455,13 @@ public:
uint32 db_len;
uint16 error_code;
ulong thread_id;
/*
For events created by Query_log_event::exec_event (and
Load_log_event::exec_event()) we need the *original* thread id, to be able
to log the event with the original (=master's) thread id (fix for
BUG#1686).
*/
ulong slave_proxy_id;
#ifndef MYSQL_CLIENT
Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
@ -543,6 +550,7 @@ protected:
public:
ulong thread_id;
ulong slave_proxy_id;
uint32 table_name_len;
uint32 db_len;
uint32 fname_len;

View File

@ -1985,7 +1985,7 @@ extern "C" pthread_handler_decl(handle_shutdown,arg)
#endif
const char *load_default_groups[]= { "mysqld","server",MYSQL_BASE_VERSION,0 };
const char *load_default_groups[]= { "mysqld","server",MYSQL_BASE_VERSION,0,0};
bool open_log(MYSQL_LOG *log, const char *hostname,
const char *opt_name, const char *extension,
@ -2733,7 +2733,7 @@ default_service_handling(char **argv,
const char *extra_opt)
{
char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
end= path_and_service + sizeof(path_and_service)-1;
end= path_and_service + sizeof(path_and_service)-3;
/* We have to quote filename if it contains spaces */
pos= add_quoted_string(path_and_service, file_path, end);
@ -2743,7 +2743,9 @@ default_service_handling(char **argv,
*pos++= ' ';
pos= add_quoted_string(pos, extra_opt, end);
}
*pos= 0; // Ensure end null
/* We must have servicename last */
*pos++= ' ';
strmake(pos, servicename, (uint) (end+2 - pos));
if (Service.got_service_option(argv, "install"))
{
@ -2786,10 +2788,16 @@ int main(int argc, char **argv)
if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
file_path, ""))
return 0;
if (Service.IsService(argv[1]))
if (Service.IsService(argv[1])) /* Start an optional service */
{
/* start an optional service */
load_default_groups[0]= argv[1];
/*
Only add the service name to the groups read from the config file
if it's not "MySQL". (The default service name should be 'mysqld'
but we started a bad tradition by calling it MySQL from the start
and we are now stuck with it.
*/
if (my_strcasecmp(argv[1],"mysql"))
load_default_groups[3]= argv[1];
start_mode= 1;
Service.Init(argv[1], mysql_service);
return 0;
@ -2797,8 +2805,7 @@ int main(int argc, char **argv)
}
else if (argc == 3) /* install or remove any optional service */
{
if (!default_service_handling(argv, argv[2], argv[2], file_path,
argv[2]))
if (!default_service_handling(argv, argv[2], argv[2], file_path, ""))
return 0;
if (Service.IsService(argv[2]))
{
@ -2810,6 +2817,8 @@ int main(int argc, char **argv)
opt_argc= 2; // Skip service-name
opt_argv=argv;
start_mode= 1;
if (my_strcasecmp(argv[2],"mysql"))
load_default_groups[3]= argv[2];
Service.Init(argv[2], mysql_service);
return 0;
}

View File

@ -355,6 +355,22 @@ void init_slave_skip_errors(const char* arg)
}
}
void st_relay_log_info::close_temporary_tables()
{
TABLE *table,*next;
for (table=save_temporary_tables ; table ; table=next)
{
next=table->next;
/*
Don't ask for disk deletion. For now, anyway they will be deleted when
slave restarts, but it is a better intention to not delete them.
*/
close_temporary(table, 0);
}
save_temporary_tables= 0;
slave_open_temp_tables= 0;
}
/*
purge_relay_logs()
@ -847,6 +863,7 @@ static int end_slave_on_walk(MASTER_INFO* mi, gptr /*unused*/)
void end_slave()
{
/* This is called when the server terminates, in close_connections(). */
if (active_mi)
{
/*
@ -1428,7 +1445,7 @@ file '%s', errno %d)", fname, my_errno);
if (init_relay_log_pos(rli,NullS,BIN_LOG_HEADER_SIZE,0 /* no data lock */,
&msg))
{
sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4");
sql_print_error("Failed to open the relay log 'FIRST' (relay_log_pos 4)");
goto err;
}
rli->group_master_log_name[0]= 0;
@ -3166,8 +3183,6 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
RPL_LOG_NAME, llstr(rli->group_master_log_pos,llbuff));
err:
/* Free temporary tables etc */
thd->cleanup();
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query = thd->db = 0; // extra safety
VOID(pthread_mutex_unlock(&LOCK_thread_count));
@ -3585,6 +3600,12 @@ void end_relay_log_info(RELAY_LOG_INFO* rli)
}
rli->inited = 0;
rli->relay_log.close(LOG_CLOSE_INDEX | LOG_CLOSE_STOP_EVENT);
/*
Delete the slave's temporary tables from memory.
In the future there will be other actions than this, to ensure persistance
of slave's temp tables after shutdown.
*/
rli->close_temporary_tables();
DBUG_VOID_RETURN;
}

View File

@ -320,10 +320,10 @@ typedef struct st_relay_log_info
int wait_for_pos(THD* thd, String* log_name, longlong log_pos,
longlong timeout);
void close_temporary_tables();
/* Check if UNTIL condition is satisfied. See slave.cc for more. */
bool is_until_satisfied();
} RELAY_LOG_INFO;

View File

@ -575,6 +575,8 @@ TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name)
uint key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
TABLE *table,**prev;
int4store(key+key_length,thd->server_id);
key_length += 4;
int4store(key+key_length,thd->variables.pseudo_thread_id);
key_length += 4;
@ -603,18 +605,27 @@ bool close_temporary_table(THD *thd, const char *db, const char *table_name)
return 0;
}
/*
Used by ALTER TABLE when the table is a temporary one. It changes something
only if the ALTER contained a RENAME clause (otherwise, table_name is the old
name).
Prepares a table cache key, which is the concatenation of db, table_name and
thd->slave_proxy_id, separated by '\0'.
*/
bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
const char *table_name)
{
char *key;
if (!(key=(char*) alloc_root(&table->mem_root,
(uint) strlen(db)+
(uint) strlen(table_name)+6)))
(uint) strlen(table_name)+6+4)))
return 1; /* purecov: inspected */
table->key_length=(uint)
(strmov((table->real_name=strmov(table->table_cache_key=key,
db)+1),
table_name) - table->table_cache_key)+1;
int4store(key+table->key_length,thd->server_id);
table->key_length += 4;
int4store(key+table->key_length,thd->variables.pseudo_thread_id);
table->key_length += 4;
return 0;
@ -771,12 +782,13 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
if (thd->killed)
DBUG_RETURN(0);
key_length= (uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
int4store(key + key_length, thd->variables.pseudo_thread_id);
int4store(key + key_length, thd->server_id);
int4store(key + key_length + 4, thd->variables.pseudo_thread_id);
for (table=thd->temporary_tables; table ; table=table->next)
{
if (table->key_length == key_length+4 &&
!memcmp(table->table_cache_key,key,key_length+4))
if (table->key_length == key_length+8 &&
!memcmp(table->table_cache_key,key,key_length+8))
{
if (table->query_id == thd->query_id)
{
@ -1671,7 +1683,7 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
total of 6 extra bytes in my_malloc in addition to table/db stuff
*/
if (!(tmp_table=(TABLE*) my_malloc(sizeof(*tmp_table)+(uint) strlen(db)+
(uint) strlen(table_name)+6,
(uint) strlen(table_name)+6+4,
MYF(MY_WME))))
DBUG_RETURN(0); /* purecov: inspected */
@ -1693,6 +1705,9 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
strmov(tmp_table->table_cache_key,db)
+1), table_name)
- tmp_table->table_cache_key)+1;
int4store(tmp_table->table_cache_key + tmp_table->key_length,
thd->server_id);
tmp_table->key_length += 4;
int4store(tmp_table->table_cache_key + tmp_table->key_length,
thd->variables.pseudo_thread_id);
tmp_table->key_length += 4;

View File

@ -2761,11 +2761,33 @@ my_bool Query_cache::move_by_type(byte **border,
relink(block, new_block, next, prev, pnext, pprev);
if (queries_blocks == block)
queries_blocks = new_block;
Query_cache_block_table *beg_of_table_table= block->table(0),
*end_of_table_table= block->table(n_tables);
byte *beg_of_new_table_table= (byte*) new_block->table(0);
for (TABLE_COUNTER_TYPE j=0; j < n_tables; j++)
{
Query_cache_block_table *block_table = new_block->table(j);
block_table->next->prev = block_table;
block_table->prev->next = block_table;
// use aligment from begining of table if 'next' is in same block
if ((beg_of_table_table <= block_table->next) &&
(block_table->next < end_of_table_table))
((Query_cache_block_table *)(beg_of_new_table_table +
(((byte*)block_table->next) -
((byte*)beg_of_table_table))))->prev=
block_table;
else
block_table->next->prev= block_table;
// use aligment from begining of table if 'prev' is in same block
if ((beg_of_table_table <= block_table->prev) &&
(block_table->prev < end_of_table_table))
((Query_cache_block_table *)(beg_of_new_table_table +
(((byte*)block_table->prev) -
((byte*)beg_of_table_table))))->next=
block_table;
else
block_table->prev->next = block_table;
}
DBUG_PRINT("qcache", ("after circle tt"));
*border += len;

View File

@ -396,6 +396,11 @@ bool THD::store_globals()
return 1;
mysys_var=my_thread_var;
dbug_thread_id=my_thread_id();
/*
By default 'slave_proxy_id' is 'thread_id'. They may later become different
if this is the slave SQL thread.
*/
slave_proxy_id= thread_id;
return 0;
}

View File

@ -481,7 +481,11 @@ public:
char priv_host[MAX_HOSTNAME];
/* remote (peer) port */
uint16 peer_port;
/* Points to info-string that will show in SHOW PROCESSLIST */
/*
Points to info-string that we show in SHOW PROCESSLIST
You are supposed to update thd->proc_info only if you have coded
a time-consuming piece that MySQL can get stuck in for a long time.
*/
const char *proc_info;
/* points to host if host is available, otherwise points to ip */
const char *host_or_ip;
@ -510,6 +514,11 @@ public:
enum enum_server_command command;
uint32 server_id;
uint32 file_id; // for LOAD DATA INFILE
/*
Used in error messages to tell user in what part of MySQL we found an
error. E. g. when where= "having clause", if fix_fields() fails, user
will know that the error was in having clause.
*/
const char *where;
time_t start_time,time_after_lock,user_time;
time_t connect_time,thr_create_time; // track down slow pthread_create

View File

@ -172,6 +172,7 @@ static int get_or_create_user_conn(THD *thd, const char *user,
}
}
thd->user_connect=uc;
uc->connections++;
end:
(void) pthread_mutex_unlock(&LOCK_user_conn);
return return_val;
@ -314,14 +315,15 @@ int check_user(THD *thd, enum enum_server_command command,
thd->db_access=0;
/* Don't allow user to connect if he has done too many queries */
if ((ur.questions || ur.updates ||
ur.connections || max_user_connections) &&
get_or_create_user_conn(thd,thd->user,thd->host_or_ip,&ur))
DBUG_RETURN(-1);
if (thd->user_connect && (thd->user_connect->user_resources.connections ||
max_user_connections) &&
check_for_max_user_connections(thd, thd->user_connect))
DBUG_RETURN(-1);
if ((ur.questions || ur.updates || ur.connections ||
max_user_connections) &&
get_or_create_user_conn(thd,thd->user,thd->host_or_ip,&ur))
DBUG_RETURN(-1);
if (thd->user_connect &&
(thd->user_connect->user_resources.connections ||
max_user_connections) &&
check_for_max_user_connections(thd, thd->user_connect))
DBUG_RETURN(-1);
/* Change database if necessary: OK or FAIL is sent in mysql_change_db */
if (db && db[0])
@ -386,42 +388,84 @@ void init_max_user_conn(void)
}
/*
check if user has already too many connections
SYNOPSIS
check_for_max_user_connections()
thd Thread handle
uc User connect object
NOTES
If check fails, we decrease user connection count, which means one
shouldn't call decrease_user_connections() after this function.
RETURN
0 ok
1 error
*/
static int check_for_max_user_connections(THD *thd, USER_CONN *uc)
{
int error=0;
DBUG_ENTER("check_for_max_user_connections");
(void) pthread_mutex_lock(&LOCK_user_conn);
if (max_user_connections &&
(max_user_connections < (uint) uc->connections))
max_user_connections < (uint) uc->connections)
{
net_printf(thd,ER_TOO_MANY_USER_CONNECTIONS, uc->user);
error=1;
goto end;
}
uc->connections++;
if (uc->user_resources.connections &&
uc->conn_per_hour++ >= uc->user_resources.connections)
uc->user_resources.connections <= uc->conn_per_hour)
{
net_printf(thd, ER_USER_LIMIT_REACHED, uc->user,
"max_connections",
(long) uc->user_resources.connections);
error=1;
goto end;
}
end:
uc->conn_per_hour++;
end:
if (error)
uc->connections--; // no need for decrease_user_connections() here
(void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_RETURN(error);
}
/*
Decrease user connection count
SYNOPSIS
decrease_user_connections()
uc User connection object
NOTES
If there is a n user connection object for a connection
(which only happens if 'max_user_connections' is defined or
if someone has created a resource grant for a user), then
the connection count is always incremented on connect.
The user connect object is not freed if some users has
'max connections per hour' defined as we need to be able to hold
count over the lifetime of the connection.
*/
static void decrease_user_connections(USER_CONN *uc)
{
DBUG_ENTER("decrease_user_connections");
if ((uc->connections && !--uc->connections) && !mqh_used)
(void) pthread_mutex_lock(&LOCK_user_conn);
DBUG_ASSERT(uc->connections);
if (!--uc->connections && !mqh_used)
{
/* Last connection for user; Delete it */
(void) pthread_mutex_lock(&LOCK_user_conn);
(void) hash_delete(&hash_user_connections,(byte*) uc);
(void) pthread_mutex_unlock(&LOCK_user_conn);
}
(void) pthread_mutex_unlock(&LOCK_user_conn);
DBUG_VOID_RETURN;
}
@ -1227,15 +1271,17 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char *save_user= thd->user;
char *save_priv_user= thd->priv_user;
char *save_db= thd->db;
USER_CONN *save_uc= thd->user_connect;
thd->user= my_strdup(user, MYF(0));
if (!thd->user)
USER_CONN *save_user_connect= thd->user_connect;
if (!(thd->user= my_strdup(user, MYF(0))))
{
thd->user= save_user;
send_error(thd, ER_OUT_OF_RESOURCES);
break;
}
/* Clear variables that are allocated */
thd->user_connect= 0;
int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, false);
if (res)
@ -1246,6 +1292,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
x_free(thd->user);
thd->user= save_user;
thd->priv_user= save_priv_user;
thd->user_connect= save_user_connect;
thd->master_access= save_master_access;
thd->db_access= save_db_access;
thd->db= save_db;
@ -1254,8 +1301,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
else
{
/* we've authenticated new user */
if (max_connections && save_uc)
decrease_user_connections(save_uc);
if (save_user_connect)
decrease_user_connections(save_user_connect);
x_free((gptr) save_db);
x_free((gptr) save_user);
}

View File

@ -1453,10 +1453,21 @@ JOIN::exec()
{
DBUG_VOID_RETURN;
}
/*
Here we sort rows for ORDER BY/GROUP BY clause, if the optimiser
chose FILESORT to be faster than INDEX SCAN or there is no
suitable index present.
Note, that create_sort_index calls test_if_skip_sort_order and may
finally replace sorting with index scan if there is a LIMIT clause in
the query. XXX: it's never shown in EXPLAIN!
OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
*/
if (create_sort_index(thd, curr_join,
curr_join->group_list ?
curr_join->group_list : curr_join->order,
curr_join->select_limit, unit->select_limit_cnt))
curr_join->select_limit,
(select_options & OPTION_FOUND_ROWS ?
HA_POS_ERROR : unit->select_limit_cnt)))
DBUG_VOID_RETURN;
}
}
@ -2856,8 +2867,6 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
!(s->table->force_index && best_key))
{ // Check full join
ha_rows rnd_records= s->found_records;
/* Estimate cost of reading table. */
tmp= s->table->file->scan_time();
/*
If there is a restriction on the table, assume that 25% of the
rows can be skipped on next part.
@ -2867,36 +2876,57 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
if (found_constraint)
rnd_records-= rnd_records/4;
if (s->on_expr) // Can't use join cache
/*
Range optimizer never proposes a RANGE if it isn't better
than FULL: so if RANGE is present, it's always preferred to FULL.
Here we estimate its cost.
*/
if (s->quick)
{
/*
For each record we:
- read record range through 'quick'
- skip rows which does not satisfy WHERE constraints
*/
tmp= record_count *
/* We have to read the whole table for each record */
(tmp +
/*
And we have to skip rows which does not satisfy join
condition for each record.
*/
(s->records - rnd_records)/(double) TIME_FOR_COMPARE);
(s->quick->read_time +
(s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
}
else
{
/* We read the table as many times as join buffer becomes full. */
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
record_count /
(double) thd->variables.join_buff_size));
/*
We don't make full cartesian product between rows in the scanned
table and existing records because we skip all rows from the
scanned table, which does not satisfy join condition when
we read the table (see flush_cached_records for details). Here we
take into account cost to read and skip these records.
*/
tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
/* Estimate cost of reading table. */
tmp= s->table->file->scan_time();
if (s->on_expr) // Can't use join cache
{
/*
For each record we have to:
- read the whole table record
- skip rows which does not satisfy join condition
*/
tmp= record_count *
(tmp +
(s->records - rnd_records)/(double) TIME_FOR_COMPARE);
}
else
{
/* We read the table as many times as join buffer becomes full. */
tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
record_count /
(double) thd->variables.join_buff_size));
/*
We don't make full cartesian product between rows in the scanned
table and existing records because we skip all rows from the
scanned table, which does not satisfy join condition when
we read the table (see flush_cached_records for details). Here we
take into account cost to read and skip these records.
*/
tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
}
}
/*
We estimate the cost of evaluating WHERE clause for found records
as record_count * rnd_records + TIME_FOR_COMPARE. This cost plus
as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
tmp give us total cost of using TABLE SCAN
*/
if (best == DBL_MAX ||
@ -3320,6 +3350,8 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
table_map used_tables;
if (join->tables > 1)
cond->update_used_tables(); // Tablenr may have changed
if (join->const_tables == join->tables)
join->const_table_map|=RAND_TABLE_BIT;
{ // Check const tables
COND *const_cond=
make_cond_for_table(cond,join->const_table_map,(table_map) 0);

View File

@ -22,7 +22,11 @@
#include "sql_select.h"
#include <hash.h>
#include <thr_alarm.h>
#if defined(HAVE_MALLINFO) && defined(HAVE_MALLOC_H)
#include <malloc.h>
#elif defined(HAVE_MALLINFO) && defined(HAVE_SYS_MALLOC_H)
#include <sys/malloc.h>
#endif
/* Intern key cache variables */
extern "C" pthread_mutex_t THR_LOCK_keycache;

View File

@ -150,16 +150,19 @@ int rea_create_table(THD *thd, my_string file_name,
my_free((gptr) screen_buff,MYF(0));
my_free((gptr) keybuff, MYF(0));
VOID(my_close(file,MYF(MY_WME)));
if (ha_create_table(file_name,create_info,0))
if (my_sync(file, MYF(MY_WME)))
goto err2;
if (my_close(file,MYF(MY_WME)) ||
ha_create_table(file_name,create_info,0))
goto err3;
DBUG_RETURN(0);
err:
my_free((gptr) screen_buff,MYF(0));
my_free((gptr) keybuff, MYF(0));
err2:
VOID(my_close(file,MYF(MY_WME)));
err2:
err3:
my_delete(file_name,MYF(0));
DBUG_RETURN(1);
} /* rea_create_table */

View File

@ -43,7 +43,7 @@
#define ERRMAPP 1 /* Errormap f|r my_error */
#define LIBLEN FN_REFLEN-FN_LEN /* Max l{ngd p} dev */
#define MAX_DBKEY_LENGTH (FN_LEN*2+6) /* extra 4 bytes for slave tmp
#define MAX_DBKEY_LENGTH (FN_LEN*2+1+1+4+4) /* extra 4+4 bytes for slave tmp
* tables */
#define MAX_ALIAS_NAME 256
#define MAX_FIELD_NAME 34 /* Max colum name length +2 */

View File

@ -108,19 +108,6 @@ else
test -z "$print_defaults" && print_defaults="my_print_defaults"
fi
#
# Set pid file if not given
#
if test -z "$pid_file"
then
pid_file=$datadir/`@HOSTNAME@`.pid
else
case "$pid_file" in
/* ) ;;
* ) pid_file="$datadir/$pid_file" ;;
esac
fi
#
# Test if someone changed datadir; In this case we should also read the
# default arguments from this directory
@ -134,6 +121,19 @@ fi
parse_arguments `$print_defaults $extra_args mysqld server mysql_server mysql.server`
#
# Set pid file if not given
#
if test -z "$pid_file"
then
pid_file=$datadir/`@HOSTNAME@`.pid
else
case "$pid_file" in
/* ) ;;
* ) pid_file="$datadir/$pid_file" ;;
esac
fi
# Safeguard (relative paths, core dumps..)
cd $basedir