Below is the list of changes that have just been committed into a local
5.0 repository of lthalmann. When lthalmann does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2018 05/10/18 17:55:37 lars@stripped +43 -0
Merge mysql.com:/users/lthalmann/bkroot/mysql-5.0
into mysql.com:/users/lthalmann/bk/mysql-5.0-wl1012
sql/share/errmsg.txt
1.52 05/10/18 17:55:30 lars@stripped +0 -0
Merge
sql/log.cc
1.179 05/10/18 17:55:30 lars@stripped +31 -31
Merge
mysql-test/r/user_var-binlog.result
1.6 05/10/18 17:55:30 lars@stripped +1 -2
Merge
mysql-test/mysql-test-run.sh
1.278 05/10/18 17:55:30 lars@stripped +1 -2
Merge
mysql-test/Makefile.am
1.65 05/10/18 17:55:30 lars@stripped +0 -0
Merge
sql/table.h
1.111 05/10/18 17:19:08 lars@stripped +0 -0
Auto merged
sql/table.cc
1.185 05/10/18 17:19:08 lars@stripped +1 -3
Auto merged
sql/sql_update.cc
1.174 05/10/18 17:19:08 lars@stripped +0 -0
Auto merged
sql/sql_union.cc
1.128 05/10/18 17:19:08 lars@stripped +0 -0
Auto merged
sql/sql_table.cc
1.275 05/10/18 17:19:07 lars@stripped +0 -0
Auto merged
sql/sql_show.cc
1.266 05/10/18 17:19:07 lars@stripped +0 -0
Auto merged
sql/sql_select.cc
1.352 05/10/18 17:19:07 lars@stripped +0 -0
Auto merged
sql/sql_parse.cc
1.473 05/10/18 17:19:06 lars@stripped +0 -3
Auto merged
sql/sql_insert.cc
1.178 05/10/18 17:19:05 lars@stripped +0 -0
Auto merged
sql/sql_class.h
1.264 05/10/18 17:19:05 lars@stripped +0 -0
Auto merged
sql/sql_class.cc
1.213 05/10/18 17:19:05 lars@stripped +0 -0
Auto merged
sql/sql_base.cc
1.311 05/10/18 17:19:04 lars@stripped +0 -0
Auto merged
sql/sp_head.cc
1.192 05/10/18 17:19:04 lars@stripped +0 -0
Auto merged
sql/sp.cc
1.93 05/10/18 17:19:04 lars@stripped +0 -0
Auto merged
sql/slave.h
1.91 05/10/18 17:19:04 lars@stripped +0 -0
Auto merged
sql/slave.cc
1.264 05/10/18 17:19:04 lars@stripped +0 -0
Auto merged
sql/mysqld.cc
1.487 05/10/18 17:19:03 lars@stripped +0 -0
Auto merged
sql/mysql_priv.h
1.348 05/10/18 17:19:02 lars@stripped +0 -0
Auto merged
sql/log_event.h
1.130 05/10/18 17:19:02 lars@stripped +0 -0
Auto merged
sql/log_event.cc
1.214 05/10/18 17:19:02 lars@stripped +0 -0
Auto merged
sql/item_func.cc
1.258 05/10/18 17:19:01 lars@stripped +0 -0
Auto merged
sql/handler.h
1.156 05/10/18 17:19:01 lars@stripped +0 -0
Auto merged
sql/handler.cc
1.201 05/10/18 17:19:00 lars@stripped +0 -0
Auto merged
sql/ha_innodb.cc
1.248 05/10/18 17:19:00 lars@stripped +0 -0
Auto merged
ndb/src/mgmsrv/Services.cpp
1.57 05/10/18 17:19:00 lars@stripped +0 -0
Auto merged
mysql-test/t/sp.test
1.160 05/10/18 17:18:59 lars@stripped +0 -0
Auto merged
mysql-test/t/rpl_stm_sp.test
1.10 05/10/18 17:18:59 lars@stripped +0 -0
Auto merged
mysql-test/t/rpl_stm_ddl.test
1.9 05/10/18 17:18:59 lars@stripped +0 -0
Auto merged
mysql-test/t/ctype_utf8.test
1.73 05/10/18 17:18:59 lars@stripped +0 -0
Auto merged
mysql-test/r/sp.result
1.166 05/10/18 17:18:59 lars@stripped +0 -0
Auto merged
mysql-test/r/rpl_stm_sp.result
1.11 05/10/18 17:18:59 lars@stripped +0 -0
Auto merged
mysql-test/r/rpl_stm_ddl.result
1.9 05/10/18 17:18:58 lars@stripped +0 -0
Auto merged
mysql-test/r/binlog_stm_ctype_cp932.result
1.8 05/10/18 17:18:58 lars@stripped +0 -0
Auto merged
mysql-test/mysql-test-run.pl
1.42 05/10/18 17:18:58 lars@stripped +0 -0
Auto merged
mysql-test/extra/binlog_tests/ctype_cp932.test
1.11 05/10/18 17:18:58 lars@stripped +0 -0
Auto merged
mysql-test/t/rpl_stm_sp.test
1.4.3.2 05/10/18 17:18:57 lars@stripped +0 -0
Merge rename: mysql-test/t/rpl_sp.test -> mysql-test/t/rpl_stm_sp.test
mysql-test/t/rpl_stm_ddl.test
1.4.2.2 05/10/18 17:18:57 lars@stripped +0 -0
Merge rename: mysql-test/t/rpl_ddl.test -> mysql-test/t/rpl_stm_ddl.test
mysql-test/extra/binlog_tests/ctype_cp932.test
1.7.1.2 05/10/18 17:18:57 lars@stripped +0 -0
Merge rename: mysql-test/t/ctype_cp932.test -> mysql-test/extra/binlog_tests/ctype_cp932.test
configure.in
1.348 05/10/18 17:18:57 lars@stripped +0 -0
Auto merged
BitKeeper/etc/config
1.21 05/10/18 17:18:57 lars@stripped +0 -1
Auto merged
BUILD/SETUP.sh
1.52 05/10/18 17:18:57 lars@stripped +0 -0
Auto merged
mysql-test/r/rpl_stm_sp.result
1.5.3.2 05/10/18 17:18:56 lars@stripped +0 -0
Merge rename: mysql-test/r/rpl_sp.result -> mysql-test/r/rpl_stm_sp.result
mysql-test/r/rpl_stm_ddl.result
1.6.2.2 05/10/18 17:18:56 lars@stripped +0 -0
Merge rename: mysql-test/r/rpl_ddl.result -> mysql-test/r/rpl_stm_ddl.result
mysql-test/r/binlog_stm_ctype_cp932.result
1.5.1.2 05/10/18 17:18:56 lars@stripped +0 -0
Merge rename: mysql-test/r/ctype_cp932.result -> mysql-test/r/binlog_stm_ctype_cp932.result
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: lars
# Host: dl145h.mysql.com
# Root: /users/lthalmann/bk/mysql-5.0-wl1012/RESYNC
--- 1.347/configure.in 2005-10-10 20:23:42 +02:00
+++ 1.348/configure.in 2005-10-18 17:18:57 +02:00
@@ -7,7 +7,7 @@
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.0.15-rc)
+AM_INIT_AUTOMAKE(mysql, 5.0.15)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@@ -19,7 +19,7 @@
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
NDB_VERSION_BUILD=15
-NDB_VERSION_STATUS="rc"
+NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
# Remember that regexps needs to quote [ and ] since this is run through m4
@@ -1022,7 +1022,7 @@
*darwin5*)
if test "$ac_cv_prog_gcc" = "yes"
then
- FLAGS="-traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH"
+ FLAGS="-traditional-cpp -DHAVE_DARWIN5_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH"
CFLAGS="$CFLAGS $FLAGS"
CXXFLAGS="$CXXFLAGS $FLAGS"
MAX_C_OPTIMIZE="-O"
@@ -1032,23 +1032,13 @@
*darwin6*)
if test "$ac_cv_prog_gcc" = "yes"
then
- FLAGS="-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH"
+ FLAGS="-D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH"
CFLAGS="$CFLAGS $FLAGS"
CXXFLAGS="$CXXFLAGS $FLAGS"
MAX_C_OPTIMIZE="-O"
fi
;;
- *darwin[[7-8]]*)
- # don't forget to escape [] like above
- if test "$ac_cv_prog_gcc" = "yes"
- then
- FLAGS="-DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT"
- CFLAGS="$CFLAGS $FLAGS"
- CXXFLAGS="$CXXFLAGS $FLAGS"
- MAX_C_OPTIMIZE="-O"
- fi
- ;;
- *darwin9*)
+ *darwin*)
if test "$ac_cv_prog_gcc" = "yes"
then
FLAGS="-D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT"
--- 1.277/mysql-test/mysql-test-run.sh 2005-09-16 13:12:00 +02:00
+++ 1.278/mysql-test/mysql-test-run.sh 2005-10-18 17:55:30 +02:00
@@ -224,6 +224,7 @@
EXTRA_MASTER_MYSQLD_OPT=@EXTRA_MASTER_MYSQLD_OPT@
EXTRA_SLAVE_MYSQLD_OPT=@EXTRA_SLAVE_MYSQLD_OPT@
EXTRA_MYSQL_TEST_OPT=""
+EXTRA_MYSQLCHECK_OPT=""
EXTRA_MYSQLDUMP_OPT=""
EXTRA_MYSQLSHOW_OPT=""
EXTRA_MYSQLBINLOG_OPT=""
@@ -457,6 +458,8 @@
--debug=d:t:i:A,$MYSQL_TEST_DIR/var/log/slave.trace"
EXTRA_MYSQL_TEST_OPT="$EXTRA_MYSQL_TEST_OPT \
--debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqltest.trace"
+ EXTRA_MYSQLCHECK_OPT="$EXTRA_MYSQLCHECK_OPT \
+ --debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqlcheck.trace"
EXTRA_MYSQLDUMP_OPT="$EXTRA_MYSQLDUMP_OPT \
--debug=d:t:A,$MYSQL_TEST_DIR/var/log/mysqldump.trace"
EXTRA_MYSQLSHOW_OPT="$EXTRA_MYSQLSHOW_OPT \
@@ -559,6 +562,11 @@
fi
MYSQL_CLIENT_TEST="$BASEDIR/tests/mysql_client_test"
fi
+ if [ -f "$BASEDIR/client/.libs/mysqlcheck" ] ; then
+ MYSQL_CHECK="$BASEDIR/client/.libs/mysqlcheck"
+ else
+ MYSQL_CHECK="$BASEDIR/client/mysqlcheck"
+ fi
if [ -f "$BASEDIR/client/.libs/mysqldump" ] ; then
MYSQL_DUMP="$BASEDIR/client/.libs/mysqldump"
else
@@ -637,6 +645,7 @@
TESTS_BINDIR="$BASEDIR/bin"
fi
MYSQL_TEST="$CLIENT_BINDIR/mysqltest"
+ MYSQL_CHECK="$CLIENT_BINDIR/mysqlcheck"
MYSQL_DUMP="$CLIENT_BINDIR/mysqldump"
MYSQL_SHOW="$CLIENT_BINDIR/mysqlshow"
MYSQL_BINLOG="$CLIENT_BINDIR/mysqlbinlog"
@@ -722,13 +731,14 @@
# Save path and name of mysqldump
MYSQL_DUMP_DIR="$MYSQL_DUMP"
export MYSQL_DUMP_DIR
+MYSQL_CHECK="$MYSQL_CHECK --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLCHECK_OPT"
MYSQL_DUMP="$MYSQL_DUMP --no-defaults -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT"
MYSQL_DUMP_SLAVE="$MYSQL_DUMP_DIR --no-defaults -uroot --socket=$SLAVE_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLDUMP_OPT"
MYSQL_SHOW="$MYSQL_SHOW -uroot --socket=$MASTER_MYSOCK --password=$DBPASSWD $EXTRA_MYSQLSHOW_OPT"
MYSQL_BINLOG="$MYSQL_BINLOG --no-defaults --local-load=$MYSQL_TMP_DIR --character-sets-dir=$CHARSETSDIR $EXTRA_MYSQLBINLOG_OPT"
MYSQL_FIX_SYSTEM_TABLES="$MYSQL_FIX_SYSTEM_TABLES --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD --basedir=$BASEDIR --bindir=$CLIENT_BINDIR --verbose"
MYSQL="$MYSQL --no-defaults --host=localhost --port=$MASTER_MYPORT --socket=$MASTER_MYSOCK --user=root --password=$DBPASSWD"
-export MYSQL MYSQL_DUMP MYSQL_DUMP_SLAVE MYSQL_SHOW MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES
+export MYSQL MYSQL_CHECK MYSQL_DUMP MYSQL_DUMP_SLAVE MYSQL_SHOW MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES
export CLIENT_BINDIR MYSQL_CLIENT_TEST CHARSETSDIR MYSQL_MY_PRINT_DEFAULTS
export NDB_TOOLS_DIR
export NDB_MGM
@@ -760,7 +770,7 @@
XTERM=`which xterm`
fi
-export MYSQL MYSQL_DUMP MYSQL_SHOW MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES CLIENT_BINDIR MASTER_MYSOCK
+export MYSQL MYSQL_CHECK MYSQL_DUMP MYSQL_SHOW MYSQL_BINLOG MYSQL_FIX_SYSTEM_TABLES CLIENT_BINDIR MASTER_MYSOCK
#++
# Function Definitions
--- 1.200/sql/handler.cc 2005-10-10 19:31:18 +02:00
+++ 1.201/sql/handler.cc 2005-10-18 17:19:00 +02:00
@@ -184,15 +184,18 @@
THD *thd= current_thd;
show_table_alias_st *table_alias;
handlerton **types;
- const char *ptr= name;
- if (thd && !my_strcasecmp(&my_charset_latin1, ptr, "DEFAULT"))
+ if (thd && !my_strnncoll(&my_charset_latin1,
+ (const uchar *)name, namelen,
+ (const uchar *)"DEFAULT", 7))
return (enum db_type) thd->variables.table_type;
retest:
for (types= sys_table_types; *types; types++)
{
- if (!my_strcasecmp(&my_charset_latin1, ptr, (*types)->name))
+ if (!my_strnncoll(&my_charset_latin1,
+ (const uchar *)name, namelen,
+ (const uchar *)(*types)->name, strlen((*types)->name)))
return (enum db_type) (*types)->db_type;
}
@@ -201,15 +204,21 @@
*/
for (table_alias= sys_table_aliases; table_alias->type; table_alias++)
{
- if (!my_strcasecmp(&my_charset_latin1, ptr, table_alias->alias))
+ if (!my_strnncoll(&my_charset_latin1,
+ (const uchar *)name, namelen,
+ (const uchar *)table_alias->alias,
+ strlen(table_alias->alias)))
{
- ptr= table_alias->type;
+ name= table_alias->type;
+ namelen= strlen(name);
goto retest;
}
}
return DB_TYPE_UNKNOWN;
}
+
+
const char *ha_get_storage_engine(enum db_type db_type)
{
handlerton **types;
@@ -218,25 +227,19 @@
if (db_type == (*types)->db_type)
return (*types)->name;
}
-
- return "none";
+ return "*NONE*";
}
+
bool ha_check_storage_engine_flag(enum db_type db_type, uint32 flag)
{
handlerton **types;
for (types= sys_table_types; *types; types++)
{
if (db_type == (*types)->db_type)
- {
- if ((*types)->flags & flag)
- return TRUE;
- else
- return FALSE;
- }
+ return test((*types)->flags & flag);
}
-
- return FALSE;
+ return FALSE; // No matching engine
}
@@ -858,17 +861,24 @@
DBUG_RETURN(error);
}
+
int ha_commit_or_rollback_by_xid(XID *xid, bool commit)
{
handlerton **types;
int res= 1;
for (types= sys_table_types; *types; types++)
+ {
if ((*types)->state == SHOW_OPTION_YES && (*types)->recover)
- res= res &&
- (*(commit ? (*types)->commit_by_xid : (*types)->rollback_by_xid))(xid);
+ {
+ if ((*(commit ? (*types)->commit_by_xid :
+ (*types)->rollback_by_xid))(xid));
+ res= 0;
+ }
+ }
return res;
}
+
#ifndef DBUG_OFF
/* this does not need to be multi-byte safe or anything */
--- 1.155/sql/handler.h 2005-10-10 18:53:04 +02:00
+++ 1.156/sql/handler.h 2005-10-18 17:19:01 +02:00
@@ -443,6 +443,7 @@
uint options; /* OR of HA_CREATE_ options */
uint raid_type,raid_chunks;
uint merge_insert_method;
+ uint extra_size; /* length of extra data segment */
bool table_existed; /* 1 in create if table existed */
bool frm_only; /* 1 if no ha_create_table() */
bool varchar; /* 1 if table has a VARCHAR */
--- 1.257/sql/item_func.cc 2005-09-30 18:00:15 +02:00
+++ 1.258/sql/item_func.cc 2005-10-18 17:19:01 +02:00
@@ -32,6 +32,11 @@
#include "sp_rcontext.h"
#include "sp.h"
+#ifdef NO_EMBEDDED_ACCESS_CHECKS
+#define sp_restore_security_context(A,B) while (0) {}
+#endif
+
+
bool check_reserved_words(LEX_STRING *name)
{
if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
@@ -2015,7 +2020,6 @@
{
String *res;
LINT_INIT(res);
- null_value= 0;
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
@@ -2030,14 +2034,11 @@
if ((cmp_sign < 0 ? cmp : -cmp) < 0)
res=res2;
}
- else
- res= 0;
}
if ((null_value= args[i]->null_value))
- break;
+ return 0;
}
- if (res) // If !NULL
- res->set_charset(collation.collation);
+ res->set_charset(collation.collation);
return res;
}
case ROW_RESULT:
@@ -2054,7 +2055,6 @@
{
DBUG_ASSERT(fixed == 1);
double value=0.0;
- null_value= 0;
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
@@ -2076,7 +2076,6 @@
{
DBUG_ASSERT(fixed == 1);
longlong value=0;
- null_value= 0;
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
@@ -2097,21 +2096,21 @@
my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
{
DBUG_ASSERT(fixed == 1);
- my_decimal tmp_buf, *tmp, *res= NULL;
- null_value= 0;
+ my_decimal tmp_buf, *tmp, *res;
+ LINT_INIT(res);
+
for (uint i=0; i < arg_count ; i++)
{
if (i == 0)
res= args[i]->val_decimal(dec);
else
{
- tmp= args[i]->val_decimal(&tmp_buf);
- if (args[i]->null_value)
- res= 0;
- else if ((my_decimal_cmp(tmp, res) * cmp_sign) < 0)
+ tmp= args[i]->val_decimal(&tmp_buf); // Zero if NULL
+ if (tmp && (my_decimal_cmp(tmp, res) * cmp_sign) < 0)
{
if (tmp == &tmp_buf)
{
+ /* Move value out of tmp_buf as this will be reused on next loop */
my_decimal2decimal(tmp, dec);
res= dec;
}
@@ -2120,7 +2119,10 @@
}
}
if ((null_value= args[i]->null_value))
+ {
+ res= 0;
break;
+ }
}
return res;
}
@@ -2349,7 +2351,7 @@
}
}
}
- agg_arg_collations_for_comparison(cmp_collation, args, 2);
+ agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV);
}
static const char separator=',';
@@ -3031,9 +3033,13 @@
thd->mysys_var->current_cond= &ull->cond;
set_timespec(abstime,lock_timeout);
- while (!thd->killed &&
- pthread_cond_timedwait(&ull->cond, &LOCK_user_locks,
- &abstime) != ETIMEDOUT && ull->locked) ;
+ while (ull->locked && !thd->killed)
+ {
+ int error= pthread_cond_timedwait(&ull->cond, &LOCK_user_locks, &abstime);
+ if (error == ETIMEDOUT || error == ETIME)
+ break;
+ }
+
if (ull->locked)
{
if (!--ull->count)
@@ -3077,7 +3083,7 @@
struct timespec abstime;
THD *thd=current_thd;
User_level_lock *ull;
- int error=0;
+ int error;
/*
In slave thread no need to get locks, everything is serialized. Anyway
@@ -3133,22 +3139,29 @@
thd->mysys_var->current_cond= &ull->cond;
set_timespec(abstime,timeout);
- while (!thd->killed &&
- (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime))
- != ETIMEDOUT && error != EINVAL && ull->locked) ;
- if (thd->killed)
- error=EINTR; // Return NULL
+ error= 0;
+ while (ull->locked && !thd->killed)
+ {
+ error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime);
+ if (error == ETIMEDOUT || error == ETIME)
+ break;
+ error= 0;
+ }
+
if (ull->locked)
{
if (!--ull->count)
+ {
+ DBUG_ASSERT(0);
delete ull; // Should never happen
- if (error != ETIMEDOUT)
+ }
+ if (!error) // Killed (thd->killed != 0)
{
error=1;
null_value=1; // Return NULL
}
}
- else
+ else // We got the lock
{
ull->locked=1;
ull->thread=thd->real_id;
@@ -3270,6 +3283,7 @@
str->append(')');
}
+
/* This function is just used to create tests with time gaps */
longlong Item_func_sleep::val_int()
@@ -3290,10 +3304,14 @@
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &cond;
- while (!thd->killed &&
- (error= pthread_cond_timedwait(&cond, &LOCK_user_locks,
- &abstime)) != ETIMEDOUT &&
- error != EINVAL) ;
+ error= 0;
+ while (!thd->killed)
+ {
+ error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime);
+ if (error == ETIMEDOUT || error == ETIME)
+ break;
+ error= 0;
+ }
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
@@ -3303,7 +3321,7 @@
pthread_mutex_unlock(&LOCK_user_locks);
pthread_cond_destroy(&cond);
- return (error == ETIMEDOUT) ? 0 : 1;
+ return test(!error); // Return 1 killed
}
@@ -4732,10 +4750,7 @@
ER_FAILED_ROUTINE_BREAK_BINLOG,
ER(ER_FAILED_ROUTINE_BREAK_BINLOG));
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
sp_restore_security_context(thd, save_ctx);
-#endif
-
error:
DBUG_RETURN(res);
}
@@ -4849,11 +4864,12 @@
find_and_check_access()
thd thread handler
want_access requested access
- backup backup of security context or 0
+ save backup of security context
RETURN
FALSE Access granted
TRUE Requested access can't be granted or function doesn't exists
+ In this case security context is not changed and *save = 0
NOTES
Checks if requested access to function can be granted to user.
@@ -4868,12 +4884,11 @@
bool
Item_func_sp::find_and_check_access(THD *thd, ulong want_access,
- Security_context **backup)
+ Security_context **save)
{
- bool res;
- Security_context *local_save,
- **save= (backup ? backup : &local_save);
- res= TRUE;
+ bool res= TRUE;
+
+ *save= 0; // Safety if error
if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
@@ -4883,26 +4898,31 @@
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (check_routine_access(thd, want_access,
m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
- {
goto error;
- }
sp_change_security_context(thd, m_sp, save);
+ /*
+ If we changed context to run as another user, we need to check the
+ access right for the new context again as someone may have deleted
+ this person the right to use the procedure
+
+ TODO:
+ Cache if the definer has the right to use the object on the first
+ usage and only reset the cache if someone does a GRANT statement
+ that 'may' affect this.
+ */
if (*save &&
check_routine_access(thd, want_access,
m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
{
- goto error_check_ctx;
+ sp_restore_security_context(thd, *save);
+ *save= 0; // Safety
+ goto error;
}
- res= FALSE;
-error_check_ctx:
- if (*save && (res || !backup))
- sp_restore_security_context(thd, local_save);
-error:
-#else
- res= 0;
-error:
#endif
+ res= FALSE; // no error
+
+error:
return res;
}
@@ -4912,7 +4932,11 @@
bool res;
DBUG_ASSERT(fixed == 0);
res= Item_func::fix_fields(thd, ref);
- if (!res && find_and_check_access(thd, EXECUTE_ACL, NULL))
- res= 1;
+ if (!res)
+ {
+ Security_context *save_ctx;
+ if (!(res= find_and_check_access(thd, EXECUTE_ACL, &save_ctx)))
+ sp_restore_security_context(thd, save_ctx);
+ }
return res;
}
--- 1.178/sql/log.cc 2005-10-10 18:53:05 +02:00
+++ 1.179/sql/log.cc 2005-10-18 17:55:30 +02:00
@@ -357,9 +357,10 @@
MYSQL_LOG::MYSQL_LOG()
:bytes_written(0), last_time(0), query_start(0), name(0),
file_id(1), open_count(1), log_type(LOG_CLOSED), write_error(0), inited(0),
- need_start_event(1), prepared_xids(0),
+ need_start_event(1), prepared_xids(0),
m_next_table_id(0), m_table_map_version(0),
- description_event_for_exec(0), description_event_for_queue(0)
+ description_event_for_exec(0), description_event_for_queue(0),
+ readers_count(0), reset_pending(false)
{
/*
We don't want to initialize LOCK_Log here as such initialization depends on
@@ -385,8 +386,10 @@
delete description_event_for_exec;
(void) pthread_mutex_destroy(&LOCK_log);
(void) pthread_mutex_destroy(&LOCK_index);
+ (void) pthread_mutex_destroy(&LOCK_readers);
(void) pthread_cond_destroy(&update_cond);
(void) pthread_mutex_destroy(&LOCK_next_table_id);
+ (void) pthread_cond_destroy(&reset_cond);
}
DBUG_VOID_RETURN;
}
@@ -431,7 +434,9 @@
inited= 1;
(void) pthread_mutex_init(&LOCK_log,MY_MUTEX_INIT_SLOW);
(void) pthread_mutex_init(&LOCK_index, MY_MUTEX_INIT_SLOW);
+ (void) pthread_mutex_init(&LOCK_readers, MY_MUTEX_INIT_SLOW);
(void) pthread_cond_init(&update_cond, 0);
+ (void) pthread_cond_init(&reset_cond, 0);
(void) pthread_mutex_init(&LOCK_next_table_id, MY_MUTEX_INIT_FAST);
}
@@ -935,6 +940,13 @@
*/
pthread_mutex_lock(&LOCK_log);
pthread_mutex_lock(&LOCK_index);
+
+ /*
+ we need one more lock to block attempts to open a log while
+ we are waiting untill all log files will be closed
+ */
+ pthread_mutex_lock(&LOCK_readers);
+
/*
The following mutex is needed to ensure that no threads call
'delete thd' as we would then risk missing a 'rollback' from this
@@ -957,6 +969,19 @@
goto err;
}
+ reset_pending= true;
+ /*
+ send update signal just in case so that all reader threads waiting
+ for log update will leave wait condition
+ */
+ signal_update();
+ /*
+ if there are active readers wait until all of them will
+ release opened files
+ */
+ if (readers_count)
+ pthread_cond_wait(&reset_cond, &LOCK_log);
+
for (;;)
{
my_delete(linfo.log_file_name, MYF(MY_WME));
@@ -975,7 +1000,10 @@
my_free((gptr) save_name, MYF(0));
err:
+ reset_pending= false;
+
(void) pthread_mutex_unlock(&LOCK_thread_count);
+ pthread_mutex_unlock(&LOCK_readers);
pthread_mutex_unlock(&LOCK_index);
pthread_mutex_unlock(&LOCK_log);
DBUG_RETURN(error);
@@ -1356,7 +1384,8 @@
to change base names at some point.
*/
THD *thd = current_thd; /* may be 0 if we are reacting to SIGHUP */
- Rotate_log_event r(thd,new_name+dirname_length(new_name));
+ Rotate_log_event r(thd,new_name+dirname_length(new_name),
+ 0, LOG_EVENT_OFFSET, 0);
r.write(&log_file);
bytes_written += r.data_written;
}
@@ -1435,7 +1464,7 @@
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
- pthread_mutex_lock(&LOCK_log);
+ safe_mutex_assert_owner(&LOCK_log);
do
{
if (my_b_append(&log_file,(byte*) buf,len))
@@ -1450,7 +1479,6 @@
new_file(0);
err:
- pthread_mutex_unlock(&LOCK_log);
if (!error)
signal_update();
DBUG_RETURN(error);
@@ -2052,6 +2080,10 @@
{
const char *old_msg;
DBUG_ENTER("wait_for_update");
+
+ if (reset_pending)
+ DBUG_VOID_RETURN;
+
old_msg= thd->enter_cond(&update_cond, &LOCK_log,
is_slave ?
"Has read all relay log; waiting for the slave I/O "
@@ -2302,7 +2334,6 @@
DBUG_VOID_RETURN;
}
-
#ifndef MYSQL_CLIENT
ulong MYSQL_LOG::get_table_id(TABLE* table)
@@ -2347,6 +2378,33 @@
}
#endif /* !defined(MYSQL_CLIENT) */
+
+void MYSQL_LOG::readers_addref()
+{
+ /*
+ There is no necessity for reference counting on *nix, since it allows to
+ delete opened files, however it is more clean way to wait
+ untill all files will be closed on *nix as well.
+ */
+ DBUG_ENTER("MYSQL_LOG::reader_addref");
+ pthread_mutex_lock(&LOCK_log);
+ pthread_mutex_lock(&LOCK_readers);
+ readers_count++;
+ pthread_mutex_unlock(&LOCK_readers);
+ pthread_mutex_unlock(&LOCK_log);
+ DBUG_VOID_RETURN;
+}
+
+void MYSQL_LOG::readers_release()
+{
+ DBUG_ENTER("MYSQL_LOG::reader_release");
+ pthread_mutex_lock(&LOCK_log);
+ readers_count--;
+ if (!readers_count)
+ pthread_cond_broadcast(&reset_cond);
+ pthread_mutex_unlock(&LOCK_log);
+ DBUG_VOID_RETURN;
+}
#ifdef __NT__
void print_buffer_to_nt_eventlog(enum loglevel level, char *buff,
--- 1.213/sql/log_event.cc 2005-10-14 21:38:40 +02:00
+++ 1.214/sql/log_event.cc 2005-10-18 17:19:02 +02:00
@@ -124,8 +124,9 @@
static inline char* slave_load_file_stem(char*buf, uint file_id,
int event_server_id)
{
- fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "",
- MY_UNPACK_FILENAME | MY_UNIX_PATH);
+ fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
+ to_unix_path(buf);
+
buf = strend(buf);
buf = int10_to_str(::server_id, buf, 10);
*buf++ = '-';
@@ -214,24 +215,18 @@
/*
Transforms a string into "" or its expression in 0x... form.
*/
+
char *str_to_hex(char *to, const char *from, uint len)
{
- char *p= to;
if (len)
{
- p= strmov(p, "0x");
- for (uint i= 0; i < len; i++, p+= 2)
- {
- /* val[i] is char. Casting to uchar helps greatly if val[i] < 0 */
- uint tmp= (uint) (uchar) from[i];
- p[0]= _dig_vec_upper[tmp >> 4];
- p[1]= _dig_vec_upper[tmp & 15];
- }
- *p= 0;
+ *to++= '0';
+ *to++= 'x';
+ to= octet2hex(to, from, len);
}
else
- p= strmov(p, "\"\"");
- return p; // pointer to end 0 of 'to'
+ to= strmov(to, "\"\"");
+ return to; // pointer to end 0 of 'to'
}
/*
@@ -1188,7 +1183,7 @@
But it's likely that we don't want to use 32 bits for 3 bits; in the future
we will probably want to reclaim the 29 bits. So we need the &.
*/
- flags2= thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG;
+ flags2= (uint32) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
DBUG_ASSERT(thd->variables.character_set_client->number < 256*256);
DBUG_ASSERT(thd->variables.collation_connection->number < 256*256);
DBUG_ASSERT(thd->variables.collation_server->number < 256*256);
@@ -3014,13 +3009,38 @@
#endif /* MYSQL_CLIENT */
+
/*
- Rotate_log_event::Rotate_log_event()
+ Rotate_log_event::Rotate_log_event() (2 constructors)
*/
+
+#ifndef MYSQL_CLIENT
+Rotate_log_event::Rotate_log_event(THD* thd_arg,
+ const char* new_log_ident_arg,
+ uint ident_len_arg, ulonglong pos_arg,
+ uint flags_arg)
+ :Log_event(), new_log_ident(new_log_ident_arg),
+ pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
+ (uint) strlen(new_log_ident_arg)), flags(flags_arg)
+{
+#ifndef DBUG_OFF
+ char buff[22];
+ DBUG_ENTER("Rotate_log_event::Rotate_log_event(THD*,...)");
+ DBUG_PRINT("enter",("new_log_ident %s pos %s flags %lu", new_log_ident_arg,
+ llstr(pos_arg, buff), flags));
+#endif
+ if (flags & DUP_NAME)
+ new_log_ident= my_strdup_with_length((const byte*) new_log_ident_arg,
+ ident_len, MYF(MY_WME));
+ DBUG_VOID_RETURN;
+}
+#endif
+
+
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
const Format_description_log_event* description_event)
- :Log_event(buf, description_event) ,new_log_ident(NULL),alloced(0)
+ :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
{
DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
@@ -3035,12 +3055,9 @@
(header_size+post_header_len));
ident_offset = post_header_len;
set_if_smaller(ident_len,FN_REFLEN-1);
- if (!(new_log_ident= my_strdup_with_length((byte*) buf +
- ident_offset,
- (uint) ident_len,
- MYF(MY_WME))))
- DBUG_VOID_RETURN;
- alloced = 1;
+ new_log_ident= my_strdup_with_length((byte*) buf + ident_offset,
+ (uint) ident_len,
+ MYF(MY_WME));
DBUG_VOID_RETURN;
}
--- 1.129/sql/log_event.h 2005-10-14 21:38:41 +02:00
+++ 1.130/sql/log_event.h 2005-10-18 17:19:02 +02:00
@@ -1271,18 +1271,17 @@
class Rotate_log_event: public Log_event
{
public:
+ enum {
+ DUP_NAME= 2 // if constructor should dup the string argument
+ };
const char* new_log_ident;
ulonglong pos;
uint ident_len;
- bool alloced;
+ uint flags;
#ifndef MYSQL_CLIENT
Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
- uint ident_len_arg = 0,
- ulonglong pos_arg = LOG_EVENT_OFFSET)
- :Log_event(), new_log_ident(new_log_ident_arg),
- pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
- (uint) strlen(new_log_ident_arg)), alloced(0)
- {}
+ uint ident_len_arg,
+ ulonglong pos_arg, uint flags);
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
int exec_event(struct st_relay_log_info* rli);
@@ -1295,8 +1294,8 @@
const Format_description_log_event* description_event);
~Rotate_log_event()
{
- if (alloced)
- my_free((gptr) new_log_ident, MYF(0));
+ if (flags & DUP_NAME)
+ my_free((gptr) new_log_ident, MYF(MY_ALLOW_ZERO_PTR));
}
Log_event_type get_type_code() { return ROTATE_EVENT;}
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
--- 1.347/sql/mysql_priv.h 2005-10-10 18:53:05 +02:00
+++ 1.348/sql/mysql_priv.h 2005-10-18 17:19:02 +02:00
@@ -757,7 +757,7 @@
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update);
TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT* mem,
bool *refresh, uint flags);
-TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table);
+bool reopen_name_locked_table(THD* thd, TABLE_LIST* table);
TABLE *find_locked_table(THD *thd, const char *db,const char *table_name);
bool reopen_table(TABLE *table,bool locked);
bool reopen_tables(THD *thd,bool get_locks,bool in_refresh);
--- 1.486/sql/mysqld.cc 2005-10-10 18:53:06 +02:00
+++ 1.487/sql/mysqld.cc 2005-10-18 17:19:03 +02:00
@@ -607,6 +607,20 @@
#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL
+#include <openssl/crypto.h>
+#ifndef HAVE_YASSL
+typedef struct CRYPTO_dynlock_value
+{
+ rw_lock_t lock;
+} openssl_lock_t;
+
+static openssl_lock_t *openssl_stdlocks;
+static openssl_lock_t *openssl_dynlock_create(const char *, int);
+static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int);
+static void openssl_lock_function(int, int, const char *, int);
+static void openssl_lock(int, openssl_lock_t *, const char *, int);
+static unsigned long openssl_id_function();
+#endif
char *des_key_file;
struct st_VioSSLAcceptorFd *ssl_acceptor_fd;
#endif /* HAVE_OPENSSL */
@@ -942,7 +956,7 @@
RETURN_FROM_KILL_SERVER;
kill_in_progress=TRUE;
abort_loop=1; // This should be set
- signal(sig,SIG_IGN);
+ my_sigset(sig,SIG_IGN);
if (sig == MYSQL_KILL_SIGNAL || sig == 0)
sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
else
@@ -991,11 +1005,6 @@
}
#endif
-#if defined(__amiga__)
-#undef sigset
-#define sigset signal
-#endif
-
extern "C" sig_handler print_signal_warning(int sig)
{
if (!DBUG_IN_USE)
@@ -1005,7 +1014,7 @@
sig,my_thread_id());
}
#ifdef DONT_REMEMBER_SIGNAL
- sigset(sig,print_signal_warning); /* int. thread system calls */
+ my_sigset(sig,print_signal_warning); /* int. thread system calls */
#endif
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
if (sig == SIGALRM)
@@ -1198,6 +1207,11 @@
(void) pthread_mutex_destroy(&LOCK_user_conn);
#ifdef HAVE_OPENSSL
(void) pthread_mutex_destroy(&LOCK_des_key_file);
+#ifndef HAVE_YASSL
+ for (int i= 0; i < CRYPTO_num_locks(); ++i)
+ (void) rwlock_destroy(&openssl_stdlocks[i].lock);
+ OPENSSL_free(openssl_stdlocks);
+#endif
#endif
#ifdef HAVE_REPLICATION
(void) pthread_mutex_destroy(&LOCK_rpl_status);
@@ -2083,8 +2097,8 @@
DBUG_ENTER("init_signals");
if (test_flags & TEST_SIGINT)
- sigset(THR_KILL_SIGNAL,end_thread_signal);
- sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
+ my_sigset(THR_KILL_SIGNAL,end_thread_signal);
+ my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
{
@@ -2118,13 +2132,8 @@
}
#endif
(void) sigemptyset(&set);
-#ifdef THREAD_SPECIFIC_SIGPIPE
- sigset(SIGPIPE,abort_thread);
- sigaddset(&set,SIGPIPE);
-#else
- (void) signal(SIGPIPE,SIG_IGN); // Can't know which thread
+ my_sigset(SIGPIPE,SIG_IGN);
sigaddset(&set,SIGPIPE);
-#endif
sigaddset(&set,SIGINT);
#ifndef IGNORE_SIGHUP_SIGQUIT
sigaddset(&set,SIGQUIT);
@@ -2351,6 +2360,8 @@
if (thd->spcont &&
thd->spcont->find_handler(error, MYSQL_ERROR::WARN_LEVEL_ERROR))
{
+ if (! thd->spcont->found_handler_here())
+ thd->net.report_error= 1; /* Make "select" abort correctly */
DBUG_RETURN(0);
}
@@ -2754,6 +2765,17 @@
(void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
#ifdef HAVE_OPENSSL
(void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
+#ifndef HAVE_YASSL
+ openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
+ sizeof(openssl_lock_t));
+ for (int i= 0; i < CRYPTO_num_locks(); ++i)
+ (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL);
+ CRYPTO_set_dynlock_create_callback(openssl_dynlock_create);
+ CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy);
+ CRYPTO_set_dynlock_lock_callback(openssl_lock);
+ CRYPTO_set_locking_callback(openssl_lock_function);
+ CRYPTO_set_id_callback(openssl_id_function);
+#endif
#endif
(void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
(void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
@@ -2784,6 +2806,75 @@
}
return 0;
}
+
+
+#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
+static unsigned long openssl_id_function()
+{
+ return (unsigned long) pthread_self();
+}
+
+
+static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
+{
+ openssl_lock_t *lock= new openssl_lock_t;
+ my_rwlock_init(&lock->lock, NULL);
+ return lock;
+}
+
+
+static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
+ int line)
+{
+ rwlock_destroy(&lock->lock);
+ delete lock;
+}
+
+
+static void openssl_lock_function(int mode, int n, const char *file, int line)
+{
+ if (n < 0 || n > CRYPTO_num_locks())
+ {
+ /* Lock number out of bounds. */
+ sql_print_error("Fatal: OpenSSL interface problem (n = %d)", n);
+ abort();
+ }
+ openssl_lock(mode, &openssl_stdlocks[n], file, line);
+}
+
+
+static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
+ int line)
+{
+ int err;
+ char const *what;
+
+ switch (mode) {
+ case CRYPTO_LOCK|CRYPTO_READ:
+ what = "read lock";
+ err = rw_rdlock(&lock->lock);
+ break;
+ case CRYPTO_LOCK|CRYPTO_WRITE:
+ what = "write lock";
+ err = rw_wrlock(&lock->lock);
+ break;
+ case CRYPTO_UNLOCK|CRYPTO_READ:
+ case CRYPTO_UNLOCK|CRYPTO_WRITE:
+ what = "unlock";
+ err = rw_unlock(&lock->lock);
+ break;
+ default:
+ /* Unknown locking mode. */
+ sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
+ abort();
+ }
+ if (err)
+ {
+ sql_print_error("Fatal: can't %s OpenSSL %s lock", what);
+ abort();
+ }
+}
+#endif /* HAVE_OPENSSL */
static void init_ssl()
--- 1.263/sql/slave.cc 2005-10-10 18:53:06 +02:00
+++ 1.264/sql/slave.cc 2005-10-18 17:19:04 +02:00
@@ -1448,9 +1448,26 @@
{
char buf[FN_REFLEN];
const char *ln;
+ static bool name_warning_sent= 0;
ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
1, buf);
-
+ /* We send the warning only at startup, not after every RESET SLAVE */
+ if (!opt_relay_logname && !opt_relaylog_index_name && !name_warning_sent)
+ {
+ /*
+ User didn't give us info to name the relay log index file.
+ Picking `hostname`-relay-bin.index like we do, causes replication to
+ fail if this slave's hostname is changed later. So, we would like to
+ instead require a name. But as we don't want to break many existing
+ setups, we only give warning, not error.
+ */
+ sql_print_warning("Neither --relay-log nor --relay-log-index were used;"
+ " so replication "
+ "may break when this MySQL server acts as a "
+ "slave and has his hostname changed!! Please "
+ "use '--relay-log=%s' to avoid this problem.", ln);
+ name_warning_sent= 1;
+ }
/*
note, that if open() fails, we'll still have index file open
but a destructor will take care of that
@@ -1674,6 +1691,55 @@
}
+/*
+ Builds a Rotate from the ignored events' info and writes it to relay log.
+
+ SYNOPSIS
+ write_ignored_events_info_to_relay_log()
+ thd pointer to I/O thread's thd
+ mi
+
+ DESCRIPTION
+ Slave I/O thread, going to die, must leave a durable trace of the
+ ignored events' end position for the use of the slave SQL thread, by
+ calling this function. Only that thread can call it (see assertion).
+ */
+static void write_ignored_events_info_to_relay_log(THD *thd, MASTER_INFO *mi)
+{
+ RELAY_LOG_INFO *rli= &mi->rli;
+ pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
+ DBUG_ASSERT(thd == mi->io_thd);
+ pthread_mutex_lock(log_lock);
+ if (rli->ign_master_log_name_end[0])
+ {
+ DBUG_PRINT("info",("writing a Rotate event to track down ignored events"));
+ Rotate_log_event *ev= new Rotate_log_event(thd, rli->ign_master_log_name_end,
+ 0, rli->ign_master_log_pos_end,
+ Rotate_log_event::DUP_NAME);
+ rli->ign_master_log_name_end[0]= 0;
+ /* can unlock before writing as slave SQL thd will soon see our Rotate */
+ pthread_mutex_unlock(log_lock);
+ if (likely((bool)ev))
+ {
+ ev->server_id= 0; // don't be ignored by slave SQL thread
+ if (unlikely(rli->relay_log.append(ev)))
+ sql_print_error("Slave I/O thread failed to write a Rotate event"
+ " to the relay log, "
+ "SHOW SLAVE STATUS may be inaccurate");
+ rli->relay_log.harvest_bytes_written(&rli->log_space_total);
+ flush_master_info(mi, 1);
+ delete ev;
+ }
+ else
+ sql_print_error("Slave I/O thread failed to create a Rotate event"
+ " (out of memory?), "
+ "SHOW SLAVE STATUS may be inaccurate");
+ }
+ else
+ pthread_mutex_unlock(log_lock);
+}
+
+
void init_master_info_with_options(MASTER_INFO* mi)
{
mi->master_log_name[0] = 0;
@@ -2270,7 +2336,7 @@
{
group_relay_log_name[0]= event_relay_log_name[0]=
group_master_log_name[0]= 0;
- last_slave_error[0]=0; until_log_name[0]= 0;
+ last_slave_error[0]= until_log_name[0]= ign_master_log_name_end[0]= 0;
bzero((char*) &info_file, sizeof(info_file));
bzero((char*) &cache_buf, sizeof(cache_buf));
cached_charset_invalidate();
@@ -2472,7 +2538,7 @@
else
pthread_cond_wait(&data_cond, &data_lock);
DBUG_PRINT("info",("Got signal of master update or timed out"));
- if (error == ETIMEDOUT)
+ if (error == ETIMEDOUT || error == ETIME)
{
error= -1;
break;
@@ -2862,12 +2928,20 @@
wait for something for example inside of next_event().
*/
pthread_mutex_lock(&rli->data_lock);
-
+ /*
+ This tests if the position of the end of the last previous executed event
+ hits the UNTIL barrier.
+ We would prefer to test if the position of the start (or possibly) end of
+ the to-be-read event hits the UNTIL barrier, this is different if there
+ was an event ignored by the I/O thread just before (BUG#13861 to be
+ fixed).
+ */
if (rli->until_condition!=RELAY_LOG_INFO::UNTIL_NONE &&
rli->is_until_satisfied())
{
+ char buf[22];
sql_print_error("Slave SQL thread stopped because it reached its"
- " UNTIL position %ld", (long) rli->until_pos());
+ " UNTIL position %s", llstr(rli->until_pos(), buf));
/*
Setting abort_slave flag because we do not want additional message about
error in query execution to be printed.
@@ -3055,6 +3129,7 @@
THD *thd; // needs to be first for thread_stack
MYSQL *mysql;
MASTER_INFO *mi = (MASTER_INFO*)arg;
+ RELAY_LOG_INFO *rli= &mi->rli;
char llbuff[22];
uint retry_count;
@@ -3297,16 +3372,16 @@
char llbuf1[22], llbuf2[22];
DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
ignore_log_space_limit=%d",
- llstr(mi->rli.log_space_limit,llbuf1),
- llstr(mi->rli.log_space_total,llbuf2),
- (int) mi->rli.ignore_log_space_limit));
+ llstr(rli->log_space_limit,llbuf1),
+ llstr(rli->log_space_total,llbuf2),
+ (int) rli->ignore_log_space_limit));
}
#endif
- if (mi->rli.log_space_limit && mi->rli.log_space_limit <
- mi->rli.log_space_total &&
- !mi->rli.ignore_log_space_limit)
- if (wait_for_relay_log_space(&mi->rli))
+ if (rli->log_space_limit && rli->log_space_limit <
+ rli->log_space_total &&
+ !rli->ignore_log_space_limit)
+ if (wait_for_relay_log_space(rli))
{
sql_print_error("Slave I/O thread aborted while waiting for relay \
log space");
@@ -3337,10 +3412,20 @@
mysql_close(mysql);
mi->mysql=0;
}
+ write_ignored_events_info_to_relay_log(thd, mi);
thd->proc_info = "Waiting for slave mutex on exit";
pthread_mutex_lock(&mi->run_lock);
mi->slave_running = 0;
mi->io_thd = 0;
+
+ /* Close log file and free buffers */
+ if (mi->rli.cur_log_fd >= 0)
+ {
+ end_io_cache(&mi->rli.cache_buf);
+ my_close(mi->rli.cur_log_fd, MYF(MY_WME));
+ mi->rli.cur_log_fd= -1;
+ }
+
/* Forget the relay log's format */
delete mi->rli.relay_log.description_event_for_queue;
mi->rli.relay_log.description_event_for_queue= 0;
@@ -3568,6 +3653,14 @@
rli->cached_charset_invalidate();
rli->save_temporary_tables = thd->temporary_tables;
+ /* Close log file and free buffers if it's already open */
+ if (rli->cur_log_fd >= 0)
+ {
+ end_io_cache(&rli->cache_buf);
+ my_close(rli->cur_log_fd, MYF(MY_WME));
+ rli->cur_log_fd = -1;
+ }
+
/*
TODO: see if we can do this conditionally in next_event() instead
to avoid unneeded position re-init
@@ -3732,6 +3825,7 @@
if (unlikely(!rev->is_valid()))
DBUG_RETURN(1);
+ /* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
mi->master_log_pos= rev->pos;
DBUG_PRINT("info", ("master_log_pos: '%s' %d",
@@ -3982,6 +4076,7 @@
int error= 0;
ulong inc_pos;
RELAY_LOG_INFO *rli= &mi->rli;
+ pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
DBUG_ENTER("queue_event");
if (mi->rli.relay_log.description_event_for_queue->binlog_version<4 &&
@@ -3990,11 +4085,6 @@
pthread_mutex_lock(&mi->data_lock);
- /*
- TODO: figure out if other events in addition to Rotate
- require special processing.
- Guilhem 2003-06 : I don't think so.
- */
switch (buf[EVENT_TYPE_OFFSET]) {
case STOP_EVENT:
/*
@@ -4079,14 +4169,21 @@
direct master (an unsupported, useless setup!).
*/
+ pthread_mutex_lock(log_lock);
+
if ((uint4korr(buf + SERVER_ID_OFFSET) == ::server_id) &&
!replicate_same_server_id)
{
/*
Do not write it to the relay log.
- We still want to increment, so that we won't re-read this event from the
- master if the slave IO thread is now stopped/restarted (more efficient if
- the events we are ignoring are big LOAD DATA INFILE).
+ a) We still want to increment mi->master_log_pos, so that we won't
+ re-read this event from the master if the slave IO thread is now
+ stopped/restarted (more efficient if the events we are ignoring are big
+ LOAD DATA INFILE).
+ b) We want to record that we are skipping events, for the information of
+ the slave SQL thread, otherwise that thread may let
+ rli->group_relay_log_pos stay too small if the last binlog's event is
+ ignored.
But events which were generated by this slave and which do not exist in
the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
mi->master_log_pos.
@@ -4094,7 +4191,13 @@
if (buf[EVENT_TYPE_OFFSET]!=FORMAT_DESCRIPTION_EVENT &&
buf[EVENT_TYPE_OFFSET]!=ROTATE_EVENT &&
buf[EVENT_TYPE_OFFSET]!=STOP_EVENT)
+ {
mi->master_log_pos+= inc_pos;
+ memcpy(rli->ign_master_log_name_end, mi->master_log_name, FN_REFLEN);
+ DBUG_ASSERT(rli->ign_master_log_name_end[0]);
+ rli->ign_master_log_pos_end= mi->master_log_pos;
+ }
+ rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
DBUG_PRINT("info", ("master_log_pos: %d, event originating from the same server, ignored", (ulong) mi->master_log_pos));
}
else
@@ -4107,8 +4210,11 @@
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
}
else
- error=3;
+ error= 3;
+ rli->ign_master_log_name_end[0]= 0; // last event is not ignored
}
+ pthread_mutex_unlock(log_lock);
+
err:
pthread_mutex_unlock(&mi->data_lock);
@@ -4491,7 +4597,28 @@
time_t save_timestamp= rli->last_master_timestamp;
rli->last_master_timestamp= 0;
- DBUG_ASSERT(rli->relay_log.get_open_count() == rli->cur_log_old_open_count);
+ DBUG_ASSERT(rli->relay_log.get_open_count() ==
+ rli->cur_log_old_open_count);
+
+ if (rli->ign_master_log_name_end[0])
+ {
+ /* We generate and return a Rotate, to make our positions advance */
+ DBUG_PRINT("info",("seeing an ignored end segment"));
+ ev= new Rotate_log_event(thd, rli->ign_master_log_name_end,
+ 0, rli->ign_master_log_pos_end,
+ Rotate_log_event::DUP_NAME);
+ rli->ign_master_log_name_end[0]= 0;
+ pthread_mutex_unlock(log_lock);
+ if (unlikely(!ev))
+ {
+ errmsg= "Slave SQL thread failed to create a Rotate event "
+ "(out of memory?), SHOW SLAVE STATUS may be inaccurate";
+ goto err;
+ }
+ ev->server_id= 0; // don't be ignored by slave SQL thread
+ DBUG_RETURN(ev);
+ }
+
/*
We can, and should release data_lock while we are waiting for
update. If we do not, show slave status will block
--- 1.310/sql/sql_base.cc 2005-10-10 18:53:07 +02:00
+++ 1.311/sql/sql_base.cc 2005-10-18 17:19:04 +02:00
@@ -977,32 +977,57 @@
}
-TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
+/*
+ Open table which is already name-locked by this thread.
+
+ SYNOPSIS
+ reopen_name_locked_table()
+ thd Thread handle
+ table_list TABLE_LIST object for table to be open, TABLE_LIST::table
+ member should point to TABLE object which was used for
+ name-locking.
+
+ NOTE
+ This function assumes that its caller already acquired LOCK_open mutex.
+
+ RETURN VALUE
+ FALSE - Success
+ TRUE - Error
+*/
+
+bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
{
- DBUG_ENTER("reopen_name_locked_table");
- if (thd->killed)
- DBUG_RETURN(0);
- TABLE *table;
+ TABLE *table= table_list->table;
TABLE_SHARE *share;
- if (!(table = table_list->table))
- DBUG_RETURN(0);
+ char *db= table_list->db;
+ char *table_name= table_list->table_name;
+ char key[MAX_DBKEY_LENGTH];
+ uint key_length;
+ TABLE orig_table;
+ DBUG_ENTER("reopen_name_locked_table");
- char* db = thd->db ? thd->db : table_list->db;
- char* table_name = table_list->table_name;
- char key[MAX_DBKEY_LENGTH];
- uint key_length;
+ safe_mutex_assert_owner(&LOCK_open);
+
+ if (thd->killed || !table)
+ DBUG_RETURN(TRUE);
+
+ orig_table= *table;
key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1;
- pthread_mutex_lock(&LOCK_open);
if (open_unireg_entry(thd, table, db, table_name, table_name, 0,
thd->mem_root) ||
!(table->s->table_cache_key= memdup_root(&table->mem_root, (char*) key,
key_length)))
{
- delete table->triggers;
- closefrm(table);
- pthread_mutex_unlock(&LOCK_open);
- DBUG_RETURN(0);
+ intern_close_table(table);
+ /*
+ If there was an error during opening of table (for example if it
+ does not exist) '*table' object can be wiped out. To be able
+ properly release name-lock in this case we should restore this
+ object to its original state.
+ */
+ *table= orig_table;
+ DBUG_RETURN(TRUE);
}
share= table->s;
@@ -1012,7 +1037,6 @@
share->flush_version=0;
table->in_use = thd;
check_unused();
- pthread_mutex_unlock(&LOCK_open);
table->next = thd->open_tables;
thd->open_tables = table;
table->tablenr=thd->current_tablenr++;
@@ -1022,7 +1046,7 @@
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= share->keys_in_use;
table->used_keys= share->keys_for_keyread;
- DBUG_RETURN(table);
+ DBUG_RETURN(FALSE);
}
@@ -2786,7 +2810,6 @@
Natural_join_column *nj_col;
Field *found_field;
Query_arena *arena, backup;
-
DBUG_ENTER("find_field_in_natural_join");
DBUG_PRINT("enter", ("field name: '%s', ref 0x%lx",
name, (ulong) ref));
@@ -2811,6 +2834,7 @@
if (nj_col->view_field)
{
+ Item *item;
/*
The found field is a view field, we do as in find_field_in_view()
and return a pointer to pointer to the Item of that field.
@@ -2818,7 +2842,7 @@
if (register_tree_change)
arena= thd->activate_stmt_arena_if_needed(&backup);
- Item *item= nj_col->create_item(thd);
+ item= nj_col->create_item(thd);
if (register_tree_change && arena)
thd->restore_active_arena(arena, &backup);
--- 1.212/sql/sql_class.cc 2005-10-10 18:53:07 +02:00
+++ 1.213/sql/sql_class.cc 2005-10-18 17:19:05 +02:00
@@ -1720,15 +1720,19 @@
int Statement_map::insert(Statement *statement)
{
- int rc= my_hash_insert(&st_hash, (byte *) statement);
+ int res= my_hash_insert(&st_hash, (byte *) statement);
+ if (res)
+ return res;
if (statement->name.str)
{
- if ((rc= my_hash_insert(&names_hash, (byte*)statement)))
+ if ((res= my_hash_insert(&names_hash, (byte*)statement)))
+ {
hash_delete(&st_hash, (byte*)statement);
+ return res;
+ }
}
- if (rc == 0)
- last_found_statement= statement;
- return rc;
+ last_found_statement= statement;
+ return res;
}
--- 1.263/sql/sql_class.h 2005-10-10 18:53:07 +02:00
+++ 1.264/sql/sql_class.h 2005-10-18 17:19:05 +02:00
@@ -192,8 +192,11 @@
{
private:
/* LOCK_log and LOCK_index are inited by init_pthread_objects() */
- pthread_mutex_t LOCK_log, LOCK_index;
+ pthread_mutex_t LOCK_log, LOCK_index, LOCK_readers;
pthread_cond_t update_cond;
+ pthread_cond_t reset_cond;
+ bool reset_pending;
+ int readers_count;
ulonglong bytes_written;
time_t last_time,query_start;
IO_CACHE log_file;
@@ -350,6 +353,9 @@
int purge_logs_before_date(time_t purge_time);
int purge_first_log(struct st_relay_log_info* rli, bool included);
bool reset_logs(THD* thd);
+ inline bool is_reset_pending() { return reset_pending; }
+ void readers_addref();
+ void readers_release();
void close(uint exiting);
// iterating through the log index file
@@ -2022,6 +2028,7 @@
Field *field; /* Field to sort */
Item *item; /* Item if not sorting fields */
uint length; /* Length of sort field */
+ uint suffix_length; /* Length suffix (0-4) */
Item_result result_type; /* Type of item */
bool reverse; /* if descending sort */
bool need_strxnfrm; /* If we have to use strxnfrm() */
--- 1.177/sql/sql_insert.cc 2005-10-10 18:53:08 +02:00
+++ 1.178/sql/sql_insert.cc 2005-10-18 17:19:05 +02:00
@@ -1810,7 +1810,7 @@
#endif
if (thd->killed || di->status)
break;
- if (error == ETIMEDOUT)
+ if (error == ETIMEDOUT || error == ETIME)
{
thd->killed= THD::KILL_CONNECTION;
break;
--- 1.472/sql/sql_parse.cc 2005-10-10 22:00:53 +02:00
+++ 1.473/sql/sql_parse.cc 2005-10-18 17:19:06 +02:00
@@ -3194,36 +3194,36 @@
if (result != 2)
break;
case SQLCOM_UPDATE_MULTI:
+ {
+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
+ /* if we switched from normal update, rights are checked */
+ if (result != 2)
{
- DBUG_ASSERT(first_table == all_tables && first_table != 0);
- /* if we switched from normal update, rights are checked */
- if (result != 2)
- {
- if ((res= multi_update_precheck(thd, all_tables)))
- break;
- }
- else
- res= 0;
+ if ((res= multi_update_precheck(thd, all_tables)))
+ break;
+ }
+ else
+ res= 0;
- if ((res= mysql_multi_update_prepare(thd)))
- break;
+ if ((res= mysql_multi_update_prepare(thd)))
+ break;
#ifdef HAVE_REPLICATION
- /* Check slave filtering rules */
- if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
- {
- /* we warn the slave SQL thread */
- my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
- break;
- }
+ /* Check slave filtering rules */
+ if (thd->slave_thread && all_tables_not_ok(thd, all_tables))
+ {
+ /* we warn the slave SQL thread */
+ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
+ break;
+ }
#endif /* HAVE_REPLICATION */
- res= mysql_multi_update(thd, all_tables,
- &select_lex->item_list,
- &lex->value_list,
- select_lex->where,
- select_lex->options,
- lex->duplicates, lex->ignore, unit, select_lex);
+ res= mysql_multi_update(thd, all_tables,
+ &select_lex->item_list,
+ &lex->value_list,
+ select_lex->where,
+ select_lex->options,
+ lex->duplicates, lex->ignore, unit, select_lex);
break;
}
case SQLCOM_REPLACE:
@@ -3684,6 +3684,8 @@
if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 1, 0) &&
check_global_access(thd,CREATE_USER_ACL))
break;
+ if (end_active_trans(thd))
+ goto error;
if (!(res= mysql_create_user(thd, lex->users_list)))
{
if (mysql_bin_log.is_open() && !binlog_row_based)
@@ -3700,6 +3702,8 @@
if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 1, 0) &&
check_global_access(thd,CREATE_USER_ACL))
break;
+ if (end_active_trans(thd))
+ goto error;
if (!(res= mysql_drop_user(thd, lex->users_list)))
{
if (mysql_bin_log.is_open() && !binlog_row_based)
@@ -3716,6 +3720,8 @@
if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
check_global_access(thd,CREATE_USER_ACL))
break;
+ if (end_active_trans(thd))
+ goto error;
if (!(res= mysql_rename_user(thd, lex->users_list)))
{
if (mysql_bin_log.is_open() && !binlog_row_based)
@@ -4509,6 +4515,9 @@
}
case SQLCOM_CREATE_VIEW:
{
+ if (end_active_trans(thd))
+ goto error;
+
if (!(res= mysql_create_view(thd, thd->lex->create_view_mode)) &&
mysql_bin_log.is_open())
{
@@ -4523,7 +4532,8 @@
command[thd->lex->create_view_mode].length);
view_store_options(thd, first_table, &buff);
buff.append("VIEW ", 5);
- if (!first_table->current_db_used)
+ /* Test if user supplied a db (ie: we did not use thd->db) */
+ if (first_table->db != thd->db && first_table->db[0])
{
append_identifier(thd, &buff, first_table->db,
first_table->db_length);
@@ -4555,6 +4565,9 @@
}
case SQLCOM_CREATE_TRIGGER:
{
+ if (end_active_trans(thd))
+ goto error;
+
res= mysql_create_or_drop_trigger(thd, all_tables, 1);
/* We don't care about trigger body after this point */
@@ -4564,6 +4577,9 @@
}
case SQLCOM_DROP_TRIGGER:
{
+ if (end_active_trans(thd))
+ goto error;
+
res= mysql_create_or_drop_trigger(thd, all_tables, 0);
break;
}
@@ -4841,7 +4857,6 @@
bool db_is_pattern= test(want_access & GRANT_ACL);
#endif
ulong dummy;
- const char *db_name;
DBUG_ENTER("check_access");
DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
db ? db : "", want_access, sctx->master_access));
@@ -4859,15 +4874,16 @@
DBUG_RETURN(TRUE); /* purecov: tested */
}
- db_name= db ? db : thd->db;
if (schema_db)
{
if (want_access & ~(SELECT_ACL | EXTRA_ACL))
{
if (!no_errors)
+ {
+ const char *db_name= db ? db : thd->db;
my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
- sctx->priv_user,
- sctx->priv_host, db_name);
+ sctx->priv_user, sctx->priv_host, db_name);
+ }
DBUG_RETURN(TRUE);
}
else
@@ -5042,11 +5058,16 @@
tables->db= db;
tables->table_name= tables->alias= name;
- if ((thd->security_ctx->master_access & want_access) == want_access &&
- !thd->db)
+ /*
+ The following test is just a shortcut for check_access() (to avoid
+ calculating db_access) under the assumption that it's common to
+ give persons global right to execute all stored SP (but not
+ necessary to create them).
+ */
+ if ((thd->security_ctx->master_access & want_access) == want_access)
tables->grant.privilege= want_access;
else if (check_access(thd,want_access,db,&tables->grant.privilege,
- 0, no_errors, test(tables->schema_table)))
+ 0, no_errors, 0))
return TRUE;
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -6133,14 +6154,12 @@
{
ptr->db= thd->db;
ptr->db_length= thd->db_length;
- ptr->current_db_used= 1;
}
else
{
/* The following can't be "" as we may do 'casedn_str()' on it */
ptr->db= empty_c_string;
ptr->db_length= 0;
- ptr->current_db_used= 1;
}
if (thd->stmt_arena->is_stmt_prepare_or_first_sp_execute())
ptr->db= thd->strdup(ptr->db);
@@ -7389,9 +7408,9 @@
Assign as view definer current user
SYNOPSIS
- default_definer()
- Secytity_context current decurity context
- definer structure where it should be assigned
+ default_view_definer()
+ sctx current security context
+ definer structure where it should be assigned
RETURN
FALSE OK
@@ -7402,15 +7421,14 @@
{
definer->user.str= sctx->priv_user;
definer->user.length= strlen(sctx->priv_user);
- if (*sctx->priv_host != 0)
- {
- definer->host.str= sctx->priv_host;
- definer->host.length= strlen(sctx->priv_host);
- }
- else
+
+ if (!*sctx->priv_host)
{
my_error(ER_NO_VIEW_USER, MYF(0));
return TRUE;
}
+
+ definer->host.str= sctx->priv_host;
+ definer->host.length= strlen(sctx->priv_host);
return FALSE;
}
--- 1.351/sql/sql_select.cc 2005-10-04 08:26:32 +02:00
+++ 1.352/sql/sql_select.cc 2005-10-18 17:19:07 +02:00
@@ -1377,7 +1377,7 @@
DBUG_PRINT("info",("Creating group table"));
/* Free first data from old join */
- curr_join->join_free(0);
+ curr_join->join_free();
if (make_simple_join(curr_join, curr_tmp_table))
DBUG_VOID_RETURN;
calc_group_buffer(curr_join, group_list);
@@ -1475,7 +1475,7 @@
if (curr_tmp_table->distinct)
curr_join->select_distinct=0; /* Each row is unique */
- curr_join->join_free(0); /* Free quick selects */
+ curr_join->join_free(); /* Free quick selects */
if (curr_join->select_distinct && ! curr_join->group_list)
{
thd->proc_info="Removing duplicates";
@@ -2474,11 +2474,11 @@
and use them in equality propagation process (see details in
OptimizerKBAndTodo)
*/
- if ((cond->functype() == Item_func::BETWEEN) &&
- value[0]->eq(value[1], field->binary()))
- eq_func= TRUE;
- else
+ if ((cond->functype() != Item_func::BETWEEN) ||
+ ((Item_func_between*) cond)->negated ||
+ !value[0]->eq(value[1], field->binary()))
return;
+ eq_func= TRUE;
}
if (field->result_type() == STRING_RESULT)
@@ -5719,33 +5719,88 @@
}
-void JOIN::join_free(bool full)
+/*
+ Partially cleanup JOIN after it has executed: close index or rnd read
+ (table cursors), free quick selects.
+
+ DESCRIPTION
+ This function is called in the end of execution of a JOIN, before the used
+ tables are unlocked and closed.
+
+ For a join that is resolved using a temporary table, the first sweep is
+ performed against actual tables and an intermediate result is inserted
+ into the temprorary table.
+ The last sweep is performed against the temporary table. Therefore,
+ the base tables and associated buffers used to fill the temporary table
+ are no longer needed, and this function is called to free them.
+
+ For a join that is performed without a temporary table, this function
+ is called after all rows are sent, but before EOF packet is sent.
+
+ For a simple SELECT with no subqueries this function performs a full
+ cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
+ tables.
+
+ If a JOIN is executed for a subquery or if it has a subquery, we can't
+ do the full cleanup and need to do a partial cleanup only.
+ o If a JOIN is not the top level join, we must not unlock the tables
+ because the outer select may not have been evaluated yet, and we
+ can't unlock only selected tables of a query.
+
+ o Additionally, if this JOIN corresponds to a correlated subquery, we
+ should not free quick selects and join buffers because they will be
+ needed for the next execution of the correlated subquery.
+
+ o However, if this is a JOIN for a [sub]select, which is not
+ a correlated subquery itself, but has subqueries, we can free it
+ fully and also free JOINs of all its subqueries. The exception
+ is a subquery in SELECT list, e.g:
+ SELECT a, (select max(b) from t1) group by c
+ This subquery will not be evaluated at first sweep and its value will
+ not be inserted into the temporary table. Instead, it's evaluated
+ when selecting from the temporary table. Therefore, it can't be freed
+ here even though it's not correlated.
+*/
+
+void JOIN::join_free()
{
SELECT_LEX_UNIT *unit;
SELECT_LEX *sl;
- DBUG_ENTER("JOIN::join_free");
-
/*
Optimization: if not EXPLAIN and we are done with the JOIN,
free all tables.
*/
- full= full || (!select_lex->uncacheable && !thd->lex->describe);
+ bool full= (!select_lex->uncacheable && !thd->lex->describe);
+ bool can_unlock= full;
+ DBUG_ENTER("JOIN::join_free");
cleanup(full);
for (unit= select_lex->first_inner_unit(); unit; unit= unit->next_unit())
for (sl= unit->first_select(); sl; sl= sl->next_select())
{
- JOIN *join= sl->join;
- if (join)
- join->join_free(full);
+ Item_subselect *subselect= sl->master_unit()->item;
+ bool full_local= full && (!subselect || subselect->is_evaluated());
+ /*
+ If this join is evaluated, we can fully clean it up and clean up all
+ its underlying joins even if they are correlated -- they will not be
+ used any more anyway.
+ If this join is not yet evaluated, we still must clean it up to
+ close its table cursors -- it may never get evaluated, as in case of
+ ... HAVING FALSE OR a IN (SELECT ...))
+ but all table cursors must be closed before the unlock.
+ */
+ sl->cleanup_all_joins(full_local);
+ /* Can't unlock if at least one JOIN is still needed */
+ can_unlock= can_unlock && full_local;
}
/*
We are not using tables anymore
Unlock all tables. We may be in an INSERT .... SELECT statement.
*/
- if (full && lock && thd->lock && !(select_options & SELECT_NO_UNLOCK) &&
+ if (can_unlock && lock && thd->lock &&
+ !(select_options & SELECT_NO_UNLOCK) &&
!select_lex->subquery_in_having &&
(select_lex == (thd->lex->unit.fake_select_lex ?
thd->lex->unit.fake_select_lex : &thd->lex->select_lex)))
@@ -5851,7 +5906,7 @@
tab->cached_eq_ref_table=1;
if (tab->type == JT_CONST) // We can skip const tables
return (tab->eq_ref_table=1); /* purecov: inspected */
- if (tab->type != JT_EQ_REF)
+ if (tab->type != JT_EQ_REF || tab->table->maybe_null)
return (tab->eq_ref_table=0); // We must use this
Item **ref_item=tab->ref.items;
Item **end=ref_item+tab->ref.key_parts;
@@ -6059,7 +6114,7 @@
DBUG_RETURN(0);
}
- join->join_free(0);
+ join->join_free();
if (send_row)
{
@@ -6254,6 +6309,21 @@
{
Item *left_item= ((Item_func*) item)->arguments()[0];
Item *right_item= ((Item_func*) item)->arguments()[1];
+
+ if (left_item->type() == Item::REF_ITEM &&
+ ((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF)
+ {
+ if (((Item_ref*)left_item)->depended_from)
+ return FALSE;
+ left_item= left_item->real_item();
+ }
+ if (right_item->type() == Item::REF_ITEM &&
+ ((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF)
+ {
+ if (((Item_ref*)right_item)->depended_from)
+ return FALSE;
+ right_item= right_item->real_item();
+ }
if (left_item->type() == Item::FIELD_ITEM &&
right_item->type() == Item::FIELD_ITEM &&
!((Item_field*)left_item)->depended_from &&
@@ -9004,7 +9074,7 @@
The following will unlock all cursors if the command wasn't an
update command
*/
- join->join_free(0); // Unlock all cursors
+ join->join_free(); // Unlock all cursors
if (join->result->send_eof())
rc= 1; // Don't send error
}
@@ -11340,7 +11410,7 @@
ulong total_length= 0;
for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
{
- uint length= (*ptr)->pack_length();
+ uint length= (*ptr)->sort_length();
(*field_length++)= length;
total_length+= length;
}
@@ -11880,11 +11950,16 @@
We check order_item->fixed because Item_func_group_concat can put
arguments for which fix_fields already was called.
*/
+ thd->lex->current_select->is_item_list_lookup= 1;
if (!order_item->fixed &&
(order_item->fix_fields(thd, order->item) ||
(order_item= *order->item)->check_cols(1) ||
thd->is_fatal_error))
+ {
+ thd->lex->current_select->is_item_list_lookup= 0;
return TRUE; /* Wrong field. */
+ }
+ thd->lex->current_select->is_item_list_lookup= 0;
uint el= all_fields.elements;
all_fields.push_front(order_item); /* Add new field to field list. */
--- 1.265/sql/sql_show.cc 2005-10-10 18:53:09 +02:00
+++ 1.266/sql/sql_show.cc 2005-10-18 17:19:07 +02:00
@@ -1023,6 +1023,11 @@
packet->append(" COMMENT=", 9);
append_unescaped(packet, share->comment, strlen(share->comment));
}
+ if (share->connect_string.length)
+ {
+ packet->append(" CONNECTION=", 12);
+ append_unescaped(packet, share->connect_string.str, share->connect_string.length);
+ }
if (file->raid_type)
{
uint length;
@@ -1258,9 +1263,6 @@
VOID(pthread_mutex_unlock(&LOCK_thread_count));
thread_info *thd_info;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- Security_context *sctx;
-#endif
time_t now= time(0);
while ((thd_info=thread_infos.get()))
{
@@ -2331,14 +2333,14 @@
table->field[7]->store((longlong) file->records, TRUE);
table->field[7]->set_notnull();
}
- table->field[8]->store((longlong) file->mean_rec_length);
- table->field[9]->store((longlong) file->data_file_length);
+ table->field[8]->store((longlong) file->mean_rec_length, TRUE);
+ table->field[9]->store((longlong) file->data_file_length, TRUE);
if (file->max_data_file_length)
{
- table->field[10]->store((longlong) file->max_data_file_length);
+ table->field[10]->store((longlong) file->max_data_file_length, TRUE);
}
- table->field[11]->store((longlong) file->index_file_length);
- table->field[12]->store((longlong) file->delete_length);
+ table->field[11]->store((longlong) file->index_file_length, TRUE);
+ table->field[12]->store((longlong) file->delete_length, TRUE);
if (show_table->found_next_number_field)
{
table->field[13]->store((longlong) file->auto_increment_value, TRUE);
@@ -2559,9 +2561,9 @@
{
longlong c_octet_len= is_blob ? (longlong) field->max_length() :
(longlong) field->max_length()/field->charset()->mbmaxlen;
- table->field[8]->store(c_octet_len, TRUE);
+ table->field[8]->store((longlong) field->max_length(), TRUE);
table->field[8]->set_notnull();
- table->field[9]->store((longlong) field->max_length());
+ table->field[9]->store(c_octet_len, TRUE);
table->field[9]->set_notnull();
}
@@ -2602,7 +2604,7 @@
if (field_length >= 0)
{
- table->field[10]->store((longlong) field_length);
+ table->field[10]->store((longlong) field_length, TRUE);
table->field[10]->set_notnull();
}
if (decimals >= 0)
--- 1.274/sql/sql_table.cc 2005-10-10 18:53:10 +02:00
+++ 1.275/sql/sql_table.cc 2005-10-18 17:19:07 +02:00
@@ -1571,7 +1571,7 @@
DBUG_RETURN(TRUE);
}
if (wait_if_global_read_lock(thd, 0, 1))
- DBUG_RETURN(error);
+ DBUG_RETURN(TRUE);
VOID(pthread_mutex_lock(&LOCK_open));
if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
{
@@ -1646,20 +1646,20 @@
mysql_bin_log.write(&qinfo);
}
error= FALSE;
- goto end;
-
-warn:
- error= 0;
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
- alias);
- create_info->table_existed= 1; // Mark that table existed
end:
VOID(pthread_mutex_unlock(&LOCK_open));
start_waiting_global_read_lock(thd);
thd->proc_info="After create";
DBUG_RETURN(error);
+
+warn:
+ error= FALSE;
+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+ ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
+ alias);
+ create_info->table_existed= 1; // Mark that table existed
+ goto end;
}
/*
@@ -1960,8 +1960,8 @@
{
char* backup_dir= thd->lex->backup_dir;
char src_path[FN_REFLEN], dst_path[FN_REFLEN];
- char* table_name = table->table_name;
- char* db = thd->db ? thd->db : table->db;
+ char* table_name= table->table_name;
+ char* db= table->db;
if (fn_format_relative_to_data_home(src_path, table_name, backup_dir,
reg_ext))
@@ -1997,12 +1997,15 @@
Now we should be able to open the partially restored table
to finish the restore in the handler later on
*/
- if (!(table->table = reopen_name_locked_table(thd, table)))
+ pthread_mutex_lock(&LOCK_open);
+ if (reopen_name_locked_table(thd, table))
{
- pthread_mutex_lock(&LOCK_open);
unlock_table_name(thd, table);
pthread_mutex_unlock(&LOCK_open);
+ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
+ "Failed to open partially restored table"));
}
+ pthread_mutex_unlock(&LOCK_open);
DBUG_RETURN(0);
}
@@ -2099,12 +2102,16 @@
Now we should be able to open the partially repaired table
to finish the repair in the handler later on.
*/
- if (!(table_list->table = reopen_name_locked_table(thd, table_list)))
+ pthread_mutex_lock(&LOCK_open);
+ if (reopen_name_locked_table(thd, table_list))
{
- pthread_mutex_lock(&LOCK_open);
unlock_table_name(thd, table_list);
pthread_mutex_unlock(&LOCK_open);
+ error= send_check_errmsg(thd, table_list, "repair",
+ "Failed to open partially repaired table");
+ goto end;
}
+ pthread_mutex_unlock(&LOCK_open);
end:
if (table == &tmp_table)
@@ -3166,15 +3173,14 @@
if (create_info->row_type == ROW_TYPE_NOT_USED)
create_info->row_type= table->s->row_type;
- DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type));
- if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED)
- || ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
+ DBUG_PRINT("info", ("old type: %d new type: %d", old_db_type, new_db_type));
+ if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
+ ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
{
DBUG_PRINT("info", ("doesn't support alter"));
my_error(ER_ILLEGAL_HA, MYF(0), table_name);
DBUG_RETURN(TRUE);
}
- DBUG_PRINT("info", ("supports alter"));
thd->proc_info="setup";
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
--- 1.184/sql/table.cc 2005-10-10 18:53:10 +02:00
+++ 1.185/sql/table.cc 2005-10-18 17:19:08 +02:00
@@ -300,6 +300,43 @@
}
#endif
+ record_offset= (ulong) (uint2korr(head+6)+
+ ((uint2korr(head+14) == 0xffff ?
+ uint4korr(head+47) : uint2korr(head+14))));
+
+ if ((n_length= uint2korr(head+55)))
+ {
+ /* Read extra data segment */
+ char *buff, *next_chunk, *buff_end;
+ if (!(next_chunk= buff= my_malloc(n_length, MYF(MY_WME))))
+ goto err;
+ buff_end= buff + n_length;
+ if (my_pread(file, (byte*)buff, n_length, record_offset + share->reclength,
+ MYF(MY_NABP)))
+ {
+ my_free(buff, MYF(0));
+ goto err;
+ }
+ share->connect_string.length= uint2korr(buff);
+ if (! (share->connect_string.str= strmake_root(&outparam->mem_root,
+ next_chunk + 2, share->connect_string.length)))
+ {
+ my_free(buff, MYF(0));
+ goto err;
+ }
+ next_chunk+= share->connect_string.length + 2;
+ if (next_chunk + 2 < buff_end)
+ {
+ uint str_db_type_length= uint2korr(next_chunk);
+ share->db_type= ha_resolve_by_name(next_chunk + 2, str_db_type_length);
+ DBUG_PRINT("enter", ("Setting dbtype to: %d - %d - '%.*s'\n",
+ share->db_type,
+ str_db_type_length, str_db_type_length,
+ next_chunk + 2));
+ next_chunk+= str_db_type_length + 2;
+ }
+ my_free(buff, MYF(0));
+ }
/* Allocate handler */
if (!(outparam->file= get_new_handler(outparam, share->db_type)))
goto err;
@@ -323,9 +360,6 @@
outparam->write_row_record= NULL;
share->default_values= (byte *) record;
- record_offset= (ulong) (uint2korr(head+6)+
- ((uint2korr(head+14) == 0xffff ?
- uint4korr(head+47) : uint2korr(head+14))));
if (my_pread(file,(byte*) record, (uint) share->reclength,
record_offset, MYF(MY_NABP)))
goto err; /* purecov: inspected */
@@ -343,20 +377,7 @@
else
outparam->record[1]= outparam->record[0]; // Safety
}
-
- if ((n_length= uint2korr(head+55)))
- {
- /* Read extra block information */
- char *buff;
- if (!(buff= alloc_root(&outparam->mem_root, n_length)))
- goto err;
- if (my_pread(file, (byte*)buff, n_length, record_offset + share->reclength,
- MYF(MY_NABP)))
- goto err;
- share->connect_string.length= uint2korr(buff);
- share->connect_string.str= buff+2;
- }
-
+
#ifdef HAVE_purify
/*
We need this because when we read var-length rows, we are not updating
@@ -458,9 +479,11 @@
{
outparam->null_flags=null_pos=(uchar*) record+1;
null_bit_pos= (db_create_options & HA_OPTION_PACK_RECORD) ? 0 : 1;
- /* null_bytes below is only correct under the condition that
- there are no bit fields. Correct values is set below after the
- table struct is initialized */
+ /*
+ null_bytes below is only correct under the condition that
+ there are no bit fields. Correct values is set below after the
+ table struct is initialized
+ */
share->null_bytes= (share->null_fields + null_bit_pos + 7) / 8;
}
else
@@ -873,8 +896,12 @@
}
}
- /* the correct null_bytes can now be set, since bitfields have been taken into account */
- share->null_bytes= null_pos - (uchar*) outparam->null_flags + (null_bit_pos + 7) / 8;
+ /*
+ the correct null_bytes can now be set, since bitfields have been taken
+ into account
+ */
+ share->null_bytes= (null_pos - (uchar*) outparam->null_flags +
+ (null_bit_pos + 7) / 8);
share->last_null_bit_pos= null_bit_pos;
/* The table struct is now initialized; Open the table */
@@ -1377,15 +1404,10 @@
ulong length;
char fill[IO_SIZE];
int create_flags= O_RDWR | O_TRUNC;
- uint extra_size;
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
create_flags|= O_EXCL | O_NOFOLLOW;
- extra_size= 0;
- if (create_info->connect_string.length)
- extra_size= 2+create_info->connect_string.length;
-
#if SIZEOF_OFF_T > 4
/* Fix this when we have new .frm files; Current limit is 4G rows (QQ) */
if (create_info->max_rows > ~(ulong) 0)
@@ -1413,7 +1435,8 @@
fileinfo[4]=1;
int2store(fileinfo+6,IO_SIZE); /* Next block starts here */
key_length=keys*(7+NAME_LEN+MAX_REF_PARTS*9)+16;
- length= next_io_size((ulong) (IO_SIZE+key_length+reclength+extra_size));
+ length= next_io_size((ulong) (IO_SIZE+key_length+reclength+
+ create_info->extra_size));
int4store(fileinfo+10,length);
tmp_key_length= (key_length < 0xffff) ? key_length : 0xffff;
int2store(fileinfo+14,tmp_key_length);
@@ -1435,7 +1458,7 @@
int4store(fileinfo+47, key_length);
tmp= MYSQL_VERSION_ID; // Store to avoid warning from int4store
int4store(fileinfo+51, tmp);
- int2store(fileinfo+55, extra_size);
+ int2store(fileinfo+55, create_info->extra_size);
bzero(fill,IO_SIZE);
for (; length > IO_SIZE ; length-= IO_SIZE)
{
--- 1.110/sql/table.h 2005-10-10 18:53:10 +02:00
+++ 1.111/sql/table.h 2005-10-18 17:19:08 +02:00
@@ -589,8 +589,6 @@
bool compact_view_format; /* Use compact format for SHOW CREATE VIEW */
/* view where processed */
bool where_processed;
- /* db part was not defined in table definition */
- bool current_db_used;
/* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type;
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
--- 1.127/sql/sql_union.cc 2005-09-27 22:13:21 +02:00
+++ 1.128/sql/sql_union.cc 2005-10-18 17:19:08 +02:00
@@ -720,3 +720,17 @@
DBUG_RETURN(error);
}
+
+void st_select_lex::cleanup_all_joins(bool full)
+{
+ SELECT_LEX_UNIT *unit;
+ SELECT_LEX *sl;
+
+ if (join)
+ join->cleanup(full);
+
+ for (unit= first_inner_unit(); unit; unit= unit->next_unit())
+ for (sl= unit->first_select(); sl; sl= sl->next_select())
+ sl->cleanup_all_joins(full);
+}
+
--- 1.51/sql/share/errmsg.txt 2005-10-10 18:53:10 +02:00
+++ 1.52/sql/share/errmsg.txt 2005-10-18 17:55:30 +02:00
@@ -5420,5 +5420,7 @@
eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)"
ER_NO_REFERENCED_ROW_2 23000
eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)"
+ER_SP_BAD_VAR_SHADOW 42000
+ eng "Variable '%-.64s' must be quoted with `...`, or renamed"
ER_BINLOG_ROW_LOGGING_FAILED
eng "Writing one row to the row-based binary log failed"
--- 1.72/mysql-test/t/ctype_utf8.test 2005-10-10 18:53:03 +02:00
+++ 1.73/mysql-test/t/ctype_utf8.test 2005-10-18 17:18:59 +02:00
@@ -853,6 +853,14 @@
select hex(a) from t1;
drop table t1;
+#
+# Bug#13751 find_in_set: Illegal mix of collations
+#
+set names 'latin1';
+create table t1 (a varchar(255)) default charset=utf8;
+select * from t1 where find_in_set('-1', a);
+drop table t1;
+
# End of 4.1 tests
#
@@ -873,18 +881,32 @@
#
set names utf8;
# correct value
-select hex(char(1));
-select char(0xd1,0x8f);
-select char(0xd18f);
-select char(53647);
+select hex(char(1 using utf8));
+select char(0xd1,0x8f using utf8);
+select char(0xd18f using utf8);
+select char(53647 using utf8);
# incorrect value: return with warning
-select char(0xff,0x8f);
+select char(0xff,0x8f using utf8);
# incorrect value in strict mode: return NULL with "Error" level warning
set sql_mode=traditional;
-select char(0xff,0x8f);
-select char(195);
-select char(196);
-select char(2557);
+select char(0xff,0x8f using utf8);
+select char(195 using utf8);
+select char(196 using utf8);
+select char(2557 using utf8);
+
+#
+# Check convert + char + using
+#
+select hex(convert(char(2557 using latin1) using utf8));
+
+#
+# char() without USING returns "binary" by default, any argument is ok
+#
+select hex(char(195));
+select hex(char(196));
+select hex(char(2557));
+
+
#
# Bug#12891: UNION doesn't return DISTINCT result for multi-byte characters
--- 1.5.3.1/mysql-test/r/rpl_sp.result 2005-10-12 21:42:40 +02:00
+++ 1.11/mysql-test/r/rpl_stm_sp.result 2005-10-18 17:18:59 +02:00
@@ -4,16 +4,11 @@
reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave;
-create database if not exists mysqltest1;
+drop database if exists mysqltest1;
+create database mysqltest1;
use mysqltest1;
create table t1 (a varchar(100));
use mysqltest1;
-drop procedure if exists foo;
-drop procedure if exists foo2;
-drop procedure if exists foo3;
-drop procedure if exists foo4;
-drop procedure if exists bar;
-drop function if exists fn1;
create procedure foo()
begin
declare b int;
@@ -22,10 +17,6 @@
insert into t1 values (unix_timestamp());
end|
ERROR HY000: This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
-show binlog events from 98|
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # create database if not exists mysqltest1
-master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100))
create procedure foo() deterministic
begin
declare b int;
@@ -51,17 +42,6 @@
end @ # #
set timestamp=1000000000;
call foo();
-show binlog events from 308;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo() deterministic
-begin
-declare b int;
-set b = 8;
-insert into t1 values (b);
-insert into t1 values (unix_timestamp());
-end
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
select * from t1;
a
8
@@ -77,15 +57,6 @@
select * from mysqltest1.t1;
call foo2();
a
-show binlog events from 518;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
-master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
-master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo2()
-not deterministic
-reads sql data
-select * from mysqltest1.t1
alter procedure foo2 contains sql;
ERROR HY000: This routine has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_routine_creators variable)
drop table t1;
@@ -109,7 +80,7 @@
insert into t1 values (5);
end|
call foo4();
-Got one of the listed errors
+ERROR 42000: INSERT command denied to user 'zedjzlcsjhd'@'localhost' for table 't1'
show warnings;
Level Code Message
Error 1142 INSERT command denied to user 'zedjzlcsjhd'@'localhost' for table 't1'
@@ -118,7 +89,7 @@
show warnings;
Level Code Message
call foo4();
-Got one of the listed errors
+ERROR 42000: INSERT command denied to user 'zedjzlcsjhd'@'127.0.0.1' for table 't1'
show warnings;
Level Code Message
Error 1142 INSERT command denied to user 'zedjzlcsjhd'@'127.0.0.1' for table 't1'
@@ -127,29 +98,6 @@
call foo4();
show warnings;
Level Code Message
-show binlog events from 990;
-Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1
-master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int)
-master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1
-master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo3()
-deterministic
-insert into t1 values (15)
-master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1
-master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1
-master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1
-master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
-deterministic
-begin
-insert into t2 values(3);
-insert into t1 values (5);
-end
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (15)
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
-master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo4 sql security invoker
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
-master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (5)
select * from t1;
a
15
@@ -168,11 +116,30 @@
3
3
3
+delete from t2;
+alter table t2 add unique (a);
+drop procedure foo4;
+create procedure foo4()
+deterministic
+begin
+insert into t2 values(20),(20);
+end|
+call foo4();
+ERROR 23000: Duplicate entry '20' for key 1
+show warnings;
+Level Code Message
+Error 1062 Duplicate entry '20' for key 1
+Warning 1417 A routine failed and has neither NO SQL nor READS SQL DATA in its declaration and binary logging is enabled; if non-transactional tables were updated, the binary log will miss their changes
+select * from t2;
+a
+20
+select * from t2;
+a
+20
select * from mysql.proc where name="foo4" and db='mysqltest1';
db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment
-mysqltest1 foo4 PROCEDURE foo4 SQL CONTAINS_SQL YES INVOKER begin
-insert into t2 values(3);
-insert into t1 values (5);
+mysqltest1 foo4 PROCEDURE foo4 SQL CONTAINS_SQL YES DEFINER begin
+insert into t2 values(20),(20);
end @ # #
drop procedure foo4;
select * from mysql.proc where name="foo4" and db='mysqltest1';
@@ -237,7 +204,6 @@
end @ # #
create trigger trg before insert on t1 for each row set new.a= 10;
ERROR 42000: Access denied; you need the SUPER privilege for this operation
-flush logs;
delete from t1;
create trigger trg before insert on t1 for each row set new.a= 10;
insert into t1 values (1);
@@ -253,14 +219,84 @@
select * from t1;
a
1
-show binlog events in 'master-bin.000002' from 98;
+show binlog events from 102;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1
-master-bin.000002 # Query 1 # use `mysqltest1`; create trigger trg before insert on t1 for each row set new.a= 10
-master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1)
-master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1
-master-bin.000002 # Query 1 # use `mysqltest1`; drop trigger trg
-master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1)
+master-bin.000001 # Query 1 # drop database if exists mysqltest1
+master-bin.000001 # Query 1 # create database mysqltest1
+master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a varchar(100))
+master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo() deterministic
+begin
+declare b int;
+set b = 8;
+insert into t1 values (b);
+insert into t1 values (unix_timestamp());
+end
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values ( NAME_CONST('b',8))
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (unix_timestamp())
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
+master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo2()
+not deterministic
+reads sql data
+select * from mysqltest1.t1
+master-bin.000001 # Query 1 # use `mysqltest1`; drop table t1
+master-bin.000001 # Query 1 # use `mysqltest1`; create table t1 (a int)
+master-bin.000001 # Query 1 # use `mysqltest1`; create table t2 like t1
+master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo3()
+deterministic
+insert into t1 values (15)
+master-bin.000001 # Query 1 # use `mysqltest1`; grant CREATE ROUTINE, EXECUTE on mysqltest1.* to "zedjzlcsjhd"@127.0.0.1
+master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT on mysqltest1.t1 to "zedjzlcsjhd"@127.0.0.1
+master-bin.000001 # Query 1 # use `mysqltest1`; grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1
+master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
+deterministic
+begin
+insert into t2 values(3);
+insert into t1 values (5);
+end
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (15)
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
+master-bin.000001 # Query 1 # use `mysqltest1`; alter procedure foo4 sql security invoker
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(3)
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (5)
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t2
+master-bin.000001 # Query 1 # use `mysqltest1`; alter table t2 add unique (a)
+master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo4
+master-bin.000001 # Query 1 # use `mysqltest1`; create procedure foo4()
+deterministic
+begin
+insert into t2 values(20),(20);
+end
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(20),(20)
+master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo4
+master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo
+master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo2
+master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo3
+master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1(x int)
+returns int
+deterministic
+begin
+insert into t1 values (x);
+return x+2;
+end
+master-bin.000001 # Query 1 # use `mysqltest1`; delete t1,t2 from t1,t2
+master-bin.000001 # Query 1 # use `mysqltest1`; DO `fn1`(20)
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t2 values(fn1(21))
+master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1
+master-bin.000001 # Query 1 # use `mysqltest1`; create function fn1()
+returns int
+deterministic
+begin
+return unix_timestamp();
+end
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values(fn1())
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
+master-bin.000001 # Query 1 # use `mysqltest1`; create trigger trg before insert on t1 for each row set new.a= 10
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1)
+master-bin.000001 # Query 1 # use `mysqltest1`; delete from t1
+master-bin.000001 # Query 1 # use `mysqltest1`; drop trigger trg
+master-bin.000001 # Query 1 # use `mysqltest1`; insert into t1 values (1)
select * from t1;
a
1
--- 1.4.3.1/mysql-test/t/rpl_sp.test 2005-10-12 21:42:40 +02:00
+++ 1.10/mysql-test/t/rpl_stm_sp.test 2005-10-18 17:18:59 +02:00
@@ -1,10 +1,15 @@
+# row-based and statement have expected binlog difference in result files
+-- source include/have_binlog_format_statement.inc
+
# Test of replication of stored procedures (WL#2146 for MySQL 5.0)
-source include/master-slave.inc;
+-- source include/master-slave.inc
-# First let's test replication of current_user() (that's a related thing)
# we need a db != test, where we don't have automatic grants
-create database if not exists mysqltest1;
+--disable_warnings
+drop database if exists mysqltest1;
+--enable_warnings
+create database mysqltest1;
use mysqltest1;
create table t1 (a varchar(100));
sync_slave_with_master;
@@ -13,20 +18,13 @@
# ********************** PART 1 : STORED PROCEDURES ***************
# Does the same proc as on master get inserted into mysql.proc ?
-# (same definer, same properties...)
+# (almost all properties should be same; definer is an exception
+# (known problem - Alik@stripped is working on it - Oct 1st 2005))
connection master;
-# cleanup
---disable_warnings
-drop procedure if exists foo;
-drop procedure if exists foo2;
-drop procedure if exists foo3;
-drop procedure if exists foo4;
-drop procedure if exists bar;
-drop function if exists fn1;
---enable_warnings
delimiter |;
+
--error 1418 # not deterministic
create procedure foo()
begin
@@ -36,9 +34,6 @@
insert into t1 values (unix_timestamp());
end|
---replace_column 2 # 5 #
-show binlog events from 98| # check that not there
-
create procedure foo() deterministic
begin
declare b int;
@@ -58,21 +53,16 @@
--replace_column 13 # 14 #
select * from mysql.proc where name='foo' and db='mysqltest1';
-# Now when we call it, does the CALL() get into binlog,
-# or the substatements?
connection master;
# see if timestamp used in SP on slave is same as on master
set timestamp=1000000000;
call foo();
---replace_column 2 # 5 #
-show binlog events from 308;
select * from t1;
sync_slave_with_master;
select * from t1;
-# Now a SP which is supposed to not update tables (CALL should not be
-# binlogged) as it's "read sql data", so should not give error even if
-# non-deterministic.
+# Now a SP which is supposed to not update tables (it's "read sql
+# data") , so should not give error even if non-deterministic.
connection master;
delete from t1;
@@ -81,9 +71,6 @@
reads sql data
select * from mysqltest1.t1;
call foo2();
-# verify CALL is not in binlog
---replace_column 2 # 5 #
-show binlog events from 518;
--error 1418
alter procedure foo2 contains sql;
@@ -115,6 +102,7 @@
set global log_bin_trust_routine_creators=1;
connection con1;
+# this routine will fail in the second INSERT because of privileges
delimiter |;
create procedure foo4()
deterministic
@@ -125,18 +113,15 @@
delimiter ;|
-# I add ,0 so that it does not print the error in the test output,
-# because this error is hostname-dependent
---error 1142,0
-call foo4(); # invoker has no INSERT grant on table => failure
+--error 1142
+call foo4(); # invoker has no INSERT grant on table t1 => failure
show warnings;
connection master;
call foo3(); # success (definer == root)
show warnings;
---replace_result localhost.localdomain localhost 127.0.0.1 localhost
---error 1142,0
+--error 1142
call foo4(); # definer's rights => failure
show warnings;
@@ -145,12 +130,9 @@
call foo4(); # invoker's rights => success
show warnings;
-# Check that only successful CALLs are in binlog
---replace_column 2 # 5 #
-show binlog events from 990;
-
-# Note that half-failed CALLs are not in binlog, which is a known
-# bug. If we compare t2 on master and slave we see they differ:
+# Thanks to the statement-based replication of CALL (binlogging
+# substatements) done in Aug 2005 by SergeyP, half-failed CALL does
+# not break replication anymore:
select * from t1;
select * from t2;
@@ -158,6 +140,30 @@
select * from t1;
select * from t2;
+# Let's check another failing-in-the-middle procedure
+connection master;
+delete from t2;
+alter table t2 add unique (a);
+
+drop procedure foo4;
+delimiter |;
+create procedure foo4()
+ deterministic
+ begin
+ insert into t2 values(20),(20);
+ end|
+
+delimiter ;|
+
+--error 1062
+call foo4();
+show warnings;
+
+select * from t2;
+sync_slave_with_master;
+# did all these failed-in-the-middle replicate right:
+select * from t2;
+
# Test of DROP PROCEDURE
--replace_result localhost.localdomain localhost 127.0.0.1 localhost
@@ -230,17 +236,13 @@
create trigger trg before insert on t1 for each row set new.a= 10;
connection master;
-# fn1() above uses timestamps, so in !ps-protocol, the timezone will be
-# binlogged, but in --ps-protocol it will not be (BUG#9359) so
-# the binlog offsets get shifted which spoils SHOW BINLOG EVENTS.
-# To be immune, we take a new binlog.
-flush logs;
delete from t1;
# TODO: when triggers can contain an update, test that this update
# does not go into binlog.
# I'm not setting user vars in the trigger, because replication of user vars
# would take care of propagating the user var's value to slave, so even if
# the trigger was not executed on slave it would not be discovered.
+
create trigger trg before insert on t1 for each row set new.a= 10;
insert into t1 values (1);
select * from t1;
@@ -252,8 +254,12 @@
drop trigger trg;
insert into t1 values (1);
select * from t1;
+
+# now inspect binlog
+
--replace_column 2 # 5 #
-show binlog events in 'master-bin.000002' from 98;
+show binlog events from 102;
+
sync_slave_with_master;
select * from t1;
--- 1.5/mysql-test/r/user_var-binlog.result 2005-10-04 08:26:25 +02:00
+++ 1.6/mysql-test/r/user_var-binlog.result 2005-10-18 17:55:30 +02:00
@@ -11,7 +11,7 @@
master-bin.000001 # User var 1 # @`a b`=_latin1 0x68656C6C6F COLLATE latin1_swedish_ci
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES(@`a b`)
master-bin.000001 # User var 1 # @`var1`=_latin1 0x273B616161 COLLATE latin1_swedish_ci
-master-bin.000001 # User var 1 # @`var2`=_latin1 0x61 COLLATE latin1_swedish_ci
+master-bin.000001 # User var 1 # @`var2`=_latin1 0x61 COLLATE binary
master-bin.000001 # Query 1 # use `test`; insert into t1 values (@var1),(@var2)
/*!40019 SET @@session.max_insert_delayed_threads=0*/;
/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
@@ -24,7 +24,7 @@
SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8;
INSERT INTO t1 VALUES(@`a b`);
SET @`var1`:=_latin1 0x273B616161 COLLATE `latin1_swedish_ci`;
-SET @`var2`:=_latin1 0x61 COLLATE `latin1_swedish_ci`;
+SET @`var2`:=_binary 0x61 COLLATE `binary`;
SET TIMESTAMP=10000;
insert into t1 values (@var1),(@var2);
# End of log file
--- 1.41/mysql-test/mysql-test-run.pl 2005-10-04 08:26:25 +02:00
+++ 1.42/mysql-test/mysql-test-run.pl 2005-10-18 17:18:58 +02:00
@@ -171,6 +171,7 @@
our $exe_mysqlbinlog;
our $exe_mysql_client_test;
our $exe_mysqld;
+our $exe_mysqlcheck; # Called from test case
our $exe_mysqldump; # Called from test case
our $exe_mysqlshow; # Called from test case
our $exe_mysql_fix_system_tables;
@@ -233,6 +234,7 @@
our $opt_skip;
our $opt_skip_rpl;
our $opt_skip_test;
+our $opt_skip_im;
our $opt_sleep;
our $opt_ps_protocol;
@@ -490,6 +492,7 @@
'do-test=s' => \$opt_do_test,
'suite=s' => \$opt_suite,
'skip-rpl' => \$opt_skip_rpl,
+ 'skip-im' => \$opt_skip_im,
'skip-test=s' => \$opt_skip_test,
# Specify ports
@@ -840,8 +843,8 @@
server_id => 1,
port => $im_mysqld1_port,
path_datadir => "$opt_vardir/im_mysqld_1.data",
- path_sock => "$opt_vardir/mysqld_1.sock",
- path_pid => "$opt_vardir/mysqld_1.pid",
+ path_sock => "$opt_tmpdir/mysqld_1.sock",
+ path_pid => "$opt_vardir/run/mysqld_1.pid",
};
$instance_manager->{'instances'}->[1]=
@@ -849,8 +852,8 @@
server_id => 2,
port => $im_mysqld2_port,
path_datadir => "$opt_vardir/im_mysqld_2.data",
- path_sock => "$opt_vardir/mysqld_2.sock",
- path_pid => "$opt_vardir/mysqld_2.pid",
+ path_sock => "$opt_tmpdir/mysqld_2.sock",
+ path_pid => "$opt_vardir/run/mysqld_2.pid",
nonguarded => 1,
};
@@ -909,6 +912,7 @@
mtr_exe_exists("$glob_basedir/tests/mysql_client_test",
"/usr/bin/false");
}
+ $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
$exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
$exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
$exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
@@ -924,6 +928,7 @@
else
{
$path_client_bindir= mtr_path_exists("$glob_basedir/bin");
+ $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck");
$exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump");
$exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow");
$exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog");
@@ -1118,7 +1123,7 @@
foreach my $instance (@{$instance_manager->{'instances'}})
{
- push (@data_dir_lst, $instance->{'path_datadir'});
+ push(@data_dir_lst, $instance->{'path_datadir'});
}
foreach my $data_dir (@data_dir_lst)
@@ -1364,7 +1369,7 @@
install_db('slave', $slave->[1]->{'path_myddir'});
install_db('slave', $slave->[2]->{'path_myddir'});
- if ( defined $exe_im)
+ if ( ! $opt_skip_im )
{
im_prepare_env($instance_manager);
}
@@ -1513,12 +1518,7 @@
EOF
;
- if ( exists $instance->{nonguarded} and
- defined $instance->{nonguarded} )
- {
- print OUT "nonguarded\n";
- }
-
+ print OUT "nonguarded\n" if $instance->{'nonguarded'};
print OUT "\n";
}
@@ -1678,7 +1678,7 @@
$master->[0]->{'running_master_is_special'}= 1;
}
}
- elsif ( $tinfo->{'component_id'} eq 'im')
+ elsif ( ! $opt_skip_im and $tinfo->{'component_id'} eq 'im' )
{
# We have to create defaults file every time, in order to ensure that it
# will be the same for each test. The problem is that test can change the
@@ -1776,7 +1776,8 @@
# Stop Instance Manager if we are processing an IM-test case.
# ----------------------------------------------------------------------
- if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' )
+ if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' and
+ $instance_manager->{'pid'} )
{
im_stop($instance_manager);
}
@@ -2195,7 +2196,7 @@
print "Ending Tests\n";
- if (defined $instance_manager->{'pid'})
+ if ( $instance_manager->{'pid'} )
{
print "Shutting-down Instance Manager\n";
im_stop($instance_manager);
@@ -2269,14 +2270,10 @@
my $instance_manager = shift;
my $opts = shift;
- if ( ! defined $exe_im)
- {
- return;
- }
-
my $args;
mtr_init_args(\$args);
- mtr_add_arg($args, "--defaults-file=" . $instance_manager->{'defaults_file'});
+ mtr_add_arg($args, "--defaults-file=%s",
+ $instance_manager->{'defaults_file'});
foreach my $opt (@{$opts})
{
@@ -2294,7 +2291,7 @@
{ append_log_file => 1 } # append log files
);
- if ( ! defined $instance_manager->{'pid'} )
+ if ( ! $instance_manager->{'pid'} )
{
mtr_report('Could not start Instance Manager');
return;
@@ -2304,10 +2301,14 @@
# several processes and the parent process, created by mtr_spawn(), exits just
# after start. So, we have to obtain Instance Manager PID from the PID file.
- sleep_until_file_created(
- $instance_manager->{'path_pid'},
- $instance_manager->{'start_timeout'},
- -1); # real PID is still unknown
+ if ( ! sleep_until_file_created(
+ $instance_manager->{'path_pid'},
+ $instance_manager->{'start_timeout'},
+ -1)) # real PID is still unknown
+ {
+ mtr_report("Instance Manager PID file is missing");
+ return;
+ }
$instance_manager->{'pid'} =
mtr_get_pid_from_file($instance_manager->{'path_pid'});
@@ -2316,16 +2317,12 @@
sub im_stop($) {
my $instance_manager = shift;
- if (! defined $instance_manager->{'pid'})
- {
- return;
- }
-
# Re-read pid from the file, since during tests Instance Manager could have
# been restarted, so its pid could have been changed.
$instance_manager->{'pid'} =
- mtr_get_pid_from_file($instance_manager->{'path_pid'});
+ mtr_get_pid_from_file($instance_manager->{'path_pid'})
+ if -f $instance_manager->{'path_pid'};
# Inspired from mtr_stop_mysqld_servers().
@@ -2340,12 +2337,12 @@
if ( -r $instances->[0]->{'path_pid'} )
{
- push @pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'});
+ push(@pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}));
}
if ( -r $instances->[1]->{'path_pid'} )
{
- push @pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'});
+ push(@pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}));
}
# Kill processes.
@@ -2360,6 +2357,15 @@
sub run_mysqltest ($) {
my $tinfo= shift;
+ my $cmdline_mysqlcheck= "$exe_mysqlcheck --no-defaults -uroot " .
+ "--port=$master->[0]->{'path_myport'} " .
+ "--socket=$master->[0]->{'path_mysock'} --password=";
+ if ( $opt_debug )
+ {
+ $cmdline_mysqlcheck .=
+ " --debug=d:t:A,$opt_vardir/log/mysqldump.trace";
+ }
+
my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .
"--port=$master->[0]->{'path_myport'} " .
"--socket=$master->[0]->{'path_mysock'} --password=";
@@ -2423,6 +2429,7 @@
# $ENV{'PATH'}= "/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$ENV{'PATH'}";
$ENV{'MYSQL'}= $cmdline_mysql;
+ $ENV{'MYSQL_CHECK'}= $cmdline_mysqlcheck;
$ENV{'MYSQL_DUMP'}= $cmdline_mysqldump;
$ENV{'MYSQL_DUMP_SLAVE'}= $cmdline_mysqldumpslave;
$ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow;
@@ -2606,6 +2613,7 @@
start-from=PREFIX Run test cases starting from test prefixed with PREFIX
suite=NAME Run the test suite named NAME. The default is "main"
skip-rpl Skip the replication test cases.
+ skip-im Don't start IM, and skip the IM test cases
skip-test=PREFIX Skip test cases which name are prefixed with PREFIX
Options that specify ports
--- 1.4.2.1/mysql-test/t/rpl_ddl.test 2005-10-13 11:12:07 +02:00
+++ 1.9/mysql-test/t/rpl_stm_ddl.test 2005-10-18 17:18:59 +02:00
@@ -29,6 +29,7 @@
#
--source include/have_innodb.inc
+--source include/have_binlog_format_statement.inc
--source include/master-slave.inc
###############################################################
--- 1.247/sql/ha_innodb.cc 2005-10-10 18:53:04 +02:00
+++ 1.248/sql/ha_innodb.cc 2005-10-18 17:19:00 +02:00
@@ -7043,8 +7043,7 @@
(const char*)ref1, len1,
(const char*)ref2, len2);
} else {
- result = field->key_cmp((const char*)ref1,
- (const char*)ref2);
+ result = field->key_cmp(ref1, ref2);
}
if (result) {
--- 1.159/mysql-test/t/sp.test 2005-10-17 17:08:55 +02:00
+++ 1.160/mysql-test/t/sp.test 2005-10-18 17:18:59 +02:00
@@ -4148,9 +4148,13 @@
--error 1062
select bug12379()|
select 1|
+# statement-based binlogging will show warning which row-based won't;
+# so we hide it (this warning is already tested in rpl_stm_sp.test)
+--disable_warnings
call bug12379_1()|
select 2|
call bug12379_2()|
+--enable_warnings
select 3|
--error 1062
call bug12379_3()|
--- 1.92/sql/sp.cc 2005-09-30 18:00:16 +02:00
+++ 1.93/sql/sp.cc 2005-10-18 17:19:04 +02:00
@@ -208,7 +208,7 @@
{
byte key[MAX_KEY_LENGTH]; // db, name, optional key length type
DBUG_ENTER("db_find_routine_aux");
- DBUG_PRINT("enter", ("type: %d name: %*s",
+ DBUG_PRINT("enter", ("type: %d name: %.*s",
type, name->m_name.length, name->m_name.str));
/*
@@ -275,7 +275,7 @@
ulong sql_mode;
Open_tables_state open_tables_state_backup;
DBUG_ENTER("db_find_routine");
- DBUG_PRINT("enter", ("type: %d name: %*s",
+ DBUG_PRINT("enter", ("type: %d name: %.*s",
type, name->m_name.length, name->m_name.str));
*sphp= 0; // In case of errors
@@ -479,7 +479,8 @@
char olddb[128];
bool dbchanged;
DBUG_ENTER("db_create_routine");
- DBUG_PRINT("enter", ("type: %d name: %*s",type,sp->m_name.length,sp->m_name.str));
+ DBUG_PRINT("enter", ("type: %d name: %.*s",type,sp->m_name.length,
+ sp->m_name.str));
dbchanged= FALSE;
if ((ret= sp_use_new_db(thd, sp->m_db.str, olddb, sizeof(olddb),
@@ -606,7 +607,7 @@
TABLE *table;
int ret;
DBUG_ENTER("db_drop_routine");
- DBUG_PRINT("enter", ("type: %d name: %*s",
+ DBUG_PRINT("enter", ("type: %d name: %.*s",
type, name->m_name.length, name->m_name.str));
if (!(table= open_proc_table_for_update(thd)))
@@ -628,7 +629,7 @@
int ret;
bool opened;
DBUG_ENTER("db_update_routine");
- DBUG_PRINT("enter", ("type: %d name: %*s",
+ DBUG_PRINT("enter", ("type: %d name: %.*s",
type, name->m_name.length, name->m_name.str));
if (!(table= open_proc_table_for_update(thd)))
@@ -922,7 +923,7 @@
{
sp_head *sp;
DBUG_ENTER("sp_find_procedure");
- DBUG_PRINT("enter", ("name: %*s.%*s",
+ DBUG_PRINT("enter", ("name: %.*s.%.*s",
name->m_db.length, name->m_db.str,
name->m_name.length, name->m_name.str));
@@ -980,7 +981,7 @@
{
int ret;
DBUG_ENTER("sp_create_procedure");
- DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", sp->m_name.length, sp->m_name.str));
ret= db_create_routine(thd, TYPE_ENUM_PROCEDURE, sp);
DBUG_RETURN(ret);
@@ -992,7 +993,7 @@
{
int ret;
DBUG_ENTER("sp_drop_procedure");
- DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
ret= db_drop_routine(thd, TYPE_ENUM_PROCEDURE, name);
if (!ret)
@@ -1006,7 +1007,7 @@
{
int ret;
DBUG_ENTER("sp_update_procedure");
- DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
ret= db_update_routine(thd, TYPE_ENUM_PROCEDURE, name, chistics);
if (!ret)
@@ -1020,7 +1021,7 @@
{
sp_head *sp;
DBUG_ENTER("sp_show_create_procedure");
- DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
if ((sp= sp_find_procedure(thd, name)))
{
@@ -1072,7 +1073,7 @@
{
sp_head *sp;
DBUG_ENTER("sp_find_function");
- DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
if (!(sp= sp_cache_lookup(&thd->sp_func_cache, name)) &&
!cache_only)
@@ -1089,7 +1090,7 @@
{
int ret;
DBUG_ENTER("sp_create_function");
- DBUG_PRINT("enter", ("name: %*s", sp->m_name.length, sp->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", sp->m_name.length, sp->m_name.str));
ret= db_create_routine(thd, TYPE_ENUM_FUNCTION, sp);
DBUG_RETURN(ret);
@@ -1101,7 +1102,7 @@
{
int ret;
DBUG_ENTER("sp_drop_function");
- DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
ret= db_drop_routine(thd, TYPE_ENUM_FUNCTION, name);
if (!ret)
@@ -1115,7 +1116,7 @@
{
int ret;
DBUG_ENTER("sp_update_procedure");
- DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
ret= db_update_routine(thd, TYPE_ENUM_FUNCTION, name, chistics);
if (!ret)
@@ -1129,7 +1130,7 @@
{
sp_head *sp;
DBUG_ENTER("sp_show_create_function");
- DBUG_PRINT("enter", ("name: %*s", name->m_name.length, name->m_name.str));
+ DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
if ((sp= sp_find_function(thd, name)))
{
--- 1.191/sql/sp_head.cc 2005-10-17 15:12:29 +02:00
+++ 1.192/sql/sp_head.cc 2005-10-18 17:19:04 +02:00
@@ -1137,47 +1137,53 @@
thd->spcont= nctx;
- binlog_save_options= thd->options;
- need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
+ /*
+ If row-based binlogging, we don't need to binlog the function's call, let
+ each substatement be binlogged its way.
+ */
+ need_binlog_call= mysql_bin_log.is_open() &&
+ (thd->options & OPTION_BIN_LOG) && !binlog_row_based;
if (need_binlog_call)
{
reset_dynamic(&thd->user_var_events);
mysql_bin_log.start_union_events(thd);
+ binlog_save_options= thd->options;
+ thd->options&= ~OPTION_BIN_LOG;
}
-
- thd->options&= ~OPTION_BIN_LOG;
+
ret= execute(thd);
- thd->options= binlog_save_options;
-
- if (need_binlog_call)
- mysql_bin_log.stop_union_events(thd);
- if (need_binlog_call && thd->binlog_evt_union.unioned_events)
+ if (need_binlog_call)
{
- char buf[256];
- String bufstr(buf, sizeof(buf), &my_charset_bin);
- bufstr.length(0);
- bufstr.append("DO ", 3);
- append_identifier(thd, &bufstr, m_name.str, m_name.length);
- bufstr.append('(');
- for (uint i=0; i < argcount; i++)
- {
- if (i)
- bufstr.append(',');
- param_values[i]->print(&bufstr);
- }
- bufstr.append(')');
-
- Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
- thd->binlog_evt_union.unioned_events_trans, FALSE);
- if (mysql_bin_log.write(&qinfo) &&
- thd->binlog_evt_union.unioned_events_trans)
+ mysql_bin_log.stop_union_events(thd);
+ thd->options= binlog_save_options;
+ if (thd->binlog_evt_union.unioned_events)
{
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
- "Invoked ROUTINE modified a transactional table but MySQL "
- "failed to reflect this change in the binary log");
+ char buf[256];
+ String bufstr(buf, sizeof(buf), &my_charset_bin);
+ bufstr.length(0);
+ bufstr.append("DO ", 3);
+ append_identifier(thd, &bufstr, m_name.str, m_name.length);
+ bufstr.append('(');
+ for (uint i=0; i < argcount; i++)
+ {
+ if (i)
+ bufstr.append(',');
+ param_values[i]->print(&bufstr);
+ }
+ bufstr.append(')');
+
+ Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
+ thd->binlog_evt_union.unioned_events_trans, FALSE);
+ if (mysql_bin_log.write(&qinfo) &&
+ thd->binlog_evt_union.unioned_events_trans)
+ {
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ "Invoked ROUTINE modified a transactional table but MySQL "
+ "failed to reflect this change in the binary log");
+ }
+ reset_dynamic(&thd->user_var_events);
}
- reset_dynamic(&thd->user_var_events);
}
if (m_type == TYPE_ENUM_FUNCTION && ret == 0)
--- 1.90/sql/slave.h 2005-10-10 18:53:06 +02:00
+++ 1.91/sql/slave.h 2005-10-18 17:19:04 +02:00
@@ -307,6 +307,17 @@
*/
ulong trans_retries, retried_trans;
+ /*
+ If the end of the hot relay log is made of master's events ignored by the
+ slave I/O thread, these two keep track of the coords (in the master's
+ binlog) of the last of these events seen by the slave I/O thread. If not,
+ ign_master_log_name_end[0] == 0.
+ As they are like a Rotate event read/written from/to the relay log, they
+ are both protected by rli->relay_log.LOCK_log.
+ */
+ char ign_master_log_name_end[FN_REFLEN];
+ ulonglong ign_master_log_pos_end;
+
st_relay_log_info();
~st_relay_log_info();
--- 1.64/mysql-test/Makefile.am 2005-09-20 09:08:15 +02:00
+++ 1.65/mysql-test/Makefile.am 2005-10-18 17:55:30 +02:00
@@ -67,7 +67,8 @@
-$(INSTALL_DATA) $(srcdir)/t/*.imtest $(distdir)/t
$(INSTALL_DATA) $(srcdir)/t/*.sql $(distdir)/t
-$(INSTALL_DATA) $(srcdir)/t/*.disabled $(distdir)/t
- $(INSTALL_DATA) $(srcdir)/t/*.opt $(srcdir)/t/*.sh $(srcdir)/t/*.slave-mi $(distdir)/t
+ $(INSTALL_DATA) $(srcdir)/t/*.opt $(srcdir)/t/*.slave-mi $(distdir)/t
+ $(INSTALL_SCRIPT) $(srcdir)/t/*.sh $(distdir)/t
$(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.test $(distdir)/extra/binlog_tests
$(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.test $(distdir)/extra/rpl_tests
-$(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.opt $(distdir)/extra/binlog_tests
@@ -79,6 +80,7 @@
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(distdir)/std_data
+ $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(distdir)/std_data
$(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(distdir)/lib
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib
@@ -98,7 +100,7 @@
$(INSTALL_DATA) $(srcdir)/t/*.sql $(DESTDIR)$(testdir)/t
-$(INSTALL_DATA) $(srcdir)/t/*.disabled $(DESTDIR)$(testdir)/t
$(INSTALL_DATA) $(srcdir)/t/*.opt $(DESTDIR)$(testdir)/t
- $(INSTALL_DATA) $(srcdir)/t/*.sh $(DESTDIR)$(testdir)/t
+ $(INSTALL_SCRIPT) $(srcdir)/t/*.sh $(DESTDIR)$(testdir)/t
$(INSTALL_DATA) $(srcdir)/t/*.slave-mi $(DESTDIR)$(testdir)/t
$(INSTALL_DATA) $(srcdir)/r/*.result $(DESTDIR)$(testdir)/r
$(INSTALL_DATA) $(srcdir)/r/*.require $(DESTDIR)$(testdir)/r
@@ -113,6 +115,7 @@
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data
+ $(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data
$(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(DESTDIR)$(testdir)/lib
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib
--- 1.5.1.1/mysql-test/r/ctype_cp932.result 2005-10-11 09:08:41 +02:00
+++ 1.8/mysql-test/r/binlog_stm_ctype_cp932.result 2005-10-18 17:18:58 +02:00
@@ -11320,11 +11320,11 @@
PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
SET @var1= x'8300';
EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
+SHOW BINLOG EVENTS FROM 102;
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000001 98 Query 1 185 use `test`; CREATE TABLE t1(f1 blob)
-master-bin.000001 185 User var 1 224 @`var1`=_binary 0x8300 COLLATE binary
-master-bin.000001 224 Query 1 317 use `test`; INSERT INTO t1 VALUES(@'var1')
+master-bin.000001 102 Query 1 189 use `test`; CREATE TABLE t1(f1 blob)
+master-bin.000001 189 User var 1 228 @`var1`=_binary 0x8300 COLLATE binary
+master-bin.000001 228 Query 1 321 use `test`; INSERT INTO t1 VALUES(@'var1')
SELECT HEX(f1) FROM t1;
HEX(f1)
8300
--- 1.7.1.1/mysql-test/t/ctype_cp932.test 2005-10-11 09:08:35 +02:00
+++ 1.11/mysql-test/extra/binlog_tests/ctype_cp932.test 2005-10-18 17:18:58 +02:00
@@ -1,3 +1,5 @@
+# show binlog events used
+#-- source include/have_binlog_format_statement.inc
-- source include/have_cp932.inc
--character_set cp932
@@ -415,7 +417,7 @@
# code (and I have used it to test the fix) until there is some way to
# exercise this code from mysql-test-run.
EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
+SHOW BINLOG EVENTS FROM 102;
SELECT HEX(f1) FROM t1;
DROP table t1;
# end test for bug#11338
--- 1.51/BUILD/SETUP.sh 2005-10-10 18:53:03 +02:00
+++ 1.52/BUILD/SETUP.sh 2005-10-18 17:18:57 +02:00
@@ -104,6 +104,10 @@
make=make
fi
+if test -z "$CC" ; then
+ CC=gcc
+fi
+
if test -z "$CXX" ; then
CXX=gcc
fi
| Thread |
|---|
| • bk commit into 5.0 tree (lars:1.2018) | Lars Thalmann | 18 Oct |