diff --git a/BUILD/compile-solaris-amd64-debug b/BUILD/compile-solaris-amd64-debug new file mode 100644 index 00000000000..ad1c298907f --- /dev/null +++ b/BUILD/compile-solaris-amd64-debug @@ -0,0 +1,10 @@ +#! /bin/sh +path=`dirname $0` +. "$path/SETUP.sh" +amd64_cflags="-m64 -mtune=athlon64" +extra_flags="$amd64_cflags $debug_cflags $max_cflags" +c_warnings="$c_warnings $debug_extra_warnings" +cxx_warnings="$cxx_warnings $debug_extra_warnings" +extra_configs="$amd64_configs $debug_configs $max_configs --enable-thread-safe-client" + +. "$path/FINISH.sh" diff --git a/BUILD/compile-solaris-amd64-forte b/BUILD/compile-solaris-amd64-forte new file mode 100644 index 00000000000..63aceb16c04 --- /dev/null +++ b/BUILD/compile-solaris-amd64-forte @@ -0,0 +1,52 @@ +#! /bin/sh + +gmake -k clean || true +/bin/rm -f */.deps/*.P config.cache + +path=`dirname $0` +. "$path/autorun.sh" + +# For "optimal" code for this computer add -fast to EXTRA +# To compile 64 bit, add -xarch=v9 to EXTRA_64_BIT + +EXTRA_64_BIT="-xarch=amd64" +EXTRA="-fast" + +# +# The following should not need to be touched +# + +export CC CXX CFLAGS CXXFLAGS +STD="-g -mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT" +ASFLAGS="$EXTRA_64_BIT" +CC=cc-5.0 +CFLAGS="-Xa -xstrconst $STD" +CXX=CC +CXXFLAGS="-noex $STD" +./configure \ + --prefix=/usr/local/mysql \ + --localstatedir=/usr/local/mysql/data \ + --libexecdir=/usr/local/mysql/bin \ + --with-extra-charsets=complex \ + --enable-thread-safe-client \ + --enable-local-infile \ + --with-zlib-dir=bundled \ + --with-big-tables \ + --with-readline \ + --with-archive-storage-engine \ + --with-named-curses=-lcurses \ + --with-big-tables \ + --with-innodb \ + --with-example-storage-engine \ + --with-blackhole-storage-engine \ + --with-federated-storage-engine \ + --with-csv-storage-engine \ + --with-ssl \ + --enable-assembler + +# Not including: +# --with-ndbcluster +# --with-berkeley-db + +gmake -j4 +test $? = 0 && make test diff --git a/BUILD/compile-solaris-amd64-forte-debug b/BUILD/compile-solaris-amd64-forte-debug new file mode 100644 index 00000000000..8e3ade9b429 --- /dev/null +++ b/BUILD/compile-solaris-amd64-forte-debug @@ -0,0 +1,54 @@ +#! /bin/sh + +gmake -k clean || true +/bin/rm -f */.deps/*.P config.cache + +path=`dirname $0` +. "$path/autorun.sh" + +# To compile 64 bit, add -xarch=amd64 to EXTRA_64_BIT +EXTRA_64_BIT="-xarch=amd64" + +# For "optimal" code for this computer add -fast to EXTRA. Note that +# this causes problem with debugging the program since -fast implies +# -xO5. +EXTRA="" + +# +# The following should not need to be touched +# + +export CC CXX CFLAGS CXXFLAGS +STD="-g -mt -D_FORTEC_ $EXTRA $EXTRA_64_BIT $debug_cflags" +ASFLAGS="$EXTRA_64_BIT" +CC=cc-5.0 +CFLAGS="-Xa -xstrconst $STD" +CXX=CC +CXXFLAGS="-noex $STD" +./configure \ + --prefix=/usr/local/mysql \ + --localstatedir=/usr/local/mysql/data \ + --libexecdir=/usr/local/mysql/bin \ + --with-extra-charsets=complex \ + --enable-thread-safe-client \ + --enable-local-infile \ + --with-zlib-dir=bundled \ + --with-big-tables \ + --with-readline \ + --with-archive-storage-engine \ + --with-named-curses=-lcurses \ + --with-big-tables \ + --with-innodb \ + --with-example-storage-engine \ + --with-blackhole-storage-engine \ + --with-federated-storage-engine \ + --with-csv-storage-engine \ + --with-ssl \ + --with-debug \ + --enable-assembler + +# Not including: +# --with-ndbcluster +# --with-berkeley-db + +gmake -j4 diff --git a/client/client_priv.h b/client/client_priv.h index 71d6ce8a635..06145232995 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -76,7 +76,7 @@ enum options_client OPT_SLAP_POST_SYSTEM, OPT_SLAP_COMMIT, OPT_SLAP_DETACH, - OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT, OPT_SERVER_ID, + OPT_MYSQL_REPLACE_INTO, OPT_BASE64_OUTPUT_MODE, OPT_SERVER_ID, OPT_FIX_TABLE_NAMES, OPT_FIX_DB_NAMES, OPT_SSL_VERIFY_SERVER_CERT, OPT_DEBUG_INFO, OPT_DEBUG_CHECK, OPT_COLUMN_TYPES, OPT_ERROR_LOG_FILE, OPT_WRITE_BINLOG, OPT_DUMP_DATE, diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 7a4135ab649..a2110bee339 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -63,7 +63,12 @@ void sql_print_error(const char *format, ...); static bool one_database=0, to_last_remote_log= 0, disable_log_bin= 0; static bool opt_hexdump= 0; -static bool opt_base64_output= 0; +const char *base64_output_mode_names[]= {"NEVER", "AUTO", "ALWAYS", NullS}; +TYPELIB base64_output_mode_typelib= + { array_elements(base64_output_mode_names) - 1, "", + base64_output_mode_names, NULL }; +static enum_base64_output_mode opt_base64_output_mode= BASE64_OUTPUT_UNSPEC; +static const char *opt_base64_output_mode_str= NullS; static const char* database= 0; static my_bool force_opt= 0, short_form= 0, remote_opt= 0; static my_bool debug_info_flag, debug_check_flag; @@ -96,7 +101,7 @@ static my_bool file_not_closed_error= 0; This is because the event will be created (alloced) in read_log_event() (which returns a pointer) in check_header(). */ -Format_description_log_event* glob_description_event; +static Format_description_log_event* glob_description_event; static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, const char* logname); @@ -265,7 +270,7 @@ public: File prepare_new_file_for_old_format(Load_log_event *le, char *filename); int load_old_format_file(NET* net, const char *server_fname, uint server_fname_len, File file); - int process_first_event(const char *bname, uint blen, const char *block, + int process_first_event(const char *bname, uint blen, const uchar *block, uint block_len, uint file_id, Create_file_log_event *ce); }; @@ -370,7 +375,7 @@ int Load_log_processor::load_old_format_file(NET* net, const char*server_fname, */ int Load_log_processor::process_first_event(const char *bname, uint blen, - const char *block, uint block_len, + const uchar *block, uint block_len, uint file_id, Create_file_log_event *ce) { @@ -557,7 +562,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, else print_event_info->hexdump_from= pos; - print_event_info->base64_output= opt_base64_output; + print_event_info->base64_output_mode= opt_base64_output_mode; DBUG_PRINT("debug", ("event_type: %s", ev->get_type_str())); @@ -565,7 +570,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case QUERY_EVENT: if (check_database(((Query_log_event*)ev)->db)) goto end; - if (opt_base64_output) + if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) write_event_header_and_base64(ev, result_file, print_event_info); else ev->print(result_file, print_event_info); @@ -589,7 +594,7 @@ int process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, filename and use LOCAL), prepared in the 'case EXEC_LOAD_EVENT' below. */ - if (opt_base64_output) + if (opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) { write_event_header_and_base64(ce, result_file, print_event_info); } @@ -678,6 +683,38 @@ Create_file event for file_id: %u\n",exv->file_id); Begin_load_query event for file_id: %u\n", exlq->file_id); break; } + case TABLE_MAP_EVENT: + case WRITE_ROWS_EVENT: + case DELETE_ROWS_EVENT: + case UPDATE_ROWS_EVENT: + case PRE_GA_WRITE_ROWS_EVENT: + case PRE_GA_DELETE_ROWS_EVENT: + case PRE_GA_UPDATE_ROWS_EVENT: + /* + These events must be printed in base64 format, if printed. + base64 format requires a FD event to be safe, so if no FD + event has been printed, we give an error. Except if user + passed --short-form, because --short-form disables printing + row events. + */ + if (!print_event_info->printed_fd_event && !short_form) + { + /* + todo: a lot to clean up here + */ + const char* type_str= ev->get_type_str(); + delete ev; + if (opt_base64_output_mode == BASE64_OUTPUT_NEVER) + die("--base64-output=never specified, but binlog contains a " + "%s event which must be printed in base64.", + type_str); + else + die("malformed binlog: it does not contain any " + "Format_description_log_event. I now found a %s event, which is " + "not safe to process without a Format_description_log_event.", + type_str); + } + /* FALL THROUGH */ default: ev->print(result_file, print_event_info); } @@ -707,12 +744,17 @@ static struct my_option my_long_options[] = {"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif - {"base64-output", OPT_BASE64_OUTPUT, - "Print all binlog entries using base64 encoding. " - "This is for debugging only. Logs produced using this option " - "should not be applied on production systems.", - (uchar**) &opt_base64_output, (uchar**) &opt_base64_output, 0, GET_BOOL, - NO_ARG, 0, 0, 0, 0, 0, 0}, + {"base64-output", OPT_BASE64_OUTPUT_MODE, + "Determine when the output statements should be base64-encoded BINLOG " + "statements: 'never' disables it and works only for binlogs without " + "row-based events; 'auto' is the default and prints base64 only when " + "necessary (i.e., for row-based events and format description events); " + "'always' prints base64 whenever possible. 'always' is for debugging " + "only and should not be used in a production system. The default is " + "'auto'. --base64-output is a short form for --base64-output=always." + ,(uchar**) &opt_base64_output_mode_str, + (uchar**) &opt_base64_output_mode_str, + 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, /* mysqlbinlog needs charsets knowledge, to be able to convert a charset number found in binlog to a charset name (to be able to print things @@ -788,7 +830,10 @@ static struct my_option my_long_options[] = {"set-charset", OPT_SET_CHARSET, "Add 'SET NAMES character_set' to the output.", (uchar**) &charset, (uchar**) &charset, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"short-form", 's', "Just show the queries, no extra info.", + {"short-form", 's', "Just show regular queries: no extra info and no " + "row-based events. This is for testing only, and should not be used in " + "production systems. If you want to suppress base64-output, consider " + "using --base64-output=never instead.", (uchar**) &short_form, (uchar**) &short_form, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", @@ -973,6 +1018,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case OPT_STOP_DATETIME: stop_datetime= convert_str_to_timestamp(stop_datetime_str); break; + case OPT_BASE64_OUTPUT_MODE: + if (argument == NULL) + opt_base64_output_mode= BASE64_OUTPUT_ALWAYS; + else + { + opt_base64_output_mode= (enum_base64_output_mode) + (find_type_or_exit(argument, &base64_output_mode_typelib, opt->name)-1); + } + break; case 'V': print_version(); exit(0); @@ -1305,8 +1359,31 @@ err: } +/** + Reads the @c Format_description_log_event from the beginning of the + input file. + + The @c Format_description_log_event is only read if it is outside + the range specified with @c --start-position; otherwise, it will be + seen later. If this is an old binlog, a fake @c + Format_description_event is created. This also prints a @c + Format_description_log_event to the output, unless we reach the + --start-position range. In this case, it is assumed that a @c + Format_description_log_event will be found when reading events the + usual way. + + @param file The file to which a @c Format_description_log_event will + be printed. + + @param description_event Pointer to the global @c + Format_description_log_event pointer. This will be updated if a new + Format_description_log_event is found. + + @param print_event_info Context state needed to print events. +*/ static void check_header(IO_CACHE* file, - Format_description_log_event **description_event) + Format_description_log_event **description_event, + PRINT_EVENT_INFO *print_event_info) { uchar header[BIN_LOG_HEADER_SIZE]; uchar buf[PROBE_HEADER_LEN]; @@ -1369,10 +1446,12 @@ Could not read entry at offset %lu : Error in log format or read error", } else { - DBUG_PRINT("info",("buf[4]=%d", buf[4])); + DBUG_PRINT("info",("buf[EVENT_TYPE_OFFSET=%d]=%d", + EVENT_TYPE_OFFSET, buf[EVENT_TYPE_OFFSET])); /* always test for a Start_v3, even if no --start-position */ - if (buf[4] == START_EVENT_V3) /* This is 3.23 or 4.x */ + if (buf[EVENT_TYPE_OFFSET] == START_EVENT_V3) { + /* This is 3.23 or 4.x */ if (uint4korr(buf + EVENT_LEN_OFFSET) < (LOG_EVENT_MINIMAL_HEADER_LEN + START_V3_HEADER_LEN)) { @@ -1384,8 +1463,9 @@ Could not read entry at offset %lu : Error in log format or read error", } else if (tmp_pos >= start_position) break; - else if (buf[4] == FORMAT_DESCRIPTION_EVENT) /* This is 5.0 */ + else if (buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) { + /* This is 5.0 */ Format_description_log_event *new_description_event; my_b_seek(file, tmp_pos); /* seek back to event's start */ if (!(new_description_event= (Format_description_log_event*) @@ -1397,11 +1477,22 @@ Could not read entry at offset %lu : Error in log format or read error", at offset %lu ; this could be a log format error or read error", tmp_pos); } - delete *description_event; - *description_event= new_description_event; + if (opt_base64_output_mode == BASE64_OUTPUT_AUTO + || opt_base64_output_mode == BASE64_OUTPUT_ALWAYS) + /* + process_event will delete *description_event and set it to + the new one, so we should not do it ourselves in this + case. + */ + process_event(print_event_info, new_description_event, tmp_pos); + else + { + delete *description_event; + *description_event= new_description_event; + } DBUG_PRINT("info",("Setting description_event")); } - else if (buf[4] == ROTATE_EVENT) + else if (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT) { Log_event *ev; my_b_seek(file, tmp_pos); /* seek back to event's start */ @@ -1430,7 +1521,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, uchar tmp_buff[BIN_LOG_HEADER_SIZE]; int error= 0; - if (logname && logname[0] != '-') + if (logname && strcmp(logname, "-") != 0) { if ((fd = my_open(logname, O_RDONLY | O_BINARY, MYF(MY_WME))) < 0) return 1; @@ -1440,7 +1531,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, my_close(fd, MYF(MY_WME)); return 1; } - check_header(file, &glob_description_event); + check_header(file, &glob_description_event, print_event_info); } else // reading from stdin; { @@ -1462,7 +1553,7 @@ static int dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, if (init_io_cache(file, fileno(stdin), 0, READ_CACHE, (my_off_t) 0, 0, MYF(MY_WME | MY_NABP | MY_DONT_CHECK_FILESIZE))) return 1; - check_header(file, &glob_description_event); + check_header(file, &glob_description_event, print_event_info); if (start_position) { /* skip 'start_position' characters from stdin */ @@ -1554,6 +1645,9 @@ int main(int argc, char** argv) exit(1); } + if (opt_base64_output_mode == BASE64_OUTPUT_UNSPEC) + opt_base64_output_mode= BASE64_OUTPUT_AUTO; + my_set_max_open_files(open_files_limit); MY_TMPDIR tmpdir; diff --git a/include/my_bitmap.h b/include/my_bitmap.h index ab69b2d671d..78642df3362 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -159,6 +159,22 @@ static inline my_bool bitmap_cmp(const MY_BITMAP *map1, const MY_BITMAP *map2) #define bitmap_set_all(MAP) \ (memset((MAP)->bitmap, 0xFF, 4*no_words_in_map((MAP)))) +/** + check, set and clear a bit of interest of an integer. + + If the bit is out of range @retval -1. Otherwise + bit_is_set @return 0 or 1 reflecting the bit is set or not; + bit_do_set @return 1 (bit is set 1) + bit_do_clear @return 0 (bit is cleared to 0) +*/ + +#define bit_is_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ + (((I) & (ULL(1) << (B))) == 0 ? 0 : 1) : -1) +#define bit_do_set(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ + ((I) |= (ULL(1) << (B)), 1) : -1) +#define bit_do_clear(I,B) (sizeof(I) * CHAR_BIT > (B) ? \ + ((I) &= ~(ULL(1) << (B)), 0) : -1) + #ifdef __cplusplus } #endif diff --git a/include/my_sys.h b/include/my_sys.h index e13c4cde78b..ee79806c40e 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -521,6 +521,11 @@ typedef int (*qsort2_cmp)(const void *, const void *, const void *); #define my_b_tell(info) ((info)->pos_in_file + \ (size_t) (*(info)->current_pos - (info)->request_pos)) +#define my_b_get_buffer_start(info) (info)->request_pos +#define my_b_get_bytes_in_buffer(info) (char*) (info)->read_end - \ + (char*) my_b_get_buffer_start(info) +#define my_b_get_pos_in_file(info) (info)->pos_in_file + /* tell write offset in the SEQ_APPEND cache */ int my_b_copy_to_file(IO_CACHE *cache, FILE *file); my_off_t my_b_append_tell(IO_CACHE* info); diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 79d11c857ab..a77dccdebf2 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -45,7 +45,8 @@ dist-hook: $(distdir)/std_data/ndb_backup51_data_be \ $(distdir)/std_data/ndb_backup51_data_le \ $(distdir)/std_data/parts \ - $(distdir)/lib + $(distdir)/lib \ + $(distdir)/lib/My -$(INSTALL_DATA) $(srcdir)/t/*.def $(distdir)/t $(INSTALL_DATA) $(srcdir)/t/*.test $(distdir)/t -$(INSTALL_DATA) $(srcdir)/t/*.imtest $(distdir)/t @@ -58,6 +59,7 @@ dist-hook: -$(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.opt $(distdir)/extra/binlog_tests -$(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.opt $(distdir)/extra/rpl_tests $(INSTALL_DATA) $(srcdir)/include/*.inc $(distdir)/include + $(INSTALL_DATA) $(srcdir)/include/*.sql $(distdir)/include $(INSTALL_DATA) $(srcdir)/include/*.test $(distdir)/include $(INSTALL_DATA) $(srcdir)/r/*.result $(srcdir)/r/*.require $(distdir)/r $(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(distdir)/std_data @@ -74,6 +76,7 @@ dist-hook: $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(distdir)/std_data/ndb_backup51_data_le $(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(distdir)/std_data/parts $(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib + $(INSTALL_DATA) $(srcdir)/lib/My/*.pm $(distdir)/lib/My -rm -rf `find $(distdir)/suite -type d -name SCCS` $(distdir)/suite/row_lock install-data-local: @@ -89,7 +92,8 @@ install-data-local: $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_be \ $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le \ $(DESTDIR)$(testdir)/std_data/parts \ - $(DESTDIR)$(testdir)/lib + $(DESTDIR)$(testdir)/lib \ + $(DESTDIR)$(testdir)/lib/My $(INSTALL_DATA) $(srcdir)/README $(DESTDIR)$(testdir) -$(INSTALL_DATA) $(srcdir)/t/*.def $(DESTDIR)$(testdir)/t $(INSTALL_DATA) $(srcdir)/t/*.test $(DESTDIR)$(testdir)/t @@ -106,6 +110,7 @@ install-data-local: -$(INSTALL_DATA) $(srcdir)/extra/binlog_tests/*.opt $(DESTDIR)$(testdir)/extra/binlog_tests -$(INSTALL_DATA) $(srcdir)/extra/rpl_tests/*.opt $(DESTDIR)$(testdir)/extra/rpl_tests $(INSTALL_DATA) $(srcdir)/include/*.inc $(DESTDIR)$(testdir)/include + $(INSTALL_DATA) $(srcdir)/include/*.sql $(DESTDIR)$(testdir)/include $(INSTALL_DATA) $(srcdir)/include/*.test $(DESTDIR)$(testdir)/include $(INSTALL_DATA) $(srcdir)/std_data/*.dat $(DESTDIR)$(testdir)/std_data $(INSTALL_DATA) $(srcdir)/std_data/*.*001 $(DESTDIR)$(testdir)/std_data @@ -123,6 +128,7 @@ install-data-local: $(INSTALL_DATA) $(srcdir)/std_data/ndb_backup51_data_le/BACKUP* $(DESTDIR)$(testdir)/std_data/ndb_backup51_data_le $(INSTALL_DATA) $(srcdir)/std_data/parts/part_* $(DESTDIR)$(testdir)/std_data/parts $(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib + $(INSTALL_DATA) $(srcdir)/lib/My/*.pm $(DESTDIR)$(testdir)/lib/My for f in `(cd $(srcdir); find suite -type f | egrep -v 'SCCS|row_lock')`; \ do \ d=$(DESTDIR)$(testdir)/`dirname $$f`; \ diff --git a/mysql-test/extra/binlog_tests/blackhole.test b/mysql-test/extra/binlog_tests/blackhole.test index df2295af4ff..59d31c3a08b 100644 --- a/mysql-test/extra/binlog_tests/blackhole.test +++ b/mysql-test/extra/binlog_tests/blackhole.test @@ -126,7 +126,12 @@ select * from t2; select * from t3; let $VERSION=`select version()`; -source include/show_binlog_events.inc; +--replace_result $VERSION VERSION +--replace_column 2 # 4 # 5 # +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ +--replace_regex /file_id=[0-9]+/file_id=#/ +show binlog events; + drop table t1,t2,t3; # @@ -178,7 +183,14 @@ start transaction; insert into t1 values(2); rollback; set autocommit=1; -source include/show_binlog_events.inc; + +let $VERSION=`select version()`; +--replace_result $VERSION VERSION +--replace_column 2 # 4 # 5 # +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ +--replace_regex /file_id=[0-9]+/file_id=#/ +show binlog events; + drop table if exists t1; # End of 5.1 tests diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test index 7141bd1abb9..0d6e824e6af 100644 --- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test +++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_binlog.test @@ -315,4 +315,323 @@ disconnect con3; connection con4; select get_lock("a",10); # wait for rollback to finish +flush logs; + +# we check that the error code of the "ROLLBACK" event is 0 and not +# ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction +# and does not make slave to stop) +if (`select @@binlog_format = 'ROW'`) +{ + --exec $MYSQL_BINLOG --start-position=524 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output +} + +if (`select @@binlog_format = 'STATEMENT' || @@binlog_format = 'MIXED'`) +{ + --exec $MYSQL_BINLOG --start-position=555 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output +} + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval select +(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output")) +is not null; +--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR +eval select +@a like "%#%error_code=0%ROLLBACK\\n/*!*/;%ROLLBACK /* added by mysqlbinlog */;%", +@a not like "%#%error_code=%error_code=%"; +drop table t1, t2; + +# +# Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack +# bug #28960 non-trans temp table changes with insert .. select +# not binlogged after rollback +# +# testing appearence of insert into temp_table in binlog. +# There are two branches of execution that require different setup. + +## send_eof() branch + +# prepare + +create temporary table tt (a int unique); +create table ti (a int) engine=innodb; +reset master; + +# action + +begin; +insert into ti values (1); +insert into ti values (2) ; +insert into tt select * from ti; +rollback; + +# check + +select count(*) from tt /* 2 */; +source include/show_binlog_events.inc; +select count(*) from ti /* zero */; +insert into ti select * from tt; +select * from ti /* that is what slave would miss - a bug */; + + +## send_error() branch +delete from ti; +delete from tt where a=1; +reset master; + +# action + +begin; +insert into ti values (1); +insert into ti values (2) /* to make the dup error in the following */; +--error ER_DUP_ENTRY +insert into tt select * from ti /* one affected and error */; +rollback; + +# check + +source include/show_binlog_events.inc; +select count(*) from ti /* zero */; +insert into ti select * from tt; +select * from tt /* that is what otherwise slave missed - the bug */; + +drop table ti, tt; + + +# +# Bug #27417 thd->no_trans_update.stmt lost value inside of SF-exec-stack +# +# Testing asserts: if there is a side effect of modifying non-transactional +# table thd->no_trans_update.stmt must be TRUE; +# the assert is active with debug build +# + +--disable_warnings +drop function if exists bug27417; +drop table if exists t1,t2; +--enable_warnings +# side effect table +CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM; +# target tables +CREATE TABLE t2 (a int NOT NULL auto_increment, PRIMARY KEY (a)); + +delimiter |; +create function bug27417(n int) +RETURNS int(11) +begin + insert into t1 values (null); + return n; +end| +delimiter ;| + +reset master; + +# execute + +insert into t2 values (bug27417(1)); +insert into t2 select bug27417(2); +reset master; + +--error ER_DUP_ENTRY +insert into t2 values (bug27417(2)); +source include/show_binlog_events.inc; /* only (!) with fixes for #23333 will show there is the query */; +select count(*) from t1 /* must be 3 */; + +reset master; +select count(*) from t2; +delete from t2 where a=bug27417(3); +select count(*) from t2 /* nothing got deleted */; +source include/show_binlog_events.inc; /* the query must be in regardless of #23333 */; +select count(*) from t1 /* must be 5 */; + +--enable_info +delete t2 from t2 where t2.a=bug27417(100) /* must not affect t2 */; +--disable_info +select count(*) from t1 /* must be 7 */; + +# function bug27417 remains for the following testing of bug#23333 +drop table t1,t2; + +# +# Bug#23333 using the patch (and the test) for bug#27471 +# +# throughout the bug tests +# t1 - non-trans side effects gatherer; +# t2 - transactional table; +# + +CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM; +CREATE TABLE t2 (a int, PRIMARY KEY (a)) ENGINE=InnoDB; +CREATE TABLE t3 (a int, PRIMARY KEY (a), b int unique) ENGINE=MyISAM; +CREATE TABLE t4 (a int, PRIMARY KEY (a), b int unique) ENGINE=Innodb; +CREATE TABLE t5 (a int, PRIMARY KEY (a)) ENGINE=InnoDB; + + +# +# INSERT +# + +# prepare + + insert into t2 values (1); + reset master; + +# execute + + --error ER_DUP_ENTRY + insert into t2 values (bug27417(1)); + +# check + + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 1 */; + +# +# INSERT SELECT +# + +# prepare + delete from t1; + delete from t2; + insert into t2 values (2); + reset master; + +# execute + + --error ER_DUP_ENTRY + insert into t2 select bug27417(1) union select bug27417(2); + +# check + + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 2 */; + +# +# UPDATE inc multi-update +# + +# prepare + delete from t1; + insert into t3 values (1,1),(2,3),(3,4); + reset master; + +# execute + --error ER_DUP_ENTRY + update t3 set b=b+bug27417(1); + +# check + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 2 */; + +## multi_update::send_eof() branch + +# prepare + delete from t3; + delete from t4; + insert into t3 values (1,1); + insert into t4 values (1,1),(2,2); + + reset master; + +# execute + --error ER_DUP_ENTRY + UPDATE t4,t3 SET t4.a=t3.a + bug27417(1) /* top level non-ta table */; + +# check + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 4 */; + +## send_error() branch of multi_update + +# prepare + delete from t1; + delete from t3; + delete from t4; + insert into t3 values (1,1),(2,2); + insert into t4 values (1,1),(2,2); + + reset master; + +# execute + --error ER_DUP_ENTRY + UPDATE t3,t4 SET t3.a=t4.a + bug27417(1); + +# check + select count(*) from t1 /* must be 1 */; + +# cleanup + drop table t4; + + +# +# DELETE incl multi-delete +# + +# prepare + delete from t1; + delete from t2; + delete from t3; + insert into t2 values (1); + insert into t3 values (1,1); + create trigger trg_del before delete on t2 for each row + insert into t3 values (bug27417(1), 2); + reset master; + +# execute + --error ER_DUP_ENTRY + delete from t2; +# check + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 1 */; + +# cleanup + drop trigger trg_del; + +# prepare + delete from t1; + delete from t2; + delete from t5; + create trigger trg_del_t2 after delete on t2 for each row + insert into t1 values (1); + insert into t2 values (2),(3); + insert into t5 values (1),(2); + reset master; + +# execute + --error ER_DUP_ENTRY + delete t2.* from t2,t5 where t2.a=t5.a + 1; + +# check + source include/show_binlog_events.inc; /* the output must denote there is the query */; + select count(*) from t1 /* must be 1 */; + + +# +# LOAD DATA +# + +# prepare + delete from t1; + create table t4 (a int default 0, b int primary key) engine=innodb; + insert into t4 values (0, 17); + reset master; + +# execute + --error ER_DUP_ENTRY + load data infile '../std_data_ln/rpl_loaddata.dat' into table t4 (a, @b) set b= @b + bug27417(2); +# check + select * from t4; + select count(*) from t1 /* must be 2 */; + source include/show_binlog_events.inc; /* the output must denote there is the query */; + +# +# bug#23333 cleanup +# + + +drop trigger trg_del_t2; +drop table t1,t2,t3,t4,t5; +drop function bug27417; + + +--echo end of tests diff --git a/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test b/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test index 03514bfdb55..0a0bef4ca4d 100644 --- a/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test +++ b/mysql-test/extra/binlog_tests/mix_innodb_myisam_side_effects.test @@ -18,7 +18,6 @@ create temporary table tt (a int unique); create table ti (a int) engine=innodb; reset master; -show master status; # action @@ -31,7 +30,6 @@ rollback; # check select count(*) from tt /* 2 */; -show master status; source include/show_binlog_events.inc; select count(*) from ti /* zero */; insert into ti select * from tt; @@ -42,7 +40,6 @@ select * from ti /* that is what slave would miss - bug#28960 */; delete from ti; delete from tt where a=1; reset master; -show master status; # action @@ -55,7 +52,6 @@ rollback; # check -show master status; source include/show_binlog_events.inc; # nothing in binlog with row bilog format select count(*) from ti /* zero */; insert into ti select * from tt; diff --git a/mysql-test/extra/rpl_tests/rpl_foreign_key.test b/mysql-test/extra/rpl_tests/rpl_foreign_key.test index 583f2d85554..8755bf5aa87 100644 --- a/mysql-test/extra/rpl_tests/rpl_foreign_key.test +++ b/mysql-test/extra/rpl_tests/rpl_foreign_key.test @@ -32,3 +32,34 @@ SET FOREIGN_KEY_CHECKS=0; DROP TABLE IF EXISTS t1,t2,t3; SET FOREIGN_KEY_CHECKS=1; sync_slave_with_master; + +# +# Bug #32468 delete rows event on a table with foreign key constraint fails +# + +connection master; + +eval create table t1 (b int primary key) engine = $engine_type; +eval create table t2 (a int primary key, b int, foreign key (b) references t1(b)) + engine = $engine_type; + +insert into t1 set b=1; +insert into t2 set a=1, b=1; + +set foreign_key_checks=0; +set @@session.binlog_format=row; +delete from t1; + +--echo must sync w/o a problem (could not with the buggy code) +sync_slave_with_master; +select count(*) from t1 /* must be zero */; + + +# cleanup for bug#32468 + +connection master; +drop table t2,t1; + +sync_slave_with_master; + + diff --git a/mysql-test/extra/rpl_tests/rpl_max_relay_size.test b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test index 6b84cf67d58..5b546bbd891 100644 --- a/mysql-test/extra/rpl_tests/rpl_max_relay_size.test +++ b/mysql-test/extra/rpl_tests/rpl_max_relay_size.test @@ -43,7 +43,7 @@ set global max_relay_log_size=8192-1; # mapped to 4096 select @@global.max_relay_log_size; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 2 @@ -55,7 +55,7 @@ set global max_relay_log_size=(5*4096); query_vertical select @@global.max_relay_log_size; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 3: max_relay_log_size = 0 @@ -67,7 +67,7 @@ set global max_relay_log_size=0; query_vertical select @@global.max_relay_log_size; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 4: Tests below are mainly to ensure that we have not coded with wrong assumptions @@ -78,7 +78,7 @@ reset slave; # test of relay log rotation when the slave is stopped # (to make sure it does not crash). flush logs; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 5 @@ -96,7 +96,7 @@ create table t1 (a int); save_master_pos; connection slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; --echo # --echo # Test 6: one more rotation, to be sure Relay_Log_Space is correctly updated @@ -108,13 +108,12 @@ drop table t1; save_master_pos; connection slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; connection master; # test that the absence of relay logs does not make a master crash flush logs; --- replace_column 3 -query_vertical show master status; +source include/show_master_status.inc; # Restore max_binlog_size connection slave; diff --git a/mysql-test/extra/rpl_tests/rpl_reset_slave.test b/mysql-test/extra/rpl_tests/rpl_reset_slave.test index 83b39d3299a..2cc041a35e1 100644 --- a/mysql-test/extra/rpl_tests/rpl_reset_slave.test +++ b/mysql-test/extra/rpl_tests/rpl_reset_slave.test @@ -13,18 +13,18 @@ connection master; save_master_pos; connection slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; stop slave; change master to master_user='test'; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; reset slave; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; start slave; sync_with_master; -source include/show_slave_status.inc; +source include/show_slave_status2.inc; # test of crash with temp tables & RESET SLAVE # (test to see if RESET SLAVE clears temp tables in memory and disk) diff --git a/mysql-test/extra/rpl_tests/rpl_row_basic.test b/mysql-test/extra/rpl_tests/rpl_row_basic.test index c35a53f15bc..48ddbaf244a 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_basic.test +++ b/mysql-test/extra/rpl_tests/rpl_row_basic.test @@ -174,11 +174,18 @@ sync_slave_with_master; INSERT INTO t7 VALUES (1,3), (2,6), (3,9); SELECT * FROM t7 ORDER BY C1; +# since bug#31552/31609 idempotency is not default any longer. In order +# the preceeding test INSERT INTO t7 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + connection master; --echo --- on master: new values inserted --- INSERT INTO t7 VALUES (1,2), (2,4), (3,6); SELECT * FROM t7 ORDER BY C1; sync_slave_with_master; + +set @@global.slave_exec_mode= default; --echo --- on slave: old values should be overwritten by replicated values --- SELECT * FROM t7 ORDER BY C1; @@ -206,12 +213,19 @@ SELECT * FROM t8 ORDER BY a; INSERT INTO t8 VALUES (1,2,3), (2,4,6), (3,6,9); SELECT * FROM t8 ORDER BY a; +# since bug#31552/31609 idempotency is not default any longer. In order +# the preceeding test INSERT INTO t8 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + connection master; --echo --- on master --- # We insert a row that will cause conflict on the primary key but not # on the other keys. INSERT INTO t8 VALUES (2,4,8); sync_slave_with_master; +set @@global.slave_exec_mode= default; + --echo --- on slave --- SELECT * FROM t8 ORDER BY a; @@ -234,12 +248,17 @@ connection master; INSERT INTO t1 VALUES ('K','K'), ('L','L'), ('M','M'); --echo **** On Master **** sync_slave_with_master; +# since bug#31552/31609 idempotency is not default any longer. In order +# the following test DELETE FROM t1 to pass the mode is switched +# temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; DELETE FROM t1 WHERE C1 = 'L'; connection master; DELETE FROM t1; query_vertical SELECT COUNT(*) FROM t1 ORDER BY c1,c2; sync_slave_with_master; +set @@global.slave_exec_mode= default; let $last_error = query_get_value("SHOW SLAVE STATUS", Last_SQL_Errno, 1); disable_query_log; eval SELECT "$last_error" AS Last_SQL_Error; diff --git a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test index 23ac16d24ae..b5795cf525d 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test +++ b/mysql-test/extra/rpl_tests/rpl_row_tabledefs.test @@ -69,6 +69,11 @@ ALTER TABLE t8 ADD e1 INT NOT NULL DEFAULT 0, ADD e2 INT NOT NULL DEFAULT 0, # Insert some values for tables on slave side. These should not be # modified when the row from the master is applied. +# since bug#31552/31609 idempotency is not default any longer. In order +# the following INSERTs to pass the mode is switched temprorarily +set @@global.slave_exec_mode= 'IDEMPOTENT'; + +# so the inserts are going to be overriden INSERT INTO t1_int VALUES (2, 4, 4711); INSERT INTO t1_char VALUES (2, 4, 'Foo is a bar'); INSERT INTO t1_bit VALUES (2, 4, b'101', b'11100', b'01'); @@ -86,6 +91,8 @@ SELECT * FROM t1_bit ORDER BY a; SELECT * FROM t1_char ORDER BY a; --echo **** On Slave **** sync_slave_with_master; +set @@global.slave_exec_mode= default; + SELECT a,b,x FROM t1_int ORDER BY a; SELECT a,b,HEX(x),HEX(y),HEX(z) FROM t1_bit ORDER BY a; SELECT a,b,x FROM t1_char ORDER BY a; @@ -115,7 +122,7 @@ INSERT INTO t1_nodef VALUES (1,2); connection slave; --source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 22 # 23 # 33 # 36 38 --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -135,7 +142,7 @@ sync_slave_with_master; --echo **** On Slave **** SELECT * FROM t2; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 22 # 23 # 33 # 36 38 --query_vertical SHOW SLAVE STATUS connection master; @@ -147,7 +154,7 @@ INSERT INTO t4 VALUES (4); connection slave; --source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 22 # 23 # 33 # 36 38 --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -161,7 +168,7 @@ INSERT INTO t5 VALUES (5,10,25); connection slave; --source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 22 # 23 # 33 # 36 38 --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -175,7 +182,7 @@ INSERT INTO t6 VALUES (6,12,36); connection slave; --source include/wait_for_slave_sql_to_stop.inc --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 22 # 23 # 33 # 36 38 --query_vertical SHOW SLAVE STATUS SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; START SLAVE; @@ -184,7 +191,7 @@ connection master; INSERT INTO t9 VALUES (6); sync_slave_with_master; --replace_result $SLAVE_MYPORT SLAVE_PORT ---replace_column 1 # 4 # 7 # 8 # 9 # 22 # 23 # 33 # +--replace_column 1 # 4 # 7 # 8 # 9 # 20 22 # 23 # 33 # 36 38 --query_vertical SHOW SLAVE STATUS # Testing some tables extra field that can be null and cannot be null diff --git a/mysql-test/include/have_binlog_format_row_or_statement.inc b/mysql-test/include/have_binlog_format_row_or_statement.inc new file mode 100644 index 00000000000..c89df82eb80 --- /dev/null +++ b/mysql-test/include/have_binlog_format_row_or_statement.inc @@ -0,0 +1,7 @@ +--source include/have_log_bin.inc + +-- require r/have_binlog_format_statement.require +--disable_query_log +--replace_result ROW STATEMENT +show variables like "binlog_format"; +--enable_query_log diff --git a/mysql-test/include/have_innodb.inc b/mysql-test/include/have_innodb.inc index cbffe6a2574..8944cc46f3e 100644 --- a/mysql-test/include/have_innodb.inc +++ b/mysql-test/include/have_innodb.inc @@ -1,4 +1,4 @@ disable_query_log; --require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'innodb'; +select (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') as `TRUE` from information_schema.engines where engine = 'innodb'; enable_query_log; diff --git a/mysql-test/include/have_local_infile.inc b/mysql-test/include/have_local_infile.inc new file mode 100644 index 00000000000..4a1362c6e30 --- /dev/null +++ b/mysql-test/include/have_local_infile.inc @@ -0,0 +1,4 @@ +--require r/have_local_infile.require +disable_query_log; +show variables like 'local_infile'; +enable_query_log; diff --git a/mysql-test/include/have_multi_ndb.inc b/mysql-test/include/have_multi_ndb.inc index 9779f181191..8b1c39825bc 100644 --- a/mysql-test/include/have_multi_ndb.inc +++ b/mysql-test/include/have_multi_ndb.inc @@ -4,18 +4,26 @@ connect (server2,127.0.0.1,root,,test,$MASTER_MYPORT1,); # Check that server1 has NDB support connection server1; +let $engines_table= query_get_value(SHOW TABLES FROM information_schema LIKE 'engines', Tables_in_information_schema (engines), 1); disable_query_log; +if (`SELECT 1 FROM dual WHERE '$engines_table' = 'engines'`) +{ --require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +SELECT (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') as `TRUE` FROM information_schema.engines WHERE engine = 'ndbcluster'; --source include/ndb_not_readonly.inc +} enable_query_log; # Check that server2 has NDB support connection server2; +let $engines_table= query_get_value(SHOW TABLES FROM information_schema LIKE 'engines', Tables_in_information_schema (engines), 1); disable_query_log; +if (`SELECT 1 FROM dual WHERE '$engines_table' = 'engines'`) +{ --require r/true.require -select (support = 'YES' or support = 'DEFAULT') as `TRUE` from information_schema.engines where engine = 'ndbcluster'; +SELECT (support = 'YES' or support = 'DEFAULT' or support = 'ENABLED') as `TRUE` FROM information_schema.engines WHERE engine = 'ndbcluster'; --source include/ndb_not_readonly.inc +} enable_query_log; # cleanup diff --git a/mysql-test/include/set_binlog_format_mixed.sql b/mysql-test/include/set_binlog_format_mixed.sql new file mode 100644 index 00000000000..836992d1080 --- /dev/null +++ b/mysql-test/include/set_binlog_format_mixed.sql @@ -0,0 +1,2 @@ +SET GLOBAL BINLOG_FORMAT=MIXED; +SET SESSION BINLOG_FORMAT=MIXED; diff --git a/mysql-test/include/set_binlog_format_row.sql b/mysql-test/include/set_binlog_format_row.sql new file mode 100644 index 00000000000..49f34c8ccd1 --- /dev/null +++ b/mysql-test/include/set_binlog_format_row.sql @@ -0,0 +1,2 @@ +SET GLOBAL BINLOG_FORMAT=ROW; +SET SESSION BINLOG_FORMAT=ROW; diff --git a/mysql-test/include/set_binlog_format_statement.sql b/mysql-test/include/set_binlog_format_statement.sql new file mode 100644 index 00000000000..ed286e7e3cc --- /dev/null +++ b/mysql-test/include/set_binlog_format_statement.sql @@ -0,0 +1,2 @@ +SET GLOBAL BINLOG_FORMAT=STATEMENT; +SET SESSION BINLOG_FORMAT=STATEMENT; diff --git a/mysql-test/include/show_binary_logs.inc b/mysql-test/include/show_binary_logs.inc new file mode 100644 index 00000000000..c3729a8f9b9 --- /dev/null +++ b/mysql-test/include/show_binary_logs.inc @@ -0,0 +1,5 @@ +# show binary logs + +# mask out the binlog position +-- replace_column 2 # +show binary logs; diff --git a/mysql-test/include/show_binlog_events.inc b/mysql-test/include/show_binlog_events.inc index 7377b4a0fed..fcdf84102aa 100644 --- a/mysql-test/include/show_binlog_events.inc +++ b/mysql-test/include/show_binlog_events.inc @@ -1,5 +1,5 @@ --let $binlog_start=106 --replace_result $binlog_start --replace_column 2 # 4 # 5 # ---replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /table_id: [0-9]+/table_id: #/ /file_id=[0-9]+/file_id=#/ --eval show binlog events from $binlog_start diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc index 234b7e06fcf..5dd272c562d 100644 --- a/mysql-test/include/show_binlog_events2.inc +++ b/mysql-test/include/show_binlog_events2.inc @@ -1,7 +1,3 @@ -# -# Differs slightly from show_binlog events in showing server_id -# which is important for some tests -# --let $binlog_start=106 --replace_result $binlog_start --replace_column 2 # 5 # diff --git a/mysql-test/include/show_master_logs.inc b/mysql-test/include/show_master_logs.inc new file mode 100644 index 00000000000..4792ebd9651 --- /dev/null +++ b/mysql-test/include/show_master_logs.inc @@ -0,0 +1,5 @@ +# show master logs + +# mask out the binlog position +-- replace_column 2 # +query_vertical show master logs; diff --git a/mysql-test/include/show_master_status.inc b/mysql-test/include/show_master_status.inc new file mode 100644 index 00000000000..b7b32a65df4 --- /dev/null +++ b/mysql-test/include/show_master_status.inc @@ -0,0 +1,5 @@ +# show master status + +# mask out the binlog position +-- replace_column 2 # 3 4 +show master status; diff --git a/mysql-test/include/show_slave_status2.inc b/mysql-test/include/show_slave_status2.inc new file mode 100644 index 00000000000..9c4e14c62c2 --- /dev/null +++ b/mysql-test/include/show_slave_status2.inc @@ -0,0 +1,8 @@ +# Include file to show the slave status, masking out some information +# that varies depending on where the test is executed. + +# masked out log positions + +--replace_result $MASTER_MYPORT MASTER_PORT +--replace_column 1 # 7 # 8 # 9 # 16 # 22 # 23 # 33 # 35 # 36 # +query_vertical SHOW SLAVE STATUS; diff --git a/mysql-test/lib/My/Config.pm b/mysql-test/lib/My/Config.pm new file mode 100644 index 00000000000..5491e341ddc --- /dev/null +++ b/mysql-test/lib/My/Config.pm @@ -0,0 +1,422 @@ +# -*- cperl -*- + +package My::Config::Option; + +use strict; +use warnings; + + +sub new { + my ($class, $option_name, $option_value)= @_; + my $self= bless { name => $option_name, + value => $option_value + }, $class; + return $self; +} + + +sub name { + my ($self)= @_; + return $self->{name}; +} + + +sub value { + my ($self)= @_; + return $self->{value}; +} + + +package My::Config::Group; + +use strict; +use warnings; + + +sub new { + my ($class, $group_name)= @_; + my $self= bless { name => $group_name, + options => [], + options_by_name => {}, + }, $class; + return $self; +} + + +sub insert { + my ($self, $option_name, $value, $if_not_exist)= @_; + my $option= $self->option($option_name); + if (defined($option) and !$if_not_exist) { + $option->{value}= $value; + } + else { + my $option= My::Config::Option->new($option_name, $value); + # Insert option in list + push(@{$self->{options}}, $option); + # Insert option in hash + $self->{options_by_name}->{$option_name}= $option; + } + return $option; +} + +sub remove { + my ($self, $option_name)= @_; + + # Check that option exists + my $option= $self->option($option_name); + + return undef unless defined $option; + + # Remove from the hash + delete($self->{options_by_name}->{$option_name}) or die; + + # Remove from the array + @{$self->{options}}= grep { $_->name ne $option_name } @{$self->{options}}; + + return $option; +} + + +sub options { + my ($self)= @_; + return @{$self->{options}}; +} + + +sub name { + my ($self)= @_; + return $self->{name}; +} + + +# +# Return a specific option in the group +# +sub option { + my ($self, $option_name)= @_; + + return $self->{options_by_name}->{$option_name}; +} + + +# +# Return a specific value for an option in the group +# +sub value { + my ($self, $option_name)= @_; + my $option= $self->option($option_name); + + die "No option named '$option_name' in this group" + if ! defined($option); + + return $option->value(); +} + + +package My::Config; + +use strict; +use warnings; +use IO::File; +use File::Basename; + +# +# Constructor for My::Config +# - represents a my.cnf config file +# +# Array of arrays +# +sub new { + my ($class, $path)= @_; + my $group_name= undef; + + my $self= bless { groups => [] }, $class; + my $F= IO::File->new($path, "<") + or die "Could not open '$path': $!"; + + while ( my $line= <$F> ) { + chomp($line); + + # [group] + if ( $line =~ /\[(.*)\]/ ) { + # New group found + $group_name= $1; + #print "group: $group_name\n"; + + $self->insert($group_name, undef, undef); + } + + # Magic #! comments + elsif ( $line =~ /^#\!/) { + my $magic= $line; + die "Found magic comment '$magic' outside of group" + unless $group_name; + + #print "$magic\n"; + $self->insert($group_name, $magic, undef); + } + + # Comments + elsif ( $line =~ /^#/ || $line =~ /^;/) { + # Skip comment + next; + } + + # Empty lines + elsif ( $line =~ /^$/ ) { + # Skip empty lines + next; + } + + # !include + elsif ( $line =~ /^\!include\s*(.*?)\s*$/ ) { + my $include_file_name= dirname($path)."/".$1; + # Check that the file exists + die "The include file '$include_file_name' does not exist" + unless -f $include_file_name; + + $self->append(My::Config->new($include_file_name)); + } + + #