diff options
45 files changed, 485 insertions, 350 deletions
diff --git a/Docs/manual.texi b/Docs/manual.texi index 575d34fc502..2ca541fcc20 100644 --- a/Docs/manual.texi +++ b/Docs/manual.texi @@ -1793,7 +1793,7 @@ and @code{row-level locking}. @item Our German, Austrian, and Swiss users will note that we have a new character -set, @code{latin_de}, which corrects the @emph{German sorting order}, +set, @code{latin1_de}, which corrects the @emph{German sorting order}, placing German umlauts in the same order as German telephone books. @item @@ -3409,9 +3409,6 @@ database if you are not using the @code{-A} option or if you are using @code{rehash}. This is especially notable when you have a big table cache. -@item -The current replication protocol cannot deal with @code{LOAD DATA INFILE} -and line terminator characters of more than 1 character. @end itemize The following problems are known and will be fixed in due time: @@ -3423,6 +3420,10 @@ When using @code{SET CHARACTER SET}, one can't use translated characters in database, table, and column names. @item +One can't use @code{_} or @code{%} with @code{ESCAPE} in @code{LIKE +... ESCAPE}. + +@item If you have a @code{DECIMAL} column with a number stored in different formats (+01.00, 1.00, 01.00), @code{GROUP BY} may regard each value as a different value. @@ -20614,7 +20615,7 @@ but normally this is never needed. @subsubsection German character set To get German sorting order, you should start @code{mysqld} with -@code{--default-character-set=latin_de}. This will give you the following +@code{--default-character-set=latin1_de}. This will give you the following characteristics. When sorting and comparing string's the following mapping is done on the @@ -50391,6 +50392,19 @@ each individual 4.0.x release. @itemize @bullet @item +@code{SELECT @@@@[global|session].var_name} didn't report +@code{global | session} in the result column name. +@item +Fixed problem in replication that @code{FLUSH LOGS} in a circular +replication setup created an infinite number of binary log files. +Now a @code{rotate-binary-log} command in the binary log will not cause slaves +to rotate logs. +@item +Removed @code{STOP EVENT} from binary log when doing @code{FLUSH LOGS}. +@item +Disable the use of @code{SHOW NEW MASTER FOR SLAVE} as this needs to be +completely changed in 4.1. +@item @code{--log-binary=a.b.c} now properly strips of @code{.b.c}. @item @code{FLUSH LOGS} removed numerical extension for all future update logs. @@ -50954,7 +50968,7 @@ Secure connections (with SSL). Unsigned @code{BIGINT} constants now work. @code{MIN()} and @code{MAX()} now handle signed and unsigned @code{BIGINT} numbers correctly. @item -New character set @code{latin_de} which provides correct German sorting. +New character set @code{latin1_de} which provides correct German sorting. @item @code{STRCMP()} now uses the current character set when doing comparisons, which means that the default comparison behaviour now is case-insensitive. diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 4109fbd76d4..58b49a748ec 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -21,7 +21,7 @@ #include "log_event.h" #define BIN_LOG_HEADER_SIZE 4 -#define PROBE_HEADER_LEN (BIN_LOG_HEADER_SIZE+EVENT_LEN_OFFSET+4) +#define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) #define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD | CLIENT_LONG_FLAG | CLIENT_LOCAL_FILES) @@ -378,31 +378,40 @@ static void dump_remote_log_entries(const char* logname) static int check_header(IO_CACHE* file) { + byte header[BIN_LOG_HEADER_SIZE]; byte buf[PROBE_HEADER_LEN]; int old_format=0; my_off_t pos = my_b_tell(file); my_b_seek(file, (my_off_t)0); - if (my_b_read(file, buf, sizeof(buf))) - die("Failed reading header"); - if (buf[EVENT_TYPE_OFFSET+4] == START_EVENT) + if (my_b_read(file, header, sizeof(header))) + die("Failed reading header; Probably an empty file"); + if (memcmp(header, BINLOG_MAGIC, sizeof(header))) + die("File is not a binary log file"); + if (!my_b_read(file, buf, sizeof(buf))) { - uint event_len; - event_len = uint4korr(buf + EVENT_LEN_OFFSET + 4); - old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN); + if (buf[4] == START_EVENT) + { + uint event_len; + event_len = uint4korr(buf + 4); + old_format = (event_len < LOG_EVENT_HEADER_LEN + START_HEADER_LEN); + } } my_b_seek(file, pos); return old_format; } + static void dump_local_log_entries(const char* logname) { File fd = -1; IO_CACHE cache,*file= &cache; ulonglong rec_count = 0; - char last_db[FN_REFLEN+1] = ""; + char last_db[FN_REFLEN+1], tmp_buff[BIN_LOG_HEADER_SIZE]; bool old_format = 0; + last_db[0]=0; + if (logname && logname[0] != '-') { if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0) @@ -435,14 +444,7 @@ static void dump_local_log_entries(const char* logname) } if (!position) - { - char magic[BIN_LOG_HEADER_SIZE]; - if (my_b_read(file, (byte*) magic, sizeof(magic))) - die("I/O error reading binlog magic number"); - if (memcmp(magic, BINLOG_MAGIC, 4)) - die("Bad magic number; The file is probably not a MySQL binary log"); - } - + my_b_read(file, tmp_buff, BIN_LOG_HEADER_SIZE); // Skip header for (;;) { char llbuff[21]; diff --git a/client/mysqltest.c b/client/mysqltest.c index d9e964997cc..533713b4f43 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -87,11 +87,8 @@ #define CON_RETRY_SLEEP 2 #define MAX_CON_TRIES 5 -#ifndef OS2 #define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */ -#else -#defile SLAVE_POLL_INTERVAL 0.3 -#endif + enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD, OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT}; @@ -423,6 +420,7 @@ static void free_used_memory() my_free(embedded_server_args[--embedded_server_arg_count],MYF(0)); delete_dynamic(&q_lines); dynstr_free(&ds_res); + free_replace(); my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); free_defaults(default_argv); mysql_server_end(); @@ -687,13 +685,23 @@ int open_file(const char* name) return 0; } +static void my_sleep(ulong m_seconds) +{ +#ifndef OS2 + struct timeval t; + t.tv_sec= m_seconds / 1000000L; + t.tv_usec= m_seconds % 1000000L; + select(0,0,0,0,&t); /* sleep */ +#else + DosSleep(m_seconds/1000+1); +#endif +} + + /* ugly long name, but we are following the convention */ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) { MYSQL* mysql = &cur_con->mysql; -#ifndef OS2 - struct timeval t; -#endif for (;;) { MYSQL_RES* res; @@ -714,15 +722,8 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) mysql_free_result(res); if (done) break; -#ifndef OS2 - t.tv_sec=0; - t.tv_usec=SLAVE_POLL_INTERVAL; - select(0,0,0,0,&t); /* sleep */ -#else - DosSleep(OS2_SLAVE_POLL_INTERVAL); -#endif + my_sleep(SLAVE_POLL_INTERVAL); } - return 0; } @@ -1000,10 +1001,18 @@ int do_sync_with_master2(const char* p) die("line %u: empty result in %s", start_lineno, query_buf); if (!row[0]) die("Error on slave while syncing with master"); - mysql_free_result(res); last_result=0; + mysql_free_result(res); + last_result=0; if (rpl_parse) mysql_enable_rpl_parse(mysql); +#ifndef TO_BE_REMOVED + /* + We need this because wait_for_pos() only waits for the relay log, + which doesn't guarantee that the slave has executed the statement. + */ + my_sleep(2*1000000L); +#endif return 0; } @@ -1082,53 +1091,15 @@ int do_disable_rpl_parse(struct st_query* q __attribute__((unused))) int do_sleep(struct st_query* q, my_bool real_sleep) { char* p=q->first_argument; - struct timeval t; - int dec_mul = 1000000; - while (*p && isspace(*p)) p++; + while (*p && isspace(*p)) + p++; if (!*p) die("Missing argument in sleep\n"); - t.tv_usec = 0; - -#ifdef OS2 - if (opt_sleep && !real_sleep) - DosSleep( opt_sleep * 1000); + my_sleep(opt_sleep * 1000000L); else - DosSleep( atof( p) * 1000); - + my_sleep((ulong) (atof(p) * 1000000L)); return 0; - -#else - if (opt_sleep && !real_sleep) - t.tv_sec = opt_sleep; - else - { - t.tv_sec = atoi(p); - while (*p && *p != '.' && !isspace(*p)) - p++; - if (*p == '.') - { - int c; - char *p_end; - p++; - p_end = p + 6; - - for (;p <= p_end; ++p) - { - c = (int) (*p - '0'); - if (c < 10 && (int) c >= 0) - { - t.tv_usec = t.tv_usec * 10 + c; - dec_mul /= 10; - } - else - break; - } - } - } - t.tv_usec *= dec_mul; - return select(0,0,0,0, &t); -#endif } static void get_file_name(char *filename, struct st_query* q) @@ -1261,8 +1232,7 @@ static void get_replace(struct st_query *q) POINTER_ARRAY to_array,from_array; DBUG_ENTER("get_replace"); - if (glob_replace) - free_replace(); + free_replace(); bzero((char*) &to_array,sizeof(to_array)); bzero((char*) &from_array,sizeof(from_array)); @@ -1298,9 +1268,12 @@ static void get_replace(struct st_query *q) void free_replace() { DBUG_ENTER("free_replace"); - my_free((char*) glob_replace,MYF(0)); - glob_replace=0; - free_replace_buffer(); + if (glob_replace) + { + my_free((char*) glob_replace,MYF(0)); + glob_replace=0; + free_replace_buffer(); + } DBUG_VOID_RETURN; } @@ -2077,7 +2050,7 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) char* query; int query_len; DBUG_ENTER("run_query"); - + if (q->type != Q_EVAL) { query = q->query; @@ -2090,6 +2063,7 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags) query = eval_query.str; query_len = eval_query.length; } + DBUG_PRINT("enter", ("query: '%-.60s'", query)); if (q->record_file[0]) { diff --git a/configure.in b/configure.in index 3d7d44c33df..93c7f883c4e 100644 --- a/configure.in +++ b/configure.in @@ -922,7 +922,7 @@ case $SYSTEM_TYPE in fi fi ;; - *darwin*) + *darwin5*) if test "$ac_cv_prog_gcc" = "yes" then CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH" @@ -931,6 +931,14 @@ case $SYSTEM_TYPE in with_named_curses="" fi ;; + *darwin6*) + if test "$ac_cv_prog_gcc" = "yes" + then + CFLAGS="$CFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DHAVE_BROKEN_REALPATH" + CXXFLAGS="$CXXFLAGS -traditional-cpp -DHAVE_DARWIN_THREADS -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ" + MAX_C_OPTIMIZE="-O" + fi + ;; *freebsd*) echo "Adding fix for interrupted reads" CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000" diff --git a/include/my_sys.h b/include/my_sys.h index 163fb72a910..e1054d825c6 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -126,13 +126,14 @@ extern int NEAR my_errno; /* Last error in mysys */ /* defines when allocating data */ #ifdef SAFEMALLOC -#define my_malloc(SZ,FLAG) _mymalloc( SZ, __FILE__, __LINE__, FLAG ) -#define my_malloc_ci(SZ,FLAG) _mymalloc( SZ, sFile, uLine, FLAG ) -#define my_realloc(PTR,SZ,FLAG) _myrealloc( PTR, SZ, __FILE__, __LINE__, FLAG ) +#define my_malloc(SZ,FLAG) _mymalloc((SZ), __FILE__, __LINE__, FLAG ) +#define my_malloc_ci(SZ,FLAG) _mymalloc((SZ), sFile, uLine, FLAG ) +#define my_realloc(PTR,SZ,FLAG) _myrealloc((PTR), (SZ), __FILE__, __LINE__, FLAG ) #define my_checkmalloc() _sanity( __FILE__, __LINE__ ) -#define my_free(PTR,FLAG) _myfree( PTR, __FILE__, __LINE__,FLAG) -#define my_memdup(A,B,C) _my_memdup(A,B,__FILE__,__LINE__,C) -#define my_strdup(A,C) _my_strdup(A,__FILE__,__LINE__,C) +#define my_free(PTR,FLAG) _myfree((PTR), __FILE__, __LINE__,FLAG) +#define my_memdup(A,B,C) _my_memdup((A),(B), __FILE__,__LINE__,C) +#define my_strdup(A,C) _my_strdup((A), __FILE__,__LINE__,C) +#define my_strdup_with_length(A,B,C) _my_strdup_with_length((A),(B),__FILE__,__LINE__,C) #define QUICK_SAFEMALLOC sf_malloc_quick=1 #define NORMAL_SAFEMALLOC sf_malloc_quick=0 extern uint sf_malloc_prehunc,sf_malloc_endhunc,sf_malloc_quick; @@ -153,6 +154,8 @@ extern gptr my_realloc(gptr oldpoint,uint Size,myf MyFlags); extern void my_no_flags_free(gptr ptr); extern gptr my_memdup(const byte *from,uint length,myf MyFlags); extern my_string my_strdup(const char *from,myf MyFlags); +extern my_string my_strdup_with_length(const char *from,uint length, + myf MyFlags); #define my_free(PTR,FG) my_no_flags_free(PTR) #define CALLER_INFO_PROTO /* nothing */ #define CALLER_INFO /* nothing */ @@ -550,6 +553,10 @@ extern gptr _my_memdup(const byte *from,uint length, const char *sFile, uint uLine,myf MyFlag); extern my_string _my_strdup(const char *from, const char *sFile, uint uLine, myf MyFlag); +extern my_string _my_strdup_with_length(const char *from, uint length, + const char *sFile, uint uLine, + myf MyFlag); + #ifndef TERMINATE extern void TERMINATE(FILE *file); #endif diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c index bab5c78b712..25a7060883c 100644 --- a/innobase/btr/btr0cur.c +++ b/innobase/btr/btr0cur.c @@ -808,7 +808,7 @@ btr_cur_optimistic_insert( if (!dtuple_check_typed_no_assert(entry)) { fprintf(stderr, -"InnoDB: Error in a tuple to insert into table %lu index %s\n", +"InnoDB: Error in a tuple to insert into table %s index %s\n", index->table_name, index->name); } diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 0c91ec11671..6f2ba791eef 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1049,21 +1049,21 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) int STDCALL mysql_master_query(MYSQL *mysql, const char *q, unsigned long length) { + DBUG_ENTER("mysql_master_query"); if (mysql_master_send_query(mysql, q, length)) - return 1; - return mysql_read_query_result(mysql); + DBUG_RETURN(1); + DBUG_RETURN(mysql_read_query_result(mysql)); } int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, unsigned long length) { - MYSQL*master = mysql->master; - if (!length) - length = strlen(q); + MYSQL *master = mysql->master; + DBUG_ENTER("mysql_master_send_query"); if (!master->net.vio && !mysql_real_connect(master,0,0,0,0,0,0,0)) - return 1; + DBUG_RETURN(1); mysql->last_used_con = master; - return simple_command(master, COM_QUERY, q, length, 1); + DBUG_RETURN(simple_command(master, COM_QUERY, q, length, 1)); } @@ -1071,30 +1071,31 @@ int STDCALL mysql_master_send_query(MYSQL *mysql, const char *q, int STDCALL mysql_slave_query(MYSQL *mysql, const char *q, unsigned long length) { + DBUG_ENTER("mysql_slave_query"); if (mysql_slave_send_query(mysql, q, length)) - return 1; - return mysql_read_query_result(mysql); + DBUG_RETURN(1); + DBUG_RETURN(mysql_read_query_result(mysql)); } int STDCALL mysql_slave_send_query(MYSQL *mysql, const char *q, unsigned long length) { MYSQL* last_used_slave, *slave_to_use = 0; + DBUG_ENTER("mysql_slave_send_query"); if ((last_used_slave = mysql->last_used_slave)) slave_to_use = last_used_slave->next_slave; else slave_to_use = mysql->next_slave; - /* next_slave is always safe to use - we have a circular list of slaves - if there are no slaves, mysql->next_slave == mysql + /* + Next_slave is always safe to use - we have a circular list of slaves + if there are no slaves, mysql->next_slave == mysql */ mysql->last_used_con = mysql->last_used_slave = slave_to_use; - if (!length) - length = strlen(q); if (!slave_to_use->net.vio && !mysql_real_connect(slave_to_use, 0,0,0, 0,0,0,0)) - return 1; - return simple_command(slave_to_use, COM_QUERY, q, length, 1); + DBUG_RETURN(1); + DBUG_RETURN(simple_command(slave_to_use, COM_QUERY, q, length, 1)); } @@ -1307,8 +1308,7 @@ err: enum mysql_rpl_type STDCALL mysql_rpl_query_type(const char* q, int len) { - const char* q_end; - q_end = (len) ? q + len : strend(q); + const char *q_end= q + len; for (; q < q_end; ++q) { char c; @@ -2203,20 +2203,24 @@ STDCALL mysql_add_slave(MYSQL* mysql, const char* host, int STDCALL mysql_send_query(MYSQL* mysql, const char* query, ulong length) { + DBUG_ENTER("mysql_send_query"); + DBUG_PRINT("enter",("rpl_parse: %d rpl_pivot: %d", + mysql->options.rpl_parse, mysql->rpl_pivot)); + if (mysql->options.rpl_parse && mysql->rpl_pivot) { switch (mysql_rpl_query_type(query, length)) { case MYSQL_RPL_MASTER: - return mysql_master_send_query(mysql, query, length); + DBUG_RETURN(mysql_master_send_query(mysql, query, length)); case MYSQL_RPL_SLAVE: - return mysql_slave_send_query(mysql, query, length); + DBUG_RETURN(mysql_slave_send_query(mysql, query, length)); case MYSQL_RPL_ADMIN: break; /* fall through */ } } mysql->last_used_con = mysql; - return simple_command(mysql, COM_QUERY, query, length, 1); + DBUG_RETURN(simple_command(mysql, COM_QUERY, query, length, 1)); } diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 9a825ea125e..b51d5fff70b 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -742,6 +742,8 @@ start_master() $RM -f $MASTER_MYDDIR/log.* # Remove stale binary logs $RM -f $MYSQL_TEST_DIR/var/log/master-bin.* + # Remove old master.info files + $RM -f $MYSQL_TEST_DIR/var/master-data/master.info #run master initialization shell script if one exists @@ -858,8 +860,9 @@ start_slave() slave_pid=$SLAVE_MYPID slave_sock="$SLAVE_MYSOCK" fi - # Remove stale binary logs - $RM -f $MYSQL_TEST_DIR/var/log/$slave_ident-bin.* + # Remove stale binary logs and old master.info files + $RM -f $MYSQL_TEST_DIR/var/log/$slave_ident-*bin.* + $RM -f $MYSQL_TEST_DIR/$slave_datadir/master.info #run slave initialization shell script if one exists if [ -f "$slave_init_script" ] ; @@ -1089,8 +1092,8 @@ run_testcase () start_master fi fi - do_slave_restart=0 + do_slave_restart=0 if [ -f $slave_opt_file ] ; then EXTRA_SLAVE_OPT=`$CAT $slave_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"` diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index c08f6094080..c77884adfb0 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -7,6 +7,9 @@ Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' GRANT SELECT ON `mysqltest`.* TO 'mysqltest_1'@'localhost' grant delete on mysqltest.* to mysqltest_1@localhost; +select * from mysql.user where user="mysqltest_1"; +Host User Password Select_priv Insert_priv Update_priv Delete_priv Create_priv Drop_priv Reload_priv Shutdown_priv Process_priv File_priv Grant_priv References_priv Index_priv Alter_priv Show_db_priv Super_priv Create_tmp_table_priv Lock_tables_priv Execute_priv Repl_slave_priv Repl_client_priv ssl_type ssl_cipher x509_issuer x509_subject max_questions max_updates max_connections +localhost mysqltest_1 N N N N N N N N N N N N N N N N N N N N N SPECIFIED EDH-RSA-DES-CBC3-SHA 0 0 0 show grants for mysqltest_1@localhost; Grants for mysqltest_1@localhost GRANT USAGE ON *.* TO 'mysqltest_1'@'localhost' REQUIRE CIPHER 'EDH-RSA-DES-CBC3-SHA' diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 4224db7c072..78b0da2769e 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -987,7 +987,7 @@ create table t1 (id int unsigned not null auto_increment, code tinyint unsigned BEGIN; SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT @@tx_isolation,@@global.tx_isolation; -@@tx_isolation @@tx_isolation +@@tx_isolation @@global.tx_isolation SERIALIZABLE READ-COMMITTED insert into t1 (code, name) values (1, 'Tim'), (1, 'Monty'), (2, 'David'); select id, code, name from t1 order by id; diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result index 1d66c4cc03d..739a47b41f1 100644 --- a/mysql-test/r/myisam.result +++ b/mysql-test/r/myisam.result @@ -108,3 +108,9 @@ OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize status OK DROP TABLE t1; +CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), KEY t1 (a, b, c)); +Specified key was too long. Max key length is 500 +CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255)); +ALTER TABLE t1 ADD INDEX t1 (a, b, c); +Specified key was too long. Max key length is 500 +DROP TABLE t1; diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result new file mode 100644 index 00000000000..40b4ca72f01 --- /dev/null +++ b/mysql-test/r/rpl_flush_log_loop.result @@ -0,0 +1,17 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +change master to master_host='127.0.0.1',master_user='root', +master_password='',master_port=9306; +slave start; +slave stop; +change master to master_host='127.0.0.1',master_user='root', +master_password='',master_port=9307; +slave start; +flush logs; +show slave status; +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +127.0.0.1 root 9307 60 slave-bin.001 79 mashka-relay-bin.001 119 slave-bin.001 Yes Yes 0 0 79 119 diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 8948460e1bd..7d1843f95fc 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -8,7 +8,6 @@ slave stop; reset master; reset slave; reset master; -drop table if exists t1; create table t1(n int not null auto_increment primary key); insert into t1 values (NULL); drop table t1; @@ -37,6 +36,9 @@ show binlog events from 79 limit 2,1; Log_name Pos Event_type Server_id Orig_log_pos Info master-bin.001 200 Query 1 200 use test; insert into t1 values (NULL) flush logs; +slave start; +flush logs; +slave stop; create table t1 (n int); insert into t1 values (1); drop table t1; @@ -52,7 +54,6 @@ master-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81 master-bin.001 556 Exec_load 1 556 ;file_id=1 master-bin.001 579 Query 1 579 use test; drop table t1 master-bin.001 627 Rotate 1 627 master-bin.002;pos=4 -master-bin.001 668 Stop 1 668 show binlog events in 'master-bin.002'; Log_name Pos Event_type Server_id Orig_log_pos Info master-bin.002 4 Query 1 4 use test; create table t1 (n int) @@ -68,32 +69,24 @@ Log_name slave-bin.001 slave-bin.002 show binlog events in 'slave-bin.001' from 4; +Log_name Pos Event_type Server_id Orig_log_pos Info +slave-bin.001 4 Start 2 4 Server ver: VERSION, Binlog ver: 3 +slave-bin.001 79 Query 1 79 use test; create table t1(n int not null auto_increment primary key) +slave-bin.001 172 Intvar 1 200 INSERT_ID=1 +slave-bin.001 200 Query 1 200 use test; insert into t1 values (NULL) +slave-bin.001 263 Query 1 263 use test; drop table t1 +slave-bin.001 311 Query 1 311 use test; create table t1 (word char(20) not null) +slave-bin.001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=81 +slave-bin.001 565 Exec_load 1 556 ;file_id=1 +slave-bin.001 588 Query 1 579 use test; drop table t1 +slave-bin.001 636 Rotate 2 636 slave-bin.002;pos=4 show binlog events in 'slave-bin.002' from 4; Log_name Pos Event_type Server_id Orig_log_pos Info -slave-bin.002 4 Slave 2 627 host=127.0.0.1,port=MASTER_PORT,log=master-bin.002,pos=4 -slave-bin.002 57 Query 1 4 use test; create table t1 (n int) -slave-bin.002 115 Query 1 62 use test; insert into t1 values (1) -slave-bin.002 175 Query 1 122 use test; drop table t1 +slave-bin.002 4 Query 1 4 use test; create table t1 (n int) +slave-bin.002 62 Query 1 62 use test; insert into t1 values (1) +slave-bin.002 122 Query 1 122 use test; drop table t1 show slave status; Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space -127.0.0.1 root MASTER_PORT 1 master-bin.002 170 slave-relay-bin.002 916 master-bin.002 Yes Yes 0 0 170 920 -show new master for slave with master_log_file='master-bin.001' and -master_log_pos=4 and master_server_id=1; -Log_name Log_pos -slave-bin.001 132 -show new master for slave with master_log_file='master-bin.001' and -master_log_pos=79 and master_server_id=1; -Log_name Log_pos -slave-bin.001 225 -show new master for slave with master_log_file='master-bin.001' and -master_log_pos=311 and master_server_id=1; -Log_name Log_pos -slave-bin.001 439 -show new master for slave with master_log_file='master-bin.002' and -master_log_pos=4 and master_server_id=1; -Log_name Log_pos -slave-bin.002 57 -show new master for slave with master_log_file='master-bin.002' and -master_log_pos=122 and master_server_id=1; -Log_name Log_pos -slave-bin.002 223 +127.0.0.1 root MASTER_PORT 1 master-bin.002 170 slave-relay-bin.002 957 master-bin.002 Yes Yes 0 0 170 961 +show binlog events in 'slave-bin.005' from 4; +Error when executing command SHOW BINLOG EVENTS: Could not find target log diff --git a/mysql-test/r/rpl_magic.result b/mysql-test/r/rpl_magic.result deleted file mode 100644 index 743bef4a053..00000000000 --- a/mysql-test/r/rpl_magic.result +++ /dev/null @@ -1,37 +0,0 @@ -slave stop; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; -drop table if exists t1; -create table t1 ( n int); -insert into t1 values (1),(2),(3),(4); -insert into t1 values(5); -select * from t1; -n -1 -2 -3 -4 -5 -select * from t1; -n -1 -2 -3 -4 -select * from t1; -n -1 -2 -3 -4 -select * from t1; -n -1 -2 -3 -4 -5 -drop table t1; diff --git a/mysql-test/r/rpl_redirect.result b/mysql-test/r/rpl_redirect.result new file mode 100644 index 00000000000..6103a075684 --- /dev/null +++ b/mysql-test/r/rpl_redirect.result @@ -0,0 +1,43 @@ +slave stop; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +reset master; +reset slave; +drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; +slave start; +SHOW SLAVE STATUS; +Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space +SHOW SLAVE HOSTS; +Server_id Host Port Rpl_recovery_rank Master_id +2 127.0.0.1 SLAVE_PORT 2 1 +drop table if exists t1; +create table t1 ( n int); +insert into t1 values (1),(2),(3),(4); +insert into t1 values(5); +select * from t1; +n +1 +2 +3 +4 +5 +select * from t1; +n +1 +2 +3 +4 +select * from t1; +n +1 +2 +3 +4 +select * from t1; +n +1 +2 +3 +4 +5 +drop table t1; +drop table t1; diff --git a/mysql-test/r/rpl_rotate_logs.result b/mysql-test/r/rpl_rotate_logs.result index d440e157ed4..6c1a0082703 100644 --- a/mysql-test/r/rpl_rotate_logs.result +++ b/mysql-test/r/rpl_rotate_logs.result @@ -2,12 +2,10 @@ slave start; Could not initialize master info structure, check permisions on master.info slave start; Could not initialize master info structure, check permisions on master.info -change master to master_host='127.0.0.1',master_port=MASTER_PORT, -master_user='root'; +change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; Could not initialize master info reset slave; -change master to master_host='127.0.0.1',master_port=MASTER_PORT, -master_user='root'; +change master to master_host='127.0.0.1',master_port=MASTER_PORT, master_user='root'; reset master; slave start; drop table if exists t1, t2, t3, t4; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 516204028fe..f708ddd2ee7 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -65,7 +65,7 @@ Variable_name Value max_join_size 4294967295 set @@max_join_size=1000, @@global.max_join_size=2000; select @@local.max_join_size, @@global.max_join_size; -@@max_join_size @@max_join_size +@@session.max_join_size @@global.max_join_size 1000 2000 select @@identity, length(@@version)>0; @@identity length(@@version)>0 diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index be1b09a9b78..c75069f8c55 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -8,6 +8,7 @@ flush privileges; grant select on mysqltest.* to mysqltest_1@localhost require cipher "EDH-RSA-DES-CBC3-SHA"; show grants for mysqltest_1@localhost; grant delete on mysqltest.* to mysqltest_1@localhost; +select * from mysql.user where user="mysqltest_1"; show grants for mysqltest_1@localhost; revoke delete on mysqltest.* from mysqltest_1@localhost; show grants for mysqltest_1@localhost; diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test index dec53e92036..cba7b522650 100644 --- a/mysql-test/t/myisam.test +++ b/mysql-test/t/myisam.test @@ -104,3 +104,13 @@ INSERT INTO t1 VALUES (1), (2), (3); OPTIMIZE TABLE t1; DROP TABLE t1; +# +# Test of creating table with too long key +# + +--error 1071 +CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255), KEY t1 (a, b, c)); +CREATE TABLE t1 (a varchar(255), b varchar(255), c varchar(255)); +--error 1071 +ALTER TABLE t1 ADD INDEX t1 (a, b, c); +DROP TABLE t1; diff --git a/mysql-test/t/rpl_flush_log_loop-master.opt b/mysql-test/t/rpl_flush_log_loop-master.opt new file mode 100644 index 00000000000..eb35347af33 --- /dev/null +++ b/mysql-test/t/rpl_flush_log_loop-master.opt @@ -0,0 +1 @@ +-O max_binlog_size=1M diff --git a/mysql-test/t/rpl_flush_log_loop-slave.opt b/mysql-test/t/rpl_flush_log_loop-slave.opt new file mode 100644 index 00000000000..eb35347af33 --- /dev/null +++ b/mysql-test/t/rpl_flush_log_loop-slave.opt @@ -0,0 +1 @@ +-O max_binlog_size=1M diff --git a/mysql-test/t/rpl_flush_log_loop.test b/mysql-test/t/rpl_flush_log_loop.test new file mode 100644 index 00000000000..2b559180a42 --- /dev/null +++ b/mysql-test/t/rpl_flush_log_loop.test @@ -0,0 +1,17 @@ +# Testing if "flush logs" command bouncing resulting in logs created in a loop +# in case of bi-directional replication + +source include/master-slave.inc + +connection slave; +eval change master to master_host='127.0.0.1',master_user='root', + master_password='',master_port=$MASTER_MYPORT; +slave start; +connection master; +slave stop; +eval change master to master_host='127.0.0.1',master_user='root', + master_password='',master_port=$SLAVE_MYPORT; +slave start; +flush logs; +sleep 5; +show slave status; diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test index 3514d435737..85782e78142 100644 --- a/mysql-test/t/rpl_log.test +++ b/mysql-test/t/rpl_log.test @@ -9,7 +9,6 @@ let $VERSION=`select version()`; connection master; reset master; -drop table if exists t1; create table t1(n int not null auto_increment primary key); insert into t1 values (NULL); drop table t1; @@ -22,6 +21,19 @@ show binlog events from 79 limit 1; show binlog events from 79 limit 2; show binlog events from 79 limit 2,1; flush logs; + +# Sync slave and force it to start on another binary log + +save_master_pos; +connection slave; +slave start; +sync_with_master; +flush logs; +slave stop; +connection master; + +# Create some entries for second log + create table t1 (n int); insert into t1 values (1); drop table t1; @@ -35,23 +47,19 @@ slave start; sync_with_master; show master logs; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION -# We can't compare binlog from slave as the result differ between -# machines based on where the LOAD DATA file is stored. -disable_result_log; - show binlog events in 'slave-bin.001' from 4; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT $VERSION VERSION -enable_result_log; show binlog events in 'slave-bin.002' from 4; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT show slave status; -show new master for slave with master_log_file='master-bin.001' and - master_log_pos=4 and master_server_id=1; -show new master for slave with master_log_file='master-bin.001' and - master_log_pos=79 and master_server_id=1; -show new master for slave with master_log_file='master-bin.001' and - master_log_pos=311 and master_server_id=1; -show new master for slave with master_log_file='master-bin.002' and - master_log_pos=4 and master_server_id=1; -show new master for slave with master_log_file='master-bin.002' and - master_log_pos=122 and master_server_id=1; + +# Need to recode the following + +#show new master for slave with master_log_file='master-bin.001' and master_log_pos=4 and master_server_id=1; +#show new master for slave with master_log_file='master-bin.001' and master_log_pos=79 and master_server_id=1; +#show new master for slave with master_log_file='master-bin.001' and master_log_pos=311 and master_server_id=1; +#show new master for slave with master_log_file='master-bin.002' and master_log_pos=4 and master_server_id=1; +#show new master for slave with master_log_file='master-bin.002' and master_log_pos=122 and master_server_id=1; + +--error 1220 +show binlog events in 'slave-bin.005' from 4; diff --git a/mysql-test/t/rpl_mystery22.test b/mysql-test/t/rpl_mystery22.test index 371c5ba21ed..5280cb360dd 100644 --- a/mysql-test/t/rpl_mystery22.test +++ b/mysql-test/t/rpl_mystery22.test @@ -13,7 +13,7 @@ insert into t1 values(NULL); insert into t1 values(NULL); save_master_pos; connection slave; -sleep 1; # there is no way around this sleep - we have to wait until +sleep 3; # there is no way around this sleep - we have to wait until # the slave tries to run the query, fails and aborts slave thread delete from t1 where n = 2; slave start; diff --git a/mysql-test/t/rpl_magic.test b/mysql-test/t/rpl_redirect.test index c93add93d9d..4082542f295 100644 --- a/mysql-test/t/rpl_magic.test +++ b/mysql-test/t/rpl_redirect.test @@ -1,3 +1,7 @@ +# +# Test of automatic redirection of queries to master/slave. +# + source include/master-slave.inc; #first, make sure the slave has had enough time to register @@ -7,6 +11,10 @@ sync_with_master; #discover slaves connection master; +--replace_result $MASTER_MYPORT MASTER_PORT +SHOW SLAVE STATUS; +--replace_result $SLAVE_MYPORT SLAVE_PORT +SHOW SLAVE HOSTS; rpl_probe; #turn on master/slave query direction auto-magic @@ -16,11 +24,12 @@ create table t1 ( n int); insert into t1 values (1),(2),(3),(4); disable_rpl_parse; save_master_pos; -enable_rpl_parse; connection slave; sync_with_master; insert into t1 values(5); connection master; +enable_rpl_parse; +# The first of the queries will be sent to the slave, the second to the master. select * from t1; select * from t1; disable_rpl_parse; @@ -28,3 +37,5 @@ select * from t1; connection slave; select * from t1; drop table t1; +connection master; +drop table t1; diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index cea2f9008dc..f6fbb76e55e 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -20,12 +20,11 @@ system chmod 600 var/slave-data/master.info; --error 1201 slave start; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT -!eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, - master_user='root'; +# Will get error 13 on Unix systems becasue file is not readable +!eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; reset slave; --replace_result 3306 MASTER_PORT 9306 MASTER_PORT 3334 MASTER_PORT 3336 MASTER_PORT -eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, - master_user='root'; +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root'; connection master; reset master; connection slave; diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index 1e7cdd3a3b5..fc2f22b079a 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -81,3 +81,15 @@ my_string my_strdup(const char *from, myf MyFlags) memcpy((byte*) ptr, (byte*) from,(size_t) length); return((my_string) ptr); } + + +gptr my_strdup_with_length(const byte *from, uint length, myf MyFlags) +{ + gptr ptr; + if ((ptr=my_malloc(length+1,MyFlags)) != 0) + { + memcpy((byte*) ptr, (byte*) from,(size_t) length); + ptr[length]=0; + } + return(ptr); +} diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index 9615126f237..f7e77878e41 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -538,3 +538,17 @@ my_string _my_strdup(const char *from, const char *sFile, uint uLine, memcpy((byte*) ptr, (byte*) from,(size_t) length); return((my_string) ptr); } /* _my_strdup */ + + +my_string _my_strdup_with_length(const char *from, uint length, + const char *sFile, uint uLine, + myf MyFlags) +{ + gptr ptr; + if ((ptr=_mymalloc(length+1,sFile,uLine,MyFlags)) != 0) + { + memcpy((byte*) ptr, (byte*) from,(size_t) length); + ptr[length]=0; + } + return((my_string) ptr); +} diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 11e6fa97ab6..7d72a4d45ae 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -655,6 +655,7 @@ sig_handler process_alarm(int sig __attribute__((unused))) bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm) { + (*alrm)= &alarm->alarmed; if (alarm_aborted) { alarm->alarmed.crono=0; @@ -663,7 +664,6 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm) if (!(alarm->alarmed.crono=SetTimer((HWND) NULL,0, sec*1000, (TIMERPROC) NULL))) return 1; - (*alrm)= &alarm->alarmed; return 0; } diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 7b8afe7b8fe..64c9ecbcb7a 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -101,7 +101,7 @@ char* innobase_unix_file_flush_method = NULL; /* Below we have boolean-valued start-up parameters, and their default values */ -my_bool innobase_flush_log_at_trx_commit = FALSE; +uint innobase_flush_log_at_trx_commit = 0; my_bool innobase_log_archive = FALSE; my_bool innobase_use_native_aio = FALSE; my_bool innobase_fast_shutdown = TRUE; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 2addd957c8c..d70a58c75f1 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -170,6 +170,7 @@ class ha_innobase: public handler extern bool innodb_skip; extern uint innobase_init_flags, innobase_lock_type; +extern uint innobase_flush_log_at_trx_commit; extern ulong innobase_cache_size; extern char *innobase_home, *innobase_tmpdir, *innobase_logdir; extern long innobase_lock_scan_time; @@ -182,7 +183,7 @@ extern char *innobase_data_home_dir, *innobase_data_file_path; extern char *innobase_log_group_home_dir, *innobase_log_arch_dir; extern char *innobase_unix_file_flush_method; /* The following variables have to be my_bool for SHOW VARIABLES to work */ -extern my_bool innobase_flush_log_at_trx_commit, innobase_log_archive, +extern my_bool innobase_log_archive, innobase_use_native_aio, innobase_fast_shutdown; extern TYPELIB innobase_lock_typelib; diff --git a/sql/item_func.cc b/sql/item_func.cc index 1bf94ae75d0..609e0042704 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2334,7 +2334,7 @@ Item *get_system_var(enum_var_type var_type, LEX_STRING name) THD *thd=current_thd; Item *item; sys_var *var; - char buff[MAX_SYS_VAR_LENGTH+3]; + char buff[MAX_SYS_VAR_LENGTH+3+8], *pos; if (!(var= find_sys_var(name.str))) { @@ -2346,8 +2346,14 @@ Item *get_system_var(enum_var_type var_type, LEX_STRING name) thd->safe_to_cache_query=0; buff[0]='@'; buff[1]='@'; - memcpy(buff+2, var->name, var->name_length+1); - item->set_name(buff,var->name_length+2); // Will allocate name + pos=buff+2; + if (var_type == OPT_SESSION) + pos=strmov(pos,"session."); + else if (var_type == OPT_GLOBAL) + pos=strmov(pos,"global."); + memcpy(pos, var->name, var->name_length+1); + // set_name() will allocate the name + item->set_name(buff,(uint) (pos-buff)+var->name_length); return item; } diff --git a/sql/log.cc b/sql/log.cc index e42d9ffa2fa..ccd3954e172 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -389,12 +389,12 @@ err: the NEXT log file name in the index file. log_name Filename to find in the index file. Is a null pointer if we want to read the first entry - need_mutex Set this to 1 if the parent doesn't already have a + need_lock Set this to 1 if the parent doesn't already have a lock on LOCK_index NOTE - On systems without the truncate function the file will end with one ore - more empty lines + On systems without the truncate function the file will end with one or + more empty lines. These will be ignored when reading the file. RETURN VALUES 0 ok @@ -1388,6 +1388,7 @@ void MYSQL_LOG:: wait_for_update(THD* thd) This can be set to 0 if we are going to do call open at once after close, in which case we don't want to close the index file. + We only write a 'stop' event to the log if exiting is set */ void MYSQL_LOG::close(bool exiting) @@ -1396,7 +1397,7 @@ void MYSQL_LOG::close(bool exiting) DBUG_PRINT("enter",("exiting: %d", (int) exiting)); if (is_open()) { - if (log_type == LOG_BIN && !no_auto_events) + if (log_type == LOG_BIN && !no_auto_events && exiting) { Stop_log_event s; s.set_log_pos(this); diff --git a/sql/log_event.cc b/sql/log_event.cc index 1f7a4013d80..ec5b7c4b5a5 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -690,7 +690,10 @@ void Rotate_log_event::print(FILE* file, bool short_form, char* last_db) if (new_log_ident) my_fwrite(file, (byte*) new_log_ident, (uint)ident_len, MYF(MY_NABP | MY_WME)); - fprintf(file, " pos: %s\n", llstr(pos, buf)); + fprintf(file, " pos: %s", llstr(pos, buf)); + if (flags & LOG_EVENT_FORCED_ROTATE_F) + fprintf(file," forced by master"); + fputc('\n', file); fflush(file); } @@ -730,20 +733,22 @@ Rotate_log_event::Rotate_log_event(const char* buf, int event_len, buf += header_size; if (old_format) { - ident_len = (uchar)(event_len - OLD_HEADER_LEN); + ident_len = (uint)(event_len - OLD_HEADER_LEN); pos = 4; ident_offset = 0; } else { - ident_len = (uchar)(event_len - ROTATE_EVENT_OVERHEAD); + ident_len = (uint)(event_len - ROTATE_EVENT_OVERHEAD); pos = uint8korr(buf + R_POS_OFFSET); ident_offset = ROTATE_HEADER_LEN; } - if (!(new_log_ident = (char*) my_memdup((byte*) buf + ident_offset, - (uint) ident_len, MYF(MY_WME)))) + set_if_smaller(ident_len,FN_REFLEN-1); + if (!(new_log_ident= (char*) my_strdup_with_length((byte*) buf + + ident_offset, + (uint) ident_len, + MYF(MY_WME)))) return; - alloced = 1; } @@ -1614,7 +1619,6 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) int expected_error,actual_error = 0; init_sql_alloc(&thd->mem_root, 8192,0); thd->db = rewrite_db((char*)db); - DBUG_ASSERT(q_len == strlen(query)); /* InnoDB internally stores the master log position it has processed so far; @@ -1643,6 +1647,8 @@ int Query_log_event::exec_event(struct st_relay_log_info* rli) if (ignored_error_code((expected_error = error_code)) || !check_expected_error(thd,rli,expected_error)) { + mysql_log.write(thd,COM_QUERY,"%s",thd->query); + DBUG_PRINT("query",("%s",thd->query)); mysql_parse(thd, thd->query, q_len); if ((expected_error != (actual_error = thd->net.last_errno)) && expected_error && @@ -1861,71 +1867,34 @@ int Stop_log_event::exec_event(struct st_relay_log_info* rli) Got a rotate log even from the master IMPLEMENTATION - - Rotate the log file if the name of the log file changed - (In practice this should always be the case) + This is mainly used so that we can later figure out the logname and + position for the master. - TODO - - Investigate/Test if we can't ignore all rotate log events - that we get from the master (and not even write it to the local - binary log). + We can't rotate the slave as this will cause infinitive rotations + in a A -> B -> A setup. RETURN VALUES - 0 ok - 1 Impossible new log file name (rotate log event is ignored) -*/ + 0 ok + */ int Rotate_log_event::exec_event(struct st_relay_log_info* rli) { - bool rotate_binlog = 0, write_slave_event = 0; char* log_name = rli->master_log_name; DBUG_ENTER("Rotate_log_event::exec_event"); pthread_mutex_lock(&rli->data_lock); - /* - TODO: probably needs re-write - rotate local binlog only if the name of remote has changed - */ - if (!*log_name || (memcmp(log_name, new_log_ident, ident_len) || - log_name[ident_len] != 0)) - { - write_slave_event = (!(flags & LOG_EVENT_FORCED_ROTATE_F) && - mysql_bin_log.is_open()); - rotate_binlog = (*log_name && write_slave_event); - if (ident_len >= sizeof(rli->master_log_name)) - { - // This should be impossible - pthread_mutex_unlock(&rli->data_lock); - DBUG_RETURN(1); - } - memcpy(log_name, new_log_ident, ident_len); - log_name[ident_len] = 0; - } + memcpy(log_name, new_log_ident, ident_len+1); rli->master_log_pos = pos; rli->relay_log_pos += get_event_len(); - if (rotate_binlog) - { - mysql_bin_log.new_file(); - rli->master_log_pos = BIN_LOG_HEADER_SIZE; - } DBUG_PRINT("info", ("master_log_pos: %d", (ulong) rli->master_log_pos)); - pthread_cond_broadcast(&rli->data_cond); pthread_mutex_unlock(&rli->data_lock); + pthread_cond_broadcast(&rli->data_cond); flush_relay_log_info(rli); - - if (write_slave_event) - { - Slave_log_event s(thd, rli); - if (s.master_host) - { - s.set_log_pos(&mysql_bin_log); - s.server_id = ::server_id; - mysql_bin_log.write(&s); - } - } DBUG_RETURN(0); } + int Intvar_log_event::exec_event(struct st_relay_log_info* rli) { switch (type) { diff --git a/sql/log_event.h b/sql/log_event.h index b69643c366a..5f7aa4ad586 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -522,16 +522,15 @@ class Rotate_log_event: public Log_event { public: const char* new_log_ident; - uchar ident_len; ulonglong pos; + uint ident_len; bool alloced; #ifndef MYSQL_CLIENT Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg, uint ident_len_arg = 0,ulonglong pos_arg = 4) : Log_event(thd_arg), new_log_ident(new_log_ident_arg), - ident_len(ident_len_arg ? ident_len_arg : - (uint) strlen(new_log_ident_arg)), pos(pos_arg), - alloced(0) + pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg : + (uint) strlen(new_log_ident_arg)), alloced(0) {} void pack_info(String* packet); int exec_event(struct st_relay_log_info* rli); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 172ed0a2968..75e6368712a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3039,7 +3039,7 @@ struct my_option my_long_options[] = "Set to 0 if you don't want to flush logs", (gptr*) &innobase_flush_log_at_trx_commit, (gptr*) &innobase_flush_log_at_trx_commit, - 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, + 0, GET_INT, OPT_ARG, 0, 0, 2, 0, 0, 0}, {"innodb_flush_method", OPT_INNODB_FLUSH_METHOD, "With which method to flush data", (gptr*) &innobase_unix_file_flush_method, (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, diff --git a/sql/net_serv.cc b/sql/net_serv.cc index bb7100f31be..122793b07a7 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -237,6 +237,7 @@ my_net_write(NET *net,const char *packet,ulong len) buff[3]= (uchar) net->pkt_nr++; if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE)) return 1; + DBUG_DUMP("packet_header",(char*) buff,NET_HEADER_SIZE); return net_write_buff(net,packet,len); } @@ -615,6 +616,7 @@ my_real_read(NET *net, ulong *complen) ("Packets out of order (Found: %d, expected %u)", (int) net->buff[net->where_b + 3], net->pkt_nr)); + DBUG_DUMP("packet_header",(char*) net->buff+net->where_b, 4); #ifdef EXTRA_DEBUG fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n", (int) net->buff[net->where_b + 3], diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 232c3de2570..81627dceb0e 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -236,7 +236,7 @@ static int find_target_pos(LEX_MASTER_INFO *mi, IO_CACHE *log, char *errmsg) return 1; } - if (ev->log_pos == log_pos && ev->server_id == target_server_id) + if (ev->log_pos >= log_pos && ev->server_id == target_server_id) { delete ev; mi->pos = my_b_tell(log); @@ -261,23 +261,24 @@ int translate_master(THD* thd, LEX_MASTER_INFO* mi, char* errmsg) int error = 1; int cmp_res; LINT_INIT(cmp_res); + DBUG_ENTER("translate_master"); if (!mysql_bin_log.is_open()) { strmov(errmsg,"Binary log is not open"); - return 1; + DBUG_RETURN(1); } if (!server_id_supplied) { strmov(errmsg, "Misconfigured master - server id was not set"); - return 1; + DBUG_RETURN(1); } if (mysql_bin_log.find_log_pos(&linfo, NullS, 1)) { strmov(errmsg,"Could not find first log"); - return 1; + DBUG_RETURN(1); } thd->current_linfo = &linfo; @@ -366,7 +367,7 @@ err: if (last_file >= 0 && last_file != file) (void) my_close(last_file, MYF(MY_WME)); - return error; + DBUG_RETURN(error); } @@ -423,12 +424,9 @@ int show_new_master(THD* thd) if (translate_master(thd, lex_mi, errmsg)) { if (errmsg[0]) - net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND, - "SHOW NEW MASTER", errmsg); - else - send_error(&thd->net, 0); - - DBUG_RETURN(1); + my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), + "SHOW NEW MASTER", errmsg); + DBUG_RETURN(-1); } else { diff --git a/sql/slave.cc b/sql/slave.cc index 7a1a1e2a6ef..7cc37d5f691 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1468,6 +1468,8 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, int event_count = 0; ulong init_abort_pos_wait; DBUG_ENTER("wait_for_pos"); + DBUG_PRINT("enter",("master_log_name: '%s' pos: %ld", + master_log_name, (ulong) master_log_pos)); pthread_mutex_lock(&data_lock); // abort only if master info changes during wait @@ -1498,6 +1500,7 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, if (pos_reached || thd->killed) break; + DBUG_PRINT("info",("Waiting for master update")); const char* msg = thd->enter_cond(&data_cond, &data_lock, "Waiting for master update"); pthread_cond_wait(&data_cond, &data_lock); @@ -2308,21 +2311,44 @@ err: } /* - We assume we already locked mi->data_lock + Start using a new binary log on the master + + SYNOPSIS + process_io_rotate() + mi master_info for the slave + rev The rotate log event read from the binary log + + DESCRIPTION + Updates the master info and relay data with the place in the next binary + log where we should start reading. + + NOTES + We assume we already locked mi->data_lock + + RETURN VALUES + 0 ok + 1 Log event is illegal */ -static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev) +static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev) { + int return_val= 1; DBUG_ENTER("process_io_rotate"); + safe_mutex_assert_owner(&mi->data_lock); if (unlikely(!rev->is_valid())) DBUG_RETURN(1); - DBUG_ASSERT(rev->ident_len < sizeof(mi->master_log_name)); - memcpy(mi->master_log_name,rev->new_log_ident, - rev->ident_len); - mi->master_log_name[rev->ident_len] = 0; - mi->master_log_pos = rev->pos; - DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); + + memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1); + mi->master_log_pos= rev->pos; + + pthread_mutex_lock(&mi->rli.data_lock); + memcpy(mi->rli.master_log_name, rev->new_log_ident, rev->ident_len+1); + mi->rli.master_log_pos= rev->pos; + pthread_mutex_unlock(&mi->rli.data_lock); + + DBUG_PRINT("info", ("master_log_pos: '%s' %d", + mi->master_log_name, (ulong) mi->master_log_pos)); #ifndef DBUG_OFF /* If we do not do this, we will be getting the first @@ -2335,23 +2361,24 @@ static int process_io_rotate(MASTER_INFO* mi, Rotate_log_event* rev) } /* - TODO: verify the issue with stop events, see if we need them at all - in the relay log - TODO: test this code before release - it has to be tested on a separte - setup with 3.23 master + TODO: + Test this code before release - it has to be tested on a separate + setup with 3.23 master */ static int queue_old_event(MASTER_INFO *mi, const char *buf, ulong event_len) { const char *errmsg = 0; - bool inc_pos = 1; - bool processed_stop_event = 0; - char* tmp_buf = 0; + ulong inc_pos; + bool ignore_event= 0; + char *tmp_buf = 0; + RELAY_LOG_INFO *rli= &mi->rli; DBUG_ENTER("queue_old_event"); - /* if we get Load event, we need to pass a non-reusable buffer - to read_log_event, so we do a trick + /* + If we get Load event, we need to pass a non-reusable buffer + to read_log_event, so we do a trick */ if (buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) { @@ -2377,54 +2404,52 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, pthread_mutex_lock(&mi->data_lock); ev->log_pos = mi->master_log_pos; switch (ev->get_type_code()) { + case STOP_EVENT: + ignore_event= mi->ignore_stop_event; + mi->ignore_stop_event=0; + inc_pos= event_len; + break; case ROTATE_EVENT: if (unlikely(process_io_rotate(mi,(Rotate_log_event*)ev))) { delete ev; pthread_mutex_unlock(&mi->data_lock); - DBUG_ASSERT(!tmp_buf); DBUG_RETURN(1); } mi->ignore_stop_event=1; - inc_pos = 0; - break; - case STOP_EVENT: - processed_stop_event=1; + inc_pos= 0; break; case CREATE_FILE_EVENT: { + /* We come here when and only when tmp_buf != 0 */ + DBUG_ASSERT(tmp_buf); int error = process_io_create_file(mi,(Create_file_log_event*)ev); delete ev; mi->master_log_pos += event_len; DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); pthread_mutex_unlock(&mi->data_lock); - DBUG_ASSERT(tmp_buf); my_free((char*)tmp_buf, MYF(0)); DBUG_RETURN(error); } default: mi->ignore_stop_event=0; + inc_pos= event_len; break; } - if (likely(!processed_stop_event || !mi->ignore_stop_event)) + if (likely(!ignore_event)) { - if (unlikely(mi->rli.relay_log.append(ev))) + if (unlikely(rli->relay_log.append(ev))) { delete ev; pthread_mutex_unlock(&mi->data_lock); - DBUG_ASSERT(!tmp_buf); DBUG_RETURN(1); } - mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); + rli->relay_log.harvest_bytes_written(&rli->log_space_total); } delete ev; - if (likely(inc_pos)) - mi->master_log_pos += event_len; + mi->master_log_pos+= inc_pos; DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); - if (unlikely(processed_stop_event)) - mi->ignore_stop_event=1; pthread_mutex_unlock(&mi->data_lock); - DBUG_ASSERT(!tmp_buf); DBUG_RETURN(0); } @@ -2435,48 +2460,52 @@ static int queue_old_event(MASTER_INFO *mi, const char *buf, int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len) { - int error=0; - bool inc_pos = 1; - bool processed_stop_event = 0; + int error= 0; + ulong inc_pos; + bool ignore_event= 0; + RELAY_LOG_INFO *rli= &mi->rli; DBUG_ENTER("queue_event"); if (mi->old_format) DBUG_RETURN(queue_old_event(mi,buf,event_len)); pthread_mutex_lock(&mi->data_lock); - + /* TODO: figure out if other events in addition to Rotate require special processing */ switch (buf[EVENT_TYPE_OFFSET]) { case STOP_EVENT: - processed_stop_event=1; + ignore_event= mi->ignore_stop_event; + mi->ignore_stop_event= 0; + inc_pos= event_len; break; case ROTATE_EVENT: { Rotate_log_event rev(buf,event_len,0); if (unlikely(process_io_rotate(mi,&rev))) + { + pthread_mutex_unlock(&mi->data_lock); DBUG_RETURN(1); - inc_pos=0; - mi->ignore_stop_event=1; + } + mi->ignore_stop_event= 1; + inc_pos= 0; break; } default: - mi->ignore_stop_event=0; + mi->ignore_stop_event= 0; + inc_pos= event_len; break; } - if (likely((!processed_stop_event || !mi->ignore_stop_event) && - !(error = mi->rli.relay_log.appendv(buf,event_len,0)))) + if (likely(!ignore_event && + !(error= rli->relay_log.appendv(buf,event_len,0)))) { - if (likely(inc_pos)) - mi->master_log_pos += event_len; + mi->master_log_pos+= inc_pos; DBUG_PRINT("info", ("master_log_pos: %d", (ulong) mi->master_log_pos)); - mi->rli.relay_log.harvest_bytes_written(&mi->rli.log_space_total); + rli->relay_log.harvest_bytes_written(&rli->log_space_total); } - if (unlikely(processed_stop_event)) - mi->ignore_stop_event=1; pthread_mutex_unlock(&mi->data_lock); DBUG_RETURN(error); } diff --git a/sql/slave.h b/sql/slave.h index b527aceb432..cbcd2957476 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -312,6 +312,7 @@ typedef struct st_master_info } MASTER_INFO; + int queue_event(MASTER_INFO* mi,const char* buf,ulong event_len); typedef struct st_table_rule_ent diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 519ac0e7ce2..c44fe2d053d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1310,18 +1310,24 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (table->fields >= 31) /* From 4.0.0 we have more fields */ { /* We write down SSL related ACL stuff */ - table->field[25]->store("",0); - table->field[26]->store("",0); - table->field[27]->store("",0); switch (thd->lex.ssl_type) { case SSL_TYPE_ANY: table->field[24]->store("ANY",3); + table->field[25]->store("",0); + table->field[26]->store("",0); + table->field[27]->store("",0); break; case SSL_TYPE_X509: table->field[24]->store("X509",4); + table->field[25]->store("",0); + table->field[26]->store("",0); + table->field[27]->store("",0); break; case SSL_TYPE_SPECIFIED: table->field[24]->store("SPECIFIED",9); + table->field[25]->store("",0); + table->field[26]->store("",0); + table->field[27]->store("",0); if (thd->lex.ssl_cipher) table->field[25]->store(thd->lex.ssl_cipher, strlen(thd->lex.ssl_cipher)); @@ -1332,8 +1338,8 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, table->field[27]->store(thd->lex.x509_subject, strlen(thd->lex.x509_subject)); break; - default: - table->field[24]->store("",0); + case SSL_TYPE_NOT_SPECIFIED: + break; // Nothing to do } USER_RESOURCES mqh = thd->lex.mqh; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e291334a29d..2973e7bd1b1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1356,7 +1356,12 @@ mysql_execute_command(void) { if (check_global_access(thd, REPL_SLAVE_ACL)) goto error; +#ifndef WORKING_NEW_MASTER + net_printf(&thd->net, ER_NOT_SUPPORTED_YET, "SHOW NEW MASTER"); + res= 1; +#else res = show_new_master(thd); +#endif break; } case SQLCOM_SHOW_SLAVE_HOSTS: diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 628b1775778..47b258d9ed2 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -910,6 +910,11 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, const char* log_file_name2, ulonglong log_pos2) { int res; + /* + TODO: Change compare function to work with file name of type + '.999 and .1000' + */ + if ((res = strcmp(log_file_name1, log_file_name2))) return res; if (log_pos1 > log_pos2) @@ -919,6 +924,7 @@ int cmp_master_pos(const char* log_file_name1, ulonglong log_pos1, return -1; } + int show_binlog_events(THD* thd) { DBUG_ENTER("show_binlog_events"); @@ -1010,15 +1016,16 @@ err: if (errmsg) { - net_printf(&thd->net, ER_ERROR_WHEN_EXECUTING_COMMAND, - "SHOW BINLOG EVENTS", errmsg); - DBUG_RETURN(1); + my_error(ER_ERROR_WHEN_EXECUTING_COMMAND, MYF(0), + "SHOW BINLOG EVENTS", errmsg); + DBUG_RETURN(-1); } send_eof(&thd->net); DBUG_RETURN(0); } + int show_binlog_info(THD* thd) { DBUG_ENTER("show_binlog_info"); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 0482313481d..021f3f07ad5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -627,7 +627,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, if (!(key_info->flags & HA_NULL_PART_KEY)) unique_key=1; key_info->key_length=(uint16) key_length; - uint max_key_length= max(file->max_key_length(), MAX_KEY_LENGTH); + uint max_key_length= min(file->max_key_length(), MAX_KEY_LENGTH); if (key_length > max_key_length && key->type != Key::FULLTEXT) { my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 8791f547ea6..cd85b3dbaf2 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -285,12 +285,14 @@ udf_func *find_udf(const char *name,uint length,bool mark_used) /* TODO: This should be changed to reader locks someday! */ pthread_mutex_lock(&THR_LOCK_udf); - udf=(udf_func*) hash_search(&udf_hash,(byte*) name, - length ? length : (uint) strlen(name)); - if (!udf->dlhandle) - udf=0; // Could not be opened - else if (mark_used) - udf->usage_count++; + if ((udf=(udf_func*) hash_search(&udf_hash,(byte*) name, + length ? length : (uint) strlen(name)))) + { + if (!udf->dlhandle) + udf=0; // Could not be opened + else if (mark_used) + udf->usage_count++; + } pthread_mutex_unlock(&THR_LOCK_udf); DBUG_RETURN(udf); } |