From 9c23a442b257c0ddb9066930c7bf9b0aac6cacdd Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Fri, 13 Nov 2009 10:30:56 +0000 Subject: [PATCH 01/47] BUG#48738: Backport patch for Bug 34582 to 5.0 codebase. From BUG 34582 commit message: Issuing 'FLUSH LOGS' does not close and reopen indexfile. Instead a SEEK_SET is performed. This patch makes index file to be closed and reopened whenever a rotation happens (FLUSH LOGS is issued or binary log exceeds maximum configured size). --- .../r/binlog_delete_and_flush_index.result | 44 +++++ .../t/binlog_delete_and_flush_index.test | 176 ++++++++++++++++++ sql/log.cc | 10 +- 3 files changed, 226 insertions(+), 4 deletions(-) create mode 100644 mysql-test/r/binlog_delete_and_flush_index.result create mode 100644 mysql-test/t/binlog_delete_and_flush_index.test diff --git a/mysql-test/r/binlog_delete_and_flush_index.result b/mysql-test/r/binlog_delete_and_flush_index.result new file mode 100644 index 00000000000..153900f3081 --- /dev/null +++ b/mysql-test/r/binlog_delete_and_flush_index.result @@ -0,0 +1,44 @@ +RESET MASTER; +CREATE TABLE t1 (a int); +### assertion: index file contains regular entries +SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); +master-bin.000001 + +### assertion: show original binlogs +show binary logs; +Log_name File_size +master-bin.000001 # +### assertion: binlog contents from regular entries +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int) +FLUSH LOGS; +### assertion: index file contains renamed binlog and the new one +SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); +master-bin-b34582.000001 +master-bin.000002 + +### assertion: original binlog content still exists, despite we +### renamed and changed the index file +show binlog events from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin-b34582.000001 # Query # # use `test`; CREATE TABLE t1 (a int) +### assertion: user changed binlog index shows correct entries +show binary logs; +Log_name File_size +master-bin-b34582.000001 # +master-bin.000002 # +DROP TABLE t1; +### assertion: purging binlogs up to binlog created after instrumenting index file should work +PURGE BINARY LOGS TO 'master-bin.000002'; +### assertion: show binary logs should only contain latest binlog +show binary logs; +Log_name File_size +master-bin.000002 # +### assertion: assert that binlog files were indeed purged (using file_exists calls) +### assertion: assert that not purged binlog file exists +### assertion: show index file contents and these should match show binary logs issued above +SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); +master-bin.000002 + +RESET MASTER; diff --git a/mysql-test/t/binlog_delete_and_flush_index.test b/mysql-test/t/binlog_delete_and_flush_index.test new file mode 100644 index 00000000000..6784043386d --- /dev/null +++ b/mysql-test/t/binlog_delete_and_flush_index.test @@ -0,0 +1,176 @@ +# BUG#34582: FLUSH LOGS does not close and reopen the binlog index +# file +# +# WHAT +# ==== +# +# We want to test that FLUSH LOGS closes and reopens binlog index +# file. +# +# HOW +# === +# +# PREPARE: +# 1. create some binlog events +# 2. show index content, binlog events and binlog contents +# for mysql-bin.000001 +# 3. copy the mysql-bin.000001 to mysql-bin-b34582.000001 +# 4. change the index file so that mysql-bin.000001 is replaced +# with mysql-bin-b34582.000001 +# 5. FLUSH the logs so that new index is closed and reopened +# +# ASSERTIONS: +# 1. index file contents shows mysql-bin-b34582.000001 and +# mysql-bin.000002 +# 1. show binary logs shows current index entries +# 2. binlog contents for mysql-bin-b34582.000001 are displayed +# 3. Purge binlogs up to the latest one succeeds +# 4. SHOW BINARY LOGS presents the latest one only after purging +# 5. Purged binlogs files don't exist in the filesystem +# 6. Not purged binlog file exists in the filesystem +# +# CLEAN UP: +# 1. RESET MASTER +# + +-- source include/have_log_bin.inc + +RESET MASTER; + +-- let $datadir= $MYSQLTEST_VARDIR/log +-- let $index=$datadir/master-bin.index +-- chmod 0666 $index + +# action: issue one command so that binlog gets some event +CREATE TABLE t1 (a int); + +-- echo ### assertion: index file contains regular entries +-- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- eval SET @index=LOAD_FILE('$index') +if (`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a + +} +if (!`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a +} + +--echo ### assertion: show original binlogs +-- source include/show_binary_logs.inc + +--echo ### assertion: binlog contents from regular entries +-- source include/show_binlog_events.inc + +# action: copy binlogs to other names and change entries in index file +-- copy_file $datadir/master-bin.000001 $datadir/master-bin-b34582.000001 +-- let newbinfile=$datadir/master-bin-b34582.000001 +let INDEX_FILE=$index; +perl; +$newbinfile= $ENV{'newbinfile'}; +$file= $ENV{'INDEX_FILE'}; +open(FILE, ">$file") || die "Unable to open $file."; +truncate(FILE,0); +print FILE $newbinfile . "\n"; +close ($file); +EOF + +# action: should cause rotation, and creation of new binlogs +FLUSH LOGS; + +# file is not used anymore - remove it (mysql closed on flush logs). +-- remove_file $datadir/master-bin.000001 + +-- echo ### assertion: index file contains renamed binlog and the new one +-- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- eval SET @index=LOAD_FILE('$index') +if (`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a + +} +if (!`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a +} + +-- echo ### assertion: original binlog content still exists, despite we +-- echo ### renamed and changed the index file +-- source include/show_binlog_events.inc + +-- echo ### assertion: user changed binlog index shows correct entries +-- source include/show_binary_logs.inc + +DROP TABLE t1; + +-- echo ### assertion: purging binlogs up to binlog created after instrumenting index file should work +-- let $current_binlog= query_get_value(SHOW MASTER STATUS, File, 1) +-- eval PURGE BINARY LOGS TO '$current_binlog' + +-- echo ### assertion: show binary logs should only contain latest binlog +-- source include/show_binary_logs.inc + +-- echo ### assertion: assert that binlog files were indeed purged (using file_exists calls) +-- error 1 +-- file_exists $datadir/master-bin-b34852.000001 + +-- echo ### assertion: assert that not purged binlog file exists +-- file_exists $datadir/$current_binlog + +-- echo ### assertion: show index file contents and these should match show binary logs issued above +-- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- eval SET @index=LOAD_FILE('$index') +if (`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a + +} +if (!`SELECT convert(@@version_compile_os using latin1) + IN ('Win32','Win64','Windows')`) +{ + -- disable_query_log + -- disable_result_log + -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` + -- enable_result_log + -- enable_query_log + + -- echo $a +} + +RESET MASTER; diff --git a/sql/log.cc b/sql/log.cc index c042651216c..8c0abaeff44 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1635,7 +1635,7 @@ void MYSQL_LOG::new_file(bool need_lock) old_name=name; save_log_type=log_type; name=0; // Don't free name - close(LOG_CLOSE_TO_BE_OPENED); + close(LOG_CLOSE_TO_BE_OPENED | LOG_CLOSE_INDEX); /* Note that at this point, log_type != LOG_CLOSED (important for is_open()). @@ -1649,9 +1649,11 @@ void MYSQL_LOG::new_file(bool need_lock) Format_description_log_event written at server startup, which should trigger temp tables deletion on slaves. */ - - open(old_name, save_log_type, new_name_ptr, - io_cache_type, no_auto_events, max_size, 1); + + /* reopen index binlog file, BUG#34582 */ + if (!open_index_file(index_file_name, 0)) + open(old_name, save_log_type, new_name_ptr, + io_cache_type, no_auto_events, max_size, 1); my_free(old_name,MYF(0)); end: From 87349334004e7f3ae3beeb347661ffba18df3e38 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 17 Nov 2009 20:02:16 +0100 Subject: [PATCH 02/47] Bug#48846: Too much time spent in ha_partition::records_in_range if not able to prune Problem was that ha_partition::records_in_range called records_in_range for all non pruned partitions, even if an estimate should be given. Solution is to only use 1/3 of the partitions (up to 10) for records_in_range and estimate the total from this subset. (And continue until a non zero return value from the called partitions records_in_range is given, since 0 means no rows will match.) sql/ha_partition.cc: Bug#48846: Too much time spent in ha_partition::records_in_range if not able to prune estimate_rows_upper_bound and records_in_range are very similar (the only difference is the function and its parameters to use) so I created a common function for this. Since these calls from the optimizer are only estimates, it is not neccesary to call them for every partition, it can use a much smaller subset of the used partitions instead, which improves performance for selects. sql/ha_partition.h: Bug#48846: Too much time spent in ha_partition::records_in_range if not able to prune Added two private functions to help some optimizer calls. --- sql/ha_partition.cc | 144 ++++++++++++++++++++++++++++---------------- sql/ha_partition.h | 12 ++++ 2 files changed, 105 insertions(+), 51 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 451631ff373..b854e270029 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5747,6 +5747,23 @@ const key_map *ha_partition::keys_to_use_for_scanning() DBUG_RETURN(m_file[0]->keys_to_use_for_scanning()); } +#define MAX_PARTS_FOR_OPTIMIZER_CALLS 10 +/* + Prepare start variables for estimating optimizer costs. + + @param[out] num_used_parts Number of partitions after pruning. + @param[out] check_min_num Number of partitions to call. + @param[out] first first used partition. +*/ +void ha_partition::partitions_optimizer_call_preparations(uint *first, + uint *num_used_parts, + uint *check_min_num) +{ + *first= bitmap_get_first_set(&(m_part_info->used_partitions)); + *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions)); + *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts); +} + /* Return time for a scan of the table @@ -5760,43 +5777,67 @@ const key_map *ha_partition::keys_to_use_for_scanning() double ha_partition::scan_time() { - double scan_time= 0; - handler **file; + double scan_time= 0.0; + uint first, part_id, num_used_parts, check_min_num, partitions_called= 0; DBUG_ENTER("ha_partition::scan_time"); - for (file= m_file; *file; file++) - if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) - scan_time+= (*file)->scan_time(); + partitions_optimizer_call_preparations(&first, &num_used_parts, &check_min_num); + for (part_id= first; partitions_called < num_used_parts ; part_id++) + { + if (!bitmap_is_set(&(m_part_info->used_partitions), part_id)) + continue; + scan_time+= m_file[part_id]->scan_time(); + partitions_called++; + if (partitions_called >= check_min_num && scan_time != 0.0) + { + DBUG_RETURN(scan_time * + (double) num_used_parts / (double) partitions_called); + } + } DBUG_RETURN(scan_time); } /* - Get time to read + Estimate rows for records_in_range or estimate_rows_upper_bound. - SYNOPSIS - read_time() - index Index number used - ranges Number of ranges - rows Number of rows + @param is_records_in_range call records_in_range instead of + estimate_rows_upper_bound. + @param inx (only for records_in_range) index to use. + @param min_key (only for records_in_range) start of range. + @param max_key (only for records_in_range) end of range. - RETURN VALUE - time for read - - DESCRIPTION - This will be optimised later to include whether or not the index can - be used with partitioning. To achieve we need to add another parameter - that specifies how many of the index fields that are bound in the ranges. - Possibly added as a new call to handlers. + @return Number of rows or HA_POS_ERROR. */ - -double ha_partition::read_time(uint index, uint ranges, ha_rows rows) +ha_rows ha_partition::estimate_rows(bool is_records_in_range, uint inx, + key_range *min_key, key_range *max_key) { - DBUG_ENTER("ha_partition::read_time"); + ha_rows rows, estimated_rows= 0; + uint first, part_id, num_used_parts, check_min_num, partitions_called= 0; + DBUG_ENTER("ha_partition::records_in_range"); - DBUG_RETURN(m_file[0]->read_time(index, ranges, rows)); + partitions_optimizer_call_preparations(&first, &num_used_parts, &check_min_num); + for (part_id= first; partitions_called < num_used_parts ; part_id++) + { + if (!bitmap_is_set(&(m_part_info->used_partitions), part_id)) + continue; + if (is_records_in_range) + rows= m_file[part_id]->records_in_range(inx, min_key, max_key); + else + rows= m_file[part_id]->estimate_rows_upper_bound(); + if (rows == HA_POS_ERROR) + DBUG_RETURN(HA_POS_ERROR); + estimated_rows+= rows; + partitions_called++; + if (partitions_called >= check_min_num && estimated_rows) + { + DBUG_RETURN(estimated_rows * num_used_parts / partitions_called); + } + } + DBUG_RETURN(estimated_rows); } + /* Find number of records in a range @@ -5824,22 +5865,9 @@ double ha_partition::read_time(uint index, uint ranges, ha_rows rows) ha_rows ha_partition::records_in_range(uint inx, key_range *min_key, key_range *max_key) { - handler **file; - ha_rows in_range= 0; DBUG_ENTER("ha_partition::records_in_range"); - file= m_file; - do - { - if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) - { - ha_rows tmp_in_range= (*file)->records_in_range(inx, min_key, max_key); - if (tmp_in_range == HA_POS_ERROR) - DBUG_RETURN(tmp_in_range); - in_range+= tmp_in_range; - } - } while (*(++file)); - DBUG_RETURN(in_range); + DBUG_RETURN(estimate_rows(TRUE, inx, min_key, max_key)); } @@ -5855,22 +5883,36 @@ ha_rows ha_partition::records_in_range(uint inx, key_range *min_key, ha_rows ha_partition::estimate_rows_upper_bound() { - ha_rows rows, tot_rows= 0; - handler **file; DBUG_ENTER("ha_partition::estimate_rows_upper_bound"); - file= m_file; - do - { - if (bitmap_is_set(&(m_part_info->used_partitions), (file - m_file))) - { - rows= (*file)->estimate_rows_upper_bound(); - if (rows == HA_POS_ERROR) - DBUG_RETURN(HA_POS_ERROR); - tot_rows+= rows; - } - } while (*(++file)); - DBUG_RETURN(tot_rows); + DBUG_RETURN(estimate_rows(FALSE, 0, NULL, NULL)); +} + + +/* + Get time to read + + SYNOPSIS + read_time() + index Index number used + ranges Number of ranges + rows Number of rows + + RETURN VALUE + time for read + + DESCRIPTION + This will be optimised later to include whether or not the index can + be used with partitioning. To achieve we need to add another parameter + that specifies how many of the index fields that are bound in the ranges. + Possibly added as a new call to handlers. +*/ + +double ha_partition::read_time(uint index, uint ranges, ha_rows rows) +{ + DBUG_ENTER("ha_partition::read_time"); + + DBUG_RETURN(m_file[0]->read_time(index, ranges, rows)); } diff --git a/sql/ha_partition.h b/sql/ha_partition.h index c08b1f77eca..9f6d9e0a5ba 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -547,6 +547,18 @@ public: ------------------------------------------------------------------------- */ +private: + /* + Helper function to get the minimum number of partitions to use for + the optimizer hints/cost calls. + */ + void partitions_optimizer_call_preparations(uint *num_used_parts, + uint *check_min_num, + uint *first); + ha_rows estimate_rows(bool is_records_in_range, uint inx, + key_range *min_key, key_range *max_key); +public: + /* keys_to_use_for_scanning can probably be implemented as the intersection of all underlying handlers if mixed handlers are used. From 595719280eeec7dc9dda340d001de72a728b0ed1 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Sun, 6 Dec 2009 01:11:32 +0000 Subject: [PATCH 03/47] BUG#49479: Slave stops with syntax error: LOAD DATA event without escaped field names When in mixed or statement mode, the master logs LOAD DATA queries by resorting to an Execute_load_query_log_event. This event does not contain the original query, but a rewritten version of it, which includes the table field names. However, the rewrite does not escape the field names. If these names match a reserved keyword, then the slave will stop with a syntax error when executing the event. We fix this by escaping the fields names as it happens already for the table name. mysql-test/extra/rpl_tests/rpl_loaddata.test: Added test case for the reported bug. mysql-test/r/mysqlbinlog.result: Changed result to support escaped field name. mysql-test/suite/binlog/r/binlog_killed_simulate.result: Changed result to support escaped field name. mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result: Changed result to support escaped field name. mysql-test/suite/binlog/r/binlog_stm_blackhole.result: Changed result to support escaped field name. mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result: Changed result to support escaped field name. mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result: Changed result to support escaped field name. mysql-test/suite/rpl/r/rpl_loaddata.result: Added result for new test. Changed show slave status positions which are now different because of extra escape character in field names. mysql-test/suite/rpl/r/rpl_loaddata_fatal.result: Changed show slave status positions which are now different because of extra escape character. mysql-test/suite/rpl/r/rpl_loaddata_map.result: Changed result to support escaped field name. mysql-test/suite/rpl/r/rpl_stm_log.result: Changed result to support escaped field name. mysql-test/t/mysqlbinlog.test: Changed positions which is now different because of extra escape character in field names. sql/sql_load.cc: Appended escape characters before and after field names. --- mysql-test/extra/rpl_tests/rpl_loaddata.test | 14 +++++++++ mysql-test/r/mysqlbinlog.result | 30 +++++++++---------- .../binlog/r/binlog_killed_simulate.result | 2 +- .../r/binlog_row_mix_innodb_myisam.result | 2 +- .../binlog/r/binlog_stm_blackhole.result | 2 +- .../r/binlog_stm_mix_innodb_myisam.result | 4 +-- .../suite/rpl/r/rpl_innodb_mixed_dml.result | 2 +- mysql-test/suite/rpl/r/rpl_loaddata.result | 21 +++++++++++-- .../suite/rpl/r/rpl_loaddata_fatal.result | 2 +- .../suite/rpl/r/rpl_loaddata_map.result | 2 +- mysql-test/suite/rpl/r/rpl_stm_log.result | 6 ++-- mysql-test/t/mysqlbinlog.test | 4 +-- sql/sql_load.cc | 6 ++++ 13 files changed, 67 insertions(+), 30 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_loaddata.test b/mysql-test/extra/rpl_tests/rpl_loaddata.test index 7db12600456..649337b2a24 100644 --- a/mysql-test/extra/rpl_tests/rpl_loaddata.test +++ b/mysql-test/extra/rpl_tests/rpl_loaddata.test @@ -219,4 +219,18 @@ source include/diff_tables.inc; -- sync_slave_with_master +# BUG#49479: LOAD DATA INFILE is binlogged without escaping field names +-- source include/master-slave-reset.inc +-- connection master +use test; +CREATE TABLE t1 (`key` TEXT, `text` TEXT); + +LOAD DATA INFILE '../../std_data/loaddata2.dat' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ','; +SELECT * FROM t1; + +-- sync_slave_with_master +-- connection master +DROP TABLE t1; +-- sync_slave_with_master + # End of 4.1 tests diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 5f32561798b..9d4fde96d18 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -44,16 +44,16 @@ SET TIMESTAMP=1000000000/*!*/; insert into t2 values () /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; DELIMITER ; # End of log file @@ -144,16 +144,16 @@ SET TIMESTAMP=1000000000/*!*/; insert into t2 values () /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (word) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`) /*!*/; DELIMITER ; # End of log file @@ -359,29 +359,29 @@ SET @@session.collation_database=DEFAULT/*!*/; create table t1 (a varchar(64) character set utf8) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=7/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=DEFAULT/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=7/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=DEFAULT/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; -LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO TABLE `t1` CHARACTER SET koi8r FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) /*!*/; SET TIMESTAMP=1000000000/*!*/; drop table t1 diff --git a/mysql-test/suite/binlog/r/binlog_killed_simulate.result b/mysql-test/suite/binlog/r/binlog_killed_simulate.result index df04f5129cf..0e1b5c92d57 100644 --- a/mysql-test/suite/binlog/r/binlog_killed_simulate.result +++ b/mysql-test/suite/binlog/r/binlog_killed_simulate.result @@ -19,7 +19,7 @@ ERROR 70100: Query execution was interrupted show binlog events from ; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, b) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, `b`) ;file_id=# select (@a:=load_file("MYSQLTEST_VARDIR/tmp/binlog_killed_bug27571.binlog")) is not null; diff --git a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result index 4ccc3b5e797..ef98275041c 100644 --- a/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_row_mix_innodb_myisam.result @@ -929,7 +929,7 @@ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# master-bin.000001 # Query # # ROLLBACK drop trigger trg_del_t2; drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result index 434c1b0896f..b2e6ac854cf 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_blackhole.result +++ b/mysql-test/suite/binlog/r/binlog_stm_blackhole.result @@ -127,7 +127,7 @@ master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; create table t2 (a varchar(200)) engine=blackhole master-bin.000001 # Query # # BEGIN master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=581 -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`) ;file_id=# master-bin.000001 # Query # # COMMIT master-bin.000001 # Query # # use `test`; alter table t1 add b int master-bin.000001 # Query # # use `test`; alter table t1 drop b diff --git a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result index de83c7a873d..e2f29295383 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @@ -628,7 +628,7 @@ master-bin.000001 # Query # # BEGIN master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Intvar # # INSERT_ID=10 -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# master-bin.000001 # Query # # ROLLBACK /* the output must denote there is the query */; drop trigger trg_del_t2; @@ -866,7 +866,7 @@ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Intvar # # INSERT_ID=10 master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, @b) SET b=((@b) + `bug27417`(2)) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=# master-bin.000001 # Query # # ROLLBACK drop trigger trg_del_t2; drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result index 3a1c2b68b01..fbfebbaa590 100644 --- a/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result +++ b/mysql-test/suite/rpl/r/rpl_innodb_mixed_dml.result @@ -885,7 +885,7 @@ master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t2 master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Begin_load_query 1 # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (a, b) ;file_id=# +master-bin.000001 # Execute_load_query 1 # use `test_rpl`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/std_data/rpl_mixed.dat' INTO TABLE `t1` FIELDS TERMINATED BY '|' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, `b`) ;file_id=# master-bin.000001 # Xid 1 # # master-bin.000001 # Query 1 # BEGIN master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 diff --git a/mysql-test/suite/rpl/r/rpl_loaddata.result b/mysql-test/suite/rpl/r/rpl_loaddata.result index ca9c14691b0..5c6a67d6f3c 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata.result @@ -36,7 +36,7 @@ set global sql_slave_skip_counter=1; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2009 # # master-bin.000001 Yes Yes # 0 0 2009 # None 0 No # No 0 0 +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2025 # # master-bin.000001 Yes Yes # 0 0 2025 # None 0 No # No 0 0 set sql_log_bin=0; delete from t1; set sql_log_bin=1; @@ -46,7 +46,7 @@ change master to master_user='test'; change master to master_user='root'; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master Master_SSL_Verify_Server_Cert Last_IO_Errno Last_IO_Error Last_SQL_Errno Last_SQL_Error -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2044 # # master-bin.000001 No No # 0 0 2044 # None 0 No # No 0 0 +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 2060 # # master-bin.000001 No No # 0 0 2060 # None 0 No # No 0 0 set global sql_slave_skip_counter=1; start slave; set sql_log_bin=0; @@ -115,3 +115,20 @@ use b48297_db1; Comparing tables master:b48297_db1.t1 and slave:b48297_db1.t1 DROP DATABASE b48297_db1; DROP DATABASE b42897_db2; +stop slave; +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; +start slave; +use test; +CREATE TABLE t1 (`key` TEXT, `text` TEXT); +LOAD DATA INFILE '../../std_data/loaddata2.dat' REPLACE INTO TABLE `t1` FIELDS TERMINATED BY ','; +SELECT * FROM t1; +key text +Field A 'Field B' +Field 1 'Field 2' +Field 3 'Field 4' +'Field 5' 'Field 6' +Field 6 'Field 7' +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result index 35696615b5a..ba0aa847cf7 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata_fatal.result @@ -53,7 +53,7 @@ Master_User root Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 -Read_Master_Log_Pos 556 +Read_Master_Log_Pos 560 Relay_Log_File # Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 diff --git a/mysql-test/suite/rpl/r/rpl_loaddata_map.result b/mysql-test/suite/rpl/r/rpl_loaddata_map.result index 006f84043a4..91624b15ef8 100644 --- a/mysql-test/suite/rpl/r/rpl_loaddata_map.result +++ b/mysql-test/suite/rpl/r/rpl_loaddata_map.result @@ -20,7 +20,7 @@ master-bin.000001 # Query # # use `test`; create table t2 (id int not null prima master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# master-bin.000001 # Append_block # # ;file_id=#;block_len=# master-bin.000001 # Append_block # # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (id) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/bug30435_5k.txt' INTO TABLE `t2` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`id`) ;file_id=# ==== Verify results on slave ==== [on slave] select count(*) from t2 /* 5 000 */; diff --git a/mysql-test/suite/rpl/r/rpl_stm_log.result b/mysql-test/suite/rpl/r/rpl_stm_log.result index d73b8990041..47556a33e97 100644 --- a/mysql-test/suite/rpl/r/rpl_stm_log.result +++ b/mysql-test/suite/rpl/r/rpl_stm_log.result @@ -25,7 +25,7 @@ master-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL) master-bin.000001 # Query 1 # use `test`; drop table t1 master-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM master-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581 -master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=1 +master-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=1 show binlog events from 106 limit 1; Log_name Pos Event_type Server_id End_log_pos Info master-bin.000001 # Query 1 # use `test`; create table t1(n int not null auto_increment primary key)ENGINE=MyISAM @@ -193,7 +193,7 @@ master-bin.000001 # Query # # use `test`; insert into t1 values (NULL) master-bin.000001 # Query # # use `test`; drop table t1 master-bin.000001 # Query # # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=# -master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=# +master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/words.dat' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=# master-bin.000001 # Rotate # # master-bin.000002;pos=4 show binlog events in 'master-bin.000002'; Log_name Pos Event_type Server_id End_log_pos Info @@ -218,7 +218,7 @@ slave-bin.000001 # Query 1 # use `test`; insert into t1 values (NULL) slave-bin.000001 # Query 1 # use `test`; drop table t1 slave-bin.000001 # Query 1 # use `test`; create table t1 (word char(20) not null)ENGINE=MyISAM slave-bin.000001 # Begin_load_query 1 # ;file_id=1;block_len=581 -slave-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (word) ;file_id=1 +slave-bin.000001 # Execute_load_query 1 # use `test`; LOAD DATA INFILE '../../tmp/SQL_LOAD-2-1-1.data' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' IGNORE 1 LINES (`word`) ;file_id=1 slave-bin.000001 # Query 1 # use `test`; create table t3 (a int)ENGINE=MyISAM slave-bin.000001 # Rotate 2 # slave-bin.000002;pos=4 show binlog events in 'slave-bin.000002' from 4; diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 78661b1bbc4..687ad62b17c 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -71,7 +71,7 @@ select "--- --position --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ ---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=330 $MYSQLD_DATADIR/master-bin.000002 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --position=332 $MYSQLD_DATADIR/master-bin.000002 # These are tests for remote binlog. @@ -108,7 +108,7 @@ select "--- --position --" as ""; --enable_query_log --replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ ---exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=330 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ --read-from-remote-server --position=332 --user=root --host=127.0.0.1 --port=$MASTER_MYPORT master-bin.000002 # Bug#7853 mysqlbinlog does not accept input from stdin --disable_query_log diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 8109ca4313e..326a7517ed6 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -640,7 +640,11 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, if (n++) pfields.append(", "); if (item->name) + { + pfields.append("`"); pfields.append(item->name); + pfields.append("`"); + } else item->print(&pfields, QT_ORDINARY); } @@ -660,7 +664,9 @@ static bool write_execute_load_query_log_event(THD *thd, sql_exchange* ex, val= lv++; if (n++) pfields.append(", "); + pfields.append("`"); pfields.append(item->name); + pfields.append("`"); pfields.append("="); val->print(&pfields, QT_ORDINARY); } From 91aa5e248ed2897a7cad0e3060ce1689fee6a5b2 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 8 Dec 2009 16:35:00 +0100 Subject: [PATCH 04/47] Raise version number after cloning 5.0.89 --- configure.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index e14b4014bea..b206dfbd079 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! # remember to also change ndb version below and update version.c in ndb -AM_INIT_AUTOMAKE(mysql, 5.0.89) +AM_INIT_AUTOMAKE(mysql, 5.0.90) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 @@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # ndb version NDB_VERSION_MAJOR=5 NDB_VERSION_MINOR=0 -NDB_VERSION_BUILD=89 +NDB_VERSION_BUILD=90 NDB_VERSION_STATUS="" # Set all version vars based on $VERSION. How do we do this more elegant ? From adc17cd41e21cb68d63b9962a97ad075da02999f Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 16 Dec 2009 19:31:19 +0200 Subject: [PATCH 05/47] Bug #48866: mysql.test fails under Fedora 12 strmov() is not guaranteed to work correctly on overlapping source and destination buffers. On some OSes it may work, but Fedora 12 has a stpcpy() that's not working correctly on overlapping buffers. Fixed to use the overlap-safe version of strmov instead. Re-vitalized the overlap-safe version of strmov. --- client/mysql.cc | 2 +- include/m_string.h | 9 +++------ strings/strmov.c | 6 +----- 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index e4eabe8de33..5ae58baa694 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -4108,7 +4108,7 @@ char *get_arg(char *line, my_bool get_next_arg) if (*ptr == '\\' && ptr[1]) // escaped character { // Remove the backslash - strmov(ptr, ptr+1); + strmov_overlapp(ptr, ptr+1); } else if ((!quoted && *ptr == ' ') || (quoted && *ptr == qtype)) { diff --git a/include/m_string.h b/include/m_string.h index c26d0fb9260..5411d0483ea 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -108,9 +108,7 @@ extern char NEAR _dig_vec_lower[]; /* Defined in strtod.c */ extern const double log_10[309]; -#ifdef BAD_STRING_COMPILER -#define strmov(A,B) (memccpy(A,B,0,INT_MAX)-1) -#else +#ifndef strmov #define strmov_overlapp(A,B) strmov(A,B) #define strmake_overlapp(A,B,C) strmake(A,B,C) #endif @@ -171,12 +169,11 @@ extern uint strinstr(const char *str,const char *search); extern uint r_strinstr(reg1 my_string str,int from, reg4 my_string search); extern char *strkey(char *dst,char *head,char *tail,char *flags); extern char *strmake(char *dst,const char *src,uint length); -#ifndef strmake_overlapp -extern char *strmake_overlapp(char *dst,const char *src, uint length); -#endif #ifndef strmov extern char *strmov(char *dst,const char *src); +#else +extern char *strmov_overlapp(char *dst,const char *src); #endif extern char *strnmov(char *dst,const char *src,uint n); extern char *strsuff(const char *src,const char *suffix); diff --git a/strings/strmov.c b/strings/strmov.c index 1393411dd8f..eedf22a4ef1 100644 --- a/strings/strmov.c +++ b/strings/strmov.c @@ -24,13 +24,11 @@ #include #include "m_string.h" -#ifdef BAD_STRING_COMPILER +#ifdef strmov #undef strmov #define strmov strmov_overlapp #endif -#ifndef strmov - #if !defined(MC68000) && !defined(DS90) char *strmov(register char *dst, register const char *src) @@ -53,5 +51,3 @@ char *strmov(dst, src) } #endif - -#endif /* strmov */ From 081bcb3b8bc861bc5609a4ce92c8eb3528ffc078 Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Tue, 22 Dec 2009 13:52:23 +0400 Subject: [PATCH 06/47] Bug#47371 reference by same column name At the end of execution top level join execution we cleanup this join with true argument. It leads to underlying join cleanup(subquery) with true argument too and to tmp_table_param->field array cleanup which is required later. The problem is that Item_func_set_user_var does not set result_filed which leads to unnecessary repeated excution of subquery on final stage. The fix is to set result_field for Item_func_set_user_var. mysql-test/r/count_distinct.result: test result mysql-test/r/user_var.result: test result mysql-test/t/count_distinct.test: test case mysql-test/t/user_var.test: test case sql/item_func.cc: At the end of execution top level join execution we cleanup this join with true argument. It leads to underlying join cleanup(subquery) with true argument too and to tmp_table_param->field array cleanup which is required later. The problem is that Item_func_set_user_var does not set result_filed which leads to unnecessary repeated excution of subquery on final stage. The fix is to set result_field for Item_func_set_user_var. --- mysql-test/r/count_distinct.result | 20 ++++++++++++++++++++ mysql-test/r/user_var.result | 15 +++++++++++++++ mysql-test/t/count_distinct.test | 19 +++++++++++++++++++ mysql-test/t/user_var.test | 20 ++++++++++++++++++++ sql/item_func.cc | 2 +- 5 files changed, 75 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/count_distinct.result b/mysql-test/r/count_distinct.result index a21748359b9..804bc1f4788 100644 --- a/mysql-test/r/count_distinct.result +++ b/mysql-test/r/count_distinct.result @@ -40,6 +40,26 @@ select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join isbn city libname a 007 Berkeley Berkeley Public1 2 000 New York New York Public Libra 2 +select t2.isbn,city,@bar:=t1.libname,count(distinct t1.libname) as a +from t3 left join t1 on t3.libname=t1.libname left join t2 +on t3.isbn=t2.isbn group by city having count(distinct +t1.libname) > 1; +isbn city @bar:=t1.libname a +007 Berkeley Berkeley Public1 2 +000 New York New York Public Libra 2 +SELECT @bar; +@bar +Berkeley Public2 +select t2.isbn,city,concat(@bar:=t1.libname),count(distinct t1.libname) as a +from t3 left join t1 on t3.libname=t1.libname left join t2 +on t3.isbn=t2.isbn group by city having count(distinct +t1.libname) > 1; +isbn city concat(@bar:=t1.libname) a +007 Berkeley Berkeley Public1 2 +000 New York New York Public Libra 2 +SELECT @bar; +@bar +Berkeley Public2 drop table t1, t2, t3; create table t1 (f1 int); insert into t1 values (1); diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index bfa95d8f92b..8236dbe94ac 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -363,4 +363,19 @@ SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b; a b 2 3 DROP TABLE t1; +CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL); +CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11)); +CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL); +INSERT INTO t1 VALUES(10, 10); +INSERT INTO t1 VALUES(10, 10); +INSERT INTO t2 VALUES(10, 10, 10); +INSERT INTO t2 VALUES(10, 10, 10); +INSERT INTO t3 VALUES(10, 10); +INSERT INTO t3 VALUES(10, 10); +SELECT MIN(t2.f1), +@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo) +FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1; +MIN(t2.f1) @bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo) +10 NULL +DROP TABLE t1, t2, t3; End of 5.0 tests diff --git a/mysql-test/t/count_distinct.test b/mysql-test/t/count_distinct.test index e63bdabdb95..d0996689aeb 100644 --- a/mysql-test/t/count_distinct.test +++ b/mysql-test/t/count_distinct.test @@ -35,6 +35,25 @@ insert into t1 values ('NYC Lib','New York'); select t2.isbn,city,t1.libname,count(t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city,t1.libname; select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct t1.libname) > 1; select t2.isbn,city,t1.libname,count(distinct t1.libname) as a from t3 left join t1 on t3.libname=t1.libname left join t2 on t3.isbn=t2.isbn group by city having count(distinct concat(t1.libname,'a')) > 1; + +select t2.isbn,city,@bar:=t1.libname,count(distinct t1.libname) as a + from t3 left join t1 on t3.libname=t1.libname left join t2 + on t3.isbn=t2.isbn group by city having count(distinct + t1.libname) > 1; +# +# Wrong result, see bug#49872 +# +SELECT @bar; + +select t2.isbn,city,concat(@bar:=t1.libname),count(distinct t1.libname) as a + from t3 left join t1 on t3.libname=t1.libname left join t2 + on t3.isbn=t2.isbn group by city having count(distinct + t1.libname) > 1; +# +# Wrong result, see bug#49872 +# +SELECT @bar; + drop table t1, t2, t3; # diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index d39b49a0e87..59a5238b35b 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -248,4 +248,24 @@ SELECT @a, @b; SELECT a, b FROM t1 WHERE a=2 AND b=3 GROUP BY a, b; DROP TABLE t1; +# +# Bug#47371: reference by same column name +# +CREATE TABLE t1 (f1 int(11) default NULL, f2 int(11) default NULL); +CREATE TABLE t2 (f1 int(11) default NULL, f2 int(11) default NULL, foo int(11)); +CREATE TABLE t3 (f1 int(11) default NULL, f2 int(11) default NULL); + +INSERT INTO t1 VALUES(10, 10); +INSERT INTO t1 VALUES(10, 10); +INSERT INTO t2 VALUES(10, 10, 10); +INSERT INTO t2 VALUES(10, 10, 10); +INSERT INTO t3 VALUES(10, 10); +INSERT INTO t3 VALUES(10, 10); + +SELECT MIN(t2.f1), +@bar:= (SELECT MIN(t3.f2) FROM t3 WHERE t3.f2 > foo) +FROM t1,t2 WHERE t1.f1 = t2.f1 ORDER BY t2.f1; + +DROP TABLE t1, t2, t3; + --echo End of 5.0 tests diff --git a/sql/item_func.cc b/sql/item_func.cc index d6f315fda50..cb0d6bdbe5f 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -610,7 +610,7 @@ void Item_func::signal_divide_by_null() Item *Item_func::get_tmp_table_item(THD *thd) { - if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC) + if (!with_sum_func && !const_item()) return new Item_field(result_field); return copy_or_same(thd); } From 8f0f1d0ddb73283f60adb696f5b46b376aed327e Mon Sep 17 00:00:00 2001 From: Satya B Date: Tue, 22 Dec 2009 18:33:39 +0530 Subject: [PATCH 07/47] Removing rpl.rpl_trigger from experimental list as it is Fixed by BUG#46656 --- mysql-test/collections/default.experimental | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 2c2e9cab626..3894f2a4368 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -20,7 +20,6 @@ ndb.* # joro : NDB tests marked as experiment rpl.rpl_get_master_version_and_clock* # Bug #49191 2009-12-01 Daogang rpl_get_master_version_and_clock failed on PB2: COM_REGISTER_SLAVE failed rpl.rpl_innodb_bug28430* @solaris # Bug#46029 -rpl.rpl_trigger* # Bug#47810 2009-10-04 joro rpl.rpl_trigger.test fails with valgrind errors with the innodb plugin rpl_ndb.* # joro : NDB tests marked as experimental as agreed with bochklin rpl_ndb.rpl_ndb_log # Bug#38998 From 877311779d8304bafc3aa24eee2e8af573d7f69f Mon Sep 17 00:00:00 2001 From: Sergey Glukhov Date: Wed, 23 Dec 2009 17:44:03 +0400 Subject: [PATCH 08/47] Bug#47649 crash during CALL procedure If first call of the procedure is failed on the open_table stage stmt_arena->state is set to EXECUTED state. On second call(if no errors on open_table stage) it leads to use of worng memory arena in find_field_in_view() function as thd->stmt_arena->is_stmt_prepare_or_first_sp_execute() returns FALSE for EXECUTED state. The item is created not in its own arena and it leads to crash on further calls of the procedure. The fix: change state of arena only if no errors on open_table stage happens. mysql-test/r/sp.result: test result mysql-test/t/sp.test: test case sql/sp_head.cc: If first call of the procedure is failed on the open_table stage stmt_arena->state is set to EXECUTED state. On second call(if no errors on open_table stage) it leads to use of worng memory arena in find_field_in_view() function as thd->stmt_arena->is_stmt_prepare_or_first_sp_execute() returns FALSE for EXECUTED state. The item is created not in its own arena and it leads to crash on further calls of the procedure. The fix: change state of arena only if no errors on open_table stage happens. --- mysql-test/r/sp.result | 16 ++++++++++++++++ mysql-test/t/sp.test | 19 +++++++++++++++++++ sql/sp_head.cc | 11 +++++++++-- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 83ad7545685..1e6227e7380 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -6963,6 +6963,22 @@ CALL p1(); CALL p1(); DROP PROCEDURE p1; DROP TABLE t1; +CREATE TABLE t1 ( f1 integer, primary key (f1)); +CREATE TABLE t2 LIKE t1; +CREATE TEMPORARY TABLE t3 LIKE t1; +CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ; +END| +CALL p1; +ERROR HY000: Can't reopen table: 'A' +CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 ); +DROP TABLE t3; +CALL p1; +f1 +CALL p1; +f1 +DROP PROCEDURE p1; +DROP TABLE t1, t2; +DROP VIEW t3; # # Bug #46629: Item_in_subselect::val_int(): Assertion `0' # on subquery inside a SP diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 73ba62612b8..5cf050146dd 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -8242,6 +8242,25 @@ while ($tab_count) DROP PROCEDURE p1; DROP TABLE t1; +# +# Bug#47649 crash during CALL procedure +# +CREATE TABLE t1 ( f1 integer, primary key (f1)); +CREATE TABLE t2 LIKE t1; +CREATE TEMPORARY TABLE t3 LIKE t1; +delimiter |; +CREATE PROCEDURE p1 () BEGIN SELECT f1 FROM t3 AS A WHERE A.f1 IN ( SELECT f1 FROM t3 ) ; +END| +delimiter ;| +--error ER_CANT_REOPEN_TABLE +CALL p1; +CREATE VIEW t3 AS SELECT f1 FROM t2 A WHERE A.f1 IN ( SELECT f1 FROM t2 ); +DROP TABLE t3; +CALL p1; +CALL p1; +DROP PROCEDURE p1; +DROP TABLE t1, t2; +DROP VIEW t3; --echo # --echo # Bug #46629: Item_in_subselect::val_int(): Assertion `0' diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 51a731138ca..d74e195048f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2773,8 +2773,15 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, m_lex->mark_as_requiring_prelocking(NULL); } thd->rollback_item_tree_changes(); - /* Update the state of the active arena. */ - thd->stmt_arena->state= Query_arena::EXECUTED; + /* + Update the state of the active arena if no errors on + open_tables stage. + */ + if (!res || !thd->is_error() || + (thd->main_da.sql_errno() != ER_CANT_REOPEN_TABLE && + thd->main_da.sql_errno() != ER_NO_SUCH_TABLE && + thd->main_da.sql_errno() != ER_UPDATE_TABLE_USED)) + thd->stmt_arena->state= Query_arena::EXECUTED; /* Merge here with the saved parent's values From 1f55f5b617d0df650161c58f7d0707abd4ca42e2 Mon Sep 17 00:00:00 2001 From: Satya B Date: Thu, 24 Dec 2009 12:02:29 +0530 Subject: [PATCH 09/47] Bug#49898 - Fix for bug#37408 introduces a linker error the declaration of THR_LOCK_myisam_mmap in mi_static is redundant as it accessible via the extern declaration in include/myisam.h myisam/mi_static.c: Bug#49898 - Fix for bug#37408 introduces a linker error Remove THR_LOCK_myisam_mmap declaration as it is redundant --- myisam/mi_static.c | 1 - 1 file changed, 1 deletion(-) diff --git a/myisam/mi_static.c b/myisam/mi_static.c index b6464e452d7..f75ede48828 100644 --- a/myisam/mi_static.c +++ b/myisam/mi_static.c @@ -41,7 +41,6 @@ my_off_t myisam_max_temp_length= MAX_FILE_SIZE; ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_data_pointer_size=4; ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0; -pthread_mutex_t THR_LOCK_myisam_mmap; static int always_valid(const char *filename __attribute__((unused))) { From a21a0b47ca46212a528c4402e4b473fe51437422 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Fri, 18 Dec 2009 14:00:30 +0200 Subject: [PATCH 10/47] Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux) or freezes (win) the server The check for equality was assuming the field object is always created. If it's not it was de-referencing a NULL pointer. Fixed to use the data in the create object instead. --- mysql-test/r/alter_table.result | 7 +++++++ mysql-test/t/alter_table.test | 12 ++++++++++++ sql/field.cc | 3 +-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 06f4e7fbe8a..004e2031fb1 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -1338,4 +1338,11 @@ ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL; affected rows: 0 info: Records: 0 Duplicates: 0 Warnings: 0 DROP TABLE t1; +# +# Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux) +# or freezes (win) the server +# +CREATE TABLE t1 (a TEXT, id INT, b INT); +ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST; +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index 5534aa0a234..4989a6c380c 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1061,4 +1061,16 @@ ALTER TABLE t1 CHANGE COLUMN f1 f1_no_real_change TIMESTAMP NULL DEFAULT NULL; --disable_info DROP TABLE t1; + +--echo # +--echo # Bug #31145: ALTER TABLE DROP COLUMN, ADD COLUMN crashes (linux) +--echo # or freezes (win) the server +--echo # + +CREATE TABLE t1 (a TEXT, id INT, b INT); +ALTER TABLE t1 DROP COLUMN a, ADD COLUMN c TEXT FIRST; + +DROP TABLE t1; + + --echo End of 5.1 tests diff --git a/sql/field.cc b/sql/field.cc index 01ccc338782..d8db3fdbae4 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8282,8 +8282,7 @@ uint Field_blob::is_equal(Create_field *new_field) return ((new_field->sql_type == get_blob_type_from_length(max_data_length())) && new_field->charset == field_charset && - ((Field_blob *)new_field->field)->max_data_length() == - max_data_length()); + new_field->pack_length == pack_length()); } From 6559a46a245264eafd1f87ec65097f83d77142bd Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 21 Dec 2009 15:41:38 +0530 Subject: [PATCH 11/47] Applying InnoDB snapshot 5.1-ss6344, part 1. Fixes BUG#49267 Detailed revision comments: r6306 | calvin | 2009-12-14 15:12:46 +0200 (Mon, 14 Dec 2009) | 5 lines branches/5.1: fix bug#49267: innodb-autoinc.test fails on windows because of different case mode There is no change to the InnoDB code, only to fix test case by changing "T1" to "t1". --- mysql-test/r/innodb-autoinc.result | 42 +++++++++++++++--------------- mysql-test/t/innodb-autoinc.test | 34 ++++++++++++------------ 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/mysql-test/r/innodb-autoinc.result b/mysql-test/r/innodb-autoinc.result index 2e0d2c1d776..fe87e11c9ec 100644 --- a/mysql-test/r/innodb-autoinc.result +++ b/mysql-test/r/innodb-autoinc.result @@ -1111,46 +1111,46 @@ c1 c2 3 innodb 4 NULL DROP TABLE t1; -CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; -CREATE INDEX i1 on T1(c2); -SHOW CREATE TABLE T1; +CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; +CREATE INDEX i1 on t1(c2); +SHOW CREATE TABLE t1; Table Create Table -T1 CREATE TABLE `T1` ( +t1 CREATE TABLE `t1` ( `c1` int(11) NOT NULL AUTO_INCREMENT, `c2` int(11) DEFAULT NULL, PRIMARY KEY (`c1`), KEY `i1` (`c2`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 -INSERT INTO T1 (c2) values (0); -SELECT * FROM T1; +INSERT INTO t1 (c2) values (0); +SELECT * FROM t1; c1 c2 10 0 -DROP TABLE T1; -DROP TABLE IF EXISTS T1; +DROP TABLE t1; +DROP TABLE IF EXISTS t1; Warnings: -Note 1051 Unknown table 'T1' -CREATE TABLE T1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; -INSERT INTO T1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); -INSERT INTO T1(C2) VALUES ('innodb'); -SHOW CREATE TABLE T1; +Note 1051 Unknown table 't1' +CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); +INSERT INTO t1(C2) VALUES ('innodb'); +SHOW CREATE TABLE t1; Table Create Table -T1 CREATE TABLE `T1` ( +t1 CREATE TABLE `t1` ( `C1` double NOT NULL AUTO_INCREMENT, `C2` char(10) DEFAULT NULL, PRIMARY KEY (`C1`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 -DROP TABLE T1; -CREATE TABLE T1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; -INSERT INTO T1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); -INSERT INTO T1(C2) VALUES ('innodb'); -SHOW CREATE TABLE T1; +DROP TABLE t1; +CREATE TABLE t1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); +INSERT INTO t1(C2) VALUES ('innodb'); +SHOW CREATE TABLE t1; Table Create Table -T1 CREATE TABLE `T1` ( +t1 CREATE TABLE `t1` ( `C1` float NOT NULL AUTO_INCREMENT, `C2` char(10) DEFAULT NULL, PRIMARY KEY (`C1`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 -DROP TABLE T1; +DROP TABLE t1; DROP TABLE IF EXISTS t1; Warnings: Note 1051 Unknown table 't1' diff --git a/mysql-test/t/innodb-autoinc.test b/mysql-test/t/innodb-autoinc.test index 4fa5ab022ad..84386280a26 100644 --- a/mysql-test/t/innodb-autoinc.test +++ b/mysql-test/t/innodb-autoinc.test @@ -614,31 +614,31 @@ DROP TABLE t1; # 47125: auto_increment start value is ignored if an index is created # and engine=innodb # -CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; -CREATE INDEX i1 on T1(c2); -SHOW CREATE TABLE T1; -INSERT INTO T1 (c2) values (0); -SELECT * FROM T1; -DROP TABLE T1; +CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; +CREATE INDEX i1 on t1(c2); +SHOW CREATE TABLE t1; +INSERT INTO t1 (c2) values (0); +SELECT * FROM t1; +DROP TABLE t1; ## # 49032: Use the correct function to read the AUTOINC column value # -DROP TABLE IF EXISTS T1; -CREATE TABLE T1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; -INSERT INTO T1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); +DROP TABLE IF EXISTS t1; +CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); # Restart the server -- source include/restart_mysqld.inc -INSERT INTO T1(C2) VALUES ('innodb'); -SHOW CREATE TABLE T1; -DROP TABLE T1; -CREATE TABLE T1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; -INSERT INTO T1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); +INSERT INTO t1(C2) VALUES ('innodb'); +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB; +INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb'); # Restart the server -- source include/restart_mysqld.inc -INSERT INTO T1(C2) VALUES ('innodb'); -SHOW CREATE TABLE T1; -DROP TABLE T1; +INSERT INTO t1(C2) VALUES ('innodb'); +SHOW CREATE TABLE t1; +DROP TABLE t1; ## # 47720: REPLACE INTO Autoincrement column with negative values From 2f04df4ab040b5821cf552c27741ede58ebec162 Mon Sep 17 00:00:00 2001 From: Satya B Date: Mon, 21 Dec 2009 15:50:32 +0530 Subject: [PATCH 12/47] Applying InnoDB snapshot 5.1-ss6344, part 2. Fixes BUG#41609 but does not address the printouts issue Detailed revision comments: r6310 | marko | 2009-12-15 15:23:54 +0200 (Tue, 15 Dec 2009) | 30 lines branches/5.1: Merge r4922 from branches/zip. This the fix for the first part of Bug #41609 from InnoDB Plugin to the built-in InnoDB in MySQL 5.1. This allows InnoDB Hot Backup to back up a database while the built-in InnoDB in MySQL 5.1 is creating temporary tables. (This fix does not address the printouts about missing .ibd files for temporary tables at InnoDB startup, which was committed to branches/zip in r6252.) rb://219 approved by Sunny Bains. branches/zip: Distinguish temporary tables in MLOG_FILE_CREATE. This addresses Mantis Issue #23 in InnoDB Hot Backup and some of MySQL Bug #41609. In MLOG_FILE_CREATE, we need to distinguish temporary tables, so that InnoDB Hot Backup can work correctly. It turns out that we can do this easily, by using a bit of the previously unused parameter for page number. (The page number parameter of MLOG_FILE_CREATE has been written as 0 ever since MySQL 4.1, which introduced MLOG_FILE_CREATE.) MLOG_FILE_FLAG_TEMP: A flag for indicating a temporary table in the page number parameter of MLOG_FILE_ operations. fil_op_write_log(): Add the parameter log_flags. fil_op_log_parse_or_replay(): Add the parameter log_flags. Do not replay MLOG_FILE_CREATE when MLOG_FILE_FLAG_TEMP is set in log_flags. This only affects ibbackup --apply-log. InnoDB itself never replays file operations. --- storage/innobase/fil/fil0fil.c | 29 +++++++++++++++++------------ storage/innobase/include/fil0fil.h | 10 +++++----- storage/innobase/include/mtr0mtr.h | 6 ++++++ storage/innobase/log/log0recv.c | 7 +++---- 4 files changed, 31 insertions(+), 21 deletions(-) diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 42e5166c9e4..3810fefd3cb 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -1740,6 +1740,8 @@ fil_op_write_log( MLOG_FILE_DELETE, or MLOG_FILE_RENAME */ ulint space_id, /* in: space id */ + ulint log_flags, /* in: redo log flags (stored + in the page number field) */ const char* name, /* in: table name in the familiar 'databasename/tablename' format, or the file path in the case of @@ -1760,8 +1762,8 @@ fil_op_write_log( return; } - log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0, - log_ptr, mtr); + log_ptr = mlog_write_initial_log_record_for_file_op( + type, space_id, log_flags, log_ptr, mtr); /* Let us store the strings as null-terminated for easier readability and handling */ @@ -1810,11 +1812,11 @@ fil_op_log_parse_or_replay( not fir completely between ptr and end_ptr */ byte* end_ptr, /* in: buffer end */ ulint type, /* in: the type of this log record */ - ibool do_replay, /* in: TRUE if we want to replay the - operation, and not just parse the log record */ - ulint space_id) /* in: if do_replay is TRUE, the space id of - the tablespace in question; otherwise - ignored */ + ulint space_id, /* in: the space id of the tablespace in + question, or 0 if the log record should + only be parsed but not replayed */ + ulint log_flags) /* in: redo log flags + (stored in the page number parameter) */ { ulint name_len; ulint new_name_len; @@ -1868,7 +1870,7 @@ fil_op_log_parse_or_replay( printf("new name %s\n", new_name); } */ - if (do_replay == FALSE) { + if (!space_id) { return(ptr); } @@ -1917,6 +1919,8 @@ fil_op_log_parse_or_replay( } else if (fil_get_space_id_for_table(name) != ULINT_UNDEFINED) { /* Do nothing */ + } else if (log_flags & MLOG_FILE_FLAG_TEMP) { + /* Temporary table, do nothing */ } else { /* Create the database directory for name, if it does not exist yet */ @@ -2078,7 +2082,7 @@ try_again: to write any log record */ mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_DELETE, id, path, NULL, &mtr); + fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr); mtr_commit(&mtr); #endif mem_free(path); @@ -2349,7 +2353,7 @@ retry: mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_RENAME, id, old_name, new_name, + fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name, &mtr); mtr_commit(&mtr); } @@ -2525,8 +2529,9 @@ error_exit2: mtr_start(&mtr); - fil_op_write_log(MLOG_FILE_CREATE, *space_id, tablename, - NULL, &mtr); + fil_op_write_log(MLOG_FILE_CREATE, *space_id, + is_temp ? MLOG_FILE_FLAG_TEMP : 0, + tablename, NULL, &mtr); mtr_commit(&mtr); } diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 6b8fd4b03d5..251d6c22547 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -330,11 +330,11 @@ fil_op_log_parse_or_replay( not fir completely between ptr and end_ptr */ byte* end_ptr, /* in: buffer end */ ulint type, /* in: the type of this log record */ - ibool do_replay, /* in: TRUE if we want to replay the - operation, and not just parse the log record */ - ulint space_id); /* in: if do_replay is TRUE, the space id of - the tablespace in question; otherwise - ignored */ + ulint space_id, /* in: the space id of the tablespace in + question, or 0 if the log record should + only be parsed but not replayed */ + ulint log_flags); /* in: redo log flags + (stored in the page number parameter) */ /*********************************************************************** Deletes a single-table tablespace. The tablespace must be cached in the memory cache. */ diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 2a160d27e0c..a6e2976830b 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -134,6 +134,12 @@ flag value must give the length also! */ #define MLOG_BIGGEST_TYPE ((byte)46) /* biggest value (used in asserts) */ +/* Flags for MLOG_FILE operations (stored in the page number +parameter, called log_flags in the functions). The page number +parameter was initially written as 0. */ +#define MLOG_FILE_FLAG_TEMP 1 /* identifies TEMPORARY TABLE in + MLOG_FILE_CREATE */ + /******************************************************************* Starts a mini-transaction and creates a mini-transaction handle and buffer in the memory buffer given by the caller. */ diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c index aef58b7b576..5d309768064 100644 --- a/storage/innobase/log/log0recv.c +++ b/storage/innobase/log/log0recv.c @@ -939,8 +939,7 @@ recv_parse_or_apply_log_rec_body( case MLOG_FILE_CREATE: case MLOG_FILE_RENAME: case MLOG_FILE_DELETE: - ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, FALSE, - ULINT_UNDEFINED); + ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0); break; default: ptr = NULL; @@ -1938,8 +1937,8 @@ loop: point to the datadir we should use there */ if (NULL == fil_op_log_parse_or_replay( - body, end_ptr, type, TRUE, - space)) { + body, end_ptr, type, + space, page_no)) { fprintf(stderr, "InnoDB: Error: file op" " log record of type %lu" From 007d77afb9ea5fd7b7a369114f8963ab147fd2c5 Mon Sep 17 00:00:00 2001 From: Serge Kozlov Date: Mon, 21 Dec 2009 14:40:08 +0300 Subject: [PATCH 13/47] Bug#8693, Bug#45521. --- mysql-test/t/disabled.def | 2 -- 1 file changed, 2 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 062667c249e..61e1226c8e3 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -16,11 +16,9 @@ im_daemon_life_cycle : Bug#20294: Instance manager tests fail randomly im_options_set : Bug#20294: Instance manager tests fail randomly im_options_unset : Bug#20294: Instance manager tests fail randomly im_utils : Bug#20294: Instance manager tests fail randomly -rpl_log_pos : Bug#8693 Test 'rpl_log_pos' fails sometimes kill : Bug#29149 Test "kill" fails on Windows ps_7ndb : Bug#38315 "Cluster Failure" in ps_7ndb strict_autoinc_5ndb : Bug#35148 "Error '4009 Cluster Failure' in various tests on various platforms" -rpl_slave_skip : Bug#45521: rpl_slave_skip fails in pb2 loaddata_autocom_ndb : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms ndb_autodiscover3 : Bug#35148: Error '4009 Cluster Failure' in various tests on various platforms ndb_autodiscover : Bug#45972: ndb.ndb_autodiscover fails occasionally with pb2 From 7344b58c32c07df496c208dad5c1e11c304e8aac Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Tue, 22 Dec 2009 10:39:29 +0400 Subject: [PATCH 14/47] Fix for bug#49570: Assertion failed: !(order->used & map) on re-execution of prepared statement Problem: some (see eq_ref_table()) ORDER BY/GROUP BY optimization is called before each PS execution. However, we don't properly initialize its stucture every time before the call. Fix: properly initialize the sturture used. mysql-test/r/ps.result: Fix for bug#49570: Assertion failed: !(order->used & map) on re-execution of prepared statement - test result. mysql-test/t/ps.test: Fix for bug#49570: Assertion failed: !(order->used & map) on re-execution of prepared statement - test case. sql/sql_select.cc: Fix for bug#49570: Assertion failed: !(order->used & map) on re-execution of prepared statement - set order->used to 0 before each eq_ref_table() call, as the function relies on that. --- mysql-test/r/ps.result | 22 ++++++++++++++++++++++ mysql-test/t/ps.test | 16 ++++++++++++++++ sql/sql_select.cc | 1 + 3 files changed, 39 insertions(+) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 8a19b9b17e1..6e017ec7253 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1916,4 +1916,26 @@ execute stmt; deallocate prepare stmt; drop table t1,t2; # +# +# Bug #49570: Assertion failed: !(order->used & map) +# on re-execution of prepared statement +# +CREATE TABLE t1(a INT PRIMARY KEY); +INSERT INTO t1 VALUES(0), (1); +PREPARE stmt FROM +"SELECT 1 FROM t1 JOIN t1 t2 USING(a) GROUP BY t2.a, t1.a"; +EXECUTE stmt; +1 +1 +1 +EXECUTE stmt; +1 +1 +1 +EXECUTE stmt; +1 +1 +1 +DEALLOCATE PREPARE stmt; +DROP TABLE t1; End of 5.0 tests. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 8f8e943913f..e207b0f154a 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1996,4 +1996,20 @@ deallocate prepare stmt; drop table t1,t2; --echo # + +--echo # +--echo # Bug #49570: Assertion failed: !(order->used & map) +--echo # on re-execution of prepared statement +--echo # +CREATE TABLE t1(a INT PRIMARY KEY); +INSERT INTO t1 VALUES(0), (1); +PREPARE stmt FROM + "SELECT 1 FROM t1 JOIN t1 t2 USING(a) GROUP BY t2.a, t1.a"; +EXECUTE stmt; +EXECUTE stmt; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +DROP TABLE t1; + + --echo End of 5.0 tests. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index d22a23a10d4..d8ec5eff5c1 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6777,6 +6777,7 @@ static void update_depend_map(JOIN *join, ORDER *order) table_map depend_map; order->item[0]->update_used_tables(); order->depend_map=depend_map=order->item[0]->used_tables(); + order->used= 0; // Not item_sum(), RAND() and no reference to table outside of sub select if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT)) && !order->item[0]->with_sum_func) From 1aed2f4d634e456bf44ad20d3d3fed934960b9c6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Dec 2009 14:27:41 +0100 Subject: [PATCH 15/47] Raise version number after cloning 5.5.1-m2 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index a5b2c5c001a..309341b6a2d 100644 --- a/configure.in +++ b/configure.in @@ -10,7 +10,7 @@ AC_CANONICAL_SYSTEM # # When changing major version number please also check switch statement # in client/mysqlbinlog.cc:check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.5.1-m2) +AM_INIT_AUTOMAKE(mysql, 5.5.2-m2) AM_CONFIG_HEADER([include/config.h:config.h.in]) # Request support for automake silent-rules if available. From 2d8869d248188c1bf393fc87d9f0e31adf691c2d Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Tue, 22 Dec 2009 17:52:15 +0200 Subject: [PATCH 16/47] Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY Several problems fixed : 1. Non constant expressions in UNION ... ORDER BY were not correctly cleaned up in st_select_lex_unit::cleanup() causing crashes in EXPLAIN EXTENDED because of fields quoted by these expressions pointing to the already freed temporary table used to calculate the UNION. Fixed by correctly cleaning up expressions of any depth. 2. Subqueries in the order by part of UNION ... ORDER BY ... caused a crash in EXPLAIN EXTENDED because of a transformation attempt made during EXPLAIN EXTENDED execution. Fixed by not doing the transformation when in EXPLAIN. 3. Fulltext functions caused crash when in the ORDER BY part of an un-parenthesized UNION that gets "promoted" to be valid for the whole union, e.g. SELECT * FROM t1 UNION SELECT * FROM t2 ORDER BY MATCHES (a) AGAINST ('abc' IN BOOLEAN MODE). This is a case that demonstrates a more general problem of parts of the query being moved to another level. When doing such transformation late in the optimization run when most of the flags about the contents of the query are already aggregated it's possible to "split" the flags so that they correctly reflect the new queries after the transformation. In specific the ST_SELECT_LEX::ftfunc_list is holding all the free text function for all the parts of the second SELECT in the UNION and we don't know what part of that is in the ORDER BY that we're to move to the UNION level and what part is about the other parts of the second SELECT. Fixed by throwing and error when such statements are about to be processed by adding a check for the presence of MATCH() inside the ORDER BY clause that's going to get promoted to UNION. To workaround this new limitation one must parenthesize the UNION SELECTs and provide a real global ORDER BY for the UNION outside of the parenthesis. --- mysql-test/r/fulltext_order_by.result | 6 +-- mysql-test/r/union.result | 63 +++++++++++++++++++++++++++ mysql-test/t/fulltext_order_by.test | 5 ++- mysql-test/t/union.test | 53 ++++++++++++++++++++++ sql/item.h | 17 ++++++++ sql/item_func.h | 5 +++ sql/sql_select.cc | 2 +- sql/sql_union.cc | 31 ++++++++++++- 8 files changed, 175 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/fulltext_order_by.result b/mysql-test/r/fulltext_order_by.result index bc466b5aba7..bd3e79ec5c2 100644 --- a/mysql-test/r/fulltext_order_by.result +++ b/mysql-test/r/fulltext_order_by.result @@ -126,7 +126,7 @@ group by a.text, b.id, b.betreff order by match(b.betreff) against ('+abc' in boolean mode) desc; -ERROR 42S22: Unknown column 'b.betreff' in 'order clause' +ERROR 42000: Incorrect usage/placement of 'MATCH()' select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -142,7 +142,7 @@ where match(c.beitrag) against ('+abc' in boolean mode) order by match(b.betreff) against ('+abc' in boolean mode) desc; -ERROR 42S22: Unknown column 'b.betreff' in 'order clause' +ERROR 42000: Incorrect usage/placement of 'MATCH()' select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -158,7 +158,7 @@ where match(c.beitrag) against ('+abc' in boolean mode) order by match(betreff) against ('+abc' in boolean mode) desc; -text id betreff +ERROR 42000: Incorrect usage/placement of 'MATCH()' (select b.id, b.betreff from t3 b) union (select b.id, b.betreff from t3 b) order by match(betreff) against ('+abc' in boolean mode) desc; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 44a3812725a..dce32d2ced4 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1588,3 +1588,66 @@ Warnings: Note 1003 select '0' AS `a` from `test`.`t1` union select '0' AS `a` from `test`.`t1` order by `a` DROP TABLE t1; End of 5.0 tests +# +# Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY +# +# +CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a)); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (1),(2); +# Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 UNION t1 ALL NULL NULL NULL NULL 2 100.00 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (`a` + 12) +# Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12; +a +1 +2 +# Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 +ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); +ERROR 42000: Incorrect usage/placement of 'MATCH()' +# Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 +ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); +ERROR 42000: Incorrect usage/placement of 'MATCH()' +# Should not crash +(SELECT * FROM t1) UNION (SELECT * FROM t1) +ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); +a +1 +2 +# Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 +ORDER BY (SELECT a FROM t2 WHERE b = 12); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +2 UNION t1 ALL NULL NULL NULL NULL 2 100.00 +3 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 Using where +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Using filesort +Warnings: +Note 1276 Field or reference 'test.t1.a' of SELECT #3 was resolved in SELECT #2 +Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1`.`a` AS `a` from `test`.`t1` order by (select `test`.`t1`.`a` AS `a` from `test`.`t2` where (`test`.`t2`.`b` = 12)) +# Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 +ORDER BY (SELECT a FROM t2 WHERE b = 12); +a +1 +2 +# Should not crash +SELECT * FROM t2 UNION SELECT * FROM t2 +ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); +b +1 +2 +DROP TABLE t1,t2; +End of 5.1 tests diff --git a/mysql-test/t/fulltext_order_by.test b/mysql-test/t/fulltext_order_by.test index 074aefbf943..814cd4a5954 100644 --- a/mysql-test/t/fulltext_order_by.test +++ b/mysql-test/t/fulltext_order_by.test @@ -80,7 +80,7 @@ CREATE TABLE t3 ( FULLTEXT KEY betreff (betreff) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=996 ; ---error 1054 +--error ER_CANT_USE_OPTION_HERE select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -100,7 +100,7 @@ group by order by match(b.betreff) against ('+abc' in boolean mode) desc; ---error 1054 +--error ER_CANT_USE_OPTION_HERE select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join @@ -117,6 +117,7 @@ where order by match(b.betreff) against ('+abc' in boolean mode) desc; +--error ER_CANT_USE_OPTION_HERE select a.text, b.id, b.betreff from t2 a inner join t3 b on a.id = b.forum inner join diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index ec169838d59..91fc9546bbe 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1102,3 +1102,56 @@ DROP TABLE t1; --echo End of 5.0 tests + + +--echo # +--echo # Bug #49734: Crash on EXPLAIN EXTENDED UNION ... ORDER BY +--echo # +--echo # + +CREATE TABLE t1 (a VARCHAR(10), FULLTEXT KEY a (a)); +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT); +INSERT INTO t2 VALUES (1),(2); + +--echo # Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12; + +--echo # Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY a + 12; + + +--echo # Should not crash +--error ER_CANT_USE_OPTION_HERE +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 + ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); + +--echo # Should not crash +--error ER_CANT_USE_OPTION_HERE +SELECT * FROM t1 UNION SELECT * FROM t1 + ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); + +--echo # Should not crash +(SELECT * FROM t1) UNION (SELECT * FROM t1) + ORDER BY MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE); + + +--echo # Should not crash +EXPLAIN EXTENDED +SELECT * FROM t1 UNION SELECT * FROM t1 + ORDER BY (SELECT a FROM t2 WHERE b = 12); + +--echo # Should not crash +SELECT * FROM t1 UNION SELECT * FROM t1 + ORDER BY (SELECT a FROM t2 WHERE b = 12); + +--echo # Should not crash +SELECT * FROM t2 UNION SELECT * FROM t2 + ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); + +DROP TABLE t1,t2; + + +--echo End of 5.1 tests diff --git a/sql/item.h b/sql/item.h index b97808ac87f..8f0e5874f3f 100644 --- a/sql/item.h +++ b/sql/item.h @@ -967,6 +967,23 @@ public: return FALSE; } + /** + Find a function of a given type + + @param arg the function type to search (enum Item_func::Functype) + @return + @retval TRUE the function type we're searching for is found + @retval FALSE the function type wasn't found + + @description + This function can be used (together with Item::walk()) to find functions + in an item tree fragment. + */ + virtual bool find_function_processor (uchar *arg) + { + return FALSE; + } + /* For SP local variable returns pointer to Item representing its current value and pointer to current Item otherwise. diff --git a/sql/item_func.h b/sql/item_func.h index 259316b0c41..71168c64e4b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -212,6 +212,11 @@ public: { return has_timestamp_args(); } + + virtual bool find_function_processor (uchar *arg) + { + return functype() == *(Functype *) arg; + } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6383fe63012..d50bb888850 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -519,7 +519,7 @@ JOIN::prepare(Item ***rref_pointer_array, thd->lex->allow_sum_func= save_allow_sum_func; } - if (!thd->lex->view_prepare_mode) + if (!thd->lex->view_prepare_mode && !(select_options & SELECT_DESCRIBE)) { Item_subselect *subselect; /* Is it subselect? */ diff --git a/sql/sql_union.cc b/sql/sql_union.cc index cbf94ad7181..1760670f9c8 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -335,6 +335,35 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, } } + /* + Disable the usage of fulltext searches in the last union branch. + This is a temporary 5.x limitation because of the way the fulltext + search functions are handled by the optimizer. + This is manifestation of the more general problems of "taking away" + parts of a SELECT statement post-fix_fields(). This is generally not + doable since various flags are collected in various places (e.g. + SELECT_LEX) that carry information about the presence of certain + expressions or constructs in the parts of the query. + When part of the query is taken away it's not clear how to "divide" + the meaning of these accumulated flags and what to carry over to the + recipient query (SELECT_LEX). + */ + if (global_parameters->ftfunc_list->elements && + global_parameters->order_list.elements && + global_parameters != fake_select_lex) + { + ORDER *ord; + Item_func::Functype ft= Item_func::FT_FUNC; + for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next) + if ((*ord->item)->walk (&Item::find_function_processor, FALSE, + (uchar *) &ft)) + { + my_error (ER_CANT_USE_OPTION_HERE, MYF(0), "MATCH()"); + goto err; + } + } + + create_options= (first_sl->options | thd_arg->options | TMP_TABLE_ALL_COLUMNS); /* @@ -669,7 +698,7 @@ bool st_select_lex_unit::cleanup() { ORDER *ord; for (ord= (ORDER*)global_parameters->order_list.first; ord; ord= ord->next) - (*ord->item)->cleanup(); + (*ord->item)->walk (&Item::cleanup_processor, 0, 0); } } From 7a84896d711a30b3412c962633b7596710e1f806 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 22 Dec 2009 23:22:42 +0100 Subject: [PATCH 17/47] Change RPM file naming: - Suffix like "-m2", "-rc" becomes part of version as "_m2", "_rc". - Release counts from 1, not 0. This is done for both the "generic" RPMs and the "shared-compat" ones. It includes introducing a new version variable "MYSQL_U_SCORE_VERSION" in "configure.in", where the dash is replaced by an underscore: 5.5.1-m2 -> 5.5.1_m2 --- configure.in | 13 +++++++---- support-files/MySQL-shared-compat.spec.sh | 28 +++++++++++++++-------- support-files/mysql.spec.sh | 14 ++++++++---- 3 files changed, 37 insertions(+), 18 deletions(-) diff --git a/configure.in b/configure.in index a5b2c5c001a..2533e43ebf9 100644 --- a/configure.in +++ b/configure.in @@ -31,12 +31,14 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0 # Remember that regexps needs to quote [ and ] since this is run through m4 # We take some made up examples # -# VERSION 5.1.40sp1-alpha 5.0.34a -# MYSQL_NO_DASH_VERSION 5.1.40sp1 5.0.34a -# MYSQL_NUMERIC_VERSION 5.1.40 5.0.34 -# MYSQL_BASE_VERSION 5.1 5.0 -# MYSQL_VERSION_ID 50140 50034 +# VERSION 5.1.40sp1-alpha 5.0.34a 5.5.1-m2 +# MYSQL_U_SCORE_VERSION 5.1.40sp1_alpha 5.0.34a 5.5.1_m2 +# MYSQL_NO_DASH_VERSION 5.1.40sp1 5.0.34a 5.5.1 +# MYSQL_NUMERIC_VERSION 5.1.40 5.0.34 5.5.1 +# MYSQL_BASE_VERSION 5.1 5.0 5.5 +# MYSQL_VERSION_ID 50140 50034 50501 # +MYSQL_U_SCORE_VERSION=`echo $VERSION | sed -e "s|-|_|"` MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|-.*$||"` MYSQL_NUMERIC_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|[[a-z]][[a-z0-9]]*$||"` MYSQL_BASE_VERSION=`echo $MYSQL_NUMERIC_VERSION | sed -e "s|\.[[^.]]*$||"` @@ -74,6 +76,7 @@ romanian russian serbian slovak spanish swedish ukrainian" ##### ##### +AC_SUBST(MYSQL_U_SCORE_VERSION) AC_SUBST(MYSQL_NO_DASH_VERSION) AC_SUBST(MYSQL_BASE_VERSION) AC_SUBST(MYSQL_VERSION_ID) diff --git a/support-files/MySQL-shared-compat.spec.sh b/support-files/MySQL-shared-compat.spec.sh index 14a98616863..72654a22d87 100644 --- a/support-files/MySQL-shared-compat.spec.sh +++ b/support-files/MySQL-shared-compat.spec.sh @@ -1,3 +1,4 @@ +# Copyright 2003-2008 MySQL AB, 2009 Sun Microsystems, Inc. # # MySQL-shared-compat.spec # @@ -7,8 +8,6 @@ # separate "MySQL-shared" package. This spec file simply repackages two # already existing MySQL-shared RPMs into a single package. # -# Copyright (C) 2003 MySQL AB -# # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; version 2 of the License. @@ -28,27 +27,27 @@ # # Change this to match the version of the shared libs you want to include # -%define version50 @MYSQL_NO_DASH_VERSION@ +%define version_cur @MYSQL_U_SCORE_VERSION@ %define version41 4.1.17 %define version40 4.0.26 %define version3 3.23.58 Name: MySQL-shared-compat -Packager: MySQL Product Engineering team -Vendor: MySQL AB +Packager: Sun Microsystems, Inc. Product Engineering Team +Vendor: Sun Microsystems, Inc. License: GPL Group: Applications/Databases URL: http://www.mysql.com/ Autoreqprov: on -Version: %{version50} -Release: 0 +Version: %{version_cur} +Release: 1 BuildRoot: %{_tmppath}/%{name}-%{version}-build Obsoletes: MySQL-shared, mysql-shared Provides: MySQL-shared Summary: MySQL shared client libraries for MySQL %{version}, %{version41}, %{version40} and %{version3} # We simply use the "MySQL-shared" subpackages as input sources instead of # rebuilding all from source -Source0: MySQL-shared-%{version50}-0.%{_arch}.rpm +Source0: MySQL-shared-%{version_cur}-1.%{_arch}.rpm Source1: MySQL-shared-%{version41}-1.%{_arch}.rpm Source2: MySQL-shared-%{version40}-0.%{_arch}.rpm Source3: MySQL-shared-%{version3}-1.%{_arch}.rpm @@ -62,7 +61,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-build %description This package includes the shared libraries for MySQL %{version3}, -MySQL %{version40}, %{version41} as well as MySQL %{version50}. +MySQL %{version40}, %{version41} as well as MySQL %{version_cur}. Install this package instead of "MySQL-shared", if you have applications installed that are dynamically linked against older versions of the MySQL client library but you want to upgrade to MySQL %{version} without breaking the @@ -84,3 +83,14 @@ rpm2cpio %{SOURCE3} | cpio -iv --make-directories %files %defattr(-, root, root) %{_libdir}/libmysqlclient* + +# The spec file changelog only includes changes made to the spec file +# itself - note that they must be ordered by date (important when +# merging BK trees) +%changelog +* Tue Dec 22 2009 Joerg Bruehe + +- Change RPM file naming: + - Suffix like "-m2", "-rc" becomes part of version as "_m2", "_rc". + - Release counts from 1, not 0. + diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 83d4550466b..271d0c39e55 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1,4 +1,4 @@ -# Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +# Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -50,9 +50,9 @@ %{!?malloc_lib_target:%define WITH_TCMALLOC 0} %if %{STATIC_BUILD} -%define release 0 +%define release 1 %else -%define release 0.glibc23 +%define release 1.glibc23 %endif %define mysql_license GPL %define mysqld_user mysql @@ -86,7 +86,7 @@ Name: MySQL Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases -Version: @MYSQL_NO_DASH_VERSION@ +Version: @MYSQL_U_SCORE_VERSION@ Release: %{release} License: Copyright 2000-2008 MySQL AB, @MYSQL_COPYRIGHT_YEAR@ Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Under %{mysql_license} license as shown in the Description field. Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz @@ -882,6 +882,12 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Tue Dec 22 2009 Joerg Bruehe + +- Change RPM file naming: + - Suffix like "-m2", "-rc" becomes part of version as "_m2", "_rc". + - Release counts from 1, not 0. + * Mon Nov 16 2009 Joerg Bruehe - Fix some problems with the directives around "tcmalloc" (experimental), From 83d5ca950ba1b6e1d5cbc2f39352a30ff7bad8b4 Mon Sep 17 00:00:00 2001 From: Satya B Date: Wed, 23 Dec 2009 12:29:34 +0530 Subject: [PATCH 18/47] Applying InnoDB snapshot 5.1-ss6344, Fixes BUG#47814 and also applying 5.1-ss6355 Detailed revision comments: r6324 | jyang | 2009-12-17 06:54:24 +0200 (Thu, 17 Dec 2009) | 8 lines branches/5.1: Fix bug #47814 - Diagnostics are frequently not printed after a long lock wait in InnoDB. Separate out the lock wait timeout check thread from monitor information printing thread. rb://200 Approved by Marko. r6349 | marko | 2009-12-22 11:09:54 +0200 (Tue, 22 Dec 2009) | 3 lines branches/5.1: lock_print_info_summary(): Remove a reference to innobase_mysql_end_print_arbitrary_thd() that should have been removed in r6347 when removing the function. r6350 | marko | 2009-12-22 11:11:09 +0200 (Tue, 22 Dec 2009) | 1 line branches/5.1: Remove an obsolete declaration of LOCK_thread_count. --- storage/innobase/handler/ha_innodb.cc | 4 +- storage/innobase/include/lock0lock.h | 9 +- storage/innobase/include/srv0srv.h | 26 +++- storage/innobase/lock/lock0lock.c | 22 +++- storage/innobase/log/log0log.c | 2 +- storage/innobase/srv/srv0srv.c | 177 ++++++++++++++++++++------ storage/innobase/srv/srv0start.c | 15 ++- 7 files changed, 194 insertions(+), 61 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2467e7b19b5..a1b8c551845 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -7394,8 +7394,8 @@ innodb_show_status( mutex_enter_noninline(&srv_monitor_file_mutex); rewind(srv_monitor_file); - srv_printf_innodb_monitor(srv_monitor_file, - &trx_list_start, &trx_list_end); + srv_printf_innodb_monitor(srv_monitor_file, FALSE, + &trx_list_start, &trx_list_end); flen = ftell(srv_monitor_file); os_file_set_eof(srv_monitor_file); diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 635724bf5a1..beaf17eda01 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -579,10 +579,15 @@ lock_rec_print( /************************************************************************* Prints info of locks for all transactions. */ -void +ibool lock_print_info_summary( /*====================*/ - FILE* file); /* in: file where to print */ + /* out: FALSE if not able to obtain + kernel mutex and exits without + printing info */ + FILE* file, /* in: file where to print */ + ibool nowait);/* in: whether to wait for the kernel + mutex */ /************************************************************************* Prints info of locks for each transaction. */ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 67144a41d3d..3dd4bb961f9 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -146,7 +146,8 @@ extern ibool srv_print_innodb_tablespace_monitor; extern ibool srv_print_verbose_log; extern ibool srv_print_innodb_table_monitor; -extern ibool srv_lock_timeout_and_monitor_active; +extern ibool srv_lock_timeout_active; +extern ibool srv_monitor_active; extern ibool srv_error_monitor_active; extern ulong srv_n_spin_wait_rounds; @@ -427,12 +428,21 @@ srv_release_mysql_thread_if_suspended( que_thr_t* thr); /* in: query thread associated with the MySQL OS thread */ /************************************************************************* -A thread which wakes up threads whose lock wait may have lasted too long. -This also prints the info output by various InnoDB monitors. */ +A thread which wakes up threads whose lock wait may have lasted too +long. */ os_thread_ret_t -srv_lock_timeout_and_monitor_thread( -/*================================*/ +srv_lock_timeout_thread( +/*====================*/ + /* out: a dummy parameter */ + void* arg); /* in: a dummy parameter required by + os_thread_create */ +/************************************************************************* +A thread which prints the info output by various InnoDB monitors. */ + +os_thread_ret_t +srv_monitor_thread( +/*===============*/ /* out: a dummy parameter */ void* arg); /* in: a dummy parameter required by os_thread_create */ @@ -449,10 +459,14 @@ srv_error_monitor_thread( /********************************************************************** Outputs to a file the output of the InnoDB Monitor. */ -void +ibool srv_printf_innodb_monitor( /*======================*/ + /* out: FALSE if not all information printed + due to failure to obtain necessary mutex */ FILE* file, /* in: output stream */ + ibool nowait, /* in: whether to wait for kernel + mutex. */ ulint* trx_start, /* out: file position of the start of the list of active transactions */ ulint* trx_end); /* out: file position of the end of diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 80aef45ea35..4cc10931060 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -4192,12 +4192,27 @@ lock_get_n_rec_locks(void) /************************************************************************* Prints info of locks for all transactions. */ -void +ibool lock_print_info_summary( /*====================*/ - FILE* file) /* in: file where to print */ + /* out: FALSE if not able to obtain + kernel mutex and exit without + printing lock info */ + FILE* file, /* in: file where to print */ + ibool nowait) /* in: whether to wait for the kernel + mutex */ { - lock_mutex_enter_kernel(); + + /* if nowait is FALSE, wait on the kernel mutex, + otherwise return immediately if fail to obtain the + mutex. */ + if (!nowait) { + lock_mutex_enter_kernel(); + } else if (mutex_enter_nowait(&kernel_mutex)) { + fputs("FAIL TO OBTAIN KERNEL MUTEX, " + "SKIP LOCK INFO PRINTING\n", file); + return(FALSE); + } if (lock_deadlock_found) { fputs("------------------------\n" @@ -4231,6 +4246,7 @@ lock_print_info_summary( "Total number of lock structs in row lock hash table %lu\n", (ulong) lock_get_n_rec_locks()); #endif /* PRINT_NUM_OF_LOCK_STRUCTS */ + return(TRUE); } /************************************************************************* diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c index b10c348b24d..3300997112b 100644 --- a/storage/innobase/log/log0log.c +++ b/storage/innobase/log/log0log.c @@ -3045,7 +3045,7 @@ loop: if (srv_fast_shutdown < 2 && (srv_error_monitor_active - || srv_lock_timeout_and_monitor_active)) { + || srv_lock_timeout_active || srv_monitor_active)) { mutex_exit(&kernel_mutex); diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 71e74ab848b..26ea7958d0d 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -64,7 +64,8 @@ ulint srv_fatal_semaphore_wait_threshold = 600; in microseconds, in order to reduce the lagging of the purge thread. */ ulint srv_dml_needed_delay = 0; -ibool srv_lock_timeout_and_monitor_active = FALSE; +ibool srv_lock_timeout_active = FALSE; +ibool srv_monitor_active = FALSE; ibool srv_error_monitor_active = FALSE; const char* srv_main_thread_op_info = ""; @@ -122,6 +123,16 @@ ulint srv_log_file_size = ULINT_MAX; /* size in database pages */ ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */ ulong srv_flush_log_at_trx_commit = 1; +/* Maximum number of times allowed to conditionally acquire +mutex before switching to blocking wait on the mutex */ +#define MAX_MUTEX_NOWAIT 20 + +/* Check whether the number of failed nonblocking mutex +acquisition attempts exceeds maximum allowed value. If so, +srv_printf_innodb_monitor() will request mutex acquisition +with mutex_enter(), which will wait until it gets the mutex. */ +#define MUTEX_NOWAIT(mutex_skipped) ((mutex_skipped) < MAX_MUTEX_NOWAIT) + byte srv_latin1_ordering[256] /* The sort order table of the latin1 character set. The following table is the MySQL order as of Feb 10th, 2002 */ @@ -1626,10 +1637,13 @@ srv_refresh_innodb_monitor_stats(void) /********************************************************************** Outputs to a file the output of the InnoDB Monitor. */ -void +ibool srv_printf_innodb_monitor( /*======================*/ + /* out: FALSE if not all information printed + due to failure to obtain necessary mutex */ FILE* file, /* in: output stream */ + ibool nowait, /* in: whether to wait for the mutex. */ ulint* trx_start, /* out: file position of the start of the list of active transactions */ ulint* trx_end) /* out: file position of the end of @@ -1638,6 +1652,7 @@ srv_printf_innodb_monitor( double time_elapsed; time_t current_time; ulint n_reserved; + ibool ret; mutex_enter(&srv_innodb_monitor_mutex); @@ -1682,24 +1697,31 @@ srv_printf_innodb_monitor( mutex_exit(&dict_foreign_err_mutex); - lock_print_info_summary(file); - if (trx_start) { - long t = ftell(file); - if (t < 0) { - *trx_start = ULINT_UNDEFINED; - } else { - *trx_start = (ulint) t; - } - } - lock_print_info_all_transactions(file); - if (trx_end) { - long t = ftell(file); - if (t < 0) { - *trx_end = ULINT_UNDEFINED; - } else { - *trx_end = (ulint) t; + /* Only if lock_print_info_summary proceeds correctly, + before we call the lock_print_info_all_transactions + to print all the lock information. */ + ret = lock_print_info_summary(file, nowait); + + if (ret) { + if (trx_start) { + long t = ftell(file); + if (t < 0) { + *trx_start = ULINT_UNDEFINED; + } else { + *trx_start = (ulint) t; + } + } + lock_print_info_all_transactions(file); + if (trx_end) { + long t = ftell(file); + if (t < 0) { + *trx_end = ULINT_UNDEFINED; + } else { + *trx_end = (ulint) t; + } } } + fputs("--------\n" "FILE I/O\n" "--------\n", file); @@ -1804,6 +1826,8 @@ srv_printf_innodb_monitor( "============================\n", file); mutex_exit(&srv_innodb_monitor_mutex); fflush(file); + + return(ret); } /********************************************************************** @@ -1883,26 +1907,23 @@ srv_export_innodb_status(void) } /************************************************************************* -A thread which wakes up threads whose lock wait may have lasted too long. -This also prints the info output by various InnoDB monitors. */ +A thread prints the info output by various InnoDB monitors. */ os_thread_ret_t -srv_lock_timeout_and_monitor_thread( -/*================================*/ +srv_monitor_thread( +/*===============*/ /* out: a dummy parameter */ void* arg __attribute__((unused))) /* in: a dummy parameter required by os_thread_create */ { - srv_slot_t* slot; double time_elapsed; time_t current_time; time_t last_table_monitor_time; time_t last_tablespace_monitor_time; time_t last_monitor_time; - ibool some_waits; - double wait_time; - ulint i; + ulint mutex_skipped; + ibool last_srv_print_monitor; #ifdef UNIV_DEBUG_THREAD_CREATION fprintf(stderr, "Lock timeout thread starts, id %lu\n", @@ -1913,13 +1934,15 @@ srv_lock_timeout_and_monitor_thread( last_table_monitor_time = time(NULL); last_tablespace_monitor_time = time(NULL); last_monitor_time = time(NULL); + mutex_skipped = 0; + last_srv_print_monitor = srv_print_innodb_monitor; loop: - srv_lock_timeout_and_monitor_active = TRUE; + srv_monitor_active = TRUE; - /* When someone is waiting for a lock, we wake up every second - and check if a timeout has passed for a lock wait */ + /* Wake up every 5 seconds to see if we need to print + monitor information. */ - os_thread_sleep(1000000); + os_thread_sleep(5000000); current_time = time(NULL); @@ -1929,14 +1952,40 @@ loop: last_monitor_time = time(NULL); if (srv_print_innodb_monitor) { - srv_printf_innodb_monitor(stderr, NULL, NULL); + /* Reset mutex_skipped counter everytime + srv_print_innodb_monitor changes. This is to + ensure we will not be blocked by kernel_mutex + for short duration information printing, + such as requested by sync_array_print_long_waits() */ + if (!last_srv_print_monitor) { + mutex_skipped = 0; + last_srv_print_monitor = TRUE; + } + + if (!srv_printf_innodb_monitor(stderr, + MUTEX_NOWAIT(mutex_skipped), + NULL, NULL)) { + mutex_skipped++; + } else { + /* Reset the counter */ + mutex_skipped = 0; + } + } else { + last_srv_print_monitor = FALSE; } + if (srv_innodb_status) { mutex_enter(&srv_monitor_file_mutex); rewind(srv_monitor_file); - srv_printf_innodb_monitor(srv_monitor_file, NULL, - NULL); + if (!srv_printf_innodb_monitor(srv_monitor_file, + MUTEX_NOWAIT(mutex_skipped), + NULL, NULL)) { + mutex_skipped++; + } else { + mutex_skipped = 0; + } + os_file_set_eof(srv_monitor_file); mutex_exit(&srv_monitor_file_mutex); } @@ -1989,6 +2038,56 @@ loop: } } + if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) { + goto exit_func; + } + + if (srv_print_innodb_monitor + || srv_print_innodb_lock_monitor + || srv_print_innodb_tablespace_monitor + || srv_print_innodb_table_monitor) { + goto loop; + } + + srv_monitor_active = FALSE; + + goto loop; + +exit_func: + srv_monitor_active = FALSE; + + /* We count the number of threads in os_thread_exit(). A created + thread should always use that to exit and not use return() to exit. */ + + os_thread_exit(NULL); + + OS_THREAD_DUMMY_RETURN; +} + +/************************************************************************* +A thread which wakes up threads whose lock wait may have lasted too long. */ + +os_thread_ret_t +srv_lock_timeout_thread( +/*====================*/ + /* out: a dummy parameter */ + void* arg __attribute__((unused))) + /* in: a dummy parameter required by + os_thread_create */ +{ + srv_slot_t* slot; + ibool some_waits; + double wait_time; + ulint i; + +loop: + /* When someone is waiting for a lock, we wake up every second + and check if a timeout has passed for a lock wait */ + + os_thread_sleep(1000000); + + srv_lock_timeout_active = TRUE; + mutex_enter(&kernel_mutex); some_waits = FALSE; @@ -2033,17 +2132,11 @@ loop: goto exit_func; } - if (some_waits || srv_print_innodb_monitor - || srv_print_innodb_lock_monitor - || srv_print_innodb_tablespace_monitor - || srv_print_innodb_table_monitor) { + if (some_waits) { goto loop; } - /* No one was waiting for a lock and no monitor was active: - suspend this thread */ - - srv_lock_timeout_and_monitor_active = FALSE; + srv_lock_timeout_active = FALSE; #if 0 /* The following synchronisation is disabled, since @@ -2053,7 +2146,7 @@ loop: goto loop; exit_func: - srv_lock_timeout_and_monitor_active = FALSE; + srv_lock_timeout_active = FALSE; /* We count the number of threads in os_thread_exit(). A created thread should always use that to exit and not use return() to exit. */ diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c index ea88039f3dd..a7950473a17 100644 --- a/storage/innobase/srv/srv0start.c +++ b/storage/innobase/srv/srv0start.c @@ -87,8 +87,8 @@ static os_file_t files[1000]; static mutex_t ios_mutex; static ulint ios; -static ulint n[SRV_MAX_N_IO_THREADS + 5]; -static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5]; +static ulint n[SRV_MAX_N_IO_THREADS + 6]; +static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6]; /* We use this mutex to test the return value of pthread_mutex_trylock on successful locking. HP-UX does NOT return 0, though Linux et al do. */ @@ -1596,15 +1596,20 @@ innobase_start_or_create_for_mysql(void) /* fprintf(stderr, "Max allowed record size %lu\n", page_get_free_space_of_empty() / 2); */ - /* Create the thread which watches the timeouts for lock waits - and prints InnoDB monitor info */ + /* Create the thread which watches the timeouts for lock + waits */ - os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL, + os_thread_create(&srv_lock_timeout_thread, NULL, thread_ids + 2 + SRV_MAX_N_IO_THREADS); /* Create the thread which warns of long semaphore waits */ os_thread_create(&srv_error_monitor_thread, NULL, thread_ids + 3 + SRV_MAX_N_IO_THREADS); + + /* Create the thread which prints InnoDB monitor info */ + os_thread_create(&srv_monitor_thread, NULL, + thread_ids + 4 + SRV_MAX_N_IO_THREADS); + srv_was_started = TRUE; srv_is_being_started = FALSE; From f7c24a2e208b0b606d9671c4cecd90a8eeb1f2e2 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Wed, 23 Dec 2009 13:06:41 +0100 Subject: [PATCH 19/47] The "semisync" plugin file name has lost its introductory "lib", adapt the file lists for the subpackages. This is a part missing from the fix for bug#48351. --- support-files/mysql.spec.sh | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 271d0c39e55..d1f364766ea 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -715,8 +715,8 @@ fi %attr(755, root, root) %{_bindir}/resolveip %attr(755, root, root) %{_libdir}/mysql/plugin/ha_example.so* -%attr(755, root, root) %{_libdir}/mysql/plugin/libsemisync_master.so* -%attr(755, root, root) %{_libdir}/mysql/plugin/libsemisync_slave.so* +%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_master.so* +%attr(755, root, root) %{_libdir}/mysql/plugin/semisync_slave.so* %if %{WITH_TCMALLOC} %attr(755, root, root) %{_libdir}/mysql/%{malloc_lib_target} @@ -849,10 +849,10 @@ fi %{_libdir}/mysql/libz.la %{_libdir}/mysql/plugin/ha_example.a %{_libdir}/mysql/plugin/ha_example.la -%{_libdir}/mysql/plugin/libsemisync_master.a -%{_libdir}/mysql/plugin/libsemisync_master.la -%{_libdir}/mysql/plugin/libsemisync_slave.a -%{_libdir}/mysql/plugin/libsemisync_slave.la +%{_libdir}/mysql/plugin/semisync_master.a +%{_libdir}/mysql/plugin/semisync_master.la +%{_libdir}/mysql/plugin/semisync_slave.a +%{_libdir}/mysql/plugin/semisync_slave.la %files shared %defattr(-, root, root, 0755) @@ -882,6 +882,12 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Wed Dec 23 2009 Joerg Bruehe + +- The "semisync" plugin file name has lost its introductory "lib", + adapt the file lists for the subpackages. + This is a part missing from the fix for bug#48351. + * Tue Dec 22 2009 Joerg Bruehe - Change RPM file naming: From f62540ee25f23b89348068c01d6697714db276d7 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Wed, 23 Dec 2009 13:38:19 +0100 Subject: [PATCH 20/47] Backport a fix from "trunk" into 5.5.1 which came after cloning only. Original comment: revno: 2930 | revision-id: alik@sun.com-20091223120351-m6l2t721tvtsiumu | parent: alik@sun.com-20091223104155-cq3uw9l2yvg6jmgc | committer: Alexander Nozdrin | branch nick: mysql-trunk-bugfixing | timestamp: Wed 2009-12-23 15:03:51 +0300 | message: | Backporting fix for Bug#49834 from mysql-next-mr-bugfixing | into mysql-trunk-bugfixing. | | Original revision: | ------------------------------------------------------------ | revision-id: vvaintroub@mysql.com-20091222115311-bam0xorumd8gvjyo | parent: mattias.jonsson@sun.com-20091221104426-x2e6c93x8iik4fo0 | committer: Vladislav Vaintroub | branch nick: mysql-next-mr-bugfixing | timestamp: Tue 2009-12-22 12:53:11 +0100 | message: | Bug#49834 - fixed a bug introduced by mismerge. | restore original innobase version --- storage/innobase/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt index 3f9808a2022..b63ed840f3c 100644 --- a/storage/innobase/CMakeLists.txt +++ b/storage/innobase/CMakeLists.txt @@ -86,5 +86,10 @@ IF (MYSQL_VERSION_ID GREATER "50137") SET_TARGET_PROPERTIES(ha_innobase PROPERTIES OUTPUT_NAME ha_innodb) ENDIF(LIB_LOCATION) ELSE (MYSQL_VERSION_ID GREATER "50137") - MYSQL_STORAGE_ENGINE(INNODB_PLUGIN) + IF (NOT SOURCE_SUBLIBS) + ADD_DEFINITIONS(-D_WIN32 -DMYSQL_SERVER) + ADD_LIBRARY(innobase STATIC ${INNOBASE_SOURCES}) + # Require mysqld_error.h, which is built as part of the GenError + ADD_DEPENDENCIES(innobase GenError) + ENDIF (NOT SOURCE_SUBLIBS) ENDIF (MYSQL_VERSION_ID GREATER "50137") From 3be15fa67c0d2d5cce990391832c42e4c4050417 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Wed, 23 Dec 2009 22:42:44 +0100 Subject: [PATCH 21/47] Remove the "fix_privilege_tables" manual from the RPM spec file, there is none in 5.5. --- support-files/mysql.spec.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index d1f364766ea..4e7f8cfcfb5 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -673,7 +673,7 @@ fi %doc %attr(644, root, man) %{_mandir}/man8/mysqld.8* %doc %attr(644, root, man) %{_mandir}/man1/mysqld_multi.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqld_safe.1* -%doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1* +#%doc %attr(644, root, man) %{_mandir}/man1/mysql_fix_privilege_tables.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_install_db.1* %doc %attr(644, root, man) %{_mandir}/man1/mysql_upgrade.1* %doc %attr(644, root, man) %{_mandir}/man1/mysqlhotcopy.1* @@ -887,6 +887,8 @@ fi - The "semisync" plugin file name has lost its introductory "lib", adapt the file lists for the subpackages. This is a part missing from the fix for bug#48351. +- Remove the "fix_privilege_tables" manual, it does not exist in 5.5 + (and likely, the whole script will go, too). * Tue Dec 22 2009 Joerg Bruehe From 416df0eaada5b644931f5b3b15f897a376641a4d Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 24 Dec 2009 15:20:58 +0000 Subject: [PATCH 22/47] BUG#48738: post-push fix. Multi-platform test improvements, mainly to make the test run gracefully on windows. There was also a syntax error in windows part of the test. --- .../r/binlog_delete_and_flush_index.result | 14 ++- .../t/binlog_delete_and_flush_index.test | 95 ++++--------------- 2 files changed, 29 insertions(+), 80 deletions(-) diff --git a/mysql-test/r/binlog_delete_and_flush_index.result b/mysql-test/r/binlog_delete_and_flush_index.result index 153900f3081..7500c17759c 100644 --- a/mysql-test/r/binlog_delete_and_flush_index.result +++ b/mysql-test/r/binlog_delete_and_flush_index.result @@ -2,7 +2,9 @@ RESET MASTER; CREATE TABLE t1 (a int); ### assertion: index file contains regular entries SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); -master-bin.000001 +SELECT @index; +@index +MYSQLD_DATADIR/master-bin.000001 ### assertion: show original binlogs show binary logs; @@ -15,8 +17,10 @@ master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a int) FLUSH LOGS; ### assertion: index file contains renamed binlog and the new one SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); -master-bin-b34582.000001 -master-bin.000002 +SELECT @index; +@index +MYSQLD_DATADIR/master-bin-b34582.000001 +MYSQLD_DATADIR/master-bin.000002 ### assertion: original binlog content still exists, despite we ### renamed and changed the index file @@ -39,6 +43,8 @@ master-bin.000002 # ### assertion: assert that not purged binlog file exists ### assertion: show index file contents and these should match show binary logs issued above SET @index=LOAD_FILE('MYSQLD_DATADIR/master-bin.index'); -master-bin.000002 +SELECT @index; +@index +MYSQLD_DATADIR/master-bin.000002 RESET MASTER; diff --git a/mysql-test/t/binlog_delete_and_flush_index.test b/mysql-test/t/binlog_delete_and_flush_index.test index 6784043386d..2899b96e317 100644 --- a/mysql-test/t/binlog_delete_and_flush_index.test +++ b/mysql-test/t/binlog_delete_and_flush_index.test @@ -45,31 +45,10 @@ RESET MASTER; CREATE TABLE t1 (a int); -- echo ### assertion: index file contains regular entries --- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- replace_result $datadir MYSQLD_DATADIR -- eval SET @index=LOAD_FILE('$index') -if (`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a - -} -if (!`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a -} +-- replace_result $datadir MYSQLD_DATADIR +SELECT @index; --echo ### assertion: show original binlogs -- source include/show_binary_logs.inc @@ -79,17 +58,23 @@ if (!`SELECT convert(@@version_compile_os using latin1) # action: copy binlogs to other names and change entries in index file -- copy_file $datadir/master-bin.000001 $datadir/master-bin-b34582.000001 --- let newbinfile=$datadir/master-bin-b34582.000001 -let INDEX_FILE=$index; +-- let newbinfile= $datadir/master-bin-b34582.000001 +-- let INDEX_FILE= $index perl; -$newbinfile= $ENV{'newbinfile'}; +use File::Spec; +$newbinfile= File::Spec->rel2abs($ENV{'newbinfile'}); $file= $ENV{'INDEX_FILE'}; open(FILE, ">$file") || die "Unable to open $file."; truncate(FILE,0); -print FILE $newbinfile . "\n"; +print FILE "$newbinfile"; close ($file); EOF +# append a new line (platform independent) +-- append_file $index + +EOF + # action: should cause rotation, and creation of new binlogs FLUSH LOGS; @@ -97,31 +82,10 @@ FLUSH LOGS; -- remove_file $datadir/master-bin.000001 -- echo ### assertion: index file contains renamed binlog and the new one --- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- replace_result $datadir MYSQLD_DATADIR -- eval SET @index=LOAD_FILE('$index') -if (`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a - -} -if (!`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a -} +-- replace_result $datadir MYSQLD_DATADIR +SELECT @index; -- echo ### assertion: original binlog content still exists, despite we -- echo ### renamed and changed the index file @@ -147,30 +111,9 @@ DROP TABLE t1; -- file_exists $datadir/$current_binlog -- echo ### assertion: show index file contents and these should match show binary logs issued above --- replace_regex /[\\\/].*master/MYSQLD_DATADIR\/master/ +-- replace_result $datadir MYSQLD_DATADIR -- eval SET @index=LOAD_FILE('$index') -if (`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir\', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a - -} -if (!`SELECT convert(@@version_compile_os using latin1) - IN ('Win32','Win64','Windows')`) -{ - -- disable_query_log - -- disable_result_log - -- let $a= `SELECT REPLACE (@index, '$datadir/', '')` - -- enable_result_log - -- enable_query_log - - -- echo $a -} +-- replace_result $datadir MYSQLD_DATADIR +SELECT @index; RESET MASTER; From d54d0d3c3155c69aa4643ccf95e2f553add6aff7 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Fri, 25 Dec 2009 17:02:08 +0100 Subject: [PATCH 23/47] Backport into the 5.5.1-m2 release build: | Bug#49898 - Fix for bug#37408 introduces a linker error | | the declaration of THR_LOCK_myisam_mmap in mi_static | is redundant as it accessible via the extern declaration | in include/myisam.h storage/myisam/mi_static.c: Bug#49898 - Fix for bug#37408 introduces a linker error Remove THR_LOCK_myisam_mmap declaration as it is redundant --- storage/myisam/mi_static.c | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/myisam/mi_static.c b/storage/myisam/mi_static.c index a43a099663b..27485e101ff 100644 --- a/storage/myisam/mi_static.c +++ b/storage/myisam/mi_static.c @@ -41,7 +41,6 @@ my_off_t myisam_max_temp_length= MAX_FILE_SIZE; ulong myisam_bulk_insert_tree_size=8192*1024; ulong myisam_data_pointer_size=4; ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0; -pthread_mutex_t THR_LOCK_myisam_mmap; static int always_valid(const char *filename __attribute__((unused))) { From e6e3b4abc3cb1b0b92dc862810d5571b8b20397f Mon Sep 17 00:00:00 2001 From: Alexey Kopytov Date: Mon, 28 Dec 2009 16:59:12 +0300 Subject: [PATCH 24/47] Fixed a build failure in mysql-trunk-merge caused by a bad merge from mysql-5.1-bugteam. --- sql/sp_head.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 130a1d3e742..6b62949f4fe 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2811,9 +2811,9 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, open_tables stage. */ if (!res || !thd->is_error() || - (thd->main_da.sql_errno() != ER_CANT_REOPEN_TABLE && - thd->main_da.sql_errno() != ER_NO_SUCH_TABLE && - thd->main_da.sql_errno() != ER_UPDATE_TABLE_USED)) + (thd->stmt_da->sql_errno() != ER_CANT_REOPEN_TABLE && + thd->stmt_da->sql_errno() != ER_NO_SUCH_TABLE && + thd->stmt_da->sql_errno() != ER_UPDATE_TABLE_USED)) thd->stmt_arena->state= Query_arena::EXECUTED; /* From 71061de025de2e9bffaaecdd182ad7f7ccd924d0 Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Wed, 30 Dec 2009 23:06:14 +0100 Subject: [PATCH 25/47] Removed unwanted Perl DBI dependency --- support-files/mysql.spec.sh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8209c4560c6..b6d822d8719 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -65,6 +65,19 @@ # See BUG#998 for details. %define _unpackaged_files_terminate_build 0 +# ------------------------------------------------------------------------------ +# RPM build tools now automatically detects Perl module dependencies. This +# detection gives problems as it is broken in some versions, and it also +# give unwanted dependencies from mandatory scripts in our package. +# Might not be possible to disable in all RPM tool versions, but here we +# try. We keep the "AutoReqProv: no" for the "test" sub package, as disabling +# here might fail, and that package has the most problems. +# See http://fedoraproject.org/wiki/Packaging/Perl#Filtering_Requires:_and_Provides +# http://www.wideopen.com/archives/rpm-list/2002-October/msg00343.html +# ------------------------------------------------------------------------------ +%undefine __perl_provides +%undefine __perl_requires + %define see_base For a description of MySQL see the base MySQL RPM or http://www.mysql.com # On SuSE 9 no separate "debuginfo" package is built. To enable basic @@ -205,7 +218,7 @@ They should be used with caution. %endif %package test -Requires: %{name}-client perl-DBI perl +Requires: %{name}-client perl Summary: MySQL - Test suite Group: Applications/Databases Provides: mysql-test From 2b2ce3d6cb01a36cd35191e8670dcb023420c84e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 31 Dec 2009 11:33:10 +0800 Subject: [PATCH 26/47] Bug #49137 Replication failure on SBR/MBR + multi-table DROP TEMPORARY TABLE In statement-based or mixed-mode replication, use DROP TEMPORARY TABLE to drop multiple tables causes different errors on master and slave, when one or more of these tables do not exist. Because when executed on slave, it would automatically add IF EXISTS to the query to ignore all ER_BAD_TABLE_ERROR errors. To fix the problem, do not add IF EXISTS when executing DROP TEMPORARY TABLE on the slave, and clear the ER_BAD_TABLE_ERROR error after execution if the query does not expect any errors. mysql-test/r/rpl_drop_temp.result: Updated for the patch of bug#49137. mysql-test/t/rpl_drop_temp.test: Added the test file to verify if DROP MULTI TEMPORARY TABLE will cause different errors on master and slave, when one or more of these tables do not exist. sql/log_event.cc: Added code to handle above cases which are removed from sql_parse.cc sql/sql_parse.cc: Remove the code to issue the 'Unknown table' error, if the temporary table does not exist when dropping it on slave. The above cases decribed in comments will be handled later in log_event.cc. --- mysql-test/r/rpl_drop_temp.result | 14 +++++++++++++ mysql-test/t/rpl_drop_temp.test | 33 +++++++++++++++++++++++++++++++ sql/log_event.cc | 12 ++++++++++- sql/sql_parse.cc | 11 ----------- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/mysql-test/r/rpl_drop_temp.result b/mysql-test/r/rpl_drop_temp.result index fff179d7056..48a21b1702b 100644 --- a/mysql-test/r/rpl_drop_temp.result +++ b/mysql-test/r/rpl_drop_temp.result @@ -18,3 +18,17 @@ show status like 'Slave_open_temp_tables'; Variable_name Value Slave_open_temp_tables 0 drop database mysqltest; +DROP TEMPORARY TABLE IF EXISTS tmp1; +Warnings: +Note 1051 Unknown table 'tmp1' +CREATE TEMPORARY TABLE t1 ( a int ); +DROP TEMPORARY TABLE t1, t2; +ERROR 42S02: Unknown table 't2' +DROP TEMPORARY TABLE tmp2; +ERROR 42S02: Unknown table 'tmp2' +stop slave; +**** On Master **** +CREATE TEMPORARY TABLE tmp3 (a int); +DROP TEMPORARY TABLE tmp3; +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; diff --git a/mysql-test/t/rpl_drop_temp.test b/mysql-test/t/rpl_drop_temp.test index c22bcbe63d0..c2dc8b0ea49 100644 --- a/mysql-test/t/rpl_drop_temp.test +++ b/mysql-test/t/rpl_drop_temp.test @@ -20,5 +20,38 @@ connection slave; show status like 'Slave_open_temp_tables'; connection master; drop database mysqltest; +sync_slave_with_master; + +# +# Bug#49137 +# This test verifies if DROP MULTI TEMPORARY TABLE +# will cause different errors on master and slave, +# when one or more of these tables do not exist. +# + +connection master; +DROP TEMPORARY TABLE IF EXISTS tmp1; +CREATE TEMPORARY TABLE t1 ( a int ); +--error 1051 +DROP TEMPORARY TABLE t1, t2; +--error 1051 +DROP TEMPORARY TABLE tmp2; +sync_slave_with_master; + +connection slave; +stop slave; +wait_for_slave_to_stop; + +--echo **** On Master **** +connection master; +CREATE TEMPORARY TABLE tmp3 (a int); +DROP TEMPORARY TABLE tmp3; + +connection slave; +SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; +START SLAVE; + +connection master; +sync_slave_with_master; # End of 4.1 tests diff --git a/sql/log_event.cc b/sql/log_event.cc index 40e29e58ab6..35d53c4fede 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2103,7 +2103,17 @@ START SLAVE; . Query: '%s'", expected_error, thd->query); compare_errors: - /* + /* + In the slave thread, we may sometimes execute some DROP / * 40005 + TEMPORARY * / TABLE that come from parts of binlogs (likely if we + use RESET SLAVE or CHANGE MASTER TO), while the temporary table + has already been dropped. To ignore such irrelevant "table does + not exist errors", we silently clear the error if TEMPORARY was used. + */ + if (thd->lex->drop_temporary && + thd->net.last_errno == ER_BAD_TABLE_ERROR && !expected_error) + thd->clear_error(); + /* If we expected a non-zero error code, and we don't get the same error code, and none of them should be ignored. */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 48df40f2614..61c2d70a563 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4038,17 +4038,6 @@ end_with_restore_list: } else { - /* - If this is a slave thread, we may sometimes execute some - DROP / * 40005 TEMPORARY * / TABLE - that come from parts of binlogs (likely if we use RESET SLAVE or CHANGE - MASTER TO), while the temporary table has already been dropped. - To not generate such irrelevant "table does not exist errors", - we silently add IF EXISTS if TEMPORARY was used. - */ - if (thd->slave_thread) - lex->drop_if_exists= 1; - /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */ thd->transaction.all.modified_non_trans_table= TRUE; } From c55a0048cc31d1bd3e7968c00d1f70c30b2a1c75 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 4 Jan 2010 15:03:09 +0100 Subject: [PATCH 27/47] Ensure that the variable "MYSQL_U_SCORE_VERSION" is expanded whereever it is used (currently, only RPM spec files). --- support-files/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/support-files/Makefile.am b/support-files/Makefile.am index 47e8c395b31..f8f6b1bb5d4 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -120,6 +120,7 @@ SUFFIXES = .sh -e 's!@''SHARED_LIB_VERSION''@!@SHARED_LIB_VERSION@!' \ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \ + -e 's!@''MYSQL_U_SCORE_VERSION''@!@MYSQL_U_SCORE_VERSION@!' \ -e 's!@''MYSQL_COPYRIGHT_YEAR''@!@MYSQL_COPYRIGHT_YEAR@!' \ -e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \ -e 's!@''PERL_DBI_VERSION''@!@PERL_DBI_VERSION@!' \ From af27d4e2003a84a28007a99053aefecafd7ecd97 Mon Sep 17 00:00:00 2001 From: He Zhenxing Date: Tue, 5 Jan 2010 14:25:29 +0800 Subject: [PATCH 28/47] Bug#48776 row based replication breaks with spatial / geometry types, cause crashes! This bug is the same problem as Bug 49836 for 5.1 versions. mysql-test/suite/rpl/r/rpl_geometry.result: Test case for bug 48776 mysql-test/suite/rpl/t/rpl_geometry.test: Test case for bug 48776 sql/rpl_utility.h: Add missing case MYSQL_TYPE_GEOMETRY --- mysql-test/suite/rpl/r/rpl_geometry.result | 18 +++++++++++++++ mysql-test/suite/rpl/t/rpl_geometry.test | 26 ++++++++++++++++++++++ sql/rpl_utility.h | 1 + 3 files changed, 45 insertions(+) create mode 100644 mysql-test/suite/rpl/r/rpl_geometry.result create mode 100644 mysql-test/suite/rpl/t/rpl_geometry.test diff --git a/mysql-test/suite/rpl/r/rpl_geometry.result b/mysql-test/suite/rpl/r/rpl_geometry.result new file mode 100644 index 00000000000..9b48dba4f22 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_geometry.result @@ -0,0 +1,18 @@ +stop slave; +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; +start slave; +create table t1(a varchar(100), +b multipoint not null, +c varchar(256)); +insert into t1 set +a='hello', +b=geomfromtext('multipoint(1 1)'), +c='geometry'; +create table t2 (a int(11) not null auto_increment primary key, +b geometrycollection default null, +c decimal(10,0)); +insert into t2(c) values (null); +drop table t1, t2; diff --git a/mysql-test/suite/rpl/t/rpl_geometry.test b/mysql-test/suite/rpl/t/rpl_geometry.test new file mode 100644 index 00000000000..eac98924b98 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_geometry.test @@ -0,0 +1,26 @@ +source include/master-slave.inc; +source include/have_binlog_format_row.inc; + +# +# Bug#48776, Bug#43784 +# +create table t1(a varchar(100), + b multipoint not null, + c varchar(256)); + +insert into t1 set + a='hello', + b=geomfromtext('multipoint(1 1)'), + c='geometry'; + +create table t2 (a int(11) not null auto_increment primary key, + b geometrycollection default null, + c decimal(10,0)); + +insert into t2(c) values (null); + +sync_slave_with_master; + +connection master; +drop table t1, t2; +source include/master-slave-end.inc; diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 1f4ca246ff1..d011e9aade8 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -95,6 +95,7 @@ public: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_DOUBLE: case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_GEOMETRY: { /* These types store a single byte. From f8758031f37840b4b1cea4f4c3aa8736b7d68f88 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Wed, 6 Jan 2010 00:44:31 +0000 Subject: [PATCH 29/47] BUG#50018: binlog corruption when table has many columns For tables with metadata sizes ranging from 251 to 255 the size of the event data (m_data_size) was being improperly calculated in the Table_map_log_event constructor. This was due to the fact that when writing the Table_map_log_event body (in Table_map_log_event::write_data_body) a call to net_store_length is made for packing the m_field_metadata_size. It happens that net_store_length uses *one* byte for storing m_field_metadata_size when it is smaller than 251 but *three* bytes when it exceeds that value. BUG 42749 had already pinpointed and fix this fact, but the fix was incomplete, as the calculation in the Table_map_log_event constructor considers 255 instead of 251 as the threshold to increment m_data_size by three. Thence, the window for having a mismatch between the number of bytes written and the number of bytes accounted in the event length (m_data_size) was left open for m_field_metadata_size values between 251 and 255. We fix this by changing the condition in the Table_map_log_event constructor to match the one in the net_store_length, ie, increment one byte if m_field_metadata_size < 251 and three if it exceeds this value. mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result: Updated result file. mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test: Changes to the original test case: added slave and moved file into the rpl suite. New test case: replicates two tables one with 250 and another with 252 metadata sizes. This exercises the usage of 1 or 3 bytes while packing the m_field_metadata_size. sql/log_event.cc: Made the m_data_size calculation for the table map log event to match the number of bytes used while packing the m_field_metadata_size value (according to net_store_length function in pack.c). --- .../suite/binlog/r/binlog_tbl_metadata.result | 156 ------ .../suite/binlog/t/binlog_tbl_metadata.test | 199 ------- .../suite/rpl/r/rpl_row_tbl_metadata.result | 437 +++++++++++++++ .../suite/rpl/t/rpl_row_tbl_metadata.test | 520 ++++++++++++++++++ sql/log_event.cc | 6 +- 5 files changed, 960 insertions(+), 358 deletions(-) delete mode 100644 mysql-test/suite/binlog/r/binlog_tbl_metadata.result delete mode 100644 mysql-test/suite/binlog/t/binlog_tbl_metadata.test create mode 100644 mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result create mode 100644 mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test diff --git a/mysql-test/suite/binlog/r/binlog_tbl_metadata.result b/mysql-test/suite/binlog/r/binlog_tbl_metadata.result deleted file mode 100644 index a2f185edc85..00000000000 --- a/mysql-test/suite/binlog/r/binlog_tbl_metadata.result +++ /dev/null @@ -1,156 +0,0 @@ -RESET MASTER; -DROP TABLE IF EXISTS `t1`; -CREATE TABLE `t1` ( -`c1` int(11) NOT NULL AUTO_INCREMENT, -`c2` varchar(30) NOT NULL, -`c3` varchar(30) DEFAULT NULL, -`c4` varchar(30) DEFAULT NULL, -`c5` varchar(30) DEFAULT NULL, -`c6` varchar(30) DEFAULT NULL, -`c7` varchar(30) DEFAULT NULL, -`c8` varchar(30) DEFAULT NULL, -`c9` varchar(30) DEFAULT NULL, -`c10` varchar(30) DEFAULT NULL, -`c11` varchar(30) DEFAULT NULL, -`c12` varchar(30) DEFAULT NULL, -`c13` varchar(30) DEFAULT NULL, -`c14` varchar(30) DEFAULT NULL, -`c15` varchar(30) DEFAULT NULL, -`c16` varchar(30) DEFAULT NULL, -`c17` varchar(30) DEFAULT NULL, -`c18` varchar(30) DEFAULT NULL, -`c19` varchar(30) DEFAULT NULL, -`c20` varchar(30) DEFAULT NULL, -`c21` varchar(30) DEFAULT NULL, -`c22` varchar(30) DEFAULT NULL, -`c23` varchar(30) DEFAULT NULL, -`c24` varchar(30) DEFAULT NULL, -`c25` varchar(30) DEFAULT NULL, -`c26` varchar(30) DEFAULT NULL, -`c27` varchar(30) DEFAULT NULL, -`c28` varchar(30) DEFAULT NULL, -`c29` varchar(30) DEFAULT NULL, -`c30` varchar(30) DEFAULT NULL, -`c31` varchar(30) DEFAULT NULL, -`c32` varchar(30) DEFAULT NULL, -`c33` varchar(30) DEFAULT NULL, -`c34` varchar(30) DEFAULT NULL, -`c35` varchar(30) DEFAULT NULL, -`c36` varchar(30) DEFAULT NULL, -`c37` varchar(30) DEFAULT NULL, -`c38` varchar(30) DEFAULT NULL, -`c39` varchar(30) DEFAULT NULL, -`c40` varchar(30) DEFAULT NULL, -`c41` varchar(30) DEFAULT NULL, -`c42` varchar(30) DEFAULT NULL, -`c43` varchar(30) DEFAULT NULL, -`c44` varchar(30) DEFAULT NULL, -`c45` varchar(30) DEFAULT NULL, -`c46` varchar(30) DEFAULT NULL, -`c47` varchar(30) DEFAULT NULL, -`c48` varchar(30) DEFAULT NULL, -`c49` varchar(30) DEFAULT NULL, -`c50` varchar(30) DEFAULT NULL, -`c51` varchar(30) DEFAULT NULL, -`c52` varchar(30) DEFAULT NULL, -`c53` varchar(30) DEFAULT NULL, -`c54` varchar(30) DEFAULT NULL, -`c55` varchar(30) DEFAULT NULL, -`c56` varchar(30) DEFAULT NULL, -`c57` varchar(30) DEFAULT NULL, -`c58` varchar(30) DEFAULT NULL, -`c59` varchar(30) DEFAULT NULL, -`c60` varchar(30) DEFAULT NULL, -`c61` varchar(30) DEFAULT NULL, -`c62` varchar(30) DEFAULT NULL, -`c63` varchar(30) DEFAULT NULL, -`c64` varchar(30) DEFAULT NULL, -`c65` varchar(30) DEFAULT NULL, -`c66` varchar(30) DEFAULT NULL, -`c67` varchar(30) DEFAULT NULL, -`c68` varchar(30) DEFAULT NULL, -`c69` varchar(30) DEFAULT NULL, -`c70` varchar(30) DEFAULT NULL, -`c71` varchar(30) DEFAULT NULL, -`c72` varchar(30) DEFAULT NULL, -`c73` varchar(30) DEFAULT NULL, -`c74` varchar(30) DEFAULT NULL, -`c75` varchar(30) DEFAULT NULL, -`c76` varchar(30) DEFAULT NULL, -`c77` varchar(30) DEFAULT NULL, -`c78` varchar(30) DEFAULT NULL, -`c79` varchar(30) DEFAULT NULL, -`c80` varchar(30) DEFAULT NULL, -`c81` varchar(30) DEFAULT NULL, -`c82` varchar(30) DEFAULT NULL, -`c83` varchar(30) DEFAULT NULL, -`c84` varchar(30) DEFAULT NULL, -`c85` varchar(30) DEFAULT NULL, -`c86` varchar(30) DEFAULT NULL, -`c87` varchar(30) DEFAULT NULL, -`c88` varchar(30) DEFAULT NULL, -`c89` varchar(30) DEFAULT NULL, -`c90` varchar(30) DEFAULT NULL, -`c91` varchar(30) DEFAULT NULL, -`c92` varchar(30) DEFAULT NULL, -`c93` varchar(30) DEFAULT NULL, -`c94` varchar(30) DEFAULT NULL, -`c95` varchar(30) DEFAULT NULL, -`c96` varchar(30) DEFAULT NULL, -`c97` varchar(30) DEFAULT NULL, -`c98` varchar(30) DEFAULT NULL, -`c99` varchar(30) DEFAULT NULL, -`c100` varchar(30) DEFAULT NULL, -`c101` varchar(30) DEFAULT NULL, -`c102` varchar(30) DEFAULT NULL, -`c103` varchar(30) DEFAULT NULL, -`c104` varchar(30) DEFAULT NULL, -`c105` varchar(30) DEFAULT NULL, -`c106` varchar(30) DEFAULT NULL, -`c107` varchar(30) DEFAULT NULL, -`c108` varchar(30) DEFAULT NULL, -`c109` varchar(30) DEFAULT NULL, -`c110` varchar(30) DEFAULT NULL, -`c111` varchar(30) DEFAULT NULL, -`c112` varchar(30) DEFAULT NULL, -`c113` varchar(30) DEFAULT NULL, -`c114` varchar(30) DEFAULT NULL, -`c115` varchar(30) DEFAULT NULL, -`c116` varchar(30) DEFAULT NULL, -`c117` varchar(30) DEFAULT NULL, -`c118` varchar(30) DEFAULT NULL, -`c119` varchar(30) DEFAULT NULL, -`c120` varchar(30) DEFAULT NULL, -`c121` varchar(30) DEFAULT NULL, -`c122` varchar(30) DEFAULT NULL, -`c123` varchar(30) DEFAULT NULL, -`c124` varchar(30) DEFAULT NULL, -`c125` varchar(30) DEFAULT NULL, -`c126` varchar(30) DEFAULT NULL, -`c127` varchar(30) DEFAULT NULL, -`c128` varchar(30) DEFAULT NULL, -`c129` varchar(30) DEFAULT NULL, -`c130` varchar(30) DEFAULT NULL, -`c131` varchar(30) DEFAULT NULL, -`c132` varchar(30) DEFAULT NULL, -`c133` varchar(30) DEFAULT NULL, -`c134` varchar(30) DEFAULT NULL, -`c135` varchar(30) DEFAULT NULL, -`c136` varchar(30) DEFAULT NULL, -`c137` varchar(30) DEFAULT NULL, -`c138` varchar(30) DEFAULT NULL, -`c139` varchar(30) DEFAULT NULL, -`c140` varchar(30) DEFAULT NULL, -`c141` varchar(30) DEFAULT NULL, -`c142` varchar(30) DEFAULT NULL, -`c143` varchar(30) DEFAULT NULL, -`c144` varchar(30) DEFAULT NULL, -`c145` varchar(30) DEFAULT NULL, -`c146` varchar(30) DEFAULT NULL, -PRIMARY KEY (`c1`) -) ENGINE=InnoDB; -LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); -DROP TABLE `t1`; -FLUSH LOGS; -=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. diff --git a/mysql-test/suite/binlog/t/binlog_tbl_metadata.test b/mysql-test/suite/binlog/t/binlog_tbl_metadata.test deleted file mode 100644 index 5e847ab5fbd..00000000000 --- a/mysql-test/suite/binlog/t/binlog_tbl_metadata.test +++ /dev/null @@ -1,199 +0,0 @@ -# -# BUG#42749: infinite loop writing to row based binlog - processlist shows -# "freeing items" -# -# WHY -# === -# -# This bug would make table map event to report data_written one byte less -# than what would actually be written in its body. This would cause one byte shorter -# event end_log_pos. The ultimate impact was that it would make fixing the -# position in MYSQL_BIN_LOG::write_cache bogus or end up in an infinite loop. -# -# HOW -# === -# -# Checking that the patch fixes the problem is done as follows: -# i) a table with several fields is created; -# ii) an insert is performed; -# iii) the logs are flushed; -# iv) mysqlbinlog is used to check if it succeeds. -# -# In step iv), before the bug was fixed, the test case would fail with -# mysqlbinlog reporting that it was unable to succeed in reading the event. -# - --- source include/have_log_bin.inc --- source include/have_innodb.inc --- source include/have_binlog_format_row.inc --- connection default - -RESET MASTER; - --- disable_warnings -DROP TABLE IF EXISTS `t1`; --- enable_warnings - -CREATE TABLE `t1` ( - `c1` int(11) NOT NULL AUTO_INCREMENT, - `c2` varchar(30) NOT NULL, - `c3` varchar(30) DEFAULT NULL, - `c4` varchar(30) DEFAULT NULL, - `c5` varchar(30) DEFAULT NULL, - `c6` varchar(30) DEFAULT NULL, - `c7` varchar(30) DEFAULT NULL, - `c8` varchar(30) DEFAULT NULL, - `c9` varchar(30) DEFAULT NULL, - `c10` varchar(30) DEFAULT NULL, - `c11` varchar(30) DEFAULT NULL, - `c12` varchar(30) DEFAULT NULL, - `c13` varchar(30) DEFAULT NULL, - `c14` varchar(30) DEFAULT NULL, - `c15` varchar(30) DEFAULT NULL, - `c16` varchar(30) DEFAULT NULL, - `c17` varchar(30) DEFAULT NULL, - `c18` varchar(30) DEFAULT NULL, - `c19` varchar(30) DEFAULT NULL, - `c20` varchar(30) DEFAULT NULL, - `c21` varchar(30) DEFAULT NULL, - `c22` varchar(30) DEFAULT NULL, - `c23` varchar(30) DEFAULT NULL, - `c24` varchar(30) DEFAULT NULL, - `c25` varchar(30) DEFAULT NULL, - `c26` varchar(30) DEFAULT NULL, - `c27` varchar(30) DEFAULT NULL, - `c28` varchar(30) DEFAULT NULL, - `c29` varchar(30) DEFAULT NULL, - `c30` varchar(30) DEFAULT NULL, - `c31` varchar(30) DEFAULT NULL, - `c32` varchar(30) DEFAULT NULL, - `c33` varchar(30) DEFAULT NULL, - `c34` varchar(30) DEFAULT NULL, - `c35` varchar(30) DEFAULT NULL, - `c36` varchar(30) DEFAULT NULL, - `c37` varchar(30) DEFAULT NULL, - `c38` varchar(30) DEFAULT NULL, - `c39` varchar(30) DEFAULT NULL, - `c40` varchar(30) DEFAULT NULL, - `c41` varchar(30) DEFAULT NULL, - `c42` varchar(30) DEFAULT NULL, - `c43` varchar(30) DEFAULT NULL, - `c44` varchar(30) DEFAULT NULL, - `c45` varchar(30) DEFAULT NULL, - `c46` varchar(30) DEFAULT NULL, - `c47` varchar(30) DEFAULT NULL, - `c48` varchar(30) DEFAULT NULL, - `c49` varchar(30) DEFAULT NULL, - `c50` varchar(30) DEFAULT NULL, - `c51` varchar(30) DEFAULT NULL, - `c52` varchar(30) DEFAULT NULL, - `c53` varchar(30) DEFAULT NULL, - `c54` varchar(30) DEFAULT NULL, - `c55` varchar(30) DEFAULT NULL, - `c56` varchar(30) DEFAULT NULL, - `c57` varchar(30) DEFAULT NULL, - `c58` varchar(30) DEFAULT NULL, - `c59` varchar(30) DEFAULT NULL, - `c60` varchar(30) DEFAULT NULL, - `c61` varchar(30) DEFAULT NULL, - `c62` varchar(30) DEFAULT NULL, - `c63` varchar(30) DEFAULT NULL, - `c64` varchar(30) DEFAULT NULL, - `c65` varchar(30) DEFAULT NULL, - `c66` varchar(30) DEFAULT NULL, - `c67` varchar(30) DEFAULT NULL, - `c68` varchar(30) DEFAULT NULL, - `c69` varchar(30) DEFAULT NULL, - `c70` varchar(30) DEFAULT NULL, - `c71` varchar(30) DEFAULT NULL, - `c72` varchar(30) DEFAULT NULL, - `c73` varchar(30) DEFAULT NULL, - `c74` varchar(30) DEFAULT NULL, - `c75` varchar(30) DEFAULT NULL, - `c76` varchar(30) DEFAULT NULL, - `c77` varchar(30) DEFAULT NULL, - `c78` varchar(30) DEFAULT NULL, - `c79` varchar(30) DEFAULT NULL, - `c80` varchar(30) DEFAULT NULL, - `c81` varchar(30) DEFAULT NULL, - `c82` varchar(30) DEFAULT NULL, - `c83` varchar(30) DEFAULT NULL, - `c84` varchar(30) DEFAULT NULL, - `c85` varchar(30) DEFAULT NULL, - `c86` varchar(30) DEFAULT NULL, - `c87` varchar(30) DEFAULT NULL, - `c88` varchar(30) DEFAULT NULL, - `c89` varchar(30) DEFAULT NULL, - `c90` varchar(30) DEFAULT NULL, - `c91` varchar(30) DEFAULT NULL, - `c92` varchar(30) DEFAULT NULL, - `c93` varchar(30) DEFAULT NULL, - `c94` varchar(30) DEFAULT NULL, - `c95` varchar(30) DEFAULT NULL, - `c96` varchar(30) DEFAULT NULL, - `c97` varchar(30) DEFAULT NULL, - `c98` varchar(30) DEFAULT NULL, - `c99` varchar(30) DEFAULT NULL, - `c100` varchar(30) DEFAULT NULL, - `c101` varchar(30) DEFAULT NULL, - `c102` varchar(30) DEFAULT NULL, - `c103` varchar(30) DEFAULT NULL, - `c104` varchar(30) DEFAULT NULL, - `c105` varchar(30) DEFAULT NULL, - `c106` varchar(30) DEFAULT NULL, - `c107` varchar(30) DEFAULT NULL, - `c108` varchar(30) DEFAULT NULL, - `c109` varchar(30) DEFAULT NULL, - `c110` varchar(30) DEFAULT NULL, - `c111` varchar(30) DEFAULT NULL, - `c112` varchar(30) DEFAULT NULL, - `c113` varchar(30) DEFAULT NULL, - `c114` varchar(30) DEFAULT NULL, - `c115` varchar(30) DEFAULT NULL, - `c116` varchar(30) DEFAULT NULL, - `c117` varchar(30) DEFAULT NULL, - `c118` varchar(30) DEFAULT NULL, - `c119` varchar(30) DEFAULT NULL, - `c120` varchar(30) DEFAULT NULL, - `c121` varchar(30) DEFAULT NULL, - `c122` varchar(30) DEFAULT NULL, - `c123` varchar(30) DEFAULT NULL, - `c124` varchar(30) DEFAULT NULL, - `c125` varchar(30) DEFAULT NULL, - `c126` varchar(30) DEFAULT NULL, - `c127` varchar(30) DEFAULT NULL, - `c128` varchar(30) DEFAULT NULL, - `c129` varchar(30) DEFAULT NULL, - `c130` varchar(30) DEFAULT NULL, - `c131` varchar(30) DEFAULT NULL, - `c132` varchar(30) DEFAULT NULL, - `c133` varchar(30) DEFAULT NULL, - `c134` varchar(30) DEFAULT NULL, - `c135` varchar(30) DEFAULT NULL, - `c136` varchar(30) DEFAULT NULL, - `c137` varchar(30) DEFAULT NULL, - `c138` varchar(30) DEFAULT NULL, - `c139` varchar(30) DEFAULT NULL, - `c140` varchar(30) DEFAULT NULL, - `c141` varchar(30) DEFAULT NULL, - `c142` varchar(30) DEFAULT NULL, - `c143` varchar(30) DEFAULT NULL, - `c144` varchar(30) DEFAULT NULL, - `c145` varchar(30) DEFAULT NULL, - `c146` varchar(30) DEFAULT NULL, - PRIMARY KEY (`c1`) -) ENGINE=InnoDB; - -LOCK TABLES `t1` WRITE; - -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); - -DROP TABLE `t1`; - -FLUSH LOGS; - --- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. - --- let $MYSQLD_DATADIR= `SELECT @@datadir`; --- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog --- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog diff --git a/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result new file mode 100644 index 00000000000..551ece5da9d --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result @@ -0,0 +1,437 @@ +stop slave; +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; +start slave; +RESET MASTER; +DROP TABLE IF EXISTS `t1`; +### TABLE with field_metadata_size == 290 +CREATE TABLE `t1` ( +`c1` int(11) NOT NULL AUTO_INCREMENT, +`c2` varchar(30) NOT NULL, +`c3` varchar(30) DEFAULT NULL, +`c4` varchar(30) DEFAULT NULL, +`c5` varchar(30) DEFAULT NULL, +`c6` varchar(30) DEFAULT NULL, +`c7` varchar(30) DEFAULT NULL, +`c8` varchar(30) DEFAULT NULL, +`c9` varchar(30) DEFAULT NULL, +`c10` varchar(30) DEFAULT NULL, +`c11` varchar(30) DEFAULT NULL, +`c12` varchar(30) DEFAULT NULL, +`c13` varchar(30) DEFAULT NULL, +`c14` varchar(30) DEFAULT NULL, +`c15` varchar(30) DEFAULT NULL, +`c16` varchar(30) DEFAULT NULL, +`c17` varchar(30) DEFAULT NULL, +`c18` varchar(30) DEFAULT NULL, +`c19` varchar(30) DEFAULT NULL, +`c20` varchar(30) DEFAULT NULL, +`c21` varchar(30) DEFAULT NULL, +`c22` varchar(30) DEFAULT NULL, +`c23` varchar(30) DEFAULT NULL, +`c24` varchar(30) DEFAULT NULL, +`c25` varchar(30) DEFAULT NULL, +`c26` varchar(30) DEFAULT NULL, +`c27` varchar(30) DEFAULT NULL, +`c28` varchar(30) DEFAULT NULL, +`c29` varchar(30) DEFAULT NULL, +`c30` varchar(30) DEFAULT NULL, +`c31` varchar(30) DEFAULT NULL, +`c32` varchar(30) DEFAULT NULL, +`c33` varchar(30) DEFAULT NULL, +`c34` varchar(30) DEFAULT NULL, +`c35` varchar(30) DEFAULT NULL, +`c36` varchar(30) DEFAULT NULL, +`c37` varchar(30) DEFAULT NULL, +`c38` varchar(30) DEFAULT NULL, +`c39` varchar(30) DEFAULT NULL, +`c40` varchar(30) DEFAULT NULL, +`c41` varchar(30) DEFAULT NULL, +`c42` varchar(30) DEFAULT NULL, +`c43` varchar(30) DEFAULT NULL, +`c44` varchar(30) DEFAULT NULL, +`c45` varchar(30) DEFAULT NULL, +`c46` varchar(30) DEFAULT NULL, +`c47` varchar(30) DEFAULT NULL, +`c48` varchar(30) DEFAULT NULL, +`c49` varchar(30) DEFAULT NULL, +`c50` varchar(30) DEFAULT NULL, +`c51` varchar(30) DEFAULT NULL, +`c52` varchar(30) DEFAULT NULL, +`c53` varchar(30) DEFAULT NULL, +`c54` varchar(30) DEFAULT NULL, +`c55` varchar(30) DEFAULT NULL, +`c56` varchar(30) DEFAULT NULL, +`c57` varchar(30) DEFAULT NULL, +`c58` varchar(30) DEFAULT NULL, +`c59` varchar(30) DEFAULT NULL, +`c60` varchar(30) DEFAULT NULL, +`c61` varchar(30) DEFAULT NULL, +`c62` varchar(30) DEFAULT NULL, +`c63` varchar(30) DEFAULT NULL, +`c64` varchar(30) DEFAULT NULL, +`c65` varchar(30) DEFAULT NULL, +`c66` varchar(30) DEFAULT NULL, +`c67` varchar(30) DEFAULT NULL, +`c68` varchar(30) DEFAULT NULL, +`c69` varchar(30) DEFAULT NULL, +`c70` varchar(30) DEFAULT NULL, +`c71` varchar(30) DEFAULT NULL, +`c72` varchar(30) DEFAULT NULL, +`c73` varchar(30) DEFAULT NULL, +`c74` varchar(30) DEFAULT NULL, +`c75` varchar(30) DEFAULT NULL, +`c76` varchar(30) DEFAULT NULL, +`c77` varchar(30) DEFAULT NULL, +`c78` varchar(30) DEFAULT NULL, +`c79` varchar(30) DEFAULT NULL, +`c80` varchar(30) DEFAULT NULL, +`c81` varchar(30) DEFAULT NULL, +`c82` varchar(30) DEFAULT NULL, +`c83` varchar(30) DEFAULT NULL, +`c84` varchar(30) DEFAULT NULL, +`c85` varchar(30) DEFAULT NULL, +`c86` varchar(30) DEFAULT NULL, +`c87` varchar(30) DEFAULT NULL, +`c88` varchar(30) DEFAULT NULL, +`c89` varchar(30) DEFAULT NULL, +`c90` varchar(30) DEFAULT NULL, +`c91` varchar(30) DEFAULT NULL, +`c92` varchar(30) DEFAULT NULL, +`c93` varchar(30) DEFAULT NULL, +`c94` varchar(30) DEFAULT NULL, +`c95` varchar(30) DEFAULT NULL, +`c96` varchar(30) DEFAULT NULL, +`c97` varchar(30) DEFAULT NULL, +`c98` varchar(30) DEFAULT NULL, +`c99` varchar(30) DEFAULT NULL, +`c100` varchar(30) DEFAULT NULL, +`c101` varchar(30) DEFAULT NULL, +`c102` varchar(30) DEFAULT NULL, +`c103` varchar(30) DEFAULT NULL, +`c104` varchar(30) DEFAULT NULL, +`c105` varchar(30) DEFAULT NULL, +`c106` varchar(30) DEFAULT NULL, +`c107` varchar(30) DEFAULT NULL, +`c108` varchar(30) DEFAULT NULL, +`c109` varchar(30) DEFAULT NULL, +`c110` varchar(30) DEFAULT NULL, +`c111` varchar(30) DEFAULT NULL, +`c112` varchar(30) DEFAULT NULL, +`c113` varchar(30) DEFAULT NULL, +`c114` varchar(30) DEFAULT NULL, +`c115` varchar(30) DEFAULT NULL, +`c116` varchar(30) DEFAULT NULL, +`c117` varchar(30) DEFAULT NULL, +`c118` varchar(30) DEFAULT NULL, +`c119` varchar(30) DEFAULT NULL, +`c120` varchar(30) DEFAULT NULL, +`c121` varchar(30) DEFAULT NULL, +`c122` varchar(30) DEFAULT NULL, +`c123` varchar(30) DEFAULT NULL, +`c124` varchar(30) DEFAULT NULL, +`c125` varchar(30) DEFAULT NULL, +`c126` varchar(30) DEFAULT NULL, +`c127` varchar(30) DEFAULT NULL, +`c128` varchar(30) DEFAULT NULL, +`c129` varchar(30) DEFAULT NULL, +`c130` varchar(30) DEFAULT NULL, +`c131` varchar(30) DEFAULT NULL, +`c132` varchar(30) DEFAULT NULL, +`c133` varchar(30) DEFAULT NULL, +`c134` varchar(30) DEFAULT NULL, +`c135` varchar(30) DEFAULT NULL, +`c136` varchar(30) DEFAULT NULL, +`c137` varchar(30) DEFAULT NULL, +`c138` varchar(30) DEFAULT NULL, +`c139` varchar(30) DEFAULT NULL, +`c140` varchar(30) DEFAULT NULL, +`c141` varchar(30) DEFAULT NULL, +`c142` varchar(30) DEFAULT NULL, +`c143` varchar(30) DEFAULT NULL, +`c144` varchar(30) DEFAULT NULL, +`c145` varchar(30) DEFAULT NULL, +`c146` varchar(30) DEFAULT NULL, +PRIMARY KEY (`c1`) +) ENGINE=InnoDB; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); +DROP TABLE `t1`; +FLUSH LOGS; +=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. +stop slave; +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; +start slave; +### TABLE with field_metadata_size == 250 +CREATE TABLE `t1` ( +`c1` int(11) NOT NULL AUTO_INCREMENT, +`c2` varchar(30) NOT NULL, +`c3` varchar(30) DEFAULT NULL, +`c4` varchar(30) DEFAULT NULL, +`c5` varchar(30) DEFAULT NULL, +`c6` varchar(30) DEFAULT NULL, +`c7` varchar(30) DEFAULT NULL, +`c8` varchar(30) DEFAULT NULL, +`c9` varchar(30) DEFAULT NULL, +`c10` varchar(30) DEFAULT NULL, +`c11` varchar(30) DEFAULT NULL, +`c12` varchar(30) DEFAULT NULL, +`c13` varchar(30) DEFAULT NULL, +`c14` varchar(30) DEFAULT NULL, +`c15` varchar(30) DEFAULT NULL, +`c16` varchar(30) DEFAULT NULL, +`c17` varchar(30) DEFAULT NULL, +`c18` varchar(30) DEFAULT NULL, +`c19` varchar(30) DEFAULT NULL, +`c20` varchar(30) DEFAULT NULL, +`c21` varchar(30) DEFAULT NULL, +`c22` varchar(30) DEFAULT NULL, +`c23` varchar(30) DEFAULT NULL, +`c24` varchar(30) DEFAULT NULL, +`c25` varchar(30) DEFAULT NULL, +`c26` varchar(30) DEFAULT NULL, +`c27` varchar(30) DEFAULT NULL, +`c28` varchar(30) DEFAULT NULL, +`c29` varchar(30) DEFAULT NULL, +`c30` varchar(30) DEFAULT NULL, +`c31` varchar(30) DEFAULT NULL, +`c32` varchar(30) DEFAULT NULL, +`c33` varchar(30) DEFAULT NULL, +`c34` varchar(30) DEFAULT NULL, +`c35` varchar(30) DEFAULT NULL, +`c36` varchar(30) DEFAULT NULL, +`c37` varchar(30) DEFAULT NULL, +`c38` varchar(30) DEFAULT NULL, +`c39` varchar(30) DEFAULT NULL, +`c40` varchar(30) DEFAULT NULL, +`c41` varchar(30) DEFAULT NULL, +`c42` varchar(30) DEFAULT NULL, +`c43` varchar(30) DEFAULT NULL, +`c44` varchar(30) DEFAULT NULL, +`c45` varchar(30) DEFAULT NULL, +`c46` varchar(30) DEFAULT NULL, +`c47` varchar(30) DEFAULT NULL, +`c48` varchar(30) DEFAULT NULL, +`c49` varchar(30) DEFAULT NULL, +`c50` varchar(30) DEFAULT NULL, +`c51` varchar(30) DEFAULT NULL, +`c52` varchar(30) DEFAULT NULL, +`c53` varchar(30) DEFAULT NULL, +`c54` varchar(30) DEFAULT NULL, +`c55` varchar(30) DEFAULT NULL, +`c56` varchar(30) DEFAULT NULL, +`c57` varchar(30) DEFAULT NULL, +`c58` varchar(30) DEFAULT NULL, +`c59` varchar(30) DEFAULT NULL, +`c60` varchar(30) DEFAULT NULL, +`c61` varchar(30) DEFAULT NULL, +`c62` varchar(30) DEFAULT NULL, +`c63` varchar(30) DEFAULT NULL, +`c64` varchar(30) DEFAULT NULL, +`c65` varchar(30) DEFAULT NULL, +`c66` varchar(30) DEFAULT NULL, +`c67` varchar(30) DEFAULT NULL, +`c68` varchar(30) DEFAULT NULL, +`c69` varchar(30) DEFAULT NULL, +`c70` varchar(30) DEFAULT NULL, +`c71` varchar(30) DEFAULT NULL, +`c72` varchar(30) DEFAULT NULL, +`c73` varchar(30) DEFAULT NULL, +`c74` varchar(30) DEFAULT NULL, +`c75` varchar(30) DEFAULT NULL, +`c76` varchar(30) DEFAULT NULL, +`c77` varchar(30) DEFAULT NULL, +`c78` varchar(30) DEFAULT NULL, +`c79` varchar(30) DEFAULT NULL, +`c80` varchar(30) DEFAULT NULL, +`c81` varchar(30) DEFAULT NULL, +`c82` varchar(30) DEFAULT NULL, +`c83` varchar(30) DEFAULT NULL, +`c84` varchar(30) DEFAULT NULL, +`c85` varchar(30) DEFAULT NULL, +`c86` varchar(30) DEFAULT NULL, +`c87` varchar(30) DEFAULT NULL, +`c88` varchar(30) DEFAULT NULL, +`c89` varchar(30) DEFAULT NULL, +`c90` varchar(30) DEFAULT NULL, +`c91` varchar(30) DEFAULT NULL, +`c92` varchar(30) DEFAULT NULL, +`c93` varchar(30) DEFAULT NULL, +`c94` varchar(30) DEFAULT NULL, +`c95` varchar(30) DEFAULT NULL, +`c96` varchar(30) DEFAULT NULL, +`c97` varchar(30) DEFAULT NULL, +`c98` varchar(30) DEFAULT NULL, +`c99` varchar(30) DEFAULT NULL, +`c100` varchar(30) DEFAULT NULL, +`c101` varchar(30) DEFAULT NULL, +`c102` varchar(30) DEFAULT NULL, +`c103` varchar(30) DEFAULT NULL, +`c104` varchar(30) DEFAULT NULL, +`c105` varchar(30) DEFAULT NULL, +`c106` varchar(30) DEFAULT NULL, +`c107` varchar(30) DEFAULT NULL, +`c108` varchar(30) DEFAULT NULL, +`c109` varchar(30) DEFAULT NULL, +`c110` varchar(30) DEFAULT NULL, +`c111` varchar(30) DEFAULT NULL, +`c112` varchar(30) DEFAULT NULL, +`c113` varchar(30) DEFAULT NULL, +`c114` varchar(30) DEFAULT NULL, +`c115` varchar(30) DEFAULT NULL, +`c116` varchar(30) DEFAULT NULL, +`c117` varchar(30) DEFAULT NULL, +`c118` varchar(30) DEFAULT NULL, +`c119` varchar(30) DEFAULT NULL, +`c120` varchar(30) DEFAULT NULL, +`c121` varchar(30) DEFAULT NULL, +`c122` varchar(30) DEFAULT NULL, +`c123` varchar(30) DEFAULT NULL, +`c124` varchar(30) DEFAULT NULL, +`c125` varchar(30) DEFAULT NULL, +`c126` varchar(30) DEFAULT NULL, +PRIMARY KEY (`c1`) +) ENGINE=InnoDB; +### TABLE with field_metadata_size == 251 +CREATE TABLE `t2` ( +`c1` float, +`c2` varchar(30) NOT NULL, +`c3` varchar(30) DEFAULT NULL, +`c4` varchar(30) DEFAULT NULL, +`c5` varchar(30) DEFAULT NULL, +`c6` varchar(30) DEFAULT NULL, +`c7` varchar(30) DEFAULT NULL, +`c8` varchar(30) DEFAULT NULL, +`c9` varchar(30) DEFAULT NULL, +`c10` varchar(30) DEFAULT NULL, +`c11` varchar(30) DEFAULT NULL, +`c12` varchar(30) DEFAULT NULL, +`c13` varchar(30) DEFAULT NULL, +`c14` varchar(30) DEFAULT NULL, +`c15` varchar(30) DEFAULT NULL, +`c16` varchar(30) DEFAULT NULL, +`c17` varchar(30) DEFAULT NULL, +`c18` varchar(30) DEFAULT NULL, +`c19` varchar(30) DEFAULT NULL, +`c20` varchar(30) DEFAULT NULL, +`c21` varchar(30) DEFAULT NULL, +`c22` varchar(30) DEFAULT NULL, +`c23` varchar(30) DEFAULT NULL, +`c24` varchar(30) DEFAULT NULL, +`c25` varchar(30) DEFAULT NULL, +`c26` varchar(30) DEFAULT NULL, +`c27` varchar(30) DEFAULT NULL, +`c28` varchar(30) DEFAULT NULL, +`c29` varchar(30) DEFAULT NULL, +`c30` varchar(30) DEFAULT NULL, +`c31` varchar(30) DEFAULT NULL, +`c32` varchar(30) DEFAULT NULL, +`c33` varchar(30) DEFAULT NULL, +`c34` varchar(30) DEFAULT NULL, +`c35` varchar(30) DEFAULT NULL, +`c36` varchar(30) DEFAULT NULL, +`c37` varchar(30) DEFAULT NULL, +`c38` varchar(30) DEFAULT NULL, +`c39` varchar(30) DEFAULT NULL, +`c40` varchar(30) DEFAULT NULL, +`c41` varchar(30) DEFAULT NULL, +`c42` varchar(30) DEFAULT NULL, +`c43` varchar(30) DEFAULT NULL, +`c44` varchar(30) DEFAULT NULL, +`c45` varchar(30) DEFAULT NULL, +`c46` varchar(30) DEFAULT NULL, +`c47` varchar(30) DEFAULT NULL, +`c48` varchar(30) DEFAULT NULL, +`c49` varchar(30) DEFAULT NULL, +`c50` varchar(30) DEFAULT NULL, +`c51` varchar(30) DEFAULT NULL, +`c52` varchar(30) DEFAULT NULL, +`c53` varchar(30) DEFAULT NULL, +`c54` varchar(30) DEFAULT NULL, +`c55` varchar(30) DEFAULT NULL, +`c56` varchar(30) DEFAULT NULL, +`c57` varchar(30) DEFAULT NULL, +`c58` varchar(30) DEFAULT NULL, +`c59` varchar(30) DEFAULT NULL, +`c60` varchar(30) DEFAULT NULL, +`c61` varchar(30) DEFAULT NULL, +`c62` varchar(30) DEFAULT NULL, +`c63` varchar(30) DEFAULT NULL, +`c64` varchar(30) DEFAULT NULL, +`c65` varchar(30) DEFAULT NULL, +`c66` varchar(30) DEFAULT NULL, +`c67` varchar(30) DEFAULT NULL, +`c68` varchar(30) DEFAULT NULL, +`c69` varchar(30) DEFAULT NULL, +`c70` varchar(30) DEFAULT NULL, +`c71` varchar(30) DEFAULT NULL, +`c72` varchar(30) DEFAULT NULL, +`c73` varchar(30) DEFAULT NULL, +`c74` varchar(30) DEFAULT NULL, +`c75` varchar(30) DEFAULT NULL, +`c76` varchar(30) DEFAULT NULL, +`c77` varchar(30) DEFAULT NULL, +`c78` varchar(30) DEFAULT NULL, +`c79` varchar(30) DEFAULT NULL, +`c80` varchar(30) DEFAULT NULL, +`c81` varchar(30) DEFAULT NULL, +`c82` varchar(30) DEFAULT NULL, +`c83` varchar(30) DEFAULT NULL, +`c84` varchar(30) DEFAULT NULL, +`c85` varchar(30) DEFAULT NULL, +`c86` varchar(30) DEFAULT NULL, +`c87` varchar(30) DEFAULT NULL, +`c88` varchar(30) DEFAULT NULL, +`c89` varchar(30) DEFAULT NULL, +`c90` varchar(30) DEFAULT NULL, +`c91` varchar(30) DEFAULT NULL, +`c92` varchar(30) DEFAULT NULL, +`c93` varchar(30) DEFAULT NULL, +`c94` varchar(30) DEFAULT NULL, +`c95` varchar(30) DEFAULT NULL, +`c96` varchar(30) DEFAULT NULL, +`c97` varchar(30) DEFAULT NULL, +`c98` varchar(30) DEFAULT NULL, +`c99` varchar(30) DEFAULT NULL, +`c100` varchar(30) DEFAULT NULL, +`c101` varchar(30) DEFAULT NULL, +`c102` varchar(30) DEFAULT NULL, +`c103` varchar(30) DEFAULT NULL, +`c104` varchar(30) DEFAULT NULL, +`c105` varchar(30) DEFAULT NULL, +`c106` varchar(30) DEFAULT NULL, +`c107` varchar(30) DEFAULT NULL, +`c108` varchar(30) DEFAULT NULL, +`c109` varchar(30) DEFAULT NULL, +`c110` varchar(30) DEFAULT NULL, +`c111` varchar(30) DEFAULT NULL, +`c112` varchar(30) DEFAULT NULL, +`c113` varchar(30) DEFAULT NULL, +`c114` varchar(30) DEFAULT NULL, +`c115` varchar(30) DEFAULT NULL, +`c116` varchar(30) DEFAULT NULL, +`c117` varchar(30) DEFAULT NULL, +`c118` varchar(30) DEFAULT NULL, +`c119` varchar(30) DEFAULT NULL, +`c120` varchar(30) DEFAULT NULL, +`c121` varchar(30) DEFAULT NULL, +`c122` varchar(30) DEFAULT NULL, +`c123` varchar(30) DEFAULT NULL, +`c124` varchar(30) DEFAULT NULL, +`c125` varchar(30) DEFAULT NULL, +`c126` varchar(30) DEFAULT NULL, +PRIMARY KEY (`c1`) +) ENGINE=InnoDB; +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); +LOCK TABLES `t2` WRITE; +INSERT INTO `t2` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); +DROP TABLE `t1`; +DROP TABLE `t2`; +FLUSH LOGS; +=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test new file mode 100644 index 00000000000..4d7ba1e0a81 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test @@ -0,0 +1,520 @@ +# +# BUG#42749: infinite loop writing to row based binlog - processlist shows +# "freeing items" +# +# BUG#50018: binlog corruption when table has many columns +# +# WHY +# === +# +# This bug would make table map event to report data_written one +# byte less than what would actually be written in its body. This +# would cause one byte shorter event end_log_pos. The ultimate +# impact was that it would make fixing the position in +# MYSQL_BIN_LOG::write_cache bogus or end up in an infinite loop. +# +# HOW +# === +# +# Checking that the patch fixes the problem is done as follows: +# +# i) tables with several fields is created (above and below a 251 +# metadata size threshold) +# ii) an insert is performed; +# iii) the logs are flushed; +# iv) mysqlbinlog is used to check if it succeeds. +# +# In step iv), before the bug was fixed, the test case would fail +# with mysqlbinlog reporting that it was unable to succeed in +# reading the event. + +-- source include/master-slave.inc +-- source include/have_log_bin.inc +-- source include/have_innodb.inc +-- source include/have_binlog_format_row.inc +-- connection default + +RESET MASTER; + +-- disable_warnings +DROP TABLE IF EXISTS `t1`; +-- enable_warnings + +-- echo ### TABLE with field_metadata_size == 290 +CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(30) NOT NULL, + `c3` varchar(30) DEFAULT NULL, + `c4` varchar(30) DEFAULT NULL, + `c5` varchar(30) DEFAULT NULL, + `c6` varchar(30) DEFAULT NULL, + `c7` varchar(30) DEFAULT NULL, + `c8` varchar(30) DEFAULT NULL, + `c9` varchar(30) DEFAULT NULL, + `c10` varchar(30) DEFAULT NULL, + `c11` varchar(30) DEFAULT NULL, + `c12` varchar(30) DEFAULT NULL, + `c13` varchar(30) DEFAULT NULL, + `c14` varchar(30) DEFAULT NULL, + `c15` varchar(30) DEFAULT NULL, + `c16` varchar(30) DEFAULT NULL, + `c17` varchar(30) DEFAULT NULL, + `c18` varchar(30) DEFAULT NULL, + `c19` varchar(30) DEFAULT NULL, + `c20` varchar(30) DEFAULT NULL, + `c21` varchar(30) DEFAULT NULL, + `c22` varchar(30) DEFAULT NULL, + `c23` varchar(30) DEFAULT NULL, + `c24` varchar(30) DEFAULT NULL, + `c25` varchar(30) DEFAULT NULL, + `c26` varchar(30) DEFAULT NULL, + `c27` varchar(30) DEFAULT NULL, + `c28` varchar(30) DEFAULT NULL, + `c29` varchar(30) DEFAULT NULL, + `c30` varchar(30) DEFAULT NULL, + `c31` varchar(30) DEFAULT NULL, + `c32` varchar(30) DEFAULT NULL, + `c33` varchar(30) DEFAULT NULL, + `c34` varchar(30) DEFAULT NULL, + `c35` varchar(30) DEFAULT NULL, + `c36` varchar(30) DEFAULT NULL, + `c37` varchar(30) DEFAULT NULL, + `c38` varchar(30) DEFAULT NULL, + `c39` varchar(30) DEFAULT NULL, + `c40` varchar(30) DEFAULT NULL, + `c41` varchar(30) DEFAULT NULL, + `c42` varchar(30) DEFAULT NULL, + `c43` varchar(30) DEFAULT NULL, + `c44` varchar(30) DEFAULT NULL, + `c45` varchar(30) DEFAULT NULL, + `c46` varchar(30) DEFAULT NULL, + `c47` varchar(30) DEFAULT NULL, + `c48` varchar(30) DEFAULT NULL, + `c49` varchar(30) DEFAULT NULL, + `c50` varchar(30) DEFAULT NULL, + `c51` varchar(30) DEFAULT NULL, + `c52` varchar(30) DEFAULT NULL, + `c53` varchar(30) DEFAULT NULL, + `c54` varchar(30) DEFAULT NULL, + `c55` varchar(30) DEFAULT NULL, + `c56` varchar(30) DEFAULT NULL, + `c57` varchar(30) DEFAULT NULL, + `c58` varchar(30) DEFAULT NULL, + `c59` varchar(30) DEFAULT NULL, + `c60` varchar(30) DEFAULT NULL, + `c61` varchar(30) DEFAULT NULL, + `c62` varchar(30) DEFAULT NULL, + `c63` varchar(30) DEFAULT NULL, + `c64` varchar(30) DEFAULT NULL, + `c65` varchar(30) DEFAULT NULL, + `c66` varchar(30) DEFAULT NULL, + `c67` varchar(30) DEFAULT NULL, + `c68` varchar(30) DEFAULT NULL, + `c69` varchar(30) DEFAULT NULL, + `c70` varchar(30) DEFAULT NULL, + `c71` varchar(30) DEFAULT NULL, + `c72` varchar(30) DEFAULT NULL, + `c73` varchar(30) DEFAULT NULL, + `c74` varchar(30) DEFAULT NULL, + `c75` varchar(30) DEFAULT NULL, + `c76` varchar(30) DEFAULT NULL, + `c77` varchar(30) DEFAULT NULL, + `c78` varchar(30) DEFAULT NULL, + `c79` varchar(30) DEFAULT NULL, + `c80` varchar(30) DEFAULT NULL, + `c81` varchar(30) DEFAULT NULL, + `c82` varchar(30) DEFAULT NULL, + `c83` varchar(30) DEFAULT NULL, + `c84` varchar(30) DEFAULT NULL, + `c85` varchar(30) DEFAULT NULL, + `c86` varchar(30) DEFAULT NULL, + `c87` varchar(30) DEFAULT NULL, + `c88` varchar(30) DEFAULT NULL, + `c89` varchar(30) DEFAULT NULL, + `c90` varchar(30) DEFAULT NULL, + `c91` varchar(30) DEFAULT NULL, + `c92` varchar(30) DEFAULT NULL, + `c93` varchar(30) DEFAULT NULL, + `c94` varchar(30) DEFAULT NULL, + `c95` varchar(30) DEFAULT NULL, + `c96` varchar(30) DEFAULT NULL, + `c97` varchar(30) DEFAULT NULL, + `c98` varchar(30) DEFAULT NULL, + `c99` varchar(30) DEFAULT NULL, + `c100` varchar(30) DEFAULT NULL, + `c101` varchar(30) DEFAULT NULL, + `c102` varchar(30) DEFAULT NULL, + `c103` varchar(30) DEFAULT NULL, + `c104` varchar(30) DEFAULT NULL, + `c105` varchar(30) DEFAULT NULL, + `c106` varchar(30) DEFAULT NULL, + `c107` varchar(30) DEFAULT NULL, + `c108` varchar(30) DEFAULT NULL, + `c109` varchar(30) DEFAULT NULL, + `c110` varchar(30) DEFAULT NULL, + `c111` varchar(30) DEFAULT NULL, + `c112` varchar(30) DEFAULT NULL, + `c113` varchar(30) DEFAULT NULL, + `c114` varchar(30) DEFAULT NULL, + `c115` varchar(30) DEFAULT NULL, + `c116` varchar(30) DEFAULT NULL, + `c117` varchar(30) DEFAULT NULL, + `c118` varchar(30) DEFAULT NULL, + `c119` varchar(30) DEFAULT NULL, + `c120` varchar(30) DEFAULT NULL, + `c121` varchar(30) DEFAULT NULL, + `c122` varchar(30) DEFAULT NULL, + `c123` varchar(30) DEFAULT NULL, + `c124` varchar(30) DEFAULT NULL, + `c125` varchar(30) DEFAULT NULL, + `c126` varchar(30) DEFAULT NULL, + `c127` varchar(30) DEFAULT NULL, + `c128` varchar(30) DEFAULT NULL, + `c129` varchar(30) DEFAULT NULL, + `c130` varchar(30) DEFAULT NULL, + `c131` varchar(30) DEFAULT NULL, + `c132` varchar(30) DEFAULT NULL, + `c133` varchar(30) DEFAULT NULL, + `c134` varchar(30) DEFAULT NULL, + `c135` varchar(30) DEFAULT NULL, + `c136` varchar(30) DEFAULT NULL, + `c137` varchar(30) DEFAULT NULL, + `c138` varchar(30) DEFAULT NULL, + `c139` varchar(30) DEFAULT NULL, + `c140` varchar(30) DEFAULT NULL, + `c141` varchar(30) DEFAULT NULL, + `c142` varchar(30) DEFAULT NULL, + `c143` varchar(30) DEFAULT NULL, + `c144` varchar(30) DEFAULT NULL, + `c145` varchar(30) DEFAULT NULL, + `c146` varchar(30) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB; + +LOCK TABLES `t1` WRITE; + +INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + +DROP TABLE `t1`; + +FLUSH LOGS; + +-- sync_slave_with_master +-- connection master + +-- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. + +-- let $MYSQLD_DATADIR= `SELECT @@datadir`; +-- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog +-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog + +-- source include/master-slave-reset.inc +-- connection master + +# Create two tables one with field_metadata_size == 250 +# and another one with field_metadata_size == 252 +# +# Each varchar field takes up to 2 metadata bytes, see: +# +# Field_varstring::do_save_field_metadata (field.cc) +# +# The integer field takes 0 bytes, see: +# +# Field::do_save_field_metadata (field.h) +# +# The float field takes 1 byte, see: +# +# Field_float::do_save_field_metadata (field.cc) +# +# We choose 250 and 252 which are the ones below and above +# the threshold for switching to use 1 or 3 bytes for the +# m_data_size increment. +# + +-- echo ### TABLE with field_metadata_size == 250 + +CREATE TABLE `t1` ( + `c1` int(11) NOT NULL AUTO_INCREMENT, + `c2` varchar(30) NOT NULL, + `c3` varchar(30) DEFAULT NULL, + `c4` varchar(30) DEFAULT NULL, + `c5` varchar(30) DEFAULT NULL, + `c6` varchar(30) DEFAULT NULL, + `c7` varchar(30) DEFAULT NULL, + `c8` varchar(30) DEFAULT NULL, + `c9` varchar(30) DEFAULT NULL, + `c10` varchar(30) DEFAULT NULL, + `c11` varchar(30) DEFAULT NULL, + `c12` varchar(30) DEFAULT NULL, + `c13` varchar(30) DEFAULT NULL, + `c14` varchar(30) DEFAULT NULL, + `c15` varchar(30) DEFAULT NULL, + `c16` varchar(30) DEFAULT NULL, + `c17` varchar(30) DEFAULT NULL, + `c18` varchar(30) DEFAULT NULL, + `c19` varchar(30) DEFAULT NULL, + `c20` varchar(30) DEFAULT NULL, + `c21` varchar(30) DEFAULT NULL, + `c22` varchar(30) DEFAULT NULL, + `c23` varchar(30) DEFAULT NULL, + `c24` varchar(30) DEFAULT NULL, + `c25` varchar(30) DEFAULT NULL, + `c26` varchar(30) DEFAULT NULL, + `c27` varchar(30) DEFAULT NULL, + `c28` varchar(30) DEFAULT NULL, + `c29` varchar(30) DEFAULT NULL, + `c30` varchar(30) DEFAULT NULL, + `c31` varchar(30) DEFAULT NULL, + `c32` varchar(30) DEFAULT NULL, + `c33` varchar(30) DEFAULT NULL, + `c34` varchar(30) DEFAULT NULL, + `c35` varchar(30) DEFAULT NULL, + `c36` varchar(30) DEFAULT NULL, + `c37` varchar(30) DEFAULT NULL, + `c38` varchar(30) DEFAULT NULL, + `c39` varchar(30) DEFAULT NULL, + `c40` varchar(30) DEFAULT NULL, + `c41` varchar(30) DEFAULT NULL, + `c42` varchar(30) DEFAULT NULL, + `c43` varchar(30) DEFAULT NULL, + `c44` varchar(30) DEFAULT NULL, + `c45` varchar(30) DEFAULT NULL, + `c46` varchar(30) DEFAULT NULL, + `c47` varchar(30) DEFAULT NULL, + `c48` varchar(30) DEFAULT NULL, + `c49` varchar(30) DEFAULT NULL, + `c50` varchar(30) DEFAULT NULL, + `c51` varchar(30) DEFAULT NULL, + `c52` varchar(30) DEFAULT NULL, + `c53` varchar(30) DEFAULT NULL, + `c54` varchar(30) DEFAULT NULL, + `c55` varchar(30) DEFAULT NULL, + `c56` varchar(30) DEFAULT NULL, + `c57` varchar(30) DEFAULT NULL, + `c58` varchar(30) DEFAULT NULL, + `c59` varchar(30) DEFAULT NULL, + `c60` varchar(30) DEFAULT NULL, + `c61` varchar(30) DEFAULT NULL, + `c62` varchar(30) DEFAULT NULL, + `c63` varchar(30) DEFAULT NULL, + `c64` varchar(30) DEFAULT NULL, + `c65` varchar(30) DEFAULT NULL, + `c66` varchar(30) DEFAULT NULL, + `c67` varchar(30) DEFAULT NULL, + `c68` varchar(30) DEFAULT NULL, + `c69` varchar(30) DEFAULT NULL, + `c70` varchar(30) DEFAULT NULL, + `c71` varchar(30) DEFAULT NULL, + `c72` varchar(30) DEFAULT NULL, + `c73` varchar(30) DEFAULT NULL, + `c74` varchar(30) DEFAULT NULL, + `c75` varchar(30) DEFAULT NULL, + `c76` varchar(30) DEFAULT NULL, + `c77` varchar(30) DEFAULT NULL, + `c78` varchar(30) DEFAULT NULL, + `c79` varchar(30) DEFAULT NULL, + `c80` varchar(30) DEFAULT NULL, + `c81` varchar(30) DEFAULT NULL, + `c82` varchar(30) DEFAULT NULL, + `c83` varchar(30) DEFAULT NULL, + `c84` varchar(30) DEFAULT NULL, + `c85` varchar(30) DEFAULT NULL, + `c86` varchar(30) DEFAULT NULL, + `c87` varchar(30) DEFAULT NULL, + `c88` varchar(30) DEFAULT NULL, + `c89` varchar(30) DEFAULT NULL, + `c90` varchar(30) DEFAULT NULL, + `c91` varchar(30) DEFAULT NULL, + `c92` varchar(30) DEFAULT NULL, + `c93` varchar(30) DEFAULT NULL, + `c94` varchar(30) DEFAULT NULL, + `c95` varchar(30) DEFAULT NULL, + `c96` varchar(30) DEFAULT NULL, + `c97` varchar(30) DEFAULT NULL, + `c98` varchar(30) DEFAULT NULL, + `c99` varchar(30) DEFAULT NULL, + `c100` varchar(30) DEFAULT NULL, + `c101` varchar(30) DEFAULT NULL, + `c102` varchar(30) DEFAULT NULL, + `c103` varchar(30) DEFAULT NULL, + `c104` varchar(30) DEFAULT NULL, + `c105` varchar(30) DEFAULT NULL, + `c106` varchar(30) DEFAULT NULL, + `c107` varchar(30) DEFAULT NULL, + `c108` varchar(30) DEFAULT NULL, + `c109` varchar(30) DEFAULT NULL, + `c110` varchar(30) DEFAULT NULL, + `c111` varchar(30) DEFAULT NULL, + `c112` varchar(30) DEFAULT NULL, + `c113` varchar(30) DEFAULT NULL, + `c114` varchar(30) DEFAULT NULL, + `c115` varchar(30) DEFAULT NULL, + `c116` varchar(30) DEFAULT NULL, + `c117` varchar(30) DEFAULT NULL, + `c118` varchar(30) DEFAULT NULL, + `c119` varchar(30) DEFAULT NULL, + `c120` varchar(30) DEFAULT NULL, + `c121` varchar(30) DEFAULT NULL, + `c122` varchar(30) DEFAULT NULL, + `c123` varchar(30) DEFAULT NULL, + `c124` varchar(30) DEFAULT NULL, + `c125` varchar(30) DEFAULT NULL, + `c126` varchar(30) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB; + +-- echo ### TABLE with field_metadata_size == 251 + +CREATE TABLE `t2` ( + `c1` float, + `c2` varchar(30) NOT NULL, + `c3` varchar(30) DEFAULT NULL, + `c4` varchar(30) DEFAULT NULL, + `c5` varchar(30) DEFAULT NULL, + `c6` varchar(30) DEFAULT NULL, + `c7` varchar(30) DEFAULT NULL, + `c8` varchar(30) DEFAULT NULL, + `c9` varchar(30) DEFAULT NULL, + `c10` varchar(30) DEFAULT NULL, + `c11` varchar(30) DEFAULT NULL, + `c12` varchar(30) DEFAULT NULL, + `c13` varchar(30) DEFAULT NULL, + `c14` varchar(30) DEFAULT NULL, + `c15` varchar(30) DEFAULT NULL, + `c16` varchar(30) DEFAULT NULL, + `c17` varchar(30) DEFAULT NULL, + `c18` varchar(30) DEFAULT NULL, + `c19` varchar(30) DEFAULT NULL, + `c20` varchar(30) DEFAULT NULL, + `c21` varchar(30) DEFAULT NULL, + `c22` varchar(30) DEFAULT NULL, + `c23` varchar(30) DEFAULT NULL, + `c24` varchar(30) DEFAULT NULL, + `c25` varchar(30) DEFAULT NULL, + `c26` varchar(30) DEFAULT NULL, + `c27` varchar(30) DEFAULT NULL, + `c28` varchar(30) DEFAULT NULL, + `c29` varchar(30) DEFAULT NULL, + `c30` varchar(30) DEFAULT NULL, + `c31` varchar(30) DEFAULT NULL, + `c32` varchar(30) DEFAULT NULL, + `c33` varchar(30) DEFAULT NULL, + `c34` varchar(30) DEFAULT NULL, + `c35` varchar(30) DEFAULT NULL, + `c36` varchar(30) DEFAULT NULL, + `c37` varchar(30) DEFAULT NULL, + `c38` varchar(30) DEFAULT NULL, + `c39` varchar(30) DEFAULT NULL, + `c40` varchar(30) DEFAULT NULL, + `c41` varchar(30) DEFAULT NULL, + `c42` varchar(30) DEFAULT NULL, + `c43` varchar(30) DEFAULT NULL, + `c44` varchar(30) DEFAULT NULL, + `c45` varchar(30) DEFAULT NULL, + `c46` varchar(30) DEFAULT NULL, + `c47` varchar(30) DEFAULT NULL, + `c48` varchar(30) DEFAULT NULL, + `c49` varchar(30) DEFAULT NULL, + `c50` varchar(30) DEFAULT NULL, + `c51` varchar(30) DEFAULT NULL, + `c52` varchar(30) DEFAULT NULL, + `c53` varchar(30) DEFAULT NULL, + `c54` varchar(30) DEFAULT NULL, + `c55` varchar(30) DEFAULT NULL, + `c56` varchar(30) DEFAULT NULL, + `c57` varchar(30) DEFAULT NULL, + `c58` varchar(30) DEFAULT NULL, + `c59` varchar(30) DEFAULT NULL, + `c60` varchar(30) DEFAULT NULL, + `c61` varchar(30) DEFAULT NULL, + `c62` varchar(30) DEFAULT NULL, + `c63` varchar(30) DEFAULT NULL, + `c64` varchar(30) DEFAULT NULL, + `c65` varchar(30) DEFAULT NULL, + `c66` varchar(30) DEFAULT NULL, + `c67` varchar(30) DEFAULT NULL, + `c68` varchar(30) DEFAULT NULL, + `c69` varchar(30) DEFAULT NULL, + `c70` varchar(30) DEFAULT NULL, + `c71` varchar(30) DEFAULT NULL, + `c72` varchar(30) DEFAULT NULL, + `c73` varchar(30) DEFAULT NULL, + `c74` varchar(30) DEFAULT NULL, + `c75` varchar(30) DEFAULT NULL, + `c76` varchar(30) DEFAULT NULL, + `c77` varchar(30) DEFAULT NULL, + `c78` varchar(30) DEFAULT NULL, + `c79` varchar(30) DEFAULT NULL, + `c80` varchar(30) DEFAULT NULL, + `c81` varchar(30) DEFAULT NULL, + `c82` varchar(30) DEFAULT NULL, + `c83` varchar(30) DEFAULT NULL, + `c84` varchar(30) DEFAULT NULL, + `c85` varchar(30) DEFAULT NULL, + `c86` varchar(30) DEFAULT NULL, + `c87` varchar(30) DEFAULT NULL, + `c88` varchar(30) DEFAULT NULL, + `c89` varchar(30) DEFAULT NULL, + `c90` varchar(30) DEFAULT NULL, + `c91` varchar(30) DEFAULT NULL, + `c92` varchar(30) DEFAULT NULL, + `c93` varchar(30) DEFAULT NULL, + `c94` varchar(30) DEFAULT NULL, + `c95` varchar(30) DEFAULT NULL, + `c96` varchar(30) DEFAULT NULL, + `c97` varchar(30) DEFAULT NULL, + `c98` varchar(30) DEFAULT NULL, + `c99` varchar(30) DEFAULT NULL, + `c100` varchar(30) DEFAULT NULL, + `c101` varchar(30) DEFAULT NULL, + `c102` varchar(30) DEFAULT NULL, + `c103` varchar(30) DEFAULT NULL, + `c104` varchar(30) DEFAULT NULL, + `c105` varchar(30) DEFAULT NULL, + `c106` varchar(30) DEFAULT NULL, + `c107` varchar(30) DEFAULT NULL, + `c108` varchar(30) DEFAULT NULL, + `c109` varchar(30) DEFAULT NULL, + `c110` varchar(30) DEFAULT NULL, + `c111` varchar(30) DEFAULT NULL, + `c112` varchar(30) DEFAULT NULL, + `c113` varchar(30) DEFAULT NULL, + `c114` varchar(30) DEFAULT NULL, + `c115` varchar(30) DEFAULT NULL, + `c116` varchar(30) DEFAULT NULL, + `c117` varchar(30) DEFAULT NULL, + `c118` varchar(30) DEFAULT NULL, + `c119` varchar(30) DEFAULT NULL, + `c120` varchar(30) DEFAULT NULL, + `c121` varchar(30) DEFAULT NULL, + `c122` varchar(30) DEFAULT NULL, + `c123` varchar(30) DEFAULT NULL, + `c124` varchar(30) DEFAULT NULL, + `c125` varchar(30) DEFAULT NULL, + `c126` varchar(30) DEFAULT NULL, + PRIMARY KEY (`c1`) +) ENGINE=InnoDB; + +LOCK TABLES `t1` WRITE; +INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + + +LOCK TABLES `t2` WRITE; +INSERT INTO `t2` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + +DROP TABLE `t1`; +DROP TABLE `t2`; + +FLUSH LOGS; + +-- sync_slave_with_master + +-- connection master + +-- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. + +-- let $MYSQLD_DATADIR= `SELECT @@datadir`; +-- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog +-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog + +-- source include/master-slave-end.inc diff --git a/sql/log_event.cc b/sql/log_event.cc index c028db3476d..d5a436cb79e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -7925,10 +7925,10 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, plus one or three bytes (see pack.c:net_store_length) for number of elements in the field metadata array. */ - if (m_field_metadata_size > 255) - m_data_size+= m_field_metadata_size + 3; - else + if (m_field_metadata_size < 251) m_data_size+= m_field_metadata_size + 1; + else + m_data_size+= m_field_metadata_size + 3; bzero(m_null_bits, num_null_bytes); for (unsigned int i= 0 ; i < m_table->s->fields ; ++i) From 0a64fbc517eef4550e5b0b75246125391f5deca1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Jan 2010 10:36:29 +0800 Subject: [PATCH 30/47] Bug #49137 Replication failure on SBR/MBR + multi-table DROP TEMPORARY TABLE Fixed valgrind failure on PB2. sql/log_event.cc: Added code to fix valgrind failure on PB2. --- sql/log_event.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 35d53c4fede..ad5c4bfeef8 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2110,8 +2110,8 @@ compare_errors: has already been dropped. To ignore such irrelevant "table does not exist errors", we silently clear the error if TEMPORARY was used. */ - if (thd->lex->drop_temporary && - thd->net.last_errno == ER_BAD_TABLE_ERROR && !expected_error) + if (thd->net.last_errno == ER_BAD_TABLE_ERROR && + !expected_error && thd->lex->drop_temporary) thd->clear_error(); /* If we expected a non-zero error code, and we don't get the same error From 98b989d7b1f250f4e245b1ca479bacd9b18ae98e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Jan 2010 13:12:40 +0800 Subject: [PATCH 31/47] Bug #49137 Replication failure on SBR/MBR + multi-table DROP TEMPORARY TABLE Fixed valgrind failure on PB2. sql/log_event.cc: Added code to fix valgrind failure on PB2. --- sql/log_event.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index ad5c4bfeef8..76fc2632cd1 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2110,8 +2110,8 @@ compare_errors: has already been dropped. To ignore such irrelevant "table does not exist errors", we silently clear the error if TEMPORARY was used. */ - if (thd->net.last_errno == ER_BAD_TABLE_ERROR && - !expected_error && thd->lex->drop_temporary) + if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary && + thd->net.last_errno == ER_BAD_TABLE_ERROR && !expected_error) thd->clear_error(); /* If we expected a non-zero error code, and we don't get the same error From 9eca4014e34add68eafb7b8d820d7f7920e0b8e1 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 6 Jan 2010 12:24:51 +0200 Subject: [PATCH 32/47] Addendum to Bug #49734 : fixed an unstable test case. --- mysql-test/r/union.result | 3 --- mysql-test/t/union.test | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index dce32d2ced4..43d7cade227 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1640,9 +1640,6 @@ Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` union select `test`.`t1 # Should not crash SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY (SELECT a FROM t2 WHERE b = 12); -a -1 -2 # Should not crash SELECT * FROM t2 UNION SELECT * FROM t2 ORDER BY (SELECT * FROM t1 WHERE MATCH(a) AGAINST ('+abc' IN BOOLEAN MODE)); diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 91fc9546bbe..c8d5ea0f8e5 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1144,8 +1144,10 @@ SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY (SELECT a FROM t2 WHERE b = 12); --echo # Should not crash +--disable_result_log SELECT * FROM t1 UNION SELECT * FROM t1 ORDER BY (SELECT a FROM t2 WHERE b = 12); +--enable_result_log --echo # Should not crash SELECT * FROM t2 UNION SELECT * FROM t2 From 585303295fba0ecb01da868adc59de7a04a0d484 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 7 Jan 2010 17:45:54 +0000 Subject: [PATCH 33/47] BUG#50018: binlog corruption when table has many columns Some improvements on the test case as suggested during review. --- .../suite/rpl/r/rpl_row_tbl_metadata.result | 309 ++------------ .../suite/rpl/t/rpl_row_tbl_metadata.test | 402 +++++------------- 2 files changed, 150 insertions(+), 561 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result index 551ece5da9d..711d0d063aa 100644 --- a/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result +++ b/mysql-test/suite/rpl/r/rpl_row_tbl_metadata.result @@ -4,7 +4,6 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -RESET MASTER; DROP TABLE IF EXISTS `t1`; ### TABLE with field_metadata_size == 290 CREATE TABLE `t1` ( @@ -157,9 +156,11 @@ CREATE TABLE `t1` ( PRIMARY KEY (`c1`) ) ENGINE=InnoDB; LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); -DROP TABLE `t1`; +INSERT INTO `t1`(c2) VALUES ('1'); FLUSH LOGS; +### assertion: the slave replicated event successfully and tables match +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE `t1`; === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. stop slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; @@ -167,271 +168,39 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; -### TABLE with field_metadata_size == 250 -CREATE TABLE `t1` ( -`c1` int(11) NOT NULL AUTO_INCREMENT, -`c2` varchar(30) NOT NULL, -`c3` varchar(30) DEFAULT NULL, -`c4` varchar(30) DEFAULT NULL, -`c5` varchar(30) DEFAULT NULL, -`c6` varchar(30) DEFAULT NULL, -`c7` varchar(30) DEFAULT NULL, -`c8` varchar(30) DEFAULT NULL, -`c9` varchar(30) DEFAULT NULL, -`c10` varchar(30) DEFAULT NULL, -`c11` varchar(30) DEFAULT NULL, -`c12` varchar(30) DEFAULT NULL, -`c13` varchar(30) DEFAULT NULL, -`c14` varchar(30) DEFAULT NULL, -`c15` varchar(30) DEFAULT NULL, -`c16` varchar(30) DEFAULT NULL, -`c17` varchar(30) DEFAULT NULL, -`c18` varchar(30) DEFAULT NULL, -`c19` varchar(30) DEFAULT NULL, -`c20` varchar(30) DEFAULT NULL, -`c21` varchar(30) DEFAULT NULL, -`c22` varchar(30) DEFAULT NULL, -`c23` varchar(30) DEFAULT NULL, -`c24` varchar(30) DEFAULT NULL, -`c25` varchar(30) DEFAULT NULL, -`c26` varchar(30) DEFAULT NULL, -`c27` varchar(30) DEFAULT NULL, -`c28` varchar(30) DEFAULT NULL, -`c29` varchar(30) DEFAULT NULL, -`c30` varchar(30) DEFAULT NULL, -`c31` varchar(30) DEFAULT NULL, -`c32` varchar(30) DEFAULT NULL, -`c33` varchar(30) DEFAULT NULL, -`c34` varchar(30) DEFAULT NULL, -`c35` varchar(30) DEFAULT NULL, -`c36` varchar(30) DEFAULT NULL, -`c37` varchar(30) DEFAULT NULL, -`c38` varchar(30) DEFAULT NULL, -`c39` varchar(30) DEFAULT NULL, -`c40` varchar(30) DEFAULT NULL, -`c41` varchar(30) DEFAULT NULL, -`c42` varchar(30) DEFAULT NULL, -`c43` varchar(30) DEFAULT NULL, -`c44` varchar(30) DEFAULT NULL, -`c45` varchar(30) DEFAULT NULL, -`c46` varchar(30) DEFAULT NULL, -`c47` varchar(30) DEFAULT NULL, -`c48` varchar(30) DEFAULT NULL, -`c49` varchar(30) DEFAULT NULL, -`c50` varchar(30) DEFAULT NULL, -`c51` varchar(30) DEFAULT NULL, -`c52` varchar(30) DEFAULT NULL, -`c53` varchar(30) DEFAULT NULL, -`c54` varchar(30) DEFAULT NULL, -`c55` varchar(30) DEFAULT NULL, -`c56` varchar(30) DEFAULT NULL, -`c57` varchar(30) DEFAULT NULL, -`c58` varchar(30) DEFAULT NULL, -`c59` varchar(30) DEFAULT NULL, -`c60` varchar(30) DEFAULT NULL, -`c61` varchar(30) DEFAULT NULL, -`c62` varchar(30) DEFAULT NULL, -`c63` varchar(30) DEFAULT NULL, -`c64` varchar(30) DEFAULT NULL, -`c65` varchar(30) DEFAULT NULL, -`c66` varchar(30) DEFAULT NULL, -`c67` varchar(30) DEFAULT NULL, -`c68` varchar(30) DEFAULT NULL, -`c69` varchar(30) DEFAULT NULL, -`c70` varchar(30) DEFAULT NULL, -`c71` varchar(30) DEFAULT NULL, -`c72` varchar(30) DEFAULT NULL, -`c73` varchar(30) DEFAULT NULL, -`c74` varchar(30) DEFAULT NULL, -`c75` varchar(30) DEFAULT NULL, -`c76` varchar(30) DEFAULT NULL, -`c77` varchar(30) DEFAULT NULL, -`c78` varchar(30) DEFAULT NULL, -`c79` varchar(30) DEFAULT NULL, -`c80` varchar(30) DEFAULT NULL, -`c81` varchar(30) DEFAULT NULL, -`c82` varchar(30) DEFAULT NULL, -`c83` varchar(30) DEFAULT NULL, -`c84` varchar(30) DEFAULT NULL, -`c85` varchar(30) DEFAULT NULL, -`c86` varchar(30) DEFAULT NULL, -`c87` varchar(30) DEFAULT NULL, -`c88` varchar(30) DEFAULT NULL, -`c89` varchar(30) DEFAULT NULL, -`c90` varchar(30) DEFAULT NULL, -`c91` varchar(30) DEFAULT NULL, -`c92` varchar(30) DEFAULT NULL, -`c93` varchar(30) DEFAULT NULL, -`c94` varchar(30) DEFAULT NULL, -`c95` varchar(30) DEFAULT NULL, -`c96` varchar(30) DEFAULT NULL, -`c97` varchar(30) DEFAULT NULL, -`c98` varchar(30) DEFAULT NULL, -`c99` varchar(30) DEFAULT NULL, -`c100` varchar(30) DEFAULT NULL, -`c101` varchar(30) DEFAULT NULL, -`c102` varchar(30) DEFAULT NULL, -`c103` varchar(30) DEFAULT NULL, -`c104` varchar(30) DEFAULT NULL, -`c105` varchar(30) DEFAULT NULL, -`c106` varchar(30) DEFAULT NULL, -`c107` varchar(30) DEFAULT NULL, -`c108` varchar(30) DEFAULT NULL, -`c109` varchar(30) DEFAULT NULL, -`c110` varchar(30) DEFAULT NULL, -`c111` varchar(30) DEFAULT NULL, -`c112` varchar(30) DEFAULT NULL, -`c113` varchar(30) DEFAULT NULL, -`c114` varchar(30) DEFAULT NULL, -`c115` varchar(30) DEFAULT NULL, -`c116` varchar(30) DEFAULT NULL, -`c117` varchar(30) DEFAULT NULL, -`c118` varchar(30) DEFAULT NULL, -`c119` varchar(30) DEFAULT NULL, -`c120` varchar(30) DEFAULT NULL, -`c121` varchar(30) DEFAULT NULL, -`c122` varchar(30) DEFAULT NULL, -`c123` varchar(30) DEFAULT NULL, -`c124` varchar(30) DEFAULT NULL, -`c125` varchar(30) DEFAULT NULL, -`c126` varchar(30) DEFAULT NULL, -PRIMARY KEY (`c1`) -) ENGINE=InnoDB; -### TABLE with field_metadata_size == 251 -CREATE TABLE `t2` ( -`c1` float, -`c2` varchar(30) NOT NULL, -`c3` varchar(30) DEFAULT NULL, -`c4` varchar(30) DEFAULT NULL, -`c5` varchar(30) DEFAULT NULL, -`c6` varchar(30) DEFAULT NULL, -`c7` varchar(30) DEFAULT NULL, -`c8` varchar(30) DEFAULT NULL, -`c9` varchar(30) DEFAULT NULL, -`c10` varchar(30) DEFAULT NULL, -`c11` varchar(30) DEFAULT NULL, -`c12` varchar(30) DEFAULT NULL, -`c13` varchar(30) DEFAULT NULL, -`c14` varchar(30) DEFAULT NULL, -`c15` varchar(30) DEFAULT NULL, -`c16` varchar(30) DEFAULT NULL, -`c17` varchar(30) DEFAULT NULL, -`c18` varchar(30) DEFAULT NULL, -`c19` varchar(30) DEFAULT NULL, -`c20` varchar(30) DEFAULT NULL, -`c21` varchar(30) DEFAULT NULL, -`c22` varchar(30) DEFAULT NULL, -`c23` varchar(30) DEFAULT NULL, -`c24` varchar(30) DEFAULT NULL, -`c25` varchar(30) DEFAULT NULL, -`c26` varchar(30) DEFAULT NULL, -`c27` varchar(30) DEFAULT NULL, -`c28` varchar(30) DEFAULT NULL, -`c29` varchar(30) DEFAULT NULL, -`c30` varchar(30) DEFAULT NULL, -`c31` varchar(30) DEFAULT NULL, -`c32` varchar(30) DEFAULT NULL, -`c33` varchar(30) DEFAULT NULL, -`c34` varchar(30) DEFAULT NULL, -`c35` varchar(30) DEFAULT NULL, -`c36` varchar(30) DEFAULT NULL, -`c37` varchar(30) DEFAULT NULL, -`c38` varchar(30) DEFAULT NULL, -`c39` varchar(30) DEFAULT NULL, -`c40` varchar(30) DEFAULT NULL, -`c41` varchar(30) DEFAULT NULL, -`c42` varchar(30) DEFAULT NULL, -`c43` varchar(30) DEFAULT NULL, -`c44` varchar(30) DEFAULT NULL, -`c45` varchar(30) DEFAULT NULL, -`c46` varchar(30) DEFAULT NULL, -`c47` varchar(30) DEFAULT NULL, -`c48` varchar(30) DEFAULT NULL, -`c49` varchar(30) DEFAULT NULL, -`c50` varchar(30) DEFAULT NULL, -`c51` varchar(30) DEFAULT NULL, -`c52` varchar(30) DEFAULT NULL, -`c53` varchar(30) DEFAULT NULL, -`c54` varchar(30) DEFAULT NULL, -`c55` varchar(30) DEFAULT NULL, -`c56` varchar(30) DEFAULT NULL, -`c57` varchar(30) DEFAULT NULL, -`c58` varchar(30) DEFAULT NULL, -`c59` varchar(30) DEFAULT NULL, -`c60` varchar(30) DEFAULT NULL, -`c61` varchar(30) DEFAULT NULL, -`c62` varchar(30) DEFAULT NULL, -`c63` varchar(30) DEFAULT NULL, -`c64` varchar(30) DEFAULT NULL, -`c65` varchar(30) DEFAULT NULL, -`c66` varchar(30) DEFAULT NULL, -`c67` varchar(30) DEFAULT NULL, -`c68` varchar(30) DEFAULT NULL, -`c69` varchar(30) DEFAULT NULL, -`c70` varchar(30) DEFAULT NULL, -`c71` varchar(30) DEFAULT NULL, -`c72` varchar(30) DEFAULT NULL, -`c73` varchar(30) DEFAULT NULL, -`c74` varchar(30) DEFAULT NULL, -`c75` varchar(30) DEFAULT NULL, -`c76` varchar(30) DEFAULT NULL, -`c77` varchar(30) DEFAULT NULL, -`c78` varchar(30) DEFAULT NULL, -`c79` varchar(30) DEFAULT NULL, -`c80` varchar(30) DEFAULT NULL, -`c81` varchar(30) DEFAULT NULL, -`c82` varchar(30) DEFAULT NULL, -`c83` varchar(30) DEFAULT NULL, -`c84` varchar(30) DEFAULT NULL, -`c85` varchar(30) DEFAULT NULL, -`c86` varchar(30) DEFAULT NULL, -`c87` varchar(30) DEFAULT NULL, -`c88` varchar(30) DEFAULT NULL, -`c89` varchar(30) DEFAULT NULL, -`c90` varchar(30) DEFAULT NULL, -`c91` varchar(30) DEFAULT NULL, -`c92` varchar(30) DEFAULT NULL, -`c93` varchar(30) DEFAULT NULL, -`c94` varchar(30) DEFAULT NULL, -`c95` varchar(30) DEFAULT NULL, -`c96` varchar(30) DEFAULT NULL, -`c97` varchar(30) DEFAULT NULL, -`c98` varchar(30) DEFAULT NULL, -`c99` varchar(30) DEFAULT NULL, -`c100` varchar(30) DEFAULT NULL, -`c101` varchar(30) DEFAULT NULL, -`c102` varchar(30) DEFAULT NULL, -`c103` varchar(30) DEFAULT NULL, -`c104` varchar(30) DEFAULT NULL, -`c105` varchar(30) DEFAULT NULL, -`c106` varchar(30) DEFAULT NULL, -`c107` varchar(30) DEFAULT NULL, -`c108` varchar(30) DEFAULT NULL, -`c109` varchar(30) DEFAULT NULL, -`c110` varchar(30) DEFAULT NULL, -`c111` varchar(30) DEFAULT NULL, -`c112` varchar(30) DEFAULT NULL, -`c113` varchar(30) DEFAULT NULL, -`c114` varchar(30) DEFAULT NULL, -`c115` varchar(30) DEFAULT NULL, -`c116` varchar(30) DEFAULT NULL, -`c117` varchar(30) DEFAULT NULL, -`c118` varchar(30) DEFAULT NULL, -`c119` varchar(30) DEFAULT NULL, -`c120` varchar(30) DEFAULT NULL, -`c121` varchar(30) DEFAULT NULL, -`c122` varchar(30) DEFAULT NULL, -`c123` varchar(30) DEFAULT NULL, -`c124` varchar(30) DEFAULT NULL, -`c125` varchar(30) DEFAULT NULL, -`c126` varchar(30) DEFAULT NULL, -PRIMARY KEY (`c1`) -) ENGINE=InnoDB; -LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); -LOCK TABLES `t2` WRITE; -INSERT INTO `t2` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); -DROP TABLE `t1`; -DROP TABLE `t2`; +### action: generating several tables with different metadata +### sizes (resorting to perl) +### testing table with 249 field metadata size. +### testing table with 250 field metadata size. +### testing table with 251 field metadata size. +### testing table with 252 field metadata size. +### testing table with 253 field metadata size. +### testing table with 254 field metadata size. +### testing table with 255 field metadata size. +### testing table with 256 field metadata size. +### testing table with 257 field metadata size. +### testing table with 258 field metadata size. FLUSH LOGS; -=== Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. +### assertion: the slave replicated event successfully and tables match for t10 +Comparing tables master:test.t10 and slave:test.t10 +### assertion: the slave replicated event successfully and tables match for t9 +Comparing tables master:test.t9 and slave:test.t9 +### assertion: the slave replicated event successfully and tables match for t8 +Comparing tables master:test.t8 and slave:test.t8 +### assertion: the slave replicated event successfully and tables match for t7 +Comparing tables master:test.t7 and slave:test.t7 +### assertion: the slave replicated event successfully and tables match for t6 +Comparing tables master:test.t6 and slave:test.t6 +### assertion: the slave replicated event successfully and tables match for t5 +Comparing tables master:test.t5 and slave:test.t5 +### assertion: the slave replicated event successfully and tables match for t4 +Comparing tables master:test.t4 and slave:test.t4 +### assertion: the slave replicated event successfully and tables match for t3 +Comparing tables master:test.t3 and slave:test.t3 +### assertion: the slave replicated event successfully and tables match for t2 +Comparing tables master:test.t2 and slave:test.t2 +### assertion: the slave replicated event successfully and tables match for t1 +Comparing tables master:test.t1 and slave:test.t1 +### assertion: check that binlog is not corrupt. Using mysqlbinlog to +### detect failure. Before the patch mysqlbinlog would find +### a corrupted event, thence would fail. diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test index 4d7ba1e0a81..022988d7ee3 100644 --- a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test +++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test @@ -2,7 +2,6 @@ # BUG#42749: infinite loop writing to row based binlog - processlist shows # "freeing items" # -# BUG#50018: binlog corruption when table has many columns # # WHY # === @@ -18,8 +17,7 @@ # # Checking that the patch fixes the problem is done as follows: # -# i) tables with several fields is created (above and below a 251 -# metadata size threshold) +# i) one table with m_field_metadata sized at 290 # ii) an insert is performed; # iii) the logs are flushed; # iv) mysqlbinlog is used to check if it succeeds. @@ -29,12 +27,8 @@ # reading the event. -- source include/master-slave.inc --- source include/have_log_bin.inc -- source include/have_innodb.inc -- source include/have_binlog_format_row.inc --- connection default - -RESET MASTER; -- disable_warnings DROP TABLE IF EXISTS `t1`; @@ -192,13 +186,20 @@ CREATE TABLE `t1` ( ) ENGINE=InnoDB; LOCK TABLES `t1` WRITE; +INSERT INTO `t1`(c2) VALUES ('1'); +FLUSH LOGS; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); +-- sync_slave_with_master +-- connection master + +-- echo ### assertion: the slave replicated event successfully and tables match +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc DROP TABLE `t1`; -FLUSH LOGS; - +-- connection master -- sync_slave_with_master -- connection master @@ -208,313 +209,132 @@ FLUSH LOGS; -- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog -- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug42749.binlog +############################################################# +# BUG#50018: binlog corruption when table has many columns +# +# Same test from BUG#42749, but now we generate some SQL which +# creates and inserts into tables with metadata size from 249 +# to 258. +# +# The test works as follows: +# 1. SQL for several CREATE TABLE and INSERTS are generated +# into a file. +# 2. This file is then "sourced" +# 3. The slave is synchronized with the master +# 4. FLUSH LOGS on master +# 5. Compare tables on master and slave. +# 6. run mysqlbinlog on master's binary log +# +# Steps #5 and #6 assert that binary log is not corrupted +# in both cases: when slave is replaying events and when +# mysqlbinlog is used to read the binary log + -- source include/master-slave-reset.inc -- connection master -# Create two tables one with field_metadata_size == 250 -# and another one with field_metadata_size == 252 +# Create several tables with field_metadata_size ranging +# from 249 to 258 (so that we cover 251 and 255 range). +# This should exercise the switch between using 1 or 3 +# bytes to pack m_field_metadata_size. # # Each varchar field takes up to 2 metadata bytes, see: # # Field_varstring::do_save_field_metadata (field.cc) # -# The integer field takes 0 bytes, see: -# -# Field::do_save_field_metadata (field.h) -# # The float field takes 1 byte, see: # # Field_float::do_save_field_metadata (field.cc) # -# We choose 250 and 252 which are the ones below and above -# the threshold for switching to use 1 or 3 bytes for the -# m_data_size increment. -# --- echo ### TABLE with field_metadata_size == 250 +-- let $generated_sql= $MYSQLTEST_VARDIR/tmp/b50018.sql +-- let B50018_FILE= $generated_sql -CREATE TABLE `t1` ( - `c1` int(11) NOT NULL AUTO_INCREMENT, - `c2` varchar(30) NOT NULL, - `c3` varchar(30) DEFAULT NULL, - `c4` varchar(30) DEFAULT NULL, - `c5` varchar(30) DEFAULT NULL, - `c6` varchar(30) DEFAULT NULL, - `c7` varchar(30) DEFAULT NULL, - `c8` varchar(30) DEFAULT NULL, - `c9` varchar(30) DEFAULT NULL, - `c10` varchar(30) DEFAULT NULL, - `c11` varchar(30) DEFAULT NULL, - `c12` varchar(30) DEFAULT NULL, - `c13` varchar(30) DEFAULT NULL, - `c14` varchar(30) DEFAULT NULL, - `c15` varchar(30) DEFAULT NULL, - `c16` varchar(30) DEFAULT NULL, - `c17` varchar(30) DEFAULT NULL, - `c18` varchar(30) DEFAULT NULL, - `c19` varchar(30) DEFAULT NULL, - `c20` varchar(30) DEFAULT NULL, - `c21` varchar(30) DEFAULT NULL, - `c22` varchar(30) DEFAULT NULL, - `c23` varchar(30) DEFAULT NULL, - `c24` varchar(30) DEFAULT NULL, - `c25` varchar(30) DEFAULT NULL, - `c26` varchar(30) DEFAULT NULL, - `c27` varchar(30) DEFAULT NULL, - `c28` varchar(30) DEFAULT NULL, - `c29` varchar(30) DEFAULT NULL, - `c30` varchar(30) DEFAULT NULL, - `c31` varchar(30) DEFAULT NULL, - `c32` varchar(30) DEFAULT NULL, - `c33` varchar(30) DEFAULT NULL, - `c34` varchar(30) DEFAULT NULL, - `c35` varchar(30) DEFAULT NULL, - `c36` varchar(30) DEFAULT NULL, - `c37` varchar(30) DEFAULT NULL, - `c38` varchar(30) DEFAULT NULL, - `c39` varchar(30) DEFAULT NULL, - `c40` varchar(30) DEFAULT NULL, - `c41` varchar(30) DEFAULT NULL, - `c42` varchar(30) DEFAULT NULL, - `c43` varchar(30) DEFAULT NULL, - `c44` varchar(30) DEFAULT NULL, - `c45` varchar(30) DEFAULT NULL, - `c46` varchar(30) DEFAULT NULL, - `c47` varchar(30) DEFAULT NULL, - `c48` varchar(30) DEFAULT NULL, - `c49` varchar(30) DEFAULT NULL, - `c50` varchar(30) DEFAULT NULL, - `c51` varchar(30) DEFAULT NULL, - `c52` varchar(30) DEFAULT NULL, - `c53` varchar(30) DEFAULT NULL, - `c54` varchar(30) DEFAULT NULL, - `c55` varchar(30) DEFAULT NULL, - `c56` varchar(30) DEFAULT NULL, - `c57` varchar(30) DEFAULT NULL, - `c58` varchar(30) DEFAULT NULL, - `c59` varchar(30) DEFAULT NULL, - `c60` varchar(30) DEFAULT NULL, - `c61` varchar(30) DEFAULT NULL, - `c62` varchar(30) DEFAULT NULL, - `c63` varchar(30) DEFAULT NULL, - `c64` varchar(30) DEFAULT NULL, - `c65` varchar(30) DEFAULT NULL, - `c66` varchar(30) DEFAULT NULL, - `c67` varchar(30) DEFAULT NULL, - `c68` varchar(30) DEFAULT NULL, - `c69` varchar(30) DEFAULT NULL, - `c70` varchar(30) DEFAULT NULL, - `c71` varchar(30) DEFAULT NULL, - `c72` varchar(30) DEFAULT NULL, - `c73` varchar(30) DEFAULT NULL, - `c74` varchar(30) DEFAULT NULL, - `c75` varchar(30) DEFAULT NULL, - `c76` varchar(30) DEFAULT NULL, - `c77` varchar(30) DEFAULT NULL, - `c78` varchar(30) DEFAULT NULL, - `c79` varchar(30) DEFAULT NULL, - `c80` varchar(30) DEFAULT NULL, - `c81` varchar(30) DEFAULT NULL, - `c82` varchar(30) DEFAULT NULL, - `c83` varchar(30) DEFAULT NULL, - `c84` varchar(30) DEFAULT NULL, - `c85` varchar(30) DEFAULT NULL, - `c86` varchar(30) DEFAULT NULL, - `c87` varchar(30) DEFAULT NULL, - `c88` varchar(30) DEFAULT NULL, - `c89` varchar(30) DEFAULT NULL, - `c90` varchar(30) DEFAULT NULL, - `c91` varchar(30) DEFAULT NULL, - `c92` varchar(30) DEFAULT NULL, - `c93` varchar(30) DEFAULT NULL, - `c94` varchar(30) DEFAULT NULL, - `c95` varchar(30) DEFAULT NULL, - `c96` varchar(30) DEFAULT NULL, - `c97` varchar(30) DEFAULT NULL, - `c98` varchar(30) DEFAULT NULL, - `c99` varchar(30) DEFAULT NULL, - `c100` varchar(30) DEFAULT NULL, - `c101` varchar(30) DEFAULT NULL, - `c102` varchar(30) DEFAULT NULL, - `c103` varchar(30) DEFAULT NULL, - `c104` varchar(30) DEFAULT NULL, - `c105` varchar(30) DEFAULT NULL, - `c106` varchar(30) DEFAULT NULL, - `c107` varchar(30) DEFAULT NULL, - `c108` varchar(30) DEFAULT NULL, - `c109` varchar(30) DEFAULT NULL, - `c110` varchar(30) DEFAULT NULL, - `c111` varchar(30) DEFAULT NULL, - `c112` varchar(30) DEFAULT NULL, - `c113` varchar(30) DEFAULT NULL, - `c114` varchar(30) DEFAULT NULL, - `c115` varchar(30) DEFAULT NULL, - `c116` varchar(30) DEFAULT NULL, - `c117` varchar(30) DEFAULT NULL, - `c118` varchar(30) DEFAULT NULL, - `c119` varchar(30) DEFAULT NULL, - `c120` varchar(30) DEFAULT NULL, - `c121` varchar(30) DEFAULT NULL, - `c122` varchar(30) DEFAULT NULL, - `c123` varchar(30) DEFAULT NULL, - `c124` varchar(30) DEFAULT NULL, - `c125` varchar(30) DEFAULT NULL, - `c126` varchar(30) DEFAULT NULL, - PRIMARY KEY (`c1`) -) ENGINE=InnoDB; +-- echo ### action: generating several tables with different metadata +-- echo ### sizes (resorting to perl) +-- perl +my $file= $ENV{'B50018_FILE'}; +open(FILE, ">", "$file") or die "Unable to open bug 50018 generated SQL file: $!" ; --- echo ### TABLE with field_metadata_size == 251 +my $tables= ""; +my $ntables= 10; +my $base_ncols= 124; -CREATE TABLE `t2` ( - `c1` float, - `c2` varchar(30) NOT NULL, - `c3` varchar(30) DEFAULT NULL, - `c4` varchar(30) DEFAULT NULL, - `c5` varchar(30) DEFAULT NULL, - `c6` varchar(30) DEFAULT NULL, - `c7` varchar(30) DEFAULT NULL, - `c8` varchar(30) DEFAULT NULL, - `c9` varchar(30) DEFAULT NULL, - `c10` varchar(30) DEFAULT NULL, - `c11` varchar(30) DEFAULT NULL, - `c12` varchar(30) DEFAULT NULL, - `c13` varchar(30) DEFAULT NULL, - `c14` varchar(30) DEFAULT NULL, - `c15` varchar(30) DEFAULT NULL, - `c16` varchar(30) DEFAULT NULL, - `c17` varchar(30) DEFAULT NULL, - `c18` varchar(30) DEFAULT NULL, - `c19` varchar(30) DEFAULT NULL, - `c20` varchar(30) DEFAULT NULL, - `c21` varchar(30) DEFAULT NULL, - `c22` varchar(30) DEFAULT NULL, - `c23` varchar(30) DEFAULT NULL, - `c24` varchar(30) DEFAULT NULL, - `c25` varchar(30) DEFAULT NULL, - `c26` varchar(30) DEFAULT NULL, - `c27` varchar(30) DEFAULT NULL, - `c28` varchar(30) DEFAULT NULL, - `c29` varchar(30) DEFAULT NULL, - `c30` varchar(30) DEFAULT NULL, - `c31` varchar(30) DEFAULT NULL, - `c32` varchar(30) DEFAULT NULL, - `c33` varchar(30) DEFAULT NULL, - `c34` varchar(30) DEFAULT NULL, - `c35` varchar(30) DEFAULT NULL, - `c36` varchar(30) DEFAULT NULL, - `c37` varchar(30) DEFAULT NULL, - `c38` varchar(30) DEFAULT NULL, - `c39` varchar(30) DEFAULT NULL, - `c40` varchar(30) DEFAULT NULL, - `c41` varchar(30) DEFAULT NULL, - `c42` varchar(30) DEFAULT NULL, - `c43` varchar(30) DEFAULT NULL, - `c44` varchar(30) DEFAULT NULL, - `c45` varchar(30) DEFAULT NULL, - `c46` varchar(30) DEFAULT NULL, - `c47` varchar(30) DEFAULT NULL, - `c48` varchar(30) DEFAULT NULL, - `c49` varchar(30) DEFAULT NULL, - `c50` varchar(30) DEFAULT NULL, - `c51` varchar(30) DEFAULT NULL, - `c52` varchar(30) DEFAULT NULL, - `c53` varchar(30) DEFAULT NULL, - `c54` varchar(30) DEFAULT NULL, - `c55` varchar(30) DEFAULT NULL, - `c56` varchar(30) DEFAULT NULL, - `c57` varchar(30) DEFAULT NULL, - `c58` varchar(30) DEFAULT NULL, - `c59` varchar(30) DEFAULT NULL, - `c60` varchar(30) DEFAULT NULL, - `c61` varchar(30) DEFAULT NULL, - `c62` varchar(30) DEFAULT NULL, - `c63` varchar(30) DEFAULT NULL, - `c64` varchar(30) DEFAULT NULL, - `c65` varchar(30) DEFAULT NULL, - `c66` varchar(30) DEFAULT NULL, - `c67` varchar(30) DEFAULT NULL, - `c68` varchar(30) DEFAULT NULL, - `c69` varchar(30) DEFAULT NULL, - `c70` varchar(30) DEFAULT NULL, - `c71` varchar(30) DEFAULT NULL, - `c72` varchar(30) DEFAULT NULL, - `c73` varchar(30) DEFAULT NULL, - `c74` varchar(30) DEFAULT NULL, - `c75` varchar(30) DEFAULT NULL, - `c76` varchar(30) DEFAULT NULL, - `c77` varchar(30) DEFAULT NULL, - `c78` varchar(30) DEFAULT NULL, - `c79` varchar(30) DEFAULT NULL, - `c80` varchar(30) DEFAULT NULL, - `c81` varchar(30) DEFAULT NULL, - `c82` varchar(30) DEFAULT NULL, - `c83` varchar(30) DEFAULT NULL, - `c84` varchar(30) DEFAULT NULL, - `c85` varchar(30) DEFAULT NULL, - `c86` varchar(30) DEFAULT NULL, - `c87` varchar(30) DEFAULT NULL, - `c88` varchar(30) DEFAULT NULL, - `c89` varchar(30) DEFAULT NULL, - `c90` varchar(30) DEFAULT NULL, - `c91` varchar(30) DEFAULT NULL, - `c92` varchar(30) DEFAULT NULL, - `c93` varchar(30) DEFAULT NULL, - `c94` varchar(30) DEFAULT NULL, - `c95` varchar(30) DEFAULT NULL, - `c96` varchar(30) DEFAULT NULL, - `c97` varchar(30) DEFAULT NULL, - `c98` varchar(30) DEFAULT NULL, - `c99` varchar(30) DEFAULT NULL, - `c100` varchar(30) DEFAULT NULL, - `c101` varchar(30) DEFAULT NULL, - `c102` varchar(30) DEFAULT NULL, - `c103` varchar(30) DEFAULT NULL, - `c104` varchar(30) DEFAULT NULL, - `c105` varchar(30) DEFAULT NULL, - `c106` varchar(30) DEFAULT NULL, - `c107` varchar(30) DEFAULT NULL, - `c108` varchar(30) DEFAULT NULL, - `c109` varchar(30) DEFAULT NULL, - `c110` varchar(30) DEFAULT NULL, - `c111` varchar(30) DEFAULT NULL, - `c112` varchar(30) DEFAULT NULL, - `c113` varchar(30) DEFAULT NULL, - `c114` varchar(30) DEFAULT NULL, - `c115` varchar(30) DEFAULT NULL, - `c116` varchar(30) DEFAULT NULL, - `c117` varchar(30) DEFAULT NULL, - `c118` varchar(30) DEFAULT NULL, - `c119` varchar(30) DEFAULT NULL, - `c120` varchar(30) DEFAULT NULL, - `c121` varchar(30) DEFAULT NULL, - `c122` varchar(30) DEFAULT NULL, - `c123` varchar(30) DEFAULT NULL, - `c124` varchar(30) DEFAULT NULL, - `c125` varchar(30) DEFAULT NULL, - `c126` varchar(30) DEFAULT NULL, - PRIMARY KEY (`c1`) -) ENGINE=InnoDB; +for my $i (1..$ntables) +{ + my $ncols= $base_ncols + $i; + my $metadata_size= $ncols_variable * 2 + 1; -LOCK TABLES `t1` WRITE; -INSERT INTO `t1` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + print FILE "-- echo ### testing table with " . ($base_ncols*2 + $i) . " field metadata size.\n"; + print FILE "CREATE TABLE t$i (\n"; + for my $n (1..$base_ncols) + { + print FILE "c$n VARCHAR(30) NOT NULL DEFAULT 'BUG#50018',\n"; + } + for my $n (1..$i) + { + print FILE "c" . ($base_ncols+$n) . " FLOAT NOT NULL DEFAULT 0"; + if ($n < $i) + { + print FILE ",\n"; + } + } -LOCK TABLES `t2` WRITE; -INSERT INTO `t2` VALUES ('1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1','1'); + print FILE ") Engine=InnoDB;\n"; -DROP TABLE `t1`; -DROP TABLE `t2`; + $tables.= " t$i WRITE"; + if ($i < $ntables) + { + $tables .=","; + } + + print FILE "LOCK TABLES t$i WRITE;\n"; + print FILE "INSERT INTO t$i(c". ($base_ncols+1) . ") VALUES (50018);\n"; +} + +close(FILE); + +EOF + +## we don't need this in the result file +## however, for debugging purposes you +## may want to reactivate query logging +-- disable_query_log +-- source $generated_sql +UNLOCK TABLES; +-- enable_query_log + +-- sync_slave_with_master +-- connection master FLUSH LOGS; --- sync_slave_with_master +-- let $ntables=10 +while($ntables) +{ + -- echo ### assertion: the slave replicated event successfully and tables match for t$ntables + -- let $diff_table_1=master:test.t$ntables + -- let $diff_table_2=slave:test.t$ntables + -- source include/diff_tables.inc --- connection master + -- connection master + -- disable_query_log + -- eval DROP TABLE t$ntables + -- enable_query_log + -- sync_slave_with_master + -- connection master --- echo === Using mysqlbinlog to detect failure. Before the patch mysqlbinlog would find a corrupted event, thence would fail. + -- dec $ntables +} +-- echo ### assertion: check that binlog is not corrupt. Using mysqlbinlog to +-- echo ### detect failure. Before the patch mysqlbinlog would find +-- echo ### a corrupted event, thence would fail. -- let $MYSQLD_DATADIR= `SELECT @@datadir`; --- exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog --- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog +-- exec $MYSQL_BINLOG -v --hex $MYSQLD_DATADIR/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog +## clean up +## For debugging purposes you might want not to remove these +-- remove_file $MYSQLTEST_VARDIR/tmp/mysqlbinlog_bug50018.binlog +-- remove_file $generated_sql -- source include/master-slave-end.inc From c1043021c81a4394b5aa9961d7106c437275b040 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Jan 2010 13:42:23 +0800 Subject: [PATCH 34/47] BUG #28421 Infinite loop on slave relay logs Manually deleteing one or more entries from 'master-bin.index', will cause master infinitely loop to send one binlog file. When starting a dump session, master opens index file and search the binlog file which is being requested by the slave. The position of the binlog file in the index file is recorded. it will be used to find the next binlog file when current binlog file has dumped completely. As only the position is used, it may not get the correct file if some entries has been removed manually from the index file. the master will reopen the current binlog file which has been dump completely and redump it if it can not get the next binlog file's name from index file. It obviously is a logical error. Even though it is allowed to manually change index file, but it is not recommended. so after this patch, master sends a fatal error to slave and close the dump session if a new binlog file has been generated and master can not get it from the index file. --- mysql-test/include/truncate_file.inc | 16 ++++ .../rpl/r/rpl_manual_change_index_file.result | 25 ++++++ .../rpl/t/rpl_manual_change_index_file.test | 85 +++++++++++++++++++ sql/sql_repl.cc | 9 +- 4 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 mysql-test/include/truncate_file.inc create mode 100644 mysql-test/suite/rpl/r/rpl_manual_change_index_file.result create mode 100644 mysql-test/suite/rpl/t/rpl_manual_change_index_file.test diff --git a/mysql-test/include/truncate_file.inc b/mysql-test/include/truncate_file.inc new file mode 100644 index 00000000000..c82108681bd --- /dev/null +++ b/mysql-test/include/truncate_file.inc @@ -0,0 +1,16 @@ +# truncate a giving file, all contents of the file are be cleared + +if (`SELECT 'x$file' = 'x'`) +{ + --echo Please assign a file name to $file!! + exit; +} + +let TRUNCATE_FILE= $file; + +perl; +use Env; +Env::import('TRUNCATE_FILE'); +open FILE, '>', $TRUNCATE_FILE || die "Can not open file $file"; +close FILE; +EOF diff --git a/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result new file mode 100644 index 00000000000..9061abca477 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_manual_change_index_file.result @@ -0,0 +1,25 @@ +stop slave; +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; +start slave; +FLUSH LOGS; +CREATE TABLE t1(c1 INT); +FLUSH LOGS; +call mtr.add_suppression('Got fatal error 1236 from master when reading data from binary log: .*could not find next log'); +Last_IO_Error +Got fatal error 1236 from master when reading data from binary log: 'could not find next log' +CREATE TABLE t2(c1 INT); +FLUSH LOGS; +CREATE TABLE t3(c1 INT); +FLUSH LOGS; +CREATE TABLE t4(c1 INT); +START SLAVE IO_THREAD; +SHOW TABLES; +Tables_in_test +t1 +t2 +t3 +t4 +DROP TABLE t1, t2, t3, t4; diff --git a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test new file mode 100644 index 00000000000..ba3dbd174f4 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test @@ -0,0 +1,85 @@ +source include/master-slave.inc; + +# +# BUG#28421 Infinite loop on slave relay logs +# +# That, manually deleteing one or more entries from 'master-bin.index', will +# cause master infinitely loop to send one binlog file. +# +# Manually changing index file is a illegal action, so when this happen, we +# send a fatal error to slave and close the dump session. + +FLUSH LOGS; +# Now, 2 entries in index file. +# ./master-bin.000001 +# ./master-bin.000002 + +CREATE TABLE t1(c1 INT); +# Now, the current dump file(master-bin.000002) is the second line of index +# file +sync_slave_with_master; +# Now, all events has been replicate to slave. As current dump file +# (master-bin.000002) is the last binlog file, so master is waiting for new +# events. + +connection master; +# Delete './master-bin.000001' from index file. +let $MYSQLD_DATADIR= `SELECT @@DATADIR`; +#remove_file $MYSQLD_DATADIR/master-bin.index; +let $file= $MYSQLD_DATADIR/master-bin.index; +source include/truncate_file.inc; + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +./master-bin.000002 +EOF +sleep 0.00000001; +} + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +.\master-bin.000002 +EOF +sleep 0.00000001; +} + +# Now, only 1 entry in index file. +# ./master-bin.000002 + +# Generate master-bin.000003, but it is in the second line. +FLUSH LOGS; +# Now, 2 entries in index file. +# ./master-bin.000002 +# ./master-bin.000003 + +# Now, master know that new binlog file(master-bin.000003) has been generated. +# It expects that the new binlog file is in third line of index file, but +# there is no third line in index file. It is so strange that master sends an +# error to slave. +call mtr.add_suppression('Got fatal error 1236 from master when reading data from binary log: .*could not find next log'); +connection slave; +source include/wait_for_slave_io_to_stop.inc; +let $last_error= query_get_value(SHOW SLAVE STATUS, Last_IO_Error, 1); +echo Last_IO_Error; +echo $last_error; + +connection master; +CREATE TABLE t2(c1 INT); +FLUSH LOGS; +CREATE TABLE t3(c1 INT); +FLUSH LOGS; +CREATE TABLE t4(c1 INT); + +connection slave; +START SLAVE IO_THREAD; +source include/wait_for_slave_io_to_start.inc; + +connection master; +sync_slave_with_master; +SHOW TABLES; + +connection master; +DROP TABLE t1, t2, t3, t4; +source include/master-slave-end.inc; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index b8f2e1e39bf..de038f8dc2c 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -711,11 +711,14 @@ impossible position"; thd_proc_info(thd, "Finished reading one binlog; switching to next binlog"); switch (mysql_bin_log.find_next_log(&linfo, 1)) { - case LOG_INFO_EOF: - loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK); - break; case 0: break; + case LOG_INFO_EOF: + if (mysql_bin_log.is_active(log_file_name)) + { + loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK); + break; + } default: errmsg = "could not find next log"; my_errno= ER_MASTER_FATAL_ERROR_READING_BINLOG; From 4ae5679f4720c8c4a5d04b0c4c4661cad1076b2c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 8 Jan 2010 23:32:40 +0800 Subject: [PATCH 35/47] Postfix Recover the right contents of the index file at the end of the test case. --- .../rpl/t/rpl_manual_change_index_file.test | 27 ++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test index ba3dbd174f4..ecdf10ac2c2 100644 --- a/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test +++ b/mysql-test/suite/rpl/t/rpl_manual_change_index_file.test @@ -25,7 +25,6 @@ sync_slave_with_master; connection master; # Delete './master-bin.000001' from index file. let $MYSQLD_DATADIR= `SELECT @@DATADIR`; -#remove_file $MYSQLD_DATADIR/master-bin.index; let $file= $MYSQLD_DATADIR/master-bin.index; source include/truncate_file.inc; @@ -45,8 +44,7 @@ EOF sleep 0.00000001; } -# Now, only 1 entry in index file. -# ./master-bin.000002 +# Now, only 1 entry in index file. ./master-bin.000002 # Generate master-bin.000003, but it is in the second line. FLUSH LOGS; @@ -66,6 +64,29 @@ echo Last_IO_Error; echo $last_error; connection master; + +source include/truncate_file.inc; + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) NOT IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +./master-bin.000001 +./master-bin.000002 +./master-bin.000003 +EOF +sleep 0.00000001; +} + +if (`SELECT CONVERT(@@VERSION_COMPILE_OS USING latin1) IN ('Win32', 'Win64', 'Windows')`) +{ +append_file $MYSQLD_DATADIR/master-bin.index; +.\master-bin.000001 +.\master-bin.000002 +.\master-bin.000003 +EOF +sleep 0.00000001; +} + CREATE TABLE t2(c1 INT); FLUSH LOGS; CREATE TABLE t3(c1 INT); From 107f34ed77aad27b1fca24aaf048d1cbb28978b2 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Mon, 11 Jan 2010 18:21:22 +0400 Subject: [PATCH 36/47] Bug #49955: ld error message: undefined reference to `strmov_overlapp' 32bit builds with the --enable-assembler flag (enabled by default) fail with an error message: undefined reference to `strmov_overlapp'. Since the fix for bug 48866 we use a home-grown strmov function instead of the ctpcpy function, but the source file for this function was missed in the Makefile.am. The strings/Makefile.am file has been modified to include strmov.c file into ASSEMBLER_x86 and ASSEMBLER_sparc32 sections. strings/Makefile.am: Bug #49955: ld error message: undefined reference to `strmov_overlapp' The strings/Makefile.am file has been modified to include strmov.c file into ASSEMBLER_x86 and ASSEMBLER_sparc32 sections. --- strings/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/strings/Makefile.am b/strings/Makefile.am index f0d6585dee4..c4712792c69 100644 --- a/strings/Makefile.am +++ b/strings/Makefile.am @@ -21,13 +21,13 @@ pkglib_LIBRARIES = libmystrings.a # Exact one of ASSEMBLER_X if ASSEMBLER_x86 ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s -CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c +CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c strmov.c else if ASSEMBLER_sparc32 # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s -CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c +CSRCS = strcont.c strfill.c strcend.c is_prefix.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c strxmov.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c strmov.c else #no assembler ASRCS = From 3c9322e73f5b994b7ec13ed73e99ce4bc94694b8 Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 11 Jan 2010 19:23:36 +0100 Subject: [PATCH 37/47] Implement the change of RPM versioning and file naming: - "release" starts from 1 - "level" ("m2", "rc", ...) is included in the RPM version. --- support-files/Makefile.am | 3 ++- support-files/mysql.spec.sh | 14 ++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/support-files/Makefile.am b/support-files/Makefile.am index 77eddea3227..c78f08a39b3 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2001, 2003-2006 MySQL AB +# Copyright (C) 2000-2006 MySQL AB, 2008-2010 Sun Microsystems, Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -119,6 +119,7 @@ SUFFIXES = .sh -e 's!@''SHARED_LIB_VERSION''@!@SHARED_LIB_VERSION@!' \ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \ + -e 's!@''MYSQL_U_SCORE_VERSION''@!@MYSQL_U_SCORE_VERSION@!' \ -e 's!@''MYSQL_COPYRIGHT_YEAR''@!@MYSQL_COPYRIGHT_YEAR@!' \ -e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \ -e 's!@''PERL_DBI_VERSION''@!@PERL_DBI_VERSION@!' \ diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 8209c4560c6..6c586d21a3c 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1,4 +1,4 @@ -# Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +# Copyright 2000-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -51,9 +51,9 @@ %{!?_with_cluster:%define CLUSTER_BUILD 0} %if %{STATIC_BUILD} -%define release 0 +%define release 1 %else -%define release 0.glibc23 +%define release 1.glibc23 %endif %define mysql_license GPL %define mysqld_user mysql @@ -87,7 +87,7 @@ Name: MySQL Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases -Version: @MYSQL_NO_DASH_VERSION@ +Version: @MYSQL_U_SCORE_VERSION@ Release: %{release} License: Copyright 2000-2008 MySQL AB, @MYSQL_COPYRIGHT_YEAR@ Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Under %{mysql_license} license as shown in the Description field. Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz @@ -882,6 +882,12 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Jan 11 2010 Joerg Bruehe + +- Change RPM file naming: + - Suffix like "-m2", "-rc" becomes part of version as "_m2", "_rc". + - Release counts from 1, not 0. + * Mon Aug 24 2009 Jonathan Perkin - Add conditionals for bundled zlib and innodb plugin From 71465af9d40b85c38cebdeed393925302003785b Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Tue, 12 Jan 2010 12:41:18 +0100 Subject: [PATCH 38/47] Implement the change of RPM versioning and file naming: - "release" starts from 1 - "level" ("m2", "rc", ...) is included in the RPM version. --- configure.in | 13 ++++++++----- support-files/Makefile.am | 3 ++- support-files/mysql.spec.sh | 14 ++++++++++---- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/configure.in b/configure.in index b206dfbd079..405ebddadbe 100644 --- a/configure.in +++ b/configure.in @@ -30,12 +30,14 @@ NDB_VERSION_STATUS="" # Remember that regexps needs to quote [ and ] since this is run through m4 # We take some made up examples # -# VERSION 5.1.40sp1-alpha 5.0.34a -# MYSQL_NO_DASH_VERSION 5.1.40sp1 5.0.34a -# MYSQL_NUMERIC_VERSION 5.1.40 5.0.34 -# MYSQL_BASE_VERSION 5.1 5.0 -# MYSQL_VERSION_ID 50140 50034 +# VERSION 5.1.40sp1-alpha 5.0.34a 5.5.1-m2 +# MYSQL_U_SCORE_VERSION 5.1.40sp1_alpha 5.0.34a 5.5.1_m2 +# MYSQL_NO_DASH_VERSION 5.1.40sp1 5.0.34a 5.5.1 +# MYSQL_NUMERIC_VERSION 5.1.40 5.0.34 5.5.1 +# MYSQL_BASE_VERSION 5.1 5.0 5.5 +# MYSQL_VERSION_ID 50140 50034 50501 # +MYSQL_U_SCORE_VERSION=`echo $VERSION | sed -e "s|-|_|"` MYSQL_NO_DASH_VERSION=`echo $VERSION | sed -e "s|-.*$||"` MYSQL_NUMERIC_VERSION=`echo $MYSQL_NO_DASH_VERSION | sed -e "s|[[a-z]][[a-z0-9]]*$||"` MYSQL_BASE_VERSION=`echo $MYSQL_NUMERIC_VERSION | sed -e "s|\.[[^.]]*$||"` @@ -78,6 +80,7 @@ romanian russian serbian slovak spanish swedish ukrainian" ##### ##### +AC_SUBST(MYSQL_U_SCORE_VERSION) AC_SUBST(MYSQL_NO_DASH_VERSION) AC_SUBST(MYSQL_BASE_VERSION) AC_SUBST(MYSQL_VERSION_ID) diff --git a/support-files/Makefile.am b/support-files/Makefile.am index b9d6fde742a..4cb8bb4645d 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2001, 2003-2006 MySQL AB +# Copyright (C) 2000-2006 MySQL AB, 2008-2010 Sun Microsystems, Inc. # # This library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -104,6 +104,7 @@ SUFFIXES = .sh -e 's!@''SHARED_LIB_VERSION''@!@SHARED_LIB_VERSION@!' \ -e 's!@''MYSQL_BASE_VERSION''@!@MYSQL_BASE_VERSION@!' \ -e 's!@''MYSQL_NO_DASH_VERSION''@!@MYSQL_NO_DASH_VERSION@!' \ + -e 's!@''MYSQL_U_SCORE_VERSION''@!@MYSQL_U_SCORE_VERSION@!' \ -e 's!@''MYSQL_TCP_PORT''@!@MYSQL_TCP_PORT@!' \ -e 's!@''PERL_DBI_VERSION''@!@PERL_DBI_VERSION@!' \ -e 's!@''PERL_DBD_VERSION''@!@PERL_DBD_VERSION@!' \ diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index 584c0abc777..98f715da94d 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -1,4 +1,4 @@ -# Copyright (C) 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +# Copyright (C) 2000-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,9 +28,9 @@ %{!?_with_yassl:%define YASSL_BUILD 0} %if %{STATIC_BUILD} -%define release 0 +%define release 1 %else -%define release 0.glibc23 +%define release 1.glibc23 %endif %define license GPL %define mysqld_user mysql @@ -64,7 +64,7 @@ Name: MySQL Summary: MySQL: a very fast and reliable SQL database server Group: Applications/Databases -Version: @MYSQL_NO_DASH_VERSION@ +Version: @MYSQL_U_SCORE_VERSION@ Release: %{release} License: %{license} Source: http://www.mysql.com/Downloads/MySQL-@MYSQL_BASE_VERSION@/mysql-%{mysql_version}.tar.gz @@ -818,6 +818,12 @@ fi # itself - note that they must be ordered by date (important when # merging BK trees) %changelog +* Mon Jan 11 2010 Joerg Bruehe + +- Change RPM file naming: + - Suffix like "-m2", "-rc" becomes part of version as "_m2", "_rc". + - Release counts from 1, not 0. + * Fri Nov 07 2008 Joerg Bruehe - Correct yesterday's fix, so that it also works for the last flag. From c8b5804f295ea109f56f29de8c350133f9070a6a Mon Sep 17 00:00:00 2001 From: Martin Hansson Date: Tue, 12 Jan 2010 15:16:26 +0100 Subject: [PATCH 39/47] Bug#48157: crash in Item_field::used_tables MySQL handles the join syntax "JOIN ... USING( field1, ... )" and natural joins by building the same parse tree as a corresponding join with an "ON t1.field1 = t2.field1 ..." expression would produce. This parse tree was not cleaned up properly in the following scenario. If a thread tries to lock some tables and finds that the tables were dropped and re-created while waiting for the lock, it cleans up column references in the statement by means a per-statement free list. But if the statement was part of a stored procedure, column references on the stored procedure's free list weren't cleaned up and thus contained pointers to freed objects. Fixed by adding a call to clean up the current prepared statement's free list. mysql-test/r/sp_sync.result: Bug#48157: Test case mysql-test/t/sp_sync.test: Bug#48157: Test result sql/item.h: Bug#48157: Commented field. sql/sql_parse.cc: Bug#48157: Commented function. sql/sql_update.cc: Bug#48157: fix --- mysql-test/r/sp_sync.result | 23 ++++++++++++++++ mysql-test/t/sp_sync.test | 55 +++++++++++++++++++++++++++++++++++++ sql/item.h | 7 +++++ sql/sql_parse.cc | 6 ++-- sql/sql_update.cc | 6 +++- 5 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 mysql-test/r/sp_sync.result create mode 100644 mysql-test/t/sp_sync.test diff --git a/mysql-test/r/sp_sync.result b/mysql-test/r/sp_sync.result new file mode 100644 index 00000000000..afa37e70531 --- /dev/null +++ b/mysql-test/r/sp_sync.result @@ -0,0 +1,23 @@ +Tests of syncronization of stored procedure execution. +# +# Bug#48157: crash in Item_field::used_tables +# +CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b; +CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b; +CREATE PROCEDURE p1() +BEGIN +UPDATE t1 JOIN t2 USING( a, b ) SET t1.b = 1, t2.b = 1; +END| +LOCK TABLES t1 WRITE, t2 WRITE; +SET DEBUG_SYNC = 'multi_update_reopen_tables SIGNAL parked WAIT_FOR go'; +CALL p1(); +DROP TABLE t1, t2; +SET DEBUG_SYNC = 'now WAIT_FOR parked'; +CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b; +CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b; +SET DEBUG_SYNC = 'now SIGNAL go'; +# Without the DEBUG_SYNC supplied in the same patch as this test in the +# code, this test statement will hang. +DROP TABLE t1, t2; +DROP PROCEDURE p1; +SET DEBUG_SYNC = 'RESET'; diff --git a/mysql-test/t/sp_sync.test b/mysql-test/t/sp_sync.test new file mode 100644 index 00000000000..98903989cd5 --- /dev/null +++ b/mysql-test/t/sp_sync.test @@ -0,0 +1,55 @@ +--echo Tests of syncronization of stored procedure execution. + +--source include/have_debug_sync.inc + +--echo # +--echo # Bug#48157: crash in Item_field::used_tables +--echo # + +CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b; +CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b; + +DELIMITER |; + +CREATE PROCEDURE p1() +BEGIN + UPDATE t1 JOIN t2 USING( a, b ) SET t1.b = 1, t2.b = 1; +END| + +DELIMITER ;| + +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); + +connection con1; +LOCK TABLES t1 WRITE, t2 WRITE; + +connection con2; +LET $ID= `select connection_id()`; +SET DEBUG_SYNC = 'multi_update_reopen_tables SIGNAL parked WAIT_FOR go'; +--send CALL p1() + +connection con1; +let $wait_condition= SELECT 1 FROM information_schema.processlist WHERE ID = $ID AND +state = "Locked"; +--source include/wait_condition.inc +DROP TABLE t1, t2; +SET DEBUG_SYNC = 'now WAIT_FOR parked'; +CREATE TABLE t1 AS SELECT 1 AS a, 1 AS b; +CREATE TABLE t2 AS SELECT 1 AS a, 1 AS b; +SET DEBUG_SYNC = 'now SIGNAL go'; + +connection con2; +--reap + +disconnect con1; +disconnect con2; +connection default; + +--echo # Without the DEBUG_SYNC supplied in the same patch as this test in the +--echo # code, this test statement will hang. +DROP TABLE t1, t2; +DROP PROCEDURE p1; + +SET DEBUG_SYNC = 'RESET'; + diff --git a/sql/item.h b/sql/item.h index 8f0e5874f3f..88e90924fcc 100644 --- a/sql/item.h +++ b/sql/item.h @@ -506,6 +506,13 @@ public: char * name; /* Name from select */ /* Original item name (if it was renamed)*/ char * orig_name; + /** + Intrusive list pointer for free list. If not null, points to the next + Item on some Query_arena's free list. For instance, stored procedures + have their own Query_arena's. + + @see Query_arena::free_list + */ Item *next; uint32 max_length; uint name_length; /* Length of name */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 69c9ddc7806..48743a2d48f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -615,8 +615,10 @@ void free_items(Item *item) DBUG_VOID_RETURN; } -/* This works because items are allocated with sql_alloc() */ - +/** + This works because items are allocated with sql_alloc(). + @note The function also handles null pointers (empty list). +*/ void cleanup_items(Item *item) { DBUG_ENTER("cleanup_items"); diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c988d746500..26f40c7fa9f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -23,6 +23,7 @@ #include "sql_select.h" #include "sp_head.h" #include "sql_trigger.h" +#include "debug_sync.h" /* Return 0 if row hasn't changed */ @@ -1143,8 +1144,11 @@ reopen_tables: items from 'fields' list, so the cleanup above is necessary to. */ cleanup_items(thd->free_list); - + cleanup_items(thd->stmt_arena->free_list); close_tables_for_reopen(thd, &table_list); + + DEBUG_SYNC(thd, "multi_update_reopen_tables"); + goto reopen_tables; } From 71fd38e488d1d10210c9c5370f56d682d9884814 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Wed, 13 Jan 2010 08:16:36 +0400 Subject: [PATCH 40/47] Bug #50096: CONCAT_WS inside procedure returning wrong data Selecting of the CONCAT_WS(......) result into a user variable may return wrong data. Item_func_concat_ws::val_str contains a number of memory allocation-saving optimization tricks. After the fix for bug 46815 the control flow has been changed to a branch that is commented as "This is quite uncommon!": one of places where we are trying to concatenate strings inplace. However, that "uncommon" place didn't care about PS parameters, that have another trick in Item_sp_variable::val_str(): they use the intermediate Item_sp_variable::str_value field, where they may store a reference to an external argument's buffer. The Item_func_concat_ws::val_str function has been modified to take into account val_str functions (such as Item_sp_variable::val_str) that return a pointer to an internal Item member variable that may reference to a buffer provided. mysql-test/r/func_concat.result: Added test case for bug #50096. mysql-test/t/func_concat.test: Added test case for bug #50096. sql/item_strfunc.cc: Bug #50096: CONCAT_WS inside procedure returning wrong data The Item_func_concat_ws::val_str function has been modified to take into account val_str functions (such as Item_sp_variable::val_str) that return a pointer to an internal Item member variable that may reference to a buffer provided. --- mysql-test/r/func_concat.result | 11 +++++++++++ mysql-test/t/func_concat.test | 13 +++++++++++++ sql/item_strfunc.cc | 4 ++-- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result index 75b4888fbb2..c4c2b46c6c2 100644 --- a/mysql-test/r/func_concat.result +++ b/mysql-test/r/func_concat.result @@ -1,4 +1,5 @@ DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS p1; CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL ); INSERT INTO t1 VALUES (1413006,'idlfmv'), (1413065,'smpsfz'),(1413127,'sljrhx'),(1413304,'qerfnd'); @@ -119,4 +120,14 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL PRIMARY 102 NULL 3 Using index 1 SIMPLE t1 eq_ref PRIMARY,a PRIMARY 318 func,const,const 1 DROP TABLE t1, t2; +# +# Bug #50096: CONCAT_WS inside procedure returning wrong data +# +CREATE PROCEDURE p1(a varchar(255), b int, c int) +SET @query = CONCAT_WS(",", a, b, c); +CALL p1("abcde", "0", "1234"); +SELECT @query; +@query +abcde,0,1234 +DROP PROCEDURE p1; # End of 5.1 tests diff --git a/mysql-test/t/func_concat.test b/mysql-test/t/func_concat.test index 1c7e5823fb2..e24b4354b61 100644 --- a/mysql-test/t/func_concat.test +++ b/mysql-test/t/func_concat.test @@ -4,6 +4,7 @@ --disable_warnings DROP TABLE IF EXISTS t1; +DROP PROCEDURE IF EXISTS p1; --enable_warnings CREATE TABLE t1 ( number INT NOT NULL, alpha CHAR(6) NOT NULL ); @@ -111,4 +112,16 @@ EXPLAIN SELECT CONCAT('gui_', t2.a), t1.d FROM t2 DROP TABLE t1, t2; +--echo # +--echo # Bug #50096: CONCAT_WS inside procedure returning wrong data +--echo # + +CREATE PROCEDURE p1(a varchar(255), b int, c int) + SET @query = CONCAT_WS(",", a, b, c); + +CALL p1("abcde", "0", "1234"); +SELECT @query; + +DROP PROCEDURE p1; + --echo # End of 5.1 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index b6d3f45f4c2..ecd839d8378 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -677,8 +677,8 @@ String *Item_func_concat_ws::val_str(String *str) res->length() + sep_str->length() + res2->length()) { /* We have room in str; We can't get any errors here */ - if (str == res2) - { // This is quote uncommon! + if (str->ptr() == res2->ptr()) + { // This is quite uncommon! str->replace(0,0,*sep_str); str->replace(0,0,*res); } From 495810cd1f8ceb19e7126daa5ab92660c8f942b0 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Wed, 13 Jan 2010 09:20:45 +0400 Subject: [PATCH 41/47] Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL Problem: copying issuer's (or subject's) name tags into an internal buffer from incoming stream we didn't check the buffer overflow. That may lead to memory overrun, crash etc. Fix: ensure we don't overrun the buffer. Note: there's no simple test case (exploit needed). extra/yassl/taocrypt/include/asn.hpp: Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL - CertDecoder::AddTag() introduced. extra/yassl/taocrypt/src/asn.cpp: Fix for bug#50227: Pre-auth buffer-overflow in mySQL through yaSSL - copying data from incoming stream to the issuer_ or subject_ buffers ensure we don't overrun them. - code cleanup. --- extra/yassl/taocrypt/include/asn.hpp | 1 + extra/yassl/taocrypt/src/asn.cpp | 123 +++++++++++++++------------ 2 files changed, 69 insertions(+), 55 deletions(-) diff --git a/extra/yassl/taocrypt/include/asn.hpp b/extra/yassl/taocrypt/include/asn.hpp index 1c1850cb47e..168b8a8c755 100644 --- a/extra/yassl/taocrypt/include/asn.hpp +++ b/extra/yassl/taocrypt/include/asn.hpp @@ -305,6 +305,7 @@ private: bool ValidateSignature(SignerList*); bool ConfirmSignature(Source&); void GetKey(); + char* AddTag(char*, const char*, const char*, word32, word32); void GetName(NameType); void GetValidity(); void GetDate(DateType); diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index 78200841bda..f87b466502e 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -652,6 +652,23 @@ word32 CertDecoder::GetDigest() } +char *CertDecoder::AddTag(char *ptr, const char *buf_end, + const char *tag_name, word32 tag_name_length, + word32 tag_value_length) +{ + if (ptr + tag_name_length + tag_value_length > buf_end) + return 0; + + memcpy(ptr, tag_name, tag_name_length); + ptr+= tag_name_length; + + memcpy(ptr, source_.get_current(), tag_value_length); + ptr+= tag_value_length; + + return ptr; +} + + // process NAME, either issuer or subject void CertDecoder::GetName(NameType nt) { @@ -659,11 +676,21 @@ void CertDecoder::GetName(NameType nt) SHA sha; word32 length = GetSequence(); // length of all distinguished names - assert (length < ASN_NAME_MAX); + + if (length >= ASN_NAME_MAX) + goto err; length += source_.get_index(); - char* ptr = (nt == ISSUER) ? issuer_ : subject_; - word32 idx = 0; + char *ptr, *buf_end; + + if (nt == ISSUER) { + ptr= issuer_; + buf_end= ptr + sizeof(issuer_) - 1; // 1 byte for trailing 0 + } + else { + ptr= subject_; + buf_end= ptr + sizeof(subject_) - 1; // 1 byte for trailing 0 + } while (source_.get_index() < length) { GetSet(); @@ -685,47 +712,36 @@ void CertDecoder::GetName(NameType nt) byte id = source_.next(); b = source_.next(); // strType word32 strLen = GetLength(source_); - bool copy = false; - if (id == COMMON_NAME) { - memcpy(&ptr[idx], "/CN=", 4); - idx += 4; - copy = true; - } - else if (id == SUR_NAME) { - memcpy(&ptr[idx], "/SN=", 4); - idx += 4; - copy = true; - } - else if (id == COUNTRY_NAME) { - memcpy(&ptr[idx], "/C=", 3); - idx += 3; - copy = true; - } - else if (id == LOCALITY_NAME) { - memcpy(&ptr[idx], "/L=", 3); - idx += 3; - copy = true; - } - else if (id == STATE_NAME) { - memcpy(&ptr[idx], "/ST=", 4); - idx += 4; - copy = true; - } - else if (id == ORG_NAME) { - memcpy(&ptr[idx], "/O=", 3); - idx += 3; - copy = true; - } - else if (id == ORGUNIT_NAME) { - memcpy(&ptr[idx], "/OU=", 4); - idx += 4; - copy = true; - } - - if (copy) { - memcpy(&ptr[idx], source_.get_current(), strLen); - idx += strLen; + switch (id) { + case COMMON_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/CN=", 4, strLen))) + goto err; + break; + case SUR_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/SN=", 4, strLen))) + goto err; + break; + case COUNTRY_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/C=", 3, strLen))) + goto err; + break; + case LOCALITY_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/L=", 3, strLen))) + goto err; + break; + case STATE_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/ST=", 4, strLen))) + goto err; + break; + case ORG_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/O=", 3, strLen))) + goto err; + break; + case ORGUNIT_NAME: + if (!(ptr= AddTag(ptr, buf_end, "/OU=", 4, strLen))) + goto err; + break; } sha.Update(source_.get_current(), strLen); @@ -739,23 +755,20 @@ void CertDecoder::GetName(NameType nt) source_.advance(oidSz + 1); word32 length = GetLength(source_); - if (email) { - memcpy(&ptr[idx], "/emailAddress=", 14); - idx += 14; - - memcpy(&ptr[idx], source_.get_current(), length); - idx += length; - } + if (email && !(ptr= AddTag(ptr, buf_end, "/emailAddress=", 14, length))) + goto err; source_.advance(length); } } - ptr[idx++] = 0; + *ptr= 0; - if (nt == ISSUER) - sha.Final(issuerHash_); - else - sha.Final(subjectHash_); + sha.Final(nt == ISSUER ? issuerHash_ : subjectHash_); + + return; + +err: + source_.SetError(CONTENT_E); } From 4dc7be62a997a0176e300878d4b5e93865606029 Mon Sep 17 00:00:00 2001 From: Sven Sandberg Date: Wed, 13 Jan 2010 10:00:03 +0100 Subject: [PATCH 42/47] BUG#49222: Mark RAND() as unsafe Problem: When RAND() is binlogged in statement mode, the seed is binlogged too, so the replication slave generates the same sequence of random numbers. This makes replication work in many cases, but not in all cases: the order of rows is not guaranteed for, e.g., UPDATE or INSERT...SELECT statements, so the row data will be different if master and slave retrieve the rows in different orders. Fix: Mark RAND() as unsafe. It will generate a warning if binlog_format=STATEMENT and switch to row-logging if binlog_format=ROW. mysql-test/extra/rpl_tests/rpl_row_func003.test: updated test case to ignore new warnings mysql-test/suite/binlog/r/binlog_unsafe.result: updated result file mysql-test/suite/binlog/t/binlog_unsafe.test: Added test for RAND(). Also clarified some old comments. mysql-test/suite/rpl/r/rpl_misc_functions.result: updated result file mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result: updated test case to ignore new warnings mysql-test/suite/rpl/r/rpl_optimize.result: updated result file mysql-test/suite/rpl/r/rpl_row_func003.result: updated result file mysql-test/suite/rpl/t/rpl_misc_functions.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_optimize.test: updated test case to ignore new warnings mysql-test/suite/rpl/t/rpl_trigger.test: updated test case to ignore new warnings mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result: updated result file sql/item_create.cc: Mark RAND() unsafe. --- .../extra/rpl_tests/rpl_row_func003.test | 6 +++++ .../suite/binlog/r/binlog_unsafe.result | 3 +++ mysql-test/suite/binlog/t/binlog_unsafe.test | 24 +++++++++++-------- .../suite/rpl/r/rpl_misc_functions.result | 1 + .../r/rpl_nondeterministic_functions.result | 1 + mysql-test/suite/rpl/r/rpl_optimize.result | 1 + mysql-test/suite/rpl/r/rpl_row_func003.result | 1 + .../suite/rpl/t/rpl_misc_functions.test | 8 +++++++ .../rpl/t/rpl_nondeterministic_functions.test | 4 ++++ mysql-test/suite/rpl/t/rpl_optimize.test | 4 +++- mysql-test/suite/rpl/t/rpl_trigger.test | 2 ++ .../suite/rpl_ndb/r/rpl_ndb_func003.result | 1 + sql/item_create.cc | 10 ++++++++ 13 files changed, 55 insertions(+), 11 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_row_func003.test b/mysql-test/extra/rpl_tests/rpl_row_func003.test index 8ee2d863527..b77465de39e 100644 --- a/mysql-test/extra/rpl_tests/rpl_row_func003.test +++ b/mysql-test/extra/rpl_tests/rpl_row_func003.test @@ -18,6 +18,8 @@ # Vs slave. # ############################################################################# +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + # Begin clean up test section connection master; --disable_warnings @@ -43,10 +45,12 @@ RETURN tmp; END| delimiter ;| +--disable_warnings INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1()); sleep 6; INSERT INTO test.t1 VALUES (null,test.f1()),(null,test.f1()),(null,test.f1()); sleep 6; +--enable_warnings #Select in this test are used for debugging #select * from test.t1; @@ -56,7 +60,9 @@ sleep 6; connection master; SET AUTOCOMMIT=0; START TRANSACTION; +--disable_warnings INSERT INTO test.t1 VALUES (null,test.f1()); +--enable_warnings ROLLBACK; SET AUTOCOMMIT=1; #select * from test.t1; diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index 8bbf993a727..6b2a83c9483 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -379,6 +379,9 @@ Note 1592 Statement may not be safe to log in statement format. INSERT INTO t1 VALUES (VERSION()); Warnings: Note 1592 Statement may not be safe to log in statement format. +INSERT INTO t1 VALUES (RAND()); +Warnings: +Note 1592 Statement may not be safe to log in statement format. DELETE FROM t1; SET TIMESTAMP=1000000; INSERT INTO t1 VALUES diff --git a/mysql-test/suite/binlog/t/binlog_unsafe.test b/mysql-test/suite/binlog/t/binlog_unsafe.test index 1acb4d090ca..5e399f3e602 100644 --- a/mysql-test/suite/binlog/t/binlog_unsafe.test +++ b/mysql-test/suite/binlog/t/binlog_unsafe.test @@ -47,6 +47,8 @@ # BUG#34768: nondeterministic INSERT using LIMIT logged in stmt mode if binlog_format=mixed # BUG#41980, SBL, INSERT .. SELECT .. LIMIT = ERROR, even when @@SQL_LOG_BIN is 0 # BUG#42640: mysqld crashes when unsafe statements are executed (STRICT_TRANS_TABLES mode) +# BUG#47995: Mark user functions as unsafe +# BUG#49222: Mare RAND() unsafe # # ==== Related test cases ==== # @@ -391,6 +393,7 @@ SET @@SESSION.SQL_MODE = @save_sql_mode; # # BUG#47995: Mark user functions as unsafe +# BUG#49222: Mare RAND() unsafe # # Test that the system functions that are supposed to be marked unsafe # generate a warning. Each INSERT statement below should generate a @@ -400,27 +403,28 @@ SET @@SESSION.SQL_MODE = @save_sql_mode; CREATE TABLE t1 (a VARCHAR(1000)); INSERT INTO t1 VALUES (CURRENT_USER()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (FOUND_ROWS()); #marked unsafe before BUG#47995 -INSERT INTO t1 VALUES (GET_LOCK('tmp', 1)); -INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp')); -INSERT INTO t1 VALUES (IS_USED_LOCK('tmp')); -INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe before BUG#47995 +INSERT INTO t1 VALUES (GET_LOCK('tmp', 1)); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (IS_FREE_LOCK('tmp')); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (IS_USED_LOCK('tmp')); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (LOAD_FILE('../../std_data/words2.dat')); #marked unsafe in BUG#39701 INSERT INTO t1 VALUES (MASTER_POS_WAIT('dummy arg', 4711, 1)); -INSERT INTO t1 VALUES (RELEASE_LOCK('tmp')); +INSERT INTO t1 VALUES (RELEASE_LOCK('tmp')); #marked unsafe in BUG#47995 INSERT INTO t1 VALUES (ROW_COUNT()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (SESSION_USER()); #marked unsafe before BUG#47995 -INSERT INTO t1 VALUES (SLEEP(1)); -INSERT INTO t1 VALUES (SYSDATE()); +INSERT INTO t1 VALUES (SLEEP(1)); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (SYSDATE()); #marked unsafe in BUG#47995 INSERT INTO t1 VALUES (SYSTEM_USER()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (USER()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (UUID()); #marked unsafe before BUG#47995 INSERT INTO t1 VALUES (UUID_SHORT()); #marked unsafe before BUG#47995 -INSERT INTO t1 VALUES (VERSION()); +INSERT INTO t1 VALUES (VERSION()); #marked unsafe in BUG#47995 +INSERT INTO t1 VALUES (RAND()); #marked unsafe in BUG#49222 DELETE FROM t1; # Since we replicate the TIMESTAMP variable, functions affected by the # TIMESTAMP variable are safe to replicate. So we check that the -# following following functions depend on the TIMESTAMP variable and -# don't generate a warning. +# following following functions that depend on the TIMESTAMP variable +# are not unsafe and don't generate a warning. SET TIMESTAMP=1000000; INSERT INTO t1 VALUES diff --git a/mysql-test/suite/rpl/r/rpl_misc_functions.result b/mysql-test/suite/rpl/r/rpl_misc_functions.result index 28b777822e4..6d69235927e 100644 --- a/mysql-test/suite/rpl/r/rpl_misc_functions.result +++ b/mysql-test/suite/rpl/r/rpl_misc_functions.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); create table t1(id int, i int, r1 int, r2 int, p varchar(100)); insert into t1 values(1, connection_id(), 0, 0, ""); insert into t1 values(2, 0, rand()*1000, rand()*1000, ""); diff --git a/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result b/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result index c4842a284cd..3b9b741e040 100644 --- a/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result +++ b/mysql-test/suite/rpl/r/rpl_nondeterministic_functions.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); CREATE TABLE t1 (a VARCHAR(1000)); INSERT INTO t1 VALUES (CONNECTION_ID()); INSERT INTO t1 VALUES (CONNECTION_ID()); diff --git a/mysql-test/suite/rpl/r/rpl_optimize.result b/mysql-test/suite/rpl/r/rpl_optimize.result index 79891169fbc..1ae94a3ca36 100644 --- a/mysql-test/suite/rpl/r/rpl_optimize.result +++ b/mysql-test/suite/rpl/r/rpl_optimize.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); create table t1 (a int not null auto_increment primary key, b int, key(b)); INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); INSERT INTO t1 (a) SELECT null FROM t1; diff --git a/mysql-test/suite/rpl/r/rpl_row_func003.result b/mysql-test/suite/rpl/r/rpl_row_func003.result index a5fd46a2ce3..94d01b50ce5 100644 --- a/mysql-test/suite/rpl/r/rpl_row_func003.result +++ b/mysql-test/suite/rpl/r/rpl_row_func003.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); DROP FUNCTION IF EXISTS test.f1; DROP TABLE IF EXISTS test.t1; CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=INNODB; diff --git a/mysql-test/suite/rpl/t/rpl_misc_functions.test b/mysql-test/suite/rpl/t/rpl_misc_functions.test index d2e61d579e3..b84042160cd 100644 --- a/mysql-test/suite/rpl/t/rpl_misc_functions.test +++ b/mysql-test/suite/rpl/t/rpl_misc_functions.test @@ -3,12 +3,16 @@ # source include/master-slave.inc; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + create table t1(id int, i int, r1 int, r2 int, p varchar(100)); insert into t1 values(1, connection_id(), 0, 0, ""); # don't put rand and password in the same query, to see if they replicate # independently # Pure rand test +--disable_warnings insert into t1 values(2, 0, rand()*1000, rand()*1000, ""); +--enable_warnings # change the rand suite on the master (we do this because otherwise password() # benefits from the fact that the above rand() is well replicated : # it picks the same sequence element, which hides a possible bug in password() replication. @@ -19,7 +23,9 @@ set sql_log_bin=1; # Pure password test insert into t1 values(3, 0, 0, 0, password('does_this_work?')); # "altogether now" +--disable_warnings insert into t1 values(4, connection_id(), rand()*1000, rand()*1000, password('does_this_still_work?')); +--enable_warnings select * into outfile 'rpl_misc_functions.outfile' from t1; let $MYSQLD_DATADIR= `select @@datadir`; sync_slave_with_master; @@ -73,11 +79,13 @@ DELIMITER ;| # Exercise the functions and procedures then compare the results on # the master to those on the slave. +--disable_warnings CALL test_replication_sp1(); CALL test_replication_sp2(); INSERT INTO t1 (col_a) VALUES (test_replication_sf()); INSERT INTO t1 (col_a) VALUES (test_replication_sf()); INSERT INTO t1 (col_a) VALUES (test_replication_sf()); +--enable_warnings --sync_slave_with_master diff --git a/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test b/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test index a30eb3be374..9ff2e2d081e 100644 --- a/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test +++ b/mysql-test/suite/rpl/t/rpl_nondeterministic_functions.test @@ -17,6 +17,8 @@ --source include/master-slave.inc +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + CREATE TABLE t1 (a VARCHAR(1000)); # We replicate the connection_id in the query_log_event @@ -41,7 +43,9 @@ INSERT INTO t1 VALUES (UTC_TIMESTAMP()); # We replicate the random seed in a rand_log_event +--disable_warnings INSERT INTO t1 VALUES (RAND()); +--enable_warnings # We replicate the last_insert_id in an intvar_log_event INSERT INTO t1 VALUES (LAST_INSERT_ID()); diff --git a/mysql-test/suite/rpl/t/rpl_optimize.test b/mysql-test/suite/rpl/t/rpl_optimize.test index f4582ba1167..87eb9dce818 100644 --- a/mysql-test/suite/rpl/t/rpl_optimize.test +++ b/mysql-test/suite/rpl/t/rpl_optimize.test @@ -13,6 +13,8 @@ -- source include/not_ndb_default.inc -- source include/master-slave.inc +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); + create table t1 (a int not null auto_increment primary key, b int, key(b)); INSERT INTO t1 (a) VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); INSERT INTO t1 (a) SELECT null FROM t1; @@ -30,8 +32,8 @@ INSERT INTO t1 (a) SELECT null FROM t1; INSERT INTO t1 (a) SELECT null FROM t1; save_master_pos; # a few updates to force OPTIMIZE to do something -update t1 set b=(a/2*rand()); --disable_warnings +update t1 set b=(a/2*rand()); delete from t1 order by b limit 10000; --enable_warnings diff --git a/mysql-test/suite/rpl/t/rpl_trigger.test b/mysql-test/suite/rpl/t/rpl_trigger.test index 4b40fbea719..e296da01bad 100644 --- a/mysql-test/suite/rpl/t/rpl_trigger.test +++ b/mysql-test/suite/rpl/t/rpl_trigger.test @@ -40,10 +40,12 @@ insert into t3 values(100,"log",0,0,0); SET @@RAND_SEED1=658490765, @@RAND_SEED2=635893186; # Emulate that we have rows 2-9 deleted on the slave +--disable_warnings insert into t1 values(1,1,rand()),(NULL,2,rand()); insert into t2 (b) values(last_insert_id()); insert into t2 values(3,0),(NULL,0); insert into t2 values(NULL,0),(500,0); +--enable_warnings select a,b, truncate(rand_value,4) from t1; select * from t2; diff --git a/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result b/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result index ad72a3fb244..7e750f2ce2a 100644 --- a/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result +++ b/mysql-test/suite/rpl_ndb/r/rpl_ndb_func003.result @@ -4,6 +4,7 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +CALL mtr.add_suppression('Statement may not be safe to log in statement format.'); DROP FUNCTION IF EXISTS test.f1; DROP TABLE IF EXISTS test.t1; CREATE TABLE test.t1 (a INT NOT NULL AUTO_INCREMENT, c CHAR(16),PRIMARY KEY(a))ENGINE=NDB; diff --git a/sql/item_create.cc b/sql/item_create.cc index 53aa8081da1..c309ccc06ca 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -4178,6 +4178,16 @@ Create_func_rand::create_native(THD *thd, LEX_STRING name, if (item_list != NULL) arg_count= item_list->elements; + /* + When RAND() is binlogged, the seed is binlogged too. So the + sequence of random numbers is the same on a replication slave as + on the master. However, if several RAND() values are inserted + into a table, the order in which the rows are modified may differ + between master and slave, because the order is undefined. Hence, + the statement is unsafe to log in statement format. + */ + thd->lex->set_stmt_unsafe(); + switch (arg_count) { case 0: { From c4ec2de72413235d5f4027758d9601b74223b01c Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 13 Jan 2010 12:43:07 +0200 Subject: [PATCH 43/47] version change --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index f044f8e62da..e613cefc614 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.1" +tree_name = "mysql-5.1-bugteam" From b3dd4d9486ca00e555823f81185fe9db83a44db5 Mon Sep 17 00:00:00 2001 From: Kristofer Pettersson Date: Wed, 13 Jan 2010 12:39:00 +0100 Subject: [PATCH 44/47] Bug#33982 debug assertion and crash reloading grant tables after sighup or kill In certain rare cases when a process was interrupted during a FLUSH PRIVILEGES operation the diagnostic area would be set to an error state but the function responsible for the operation would still signal success. This would lead to a debug assertion error later on when the server would attempt to reset the DA before sending the error message. This patch fixes the issue by assuring that reload_acl_and_cache() always fails if an error condition is raised. The second issue was that a KILL could cause a console error message which referred to a DA state without first making sure that such a state existed. This patch fixes this issue in two different palces by first checking DA state before fetching the error message. sql/sql_acl.cc: * Make sure that there is an error to print before attempting to do so. * Minor style change: change 1 to TRUE for clarity. sql/sql_parse.cc: * Always fail reload_acl_and_cache() if the query was killed. sql/sql_servers.cc: * Make sure that there is an error to print before attempting to do so. --- sql/sql_acl.cc | 15 ++++++++++----- sql/sql_parse.cc | 9 ++++++--- sql/sql_servers.cc | 10 ++++++++-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 7d8f8ea71b3..7ba1a657578 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -310,7 +310,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) { TABLE *table; READ_RECORD read_record_info; - my_bool return_val= 1; + my_bool return_val= TRUE; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; char tmp_name[NAME_LEN+1]; int password_length; @@ -623,7 +623,7 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) init_check_host(); initialized=1; - return_val=0; + return_val= FALSE; end: thd->variables.sql_mode= old_sql_mode; @@ -674,7 +674,7 @@ my_bool acl_reload(THD *thd) DYNAMIC_ARRAY old_acl_hosts,old_acl_users,old_acl_dbs; MEM_ROOT old_mem; bool old_initialized; - my_bool return_val= 1; + my_bool return_val= TRUE; DBUG_ENTER("acl_reload"); if (thd->locked_tables) @@ -701,8 +701,13 @@ my_bool acl_reload(THD *thd) if (simple_open_n_lock_tables(thd, tables)) { - sql_print_error("Fatal error: Can't open and lock privilege tables: %s", - thd->main_da.message()); + /* + Execution might have been interrupted; only print the error message + if an error condition has been raised. + */ + if (thd->main_da.is_error()) + sql_print_error("Fatal error: Can't open and lock privilege tables: %s", + thd->main_da.message()); goto end; } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 69c9ddc7806..2c466d31e7c 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6787,13 +6787,13 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, thd->store_globals(); lex_start(thd); } - + if (thd) { bool reload_acl_failed= acl_reload(thd); bool reload_grants_failed= grant_reload(thd); bool reload_servers_failed= servers_reload(thd); - + if (reload_acl_failed || reload_grants_failed || reload_servers_failed) { result= 1; @@ -6949,7 +6949,10 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, if (options & REFRESH_USER_RESOURCES) reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */ *write_to_binlog= tmp_write_to_binlog; - return result; + /* + If the query was killed then this function must fail. + */ + return result || thd->killed; } diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index f8a8dea18ff..1655426bb4a 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -241,8 +241,14 @@ bool servers_reload(THD *thd) if (simple_open_n_lock_tables(thd, tables)) { - sql_print_error("Can't open and lock privilege tables: %s", - thd->main_da.message()); + /* + Execution might have been interrupted; only print the error message + if an error condition has been raised. + */ + if (thd->main_da.is_error()) + sql_print_error("Can't open and lock privilege tables: %s", + thd->main_da.message()); + return_val= FALSE; goto end; } From 7ecd6c6d0269d1b8580f87cbdda1924d7ab0d499 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Thu, 14 Jan 2010 10:24:02 +0200 Subject: [PATCH 45/47] version change --- .bzr-mysql/default.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf index 557df1b1ffe..f79c1cd6319 100644 --- a/.bzr-mysql/default.conf +++ b/.bzr-mysql/default.conf @@ -1,4 +1,4 @@ [MYSQL] post_commit_to = "commits@lists.mysql.com" post_push_to = "commits@lists.mysql.com" -tree_name = "mysql-5.0-bugteam" +tree_name = "mysql-5.0" From 5ae7b3c99634609b2890253590ccf82c5fb4f085 Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 14 Jan 2010 10:49:40 +0000 Subject: [PATCH 46/47] BUG#50018: binlog corruption when table has many columns Small fix in the test case. Changed the UNLOCK tables to happen after each insert. --- mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test index 022988d7ee3..be5ebb661ca 100644 --- a/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test +++ b/mysql-test/suite/rpl/t/rpl_row_tbl_metadata.test @@ -290,6 +290,7 @@ for my $i (1..$ntables) print FILE "LOCK TABLES t$i WRITE;\n"; print FILE "INSERT INTO t$i(c". ($base_ncols+1) . ") VALUES (50018);\n"; + print FILE "UNLOCK TABLES;"; } close(FILE); @@ -301,7 +302,6 @@ EOF ## may want to reactivate query logging -- disable_query_log -- source $generated_sql -UNLOCK TABLES; -- enable_query_log -- sync_slave_with_master From 32aa612819ff756b284e639de50627b3d6d7fa0d Mon Sep 17 00:00:00 2001 From: Luis Soares Date: Thu, 14 Jan 2010 14:26:51 +0000 Subject: [PATCH 47/47] Fix for BUG#49481 and BUG#49482. BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on delete: cant find record BUG#49482: RBR: Replication may break on deletes when MyISAM tables + char field are used When using MyISAM tables, despite the fact that the null bit is set for some fields, their old value is still in the row. This can cause the comparison of records to fail when the slave is doing an index or range scan. We fix this by avoiding memcmp for MyISAM tables when comparing records. Additionally, when comparing field by field, we first check if both fields are not null and if so, then we compare them. If just one field is null we return failure immediately. If both fields are null, we move on to the next field. --- .../suite/rpl/r/rpl_myisam_null_values.result | 24 +++++++++ .../suite/rpl/t/rpl_myisam_null_values.test | 53 +++++++++++++++++++ sql/log_event.cc | 39 +++++++++++++- sql/log_event_old.cc | 39 +++++++++++++- 4 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_myisam_null_values.result create mode 100644 mysql-test/suite/rpl/t/rpl_myisam_null_values.test diff --git a/mysql-test/suite/rpl/r/rpl_myisam_null_values.result b/mysql-test/suite/rpl/r/rpl_myisam_null_values.result new file mode 100644 index 00000000000..574528a8d79 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_myisam_null_values.result @@ -0,0 +1,24 @@ +stop slave; +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; +start slave; +CREATE TABLE t1 (c1 BIT, c2 INT); +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 WHERE c2=1 LIMIT 1; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; +CREATE TABLE t1 (c1 CHAR); +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +c1 +w +# should trigger switch to row due to LIMIT +UPDATE t1 SET c1=NULL WHERE c1='w' LIMIT 2; +Comparing tables master:test.t1 and slave:test.t1 +DELETE FROM t1 LIMIT 2; +Comparing tables master:test.t1 and slave:test.t1 +DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_myisam_null_values.test b/mysql-test/suite/rpl/t/rpl_myisam_null_values.test new file mode 100644 index 00000000000..d9ec95fc510 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_myisam_null_values.test @@ -0,0 +1,53 @@ +# BUG#49481: RBR: MyISAM and bit fields may cause slave to stop on delete cant find record +# BUG#49482: RBR: Replication may break on deletes when MyISAM tables + char field are used + +-- source include/master-slave.inc +-- source include/have_binlog_format_mixed_or_row.inc + +-- connection master +CREATE TABLE t1 (c1 BIT, c2 INT); +INSERT INTO `t1` VALUES ( 1, 1 ); +UPDATE t1 SET c1=NULL where c2=1; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DELETE FROM t1 WHERE c2=1 LIMIT 1; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master + +-- connection master + +CREATE TABLE t1 (c1 CHAR); + +INSERT INTO t1 ( c1 ) VALUES ( 'w' ) ; +SELECT * FROM t1; +-- echo # should trigger switch to row due to LIMIT +UPDATE t1 SET c1=NULL WHERE c1='w' LIMIT 2; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DELETE FROM t1 LIMIT 2; +-- sync_slave_with_master + +-- let $diff_table_1=master:test.t1 +-- let $diff_table_2=slave:test.t1 +-- source include/diff_tables.inc + +-- connection master +DROP TABLE t1; +-- sync_slave_with_master diff --git a/sql/log_event.cc b/sql/log_event.cc index 6b21087b6aa..61f5e93e29e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8724,6 +8724,24 @@ static bool record_compare(TABLE *table) } } + /** + Check if we are using MyISAM. + + If this is a myisam table, then we cannot do a memcmp + right away because some NULL fields can still contain + an old value in the row - they are not shown to the user + because the null bit is set, however, the contents are + not cleared. As such, plain memory comparison cannot be + assured to work. See: BUG#49482 and BUG#49481. + + On top of this, we do not store field contents for null + fields in the binlog, so this is extra important when + comparing records fetched from binlog and from storage + engine. + */ + if (table->file->ht->db_type == DB_TYPE_MYISAM) + goto record_compare_field_by_field; + if (table->s->blob_fields + table->s->varchar_fields == 0) { result= cmp_record(table,record[1]); @@ -8739,14 +8757,33 @@ static bool record_compare(TABLE *table) goto record_compare_exit; } +record_compare_field_by_field: + /* Compare updated fields */ for (Field **ptr=table->field ; *ptr ; ptr++) { - if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length)) + Field *f= *ptr; + + /* if just one of the fields is null then there is no match */ + if ((f->is_null_in_record(table->record[0])) == + !(f->is_null_in_record(table->record[1]))) { result= TRUE; goto record_compare_exit; } + + /* if both fields are not null then we can compare */ + if (!(f->is_null_in_record(table->record[0])) && + !(f->is_null_in_record(table->record[1]))) + { + if (f->cmp_binary_offset(table->s->rec_buff_length)) + { + result= TRUE; + goto record_compare_exit; + } + } + + /* if both fields are null then there is a match. compare next field */ } record_compare_exit: diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 357bc78b1cd..72a6e159535 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -351,6 +351,24 @@ static bool record_compare(TABLE *table) } } + /** + Check if we are using MyISAM. + + If this is a myisam table, then we cannot do a memcmp + right away because some NULL fields can still contain + an old value in the row - they are not shown to the user + because the null bit is set, however, the contents are + not cleared. As such, plain memory comparison cannot be + assured to work. See: BUG#49482 and BUG#49481. + + On top of this, we do not store field contents for null + fields in the binlog, so this is extra important when + comparing records fetched from binlog and from storage + engine. + */ + if (table->file->ht->db_type == DB_TYPE_MYISAM) + goto record_compare_field_by_field; + if (table->s->blob_fields + table->s->varchar_fields == 0) { result= cmp_record(table,record[1]); @@ -366,14 +384,33 @@ static bool record_compare(TABLE *table) goto record_compare_exit; } +record_compare_field_by_field: + /* Compare updated fields */ for (Field **ptr=table->field ; *ptr ; ptr++) { - if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length)) + Field *f= *ptr; + + /* if just one of the fields is null then there is no match */ + if ((f->is_null_in_record(table->record[0])) == + !(f->is_null_in_record(table->record[1]))) { result= TRUE; goto record_compare_exit; } + + /* if both fields are not null then we can compare */ + if (!(f->is_null_in_record(table->record[0])) && + !(f->is_null_in_record(table->record[1]))) + { + if (f->cmp_binary_offset(table->s->rec_buff_length)) + { + result= TRUE; + goto record_compare_exit; + } + } + + /* if both fields are null then there is a match. compare next field */ } record_compare_exit: