From 5f4dc7531fec2e3e83ac85da813d3bd1f97f2932 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 18 Oct 2012 11:59:47 +0200 Subject: [PATCH 001/324] Bug#14589559: ASSERTION `FILE_ENTRY_BUF[2] == 0' FAILED IN DEACTIVATE_DDL_LOG_ENTRY deallocate_ddl_log_entry() can be called without having locked LOCK_gdl. It uses a global buffer for reading and writing entries in the ddl_log, and since it is not protected by any mutex, two concurrent threads can overwrite the content in the global buffer, so it can be different from what was read. Thread a reads from entry 1 into global buffer, thread b reads from entry 2 into global buffer, thread a writes from global buffer into entry 1 -> entry 1 is not the content of entry 2. This is especially bad for replace entries, which uses two phases, and does not deactivate the whole entry after the first phase, but increases the phase instead. Fixed by using thread local storage (stack) instead of global storage (global buffer). Also added buffer and size arguments to read/write_ddl_log_file_entry. Also only read/write first bytes in entries in deactivate_ddl_log_entry. Also fixed the scenario where it will try to recover from a server compiled with a different value of IO_SIZE (very uncommon!) updated patch with set_ddl_log_entry_from_buf and removed read_ddl_log_entry. Manually tested, no test case included. --- sql/sql_table.cc | 218 ++++++++++++++++++++++++++--------------------- 1 file changed, 120 insertions(+), 98 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 39eee62ee91..cf725a5261d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -617,13 +617,6 @@ uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen) struct st_global_ddl_log { - /* - We need to adjust buffer size to be able to handle downgrades/upgrades - where IO_SIZE has changed. We'll set the buffer size such that we can - handle that the buffer size was upto 4 times bigger in the version - that wrote the DDL log. - */ - char file_entry_buf[4*IO_SIZE]; char file_name_str[FN_REFLEN]; char *file_name; DDL_LOG_MEMORY_ENTRY *first_free; @@ -651,51 +644,60 @@ pthread_mutex_t LOCK_gdl; #define DDL_LOG_NUM_ENTRY_POS 0 #define DDL_LOG_NAME_LEN_POS 4 #define DDL_LOG_IO_SIZE_POS 8 +#define DDL_LOG_HEADER_SIZE 12 -/* - Read one entry from ddl log file - SYNOPSIS - read_ddl_log_file_entry() - entry_no Entry number to read - RETURN VALUES - TRUE Error - FALSE Success +/** + Read one entry from ddl log file. + @param[out] file_entry_buf Buffer to read into + @param entry_no Entry number to read + @param size Number of bytes of the entry to read + + @return Operation status + @retval true Error + @retval false Success */ -static bool read_ddl_log_file_entry(uint entry_no) +static bool read_ddl_log_file_entry(uchar *file_entry_buf, + uint entry_no, + uint size) { bool error= FALSE; File file_id= global_ddl_log.file_id; - uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf; uint io_size= global_ddl_log.io_size; DBUG_ENTER("read_ddl_log_file_entry"); + DBUG_ASSERT(io_size >= size); - if (my_pread(file_id, file_entry_buf, io_size, io_size * entry_no, - MYF(MY_WME)) != io_size) + if (my_pread(file_id, file_entry_buf, size, io_size * entry_no, + MYF(MY_WME)) != size) error= TRUE; DBUG_RETURN(error); } -/* - Write one entry from ddl log file - SYNOPSIS - write_ddl_log_file_entry() - entry_no Entry number to write - RETURN VALUES - TRUE Error - FALSE Success +/** + Write one entry to ddl log file. + + @param file_entry_buf Buffer to write + @param entry_no Entry number to write + @param size Number of bytes of the entry to write + + @return Operation status + @retval true Error + @retval false Success */ -static bool write_ddl_log_file_entry(uint entry_no) +static bool write_ddl_log_file_entry(uchar *file_entry_buf, + uint entry_no, + uint size) { bool error= FALSE; File file_id= global_ddl_log.file_id; - char *file_entry_buf= (char*)global_ddl_log.file_entry_buf; + uint io_size= global_ddl_log.io_size; DBUG_ENTER("write_ddl_log_file_entry"); + DBUG_ASSERT(io_size >= size); - if (my_pwrite(file_id, (uchar*)file_entry_buf, - IO_SIZE, IO_SIZE * entry_no, MYF(MY_WME)) != IO_SIZE) + if (my_pwrite(file_id, file_entry_buf, size, + io_size * entry_no, MYF(MY_WME)) != size) error= TRUE; DBUG_RETURN(error); } @@ -714,17 +716,20 @@ static bool write_ddl_log_header() { uint16 const_var; bool error= FALSE; + uchar file_entry_buf[DDL_LOG_HEADER_SIZE]; DBUG_ENTER("write_ddl_log_header"); + DBUG_ASSERT((DDL_LOG_NAME_POS + 3 * global_ddl_log.name_len) + <= global_ddl_log.io_size); - int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS], + int4store(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS], global_ddl_log.num_entries); - const_var= FN_LEN; - int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS], + const_var= global_ddl_log.name_len; + int4store(&file_entry_buf[DDL_LOG_NAME_LEN_POS], (ulong) const_var); - const_var= IO_SIZE; - int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS], + const_var= global_ddl_log.io_size; + int4store(&file_entry_buf[DDL_LOG_IO_SIZE_POS], (ulong) const_var); - if (write_ddl_log_file_entry(0UL)) + if (write_ddl_log_file_entry(file_entry_buf, 0UL, DDL_LOG_HEADER_SIZE)) { sql_print_error("Error writing ddl log header"); DBUG_RETURN(TRUE); @@ -764,17 +769,19 @@ static inline void create_ddl_log_file_name(char *file_name) static uint read_ddl_log_header() { - char *file_entry_buf= (char*)global_ddl_log.file_entry_buf; + char file_entry_buf[DDL_LOG_HEADER_SIZE]; char file_name[FN_REFLEN]; uint entry_no; bool successful_open= FALSE; DBUG_ENTER("read_ddl_log_header"); + DBUG_ASSERT(global_ddl_log.io_size <= IO_SIZE); create_ddl_log_file_name(file_name); if ((global_ddl_log.file_id= my_open(file_name, O_RDWR | O_BINARY, MYF(0))) >= 0) { - if (read_ddl_log_file_entry(0UL)) + if (read_ddl_log_file_entry((uchar *) file_entry_buf, 0UL, + DDL_LOG_HEADER_SIZE)) { /* Write message into error log */ sql_print_error("Failed to read ddl log file in recovery"); @@ -787,8 +794,6 @@ static uint read_ddl_log_header() entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]); global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]); global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]); - DBUG_ASSERT(global_ddl_log.io_size <= - sizeof(global_ddl_log.file_entry_buf)); } else { @@ -803,30 +808,21 @@ static uint read_ddl_log_header() } -/* - Read a ddl log entry - SYNOPSIS - read_ddl_log_entry() - read_entry Number of entry to read - out:entry_info Information from entry - RETURN VALUES - TRUE Error - FALSE Success - DESCRIPTION - Read a specified entry in the ddl log +/** + Set ddl log entry struct from buffer + @param read_entry Entry number + @param file_entry_buf Buffer to use + @param ddl_log_entry Entry to be set + + @note Pointers in ddl_log_entry will point into file_entry_buf! */ -bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry) +static void set_ddl_log_entry_from_buf(uint read_entry, + uchar *file_entry_buf, + DDL_LOG_ENTRY *ddl_log_entry) { - char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf; uint inx; uchar single_char; - DBUG_ENTER("read_ddl_log_entry"); - - if (read_ddl_log_file_entry(read_entry)) - { - DBUG_RETURN(TRUE); - } ddl_log_entry->entry_pos= read_entry; single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]; ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char; @@ -834,14 +830,13 @@ bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry) ddl_log_entry->action_type= (enum ddl_log_action_code)single_char; ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS]; ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]); - ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS]; + ddl_log_entry->name= (char*) &file_entry_buf[DDL_LOG_NAME_POS]; inx= DDL_LOG_NAME_POS + global_ddl_log.name_len; - ddl_log_entry->from_name= &file_entry_buf[inx]; + ddl_log_entry->from_name= (char*) &file_entry_buf[inx]; inx+= global_ddl_log.name_len; - ddl_log_entry->handler_name= &file_entry_buf[inx]; - DBUG_RETURN(FALSE); + ddl_log_entry->handler_name= (char*) &file_entry_buf[inx]; } - + /* Initialise ddl log @@ -1044,6 +1039,7 @@ static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry, DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used; DBUG_ENTER("get_free_ddl_log_entry"); + safe_mutex_assert_owner(&LOCK_gdl); if (global_ddl_log.first_free == NULL) { if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc( @@ -1100,34 +1096,35 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, DDL_LOG_MEMORY_ENTRY **active_entry) { bool error, write_header; + char file_entry_buf[IO_SIZE]; DBUG_ENTER("write_ddl_log_entry"); if (init_ddl_log()) { DBUG_RETURN(TRUE); } - global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= + file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_ENTRY_CODE; - global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= + file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= (char)ddl_log_entry->action_type; - global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0; - int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], + file_entry_buf[DDL_LOG_PHASE_POS]= 0; + int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], ddl_log_entry->next_entry); - DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_LEN); - strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS], - ddl_log_entry->name, FN_LEN - 1); + DBUG_ASSERT(strlen(ddl_log_entry->name) < global_ddl_log.name_len); + strmake(&file_entry_buf[DDL_LOG_NAME_POS], ddl_log_entry->name, + global_ddl_log.name_len - 1); if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION || ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION) { - DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_LEN); - strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN], - ddl_log_entry->from_name, FN_LEN - 1); + DBUG_ASSERT(strlen(ddl_log_entry->from_name) < global_ddl_log.name_len); + strmake(&file_entry_buf[DDL_LOG_NAME_POS + global_ddl_log.name_len], + ddl_log_entry->from_name, global_ddl_log.name_len - 1); } else - global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0; - DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_LEN); - strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)], - ddl_log_entry->handler_name, FN_LEN - 1); + file_entry_buf[DDL_LOG_NAME_POS + global_ddl_log.name_len]= 0; + DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < global_ddl_log.name_len); + strmake(&file_entry_buf[DDL_LOG_NAME_POS + (2*global_ddl_log.name_len)], + ddl_log_entry->handler_name, global_ddl_log.name_len - 1); if (get_free_ddl_log_entry(active_entry, &write_header)) { DBUG_RETURN(TRUE); @@ -1135,14 +1132,15 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, error= FALSE; DBUG_PRINT("ddl_log", ("write type %c next %u name '%s' from_name '%s' handler '%s'", - (char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS], + (char) file_entry_buf[DDL_LOG_ACTION_TYPE_POS], ddl_log_entry->next_entry, - (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS], - (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS - + FN_LEN], - (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS - + (2*FN_LEN)])); - if (write_ddl_log_file_entry((*active_entry)->entry_pos)) + (char*) &file_entry_buf[DDL_LOG_NAME_POS], + (char*) &file_entry_buf[DDL_LOG_NAME_POS + + global_ddl_log.name_len], + (char*) &file_entry_buf[DDL_LOG_NAME_POS + + (2*global_ddl_log.name_len)])); + if (write_ddl_log_file_entry((uchar*) file_entry_buf, + (*active_entry)->entry_pos, IO_SIZE)) { error= TRUE; sql_print_error("Failed to write entry_no = %u", @@ -1192,7 +1190,7 @@ bool write_execute_ddl_log_entry(uint first_entry, DDL_LOG_MEMORY_ENTRY **active_entry) { bool write_header= FALSE; - char *file_entry_buf= (char*)global_ddl_log.file_entry_buf; + char file_entry_buf[IO_SIZE]; DBUG_ENTER("write_execute_ddl_log_entry"); if (init_ddl_log()) @@ -1216,8 +1214,8 @@ bool write_execute_ddl_log_entry(uint first_entry, file_entry_buf[DDL_LOG_PHASE_POS]= 0; int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry); file_entry_buf[DDL_LOG_NAME_POS]= 0; - file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0; - file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0; + file_entry_buf[DDL_LOG_NAME_POS + global_ddl_log.name_len]= 0; + file_entry_buf[DDL_LOG_NAME_POS + 2*global_ddl_log.name_len]= 0; if (!(*active_entry)) { if (get_free_ddl_log_entry(active_entry, &write_header)) @@ -1225,7 +1223,9 @@ bool write_execute_ddl_log_entry(uint first_entry, DBUG_RETURN(TRUE); } } - if (write_ddl_log_file_entry((*active_entry)->entry_pos)) + if (write_ddl_log_file_entry((uchar*) file_entry_buf, + (*active_entry)->entry_pos, + IO_SIZE)) { sql_print_error("Error writing execute entry in ddl log"); release_ddl_log_memory_entry(*active_entry); @@ -1270,10 +1270,16 @@ bool write_execute_ddl_log_entry(uint first_entry, bool deactivate_ddl_log_entry(uint entry_no) { - char *file_entry_buf= (char*)global_ddl_log.file_entry_buf; + uchar file_entry_buf[DDL_LOG_NAME_POS]; DBUG_ENTER("deactivate_ddl_log_entry"); - if (!read_ddl_log_file_entry(entry_no)) + + /* + Only need to read and write the first bytes of the entry, where + ENTRY_TYPE, ACTION_TYPE and PHASE reside. Using DDL_LOG_NAME_POS + to include all info except for the names. + */ + if (!read_ddl_log_file_entry(file_entry_buf, entry_no, DDL_LOG_NAME_POS)) { if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE) { @@ -1291,7 +1297,7 @@ bool deactivate_ddl_log_entry(uint entry_no) { DBUG_ASSERT(0); } - if (write_ddl_log_file_entry(entry_no)) + if (write_ddl_log_file_entry(file_entry_buf, entry_no, DDL_LOG_NAME_POS)) { sql_print_error("Error in deactivating log entry. Position = %u", entry_no); @@ -1352,6 +1358,7 @@ void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry) DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry; DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry; DBUG_ENTER("release_ddl_log_memory_entry"); + safe_mutex_assert_owner(&LOCK_gdl); global_ddl_log.first_free= log_entry; log_entry->next_log_entry= first_free; @@ -1381,18 +1388,20 @@ bool execute_ddl_log_entry(THD *thd, uint first_entry) { DDL_LOG_ENTRY ddl_log_entry; uint read_entry= first_entry; + uchar file_entry_buf[IO_SIZE]; DBUG_ENTER("execute_ddl_log_entry"); pthread_mutex_lock(&LOCK_gdl); do { - if (read_ddl_log_entry(read_entry, &ddl_log_entry)) + if (read_ddl_log_file_entry(file_entry_buf, read_entry, IO_SIZE)) { /* Write to error log and continue with next log entry */ sql_print_error("Failed to read entry = %u from ddl log", read_entry); break; } + set_ddl_log_entry_from_buf(read_entry, file_entry_buf, &ddl_log_entry); DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE || ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE); @@ -1443,13 +1452,14 @@ void execute_ddl_log_recovery() uint num_entries, i; THD *thd; DDL_LOG_ENTRY ddl_log_entry; + uchar *file_entry_buf; + uint io_size; char file_name[FN_REFLEN]; DBUG_ENTER("execute_ddl_log_recovery"); /* Initialise global_ddl_log struct */ - bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf)); global_ddl_log.inited= FALSE; global_ddl_log.recovery_phase= TRUE; global_ddl_log.io_size= IO_SIZE; @@ -1464,14 +1474,23 @@ void execute_ddl_log_recovery() thd->store_globals(); num_entries= read_ddl_log_header(); + io_size= global_ddl_log.io_size; + file_entry_buf= (uchar*) my_malloc(io_size, MYF(0)); + if (!file_entry_buf) + { + sql_print_error("Failed to allocate buffer for recover ddl log"); + DBUG_VOID_RETURN; + } for (i= 1; i < num_entries + 1; i++) { - if (read_ddl_log_entry(i, &ddl_log_entry)) + if (read_ddl_log_file_entry(file_entry_buf, i, io_size)) { sql_print_error("Failed to read entry no = %u from ddl log", i); continue; } + + set_ddl_log_entry_from_buf(i, file_entry_buf, &ddl_log_entry); if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE) { if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry)) @@ -1486,6 +1505,7 @@ void execute_ddl_log_recovery() VOID(my_delete(file_name, MYF(0))); global_ddl_log.recovery_phase= FALSE; delete thd; + my_free(file_entry_buf, MYF(0)); /* Remember that we don't have a THD */ my_pthread_setspecific_ptr(THR_THD, 0); DBUG_VOID_RETURN; @@ -1502,14 +1522,16 @@ void execute_ddl_log_recovery() void release_ddl_log() { - DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free; - DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used; + DDL_LOG_MEMORY_ENTRY *free_list; + DDL_LOG_MEMORY_ENTRY *used_list; DBUG_ENTER("release_ddl_log"); if (!global_ddl_log.do_release) DBUG_VOID_RETURN; pthread_mutex_lock(&LOCK_gdl); + free_list= global_ddl_log.first_free; + used_list= global_ddl_log.first_used; while (used_list) { DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry; From 20ca730f5616c15935d0af7a0b48b29ee9124541 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 3 Nov 2012 05:06:09 +0100 Subject: [PATCH 002/324] Raise version number after cloning 5.5.29 --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 1889f4c8aff..3c7056de633 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=29 +MYSQL_VERSION_PATCH=30 MYSQL_VERSION_EXTRA= From 574b107a5704575d0353ac2771286be97a0ff597 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 4 Nov 2012 22:11:34 +0100 Subject: [PATCH 003/324] mtr.pl - improve the logic that decides when ndbcluster should be enabled and the extra test suites for MySQL Cluster should be added. Should be consistent and logical now ;) --- mysql-test/lib/mtr_cases.pm | 13 +--- mysql-test/mysql-test-run.pl | 114 +++++++++++++++++++++++++---------- 2 files changed, 85 insertions(+), 42 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index af059af7121..b3bc2a83b92 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -963,18 +963,11 @@ sub collect_one_test_case { if ( $tinfo->{'ndb_test'} ) { # This is a NDB test - if ( $::opt_skip_ndbcluster == 2 ) + if ( $::ndbcluster_enabled == 0) { - # Ndb is not supported, skip it + # ndbcluster is disabled $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No ndbcluster support or ndb tests not enabled"; - return $tinfo; - } - elsif ( $::opt_skip_ndbcluster ) - { - # All ndb test's should be skipped - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No ndbcluster tests(--skip-ndbcluster)"; + $tinfo->{'comment'}= "ndbcluster disabled"; return $tinfo; } } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index a9add9be394..25c741cb821 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -310,8 +310,9 @@ sub check_timeout ($) { return testcase_timeout($_[0]) / 10; } our $opt_warnings= 1; -our $opt_include_ndbcluster= 0; -our $opt_skip_ndbcluster= 1; +our $ndbcluster_enabled= 0; +my $opt_include_ndbcluster= 0; +my $opt_skip_ndbcluster= 0; my $exe_ndbd; my $exe_ndbmtd; @@ -1070,7 +1071,7 @@ sub command_line_setup { # Control what test suites or cases to run 'force' => \$opt_force, 'with-ndbcluster-only' => \&collect_option, - 'include-ndbcluster' => \$opt_include_ndbcluster, + 'ndb|include-ndbcluster' => \$opt_include_ndbcluster, 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster, 'suite|suites=s' => \$opt_suites, 'skip-rpl' => \&collect_option, @@ -1519,7 +1520,6 @@ sub command_line_setup { } $ENV{'PATH'}= "$ENV{'PATH'}".$separator.$lib_mysqld; } - $opt_skip_ndbcluster= 1; # Turn off use of NDB cluster $opt_skip_ssl= 1; # Turn off use of SSL # Turn off use of bin log @@ -1999,7 +1999,7 @@ sub executable_setup () { $exe_mysql_embedded= mtr_exe_maybe_exists("$basedir/libmysqld/examples/mysql_embedded"); - if ( ! $opt_skip_ndbcluster ) + if ( $ndbcluster_enabled ) { # Look for single threaded NDB $exe_ndbd= @@ -2270,7 +2270,7 @@ sub environment_setup { # -------------------------------------------------------------------------- # Add the path where libndbclient can be found # -------------------------------------------------------------------------- - if ( !$opt_skip_ndbcluster ) + if ( $ndbcluster_enabled ) { push(@ld_library_paths, "$basedir/storage/ndb/src/.libs"); } @@ -2358,7 +2358,7 @@ sub environment_setup { # ---------------------------------------------------- # Setup env for NDB # ---------------------------------------------------- - if ( ! $opt_skip_ndbcluster ) + if ( $ndbcluster_enabled ) { $ENV{'NDB_MGM'}= my_find_bin($bindir, @@ -2753,37 +2753,87 @@ sub vs_config_dirs ($$) { sub check_ndbcluster_support ($) { my $mysqld_variables= shift; + my $ndbcluster_supported = 0; + if ($mysqld_variables{'ndb-connectstring'}) + { + $ndbcluster_supported = 1; + } + + if ($opt_skip_ndbcluster && $opt_include_ndbcluster) + { + # User is ambivalent. Theoretically the arg which was + # given last on command line should win, but that order is + # unknown at this time. + mtr_error("Ambigous command, both --include-ndbcluster " . + " and --skip-ndbcluster was specified"); + } + # Check if this is MySQL Cluster, ie. mysql version string ends # with -ndb-Y.Y.Y[-status] if ( defined $mysql_version_extra && - $mysql_version_extra =~ /^-ndb-/ ) + $mysql_version_extra =~ /-ndb-([0-9]*)\.([0-9]*)\.([0-9]*)/ ) { - mtr_report(" - MySQL Cluster"); - # Enable ndb engine and add more test suites - $opt_include_ndbcluster = 1; - $DEFAULT_SUITES.=",ndb"; + # MySQL Cluster tree + mtr_report(" - MySQL Cluster detected"); + + if ($opt_skip_ndbcluster) + { + mtr_report(" - skipping ndbcluster(--skip-ndbcluster)"); + return; + } + + if (!$ndbcluster_supported) + { + # MySQL Cluster tree, but mysqld was not compiled with + # ndbcluster -> fail unless --skip-ndbcluster was used + mtr_error("This is MySQL Cluster but mysqld does not " . + "support ndbcluster. Use --skip-ndbcluster to " . + "force mtr to run without it."); + } + + # mysqld was compiled with ndbcluster -> auto enable + } + else + { + # Not a MySQL Cluster tree + if (!$ndbcluster_supported) + { + if ($opt_include_ndbcluster) + { + mtr_error("Could not detect ndbcluster support ". + "requested with --include-ndbcluster"); + } + + # Silently skip, mysqld was compiled without ndbcluster + # which is the default case + return; + } + + if ($opt_skip_ndbcluster) + { + # Compiled with ndbcluster but ndbcluster skipped + mtr_report(" - skipping ndbcluster(--skip-ndbcluster)"); + return; + } + + + # Not a MySQL Cluster tree, enable ndbcluster + # if --include-ndbcluster was used + if ($opt_include_ndbcluster) + { + # enable ndbcluster + } + else + { + mtr_report(" - skipping ndbcluster(disabled by default)"); + return; + } } - if ($opt_include_ndbcluster) - { - $opt_skip_ndbcluster= 0; - } - - if ($opt_skip_ndbcluster) - { - mtr_report(" - skipping ndbcluster"); - return; - } - - if ( ! $mysqld_variables{'ndb-connectstring'} ) - { - mtr_report(" - skipping ndbcluster, mysqld not compiled with ndbcluster"); - $opt_skip_ndbcluster= 2; - return; - } - - mtr_report(" - using ndbcluster when necessary, mysqld supports it"); - + mtr_report(" - enabling ndbcluster"); + $ndbcluster_enabled= 1; + # Add MySQL Cluster test suites + $DEFAULT_SUITES.=",ndb,ndb_binlog,rpl_ndb,ndb_rpl,ndb_memcache"; return; } From da599d5ec522be6bd5b6cc0e7d6f46531bee0672 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 4 Nov 2012 22:17:17 +0100 Subject: [PATCH 004/324] mtr.pl - remove unused hack to turn on extra suites based on current directory name - remove 4 your old debug printout of "vardir: " --- mysql-test/mysql-test-run.pl | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 25c741cb821..c8589bb50eb 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -366,26 +366,6 @@ sub main { if (!$opt_suites) { $opt_suites= $DEFAULT_SUITES; - - # Check for any extra suites to enable based on the path name - my %extra_suites= - ( - "mysql-5.1-new-ndb" => "ndb_team", - "mysql-5.1-new-ndb-merge" => "ndb_team", - "mysql-5.1-telco-6.2" => "ndb_team", - "mysql-5.1-telco-6.2-merge" => "ndb_team", - "mysql-5.1-telco-6.3" => "ndb_team", - "mysql-6.0-ndb" => "ndb_team", - ); - - foreach my $dir ( reverse splitdir($basedir) ) { - my $extra_suite= $extra_suites{$dir}; - if (defined $extra_suite) { - mtr_report("Found extra suite: $extra_suite"); - $opt_suites= "$extra_suite,$opt_suites"; - last; - } - } } mtr_report("Using suites: $opt_suites") unless @opt_cases; @@ -409,7 +389,6 @@ sub main { unshift(@$tests, $tinfo); } - print "vardir: $opt_vardir\n"; initialize_servers(); ####################################################################### From 350bf6cb394ebce1f5b0e96281529b6c9c07059a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 5 Nov 2012 11:05:46 +0100 Subject: [PATCH 005/324] Raise version number after cloning 5.1.67 --- configure.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.in b/configure.in index 9f361d88a38..e4618f58a91 100644 --- a/configure.in +++ b/configure.in @@ -12,7 +12,7 @@ dnl dnl When changing the major version number please also check the switch dnl statement in mysqlbinlog::check_master_version(). You may also need dnl to update version.c in ndb. -AC_INIT([MySQL Server], [5.1.67], [], [mysql]) +AC_INIT([MySQL Server], [5.1.68], [], [mysql]) AC_CONFIG_SRCDIR([sql/mysqld.cc]) AC_CANONICAL_SYSTEM From 2dce6cde752dcf4daf4ec61e4b5f9689350527d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 5 Nov 2012 17:45:13 +0530 Subject: [PATCH 006/324] From b6d3362948b0d0fb29fe4bb5bcef03b88e8052e3 Mon Sep 17 00:00:00 2001 From: Aditya A Date: Tue, 6 Nov 2012 18:35:03 +0530 Subject: [PATCH 007/324] Bug#11751825 - OPTIMIZE PARTITION RECREATES FULL TABLE INSTEAD JUST PARTITION PROBLEM ------- optimize on partiton will recreate the whole table instead of just partition. ANALYSIS -------- At present innodb doesn't support optimize option ,so we do a rebuild of the whole table and then call analyze() on the table.Presently for any optimize() option (on table or partition) we display the following info to the user "Table does not support optimize, doing recreate + analyze instead". FIX --- It was decided for GA versions(5.1 and 5.5) whenever the user tries to optimize a partition(s) we will will display the following info the user "Table does not support optimize on partitions. All partitions will be rebuilt and analyzed." Earlier partitions were not analyzed.Now all partitions will be analyzed. If the user wants to optimize the whole table ,we will display the previous info to the user. i.e "Table does not support optimize, doing recreate + analyze instead" For 5.6+ versions we will raise a new bug to support optimize() options in innodb. --- sql/sql_table.cc | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b8d57341e42..a0545bb5342 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4908,6 +4908,11 @@ send_result_message: case HA_ADMIN_TRY_ALTER: { + uint save_flags; + Alter_info *alter_info= &lex->alter_info; + + /* Store the original value of alter_info->flags */ + save_flags= alter_info->flags; /* This is currently used only by InnoDB. ha_innobase::optimize() answers "try with alter", so here we close the table, do an ALTER TABLE, @@ -4915,9 +4920,18 @@ send_result_message: We have to end the row, so analyze could return more rows. */ protocol->store(STRING_WITH_LEN("note"), system_charset_info); - protocol->store(STRING_WITH_LEN( - "Table does not support optimize, doing recreate + analyze instead"), - system_charset_info); + if(alter_info->flags & ALTER_ADMIN_PARTITION) + { + protocol->store(STRING_WITH_LEN( + "Table does not support optimize on partitions. All partitions " + "will be rebuilt and analyzed."),system_charset_info); + } + else + { + protocol->store(STRING_WITH_LEN( + "Table does not support optimize, doing recreate + analyze instead"), + system_charset_info); + } if (protocol->write()) goto err; ha_autocommit_or_rollback(thd, 0); @@ -4941,9 +4955,15 @@ send_result_message: close_thread_tables(thd); if (!result_code) // recreation went ok { + /* + Reset the ALTER_ADMIN_PARTITION bit in alter_info->flags + to force analyze on all partitions. + */ + alter_info->flags &= ~(ALTER_ADMIN_PARTITION); if ((table->table= open_ltable(thd, table, lock_type, 0)) && ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0)) result_code= 0; // analyze went ok + alter_info->flags= save_flags; } /* Start a new row for the final status row */ protocol->prepare_for_resend(); From 2226b1084ce0209ad4ff8e3805ed944600af3abb Mon Sep 17 00:00:00 2001 From: Venkata Sidagam Date: Wed, 7 Nov 2012 09:00:17 +0530 Subject: [PATCH 008/324] Bug #11759445: CAN'T DELETE ROWS FROM MEMORY TABLE WITH HASH KEY. Brief description: After insert some rows to MEMORY table with HASH key some rows can't be deleted in one step. Problem Analysis/solution: info->current_ptr will have the information about the current hash pointer from where we can traverse to the list to get all the remaining tuples. In hp_delete_key we are updating info->current_ptr with the last_pos based on the flag parameter(which is the keydef and last index are same). As part of the fix we are making it to zero only when the code flow reaches to the end of the function hp_delete_key() it means that the next record which has to get deleted will be at the starting of the list so, that in the next call to read record(heap_rnext()) will take line number 100 path instead of 102 path, please see the below code in file hp_rnext.c, function heap_rnext(). 99 else if (!info->current_ptr) /* Deleted or first call */ 100 pos= hp_search(info, keyinfo, info->lastkey, 0); 101 else 102 pos= hp_search(info, keyinfo, info->lastkey, 1); with that change the hp_search() will update the info->current_ptr with the record which needs to be deleted. storage/heap/hp_delete.c: In heap_delete_key() function we are making info->current_ptr to 0 if flag is enabled. --- storage/heap/hp_delete.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/storage/heap/hp_delete.c b/storage/heap/hp_delete.c index ceba0fcf12e..3090b60d611 100644 --- a/storage/heap/hp_delete.c +++ b/storage/heap/hp_delete.c @@ -104,7 +104,7 @@ int hp_rb_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, const uchar *record, uchar *recpos, int flag) { - ulong blength,pos2,pos_hashnr,lastpos_hashnr; + ulong blength, pos2, pos_hashnr, lastpos_hashnr, key_pos; HASH_INFO *lastpos,*gpos,*pos,*pos3,*empty,*last_ptr; HP_SHARE *share=info->s; DBUG_ENTER("hp_delete_key"); @@ -116,9 +116,9 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, last_ptr=0; /* Search after record with key */ - pos= hp_find_hash(&keyinfo->block, - hp_mask(hp_rec_hashnr(keyinfo, record), blength, - share->records + 1)); + key_pos= hp_mask(hp_rec_hashnr(keyinfo, record), blength, share->records + 1); + pos= hp_find_hash(&keyinfo->block, key_pos); + gpos = pos3 = 0; while (pos->ptr_to_rec != recpos) @@ -188,6 +188,16 @@ int hp_delete_key(HP_INFO *info, register HP_KEYDEF *keyinfo, DBUG_RETURN(0); } pos3= pos; /* Link pos->next after lastpos */ + /* + One of elements from the bucket we're scanning is moved to the + beginning of the list. Reset search since this element may not have + been processed yet. + */ + if (flag && pos2 == key_pos) + { + info->current_ptr= 0; + info->current_hash_ptr= 0; + } } else { From f5fbcfe3c8b87f0a66293a9d69e65ed2a127180c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 7 Nov 2012 18:41:42 +0530 Subject: [PATCH 009/324] From d912a758b02399c28cb30d97496ad5cdab35d214 Mon Sep 17 00:00:00 2001 From: Praveenkumar Hulakund Date: Wed, 7 Nov 2012 19:08:33 +0530 Subject: [PATCH 010/324] Bug#14466617 - INVALID WRITES AND/OR CRASH WITH USER VARIABLES Analysis: ------------- After executing the query, new value of the user defined variables are set in the function "select_dumpvar::send_data". "select_dumpvar::send_data" first calls function "Item_func_set_user_var::save_item_result()". This function checks the nullness of the Item_field passed as parameter to it and saves it. The nullness of item is stored with arg[0]'s null_value flag. Then "select_dumpvar::send_data" calls "Item_func_set_user_var::update()" which notices null result that was saved and calls "Item_func_set_user_var:: update_hash". But here null_value is not set and args[0] is different from that given to function "Item_func_set_user_var:: set_item_result()". This causes "Item_func_set_user_var:: update_hash" function to believe that its getting non-null value. "user_var_entry::length" set to 0 and hence "user_var_entry::value" is made to point to extra_area allocated in "user_var_entry". And "Item_func_set_user_var::update_hash" tries to write at memory beyond extra_area for result type DECIMAL. Because of this invalid write issue is reported by Valgrind. Before this bug was introduced, we avoided this problem by creating "Item_func_set_user_var" object with the same Item_field as arg[0] and as parameter to Item_func_set_user_var::save_item_result(). But now they are refering to different args[0]. Because of this null_value flag set in parameter Item_field in function "Item_func_set_user_var::save_item_result()" is not reflected in "Item_func_set_user_var" object. Fix: ------------ This issue is reported on versions 5.5.24. Issue does not exists in 5.5.23, 5.1, 5.6 and trunk. This issue was introduced by revid:georgi.kodinov@oracle.com-20120309130449-82e3bs5v3et1x0ef (fix for bug #12408412), which was pushed into 5.5 and later releases. This patch has later been reversed in 5.6 and trunk by revid:norvald.ryeng@oracle.com-20121010135242-xj34gg73h04hrmyh (fix for bug #14664077). Backported this patch in 5.5 also to fix this issue. sql/item_func.cc: here unsigned value is converted to signed value. sql/item_func.h: last_insert_id() gives an auto_incremented value which can be positive only,so defined it as a unsigned longlong sets the unsigned_flag to 1. --- sql/item_func.cc | 29 +++++++++++++++++------- sql/item_func.h | 18 +++++++++++++-- sql/log_event.cc | 3 ++- sql/protocol.cc | 2 +- sql/sql_class.cc | 58 ++++++++++++++++-------------------------------- sql/sql_class.h | 1 - sql/sql_yacc.yy | 4 ++-- 7 files changed, 61 insertions(+), 54 deletions(-) diff --git a/sql/item_func.cc b/sql/item_func.cc index be8ee84712a..39d19fab421 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -4222,13 +4222,18 @@ bool Item_func_set_user_var::set_entry(THD *thd, bool create_if_not_exists) return TRUE; } entry_thread_id= thd->thread_id; - /* - Remember the last query which updated it, this way a query can later know - if this variable is a constant item in the query (it is if update_query_id - is different from query_id). - */ + end: - entry->update_query_id= thd->query_id; + /* + Remember the last query which updated it, this way a query can later know + if this variable is a constant item in the query (it is if update_query_id + is different from query_id). + + If this object has delayed setting of non-constness, we delay this + until Item_func_set-user_var::save_item_result() + */ + if (!delayed_non_constness) + entry->update_query_id= thd->query_id; return FALSE; } @@ -4616,6 +4621,13 @@ void Item_func_set_user_var::save_item_result(Item *item) DBUG_ASSERT(0); break; } + /* + Set the ID of the query that last updated this variable. This is + usually set by Item_func_set_user_var::set_entry(), but if this + item has delayed setting of non-constness, we must do it now. + */ + if (delayed_non_constness) + entry->update_query_id= current_thd->query_id; DBUG_VOID_RETURN; } @@ -5022,7 +5034,8 @@ get_var_with_binlog(THD *thd, enum_sql_command sql_command, thd->lex= &lex_tmp; lex_start(thd); tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name, - new Item_null()))); + new Item_null(), + false))); /* Create the variable */ if (sql_set_variables(thd, &tmp_var_list)) { @@ -5185,7 +5198,7 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const bool Item_func_get_user_var::set_value(THD *thd, sp_rcontext * /*ctx*/, Item **it) { - Item_func_set_user_var *suv= new Item_func_set_user_var(get_name(), *it); + Item_func_set_user_var *suv= new Item_func_set_user_var(get_name(), *it, false); /* Item_func_set_user_var is not fixed after construction, call fix_fields(). diff --git a/sql/item_func.h b/sql/item_func.h index 6ac0b1b82bd..b897dcfaaaa 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1457,6 +1457,20 @@ class Item_func_set_user_var :public Item_func user variable it the first connection context). */ my_thread_id entry_thread_id; + /** + Delayed setting of non-constness. + + Normally, Item_func_get_user_var objects are tagged as not const + when Item_func_set_user_var::fix_fields() is called for the same + variable in the same query. If delayed_non_constness is set, the + tagging is delayed until the variable is actually set. This means + that Item_func_get_user_var objects will still be treated as a + constant by the optimizer and executor until the variable is + actually changed. + + @see select_dumpvar::send_data(). + */ + bool delayed_non_constness; char buffer[MAX_FIELD_WIDTH]; String value; my_decimal decimal_buff; @@ -1471,9 +1485,9 @@ class Item_func_set_user_var :public Item_func public: LEX_STRING name; // keep it public - Item_func_set_user_var(LEX_STRING a,Item *b) + Item_func_set_user_var(LEX_STRING a,Item *b, bool delayed) :Item_func(b), cached_result_type(INT_RESULT), - entry(NULL), entry_thread_id(0), name(a) + entry(NULL), entry_thread_id(0), delayed_non_constness(delayed), name(a) {} enum Functype functype() const { return SUSERVAR_FUNC; } double val_real(); diff --git a/sql/log_event.cc b/sql/log_event.cc index eb848927c12..766c079d3a6 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -6164,7 +6164,8 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) } } - Item_func_set_user_var *e= new Item_func_set_user_var(user_var_name, it); + Item_func_set_user_var *e= + new Item_func_set_user_var(user_var_name, it, false); /* Item_func_set_user_var can't substitute something else on its place => 0 can be passed as last argument (reference on item) diff --git a/sql/protocol.cc b/sql/protocol.cc index 5c1533ad10d..5736a74638d 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1213,7 +1213,7 @@ bool Protocol_text::send_out_parameters(List *sp_params) continue; // It's an IN-parameter. Item_func_set_user_var *suv= - new Item_func_set_user_var(*user_var_name, item_param); + new Item_func_set_user_var(*user_var_name, item_param, false); /* Item_func_set_user_var is not fixed after construction, call fix_fields(). diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b0d7cac1864..e32844d06ea 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2884,12 +2884,7 @@ bool select_exists_subselect::send_data(List &items) int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) { unit= u; - List_iterator_fast var_li(var_list); - List_iterator_fast it(list); - Item *item; - my_var *mv; - Item_func_set_user_var **suv; - + if (var_list.elements != list.elements) { my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT, @@ -2897,29 +2892,6 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) return 1; } - /* - Iterate over the destination variables and mark them as being - updated in this query. - We need to do this at JOIN::prepare time to ensure proper - const detection of Item_func_get_user_var that is determined - by the presence of Item_func_set_user_vars - */ - - suv= set_var_items= (Item_func_set_user_var **) - sql_alloc(sizeof(Item_func_set_user_var *) * list.elements); - - while ((mv= var_li++) && (item= it++)) - { - if (!mv->local) - { - *suv= new Item_func_set_user_var(mv->s, item); - (*suv)->fix_fields(thd, 0); - } - else - *suv= NULL; - suv++; - } - return 0; } @@ -3236,33 +3208,41 @@ bool select_dumpvar::send_data(List &items) List_iterator it(items); Item *item; my_var *mv; - Item_func_set_user_var **suv; DBUG_ENTER("select_dumpvar::send_data"); if (unit->offset_limit_cnt) { // using limit offset,count unit->offset_limit_cnt--; - DBUG_RETURN(0); + DBUG_RETURN(false); } if (row_count++) { my_message(ER_TOO_MANY_ROWS, ER(ER_TOO_MANY_ROWS), MYF(0)); - DBUG_RETURN(1); + DBUG_RETURN(true); } - for (suv= set_var_items; ((mv= var_li++) && (item= it++)); suv++) + while ((mv= var_li++) && (item= it++)) { if (mv->local) { - DBUG_ASSERT(!*suv); if (thd->spcont->set_variable(thd, mv->offset, &item)) - DBUG_RETURN(1); + DBUG_RETURN(true); } else { - DBUG_ASSERT(*suv); - (*suv)->save_item_result(item); - if ((*suv)->update()) - DBUG_RETURN (1); + /* + Create Item_func_set_user_vars with delayed non-constness. We + do this so that Item_get_user_var::const_item() will return + the same result during + Item_func_set_user_var::save_item_result() as they did during + optimization and execution. + */ + Item_func_set_user_var *suv= + new Item_func_set_user_var(mv->s, item, true); + if (suv->fix_fields(thd, 0)) + DBUG_RETURN(true); + suv->save_item_result(item); + if (suv->update()) + DBUG_RETURN(true); } } DBUG_RETURN(thd->is_error()); diff --git a/sql/sql_class.h b/sql/sql_class.h index d799980f8e1..4f65aa25796 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3552,7 +3552,6 @@ public: class select_dumpvar :public select_result_interceptor { ha_rows row_count; - Item_func_set_user_var **set_var_items; public: List var_list; select_dumpvar() { var_list.empty(); row_count= 0;} diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index e93ed4e8853..7f1b5a57ac4 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -8980,7 +8980,7 @@ variable_aux: ident_or_text SET_VAR expr { Item_func_set_user_var *item; - $$= item= new (YYTHD->mem_root) Item_func_set_user_var($1, $3); + $$= item= new (YYTHD->mem_root) Item_func_set_user_var($1, $3, false); if ($$ == NULL) MYSQL_YYABORT; LEX *lex= Lex; @@ -12970,7 +12970,7 @@ option_value: '@' ident_or_text equal expr { Item_func_set_user_var *item; - item= new (YYTHD->mem_root) Item_func_set_user_var($2, $4); + item= new (YYTHD->mem_root) Item_func_set_user_var($2, $4, false); if (item == NULL) MYSQL_YYABORT; set_var_user *var= new set_var_user(item); From 7e613db478c98c32e4bdcf2ffe72742bb9416f7a Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Wed, 7 Nov 2012 17:45:02 +0100 Subject: [PATCH 011/324] Placement change: Top level "SPECIFIC-ULN/" was inappropriate, put the files to create RPMs for ULN into "packaging/rpm-uln/". --- CMakeLists.txt | 2 +- cmake/install_layout.cmake | 2 +- {SPECIFIC-ULN => packaging/rpm-uln}/CMakeLists.txt | 0 {SPECIFIC-ULN => packaging/rpm-uln}/README-ULN | 0 {SPECIFIC-ULN => packaging/rpm-uln}/README.mysql-docs | 0 {SPECIFIC-ULN => packaging/rpm-uln}/filter-requires-mysql.sh | 0 {SPECIFIC-ULN => packaging/rpm-uln}/generate-tarball.sh | 0 {SPECIFIC-ULN => packaging/rpm-uln}/my.cnf | 0 {SPECIFIC-ULN => packaging/rpm-uln}/my_config.h | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-errno.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-fix-tests.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-libdir.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-mtr1.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-stack-guard.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-testing.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-chain-certs.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-embedded-check.c | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-expired-certs.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-install-test.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql-strmov.patch | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql.init | 0 {SPECIFIC-ULN => packaging/rpm-uln}/mysql.spec.sh | 0 {SPECIFIC-ULN => packaging/rpm-uln}/scriptstub.c | 0 23 files changed, 2 insertions(+), 2 deletions(-) rename {SPECIFIC-ULN => packaging/rpm-uln}/CMakeLists.txt (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/README-ULN (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/README.mysql-docs (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/filter-requires-mysql.sh (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/generate-tarball.sh (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/my.cnf (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/my_config.h (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-errno.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-fix-tests.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-libdir.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-mtr1.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-stack-guard.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-5.5-testing.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-chain-certs.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-embedded-check.c (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-expired-certs.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-install-test.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql-strmov.patch (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql.init (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/mysql.spec.sh (100%) rename {SPECIFIC-ULN => packaging/rpm-uln}/scriptstub.c (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 85a01a8b399..7429a335009 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -328,7 +328,7 @@ IF(NOT WITHOUT_SERVER) IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt) ADD_SUBDIRECTORY(internal) ENDIF() - ADD_SUBDIRECTORY(SPECIFIC-ULN) + ADD_SUBDIRECTORY(packaging/rpm-uln) ENDIF() INCLUDE(cmake/abi_check.cmake) diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index 18c7afd8037..4adda0b6eac 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -138,7 +138,7 @@ SET(INSTALL_PLUGINTESTDIR_STANDALONE ${plugin_tests}) # # RPM layout # -# See "SPECIFIC-ULN/mysql-5.5-libdir.patch" for the differences +# See "packaging/rpm-uln/mysql-5.5-libdir.patch" for the differences # which apply to RPMs in ULN (Oracle Linux), that patch file will # be applied at build time via "rpmbuild". # diff --git a/SPECIFIC-ULN/CMakeLists.txt b/packaging/rpm-uln/CMakeLists.txt similarity index 100% rename from SPECIFIC-ULN/CMakeLists.txt rename to packaging/rpm-uln/CMakeLists.txt diff --git a/SPECIFIC-ULN/README-ULN b/packaging/rpm-uln/README-ULN similarity index 100% rename from SPECIFIC-ULN/README-ULN rename to packaging/rpm-uln/README-ULN diff --git a/SPECIFIC-ULN/README.mysql-docs b/packaging/rpm-uln/README.mysql-docs similarity index 100% rename from SPECIFIC-ULN/README.mysql-docs rename to packaging/rpm-uln/README.mysql-docs diff --git a/SPECIFIC-ULN/filter-requires-mysql.sh b/packaging/rpm-uln/filter-requires-mysql.sh similarity index 100% rename from SPECIFIC-ULN/filter-requires-mysql.sh rename to packaging/rpm-uln/filter-requires-mysql.sh diff --git a/SPECIFIC-ULN/generate-tarball.sh b/packaging/rpm-uln/generate-tarball.sh similarity index 100% rename from SPECIFIC-ULN/generate-tarball.sh rename to packaging/rpm-uln/generate-tarball.sh diff --git a/SPECIFIC-ULN/my.cnf b/packaging/rpm-uln/my.cnf similarity index 100% rename from SPECIFIC-ULN/my.cnf rename to packaging/rpm-uln/my.cnf diff --git a/SPECIFIC-ULN/my_config.h b/packaging/rpm-uln/my_config.h similarity index 100% rename from SPECIFIC-ULN/my_config.h rename to packaging/rpm-uln/my_config.h diff --git a/SPECIFIC-ULN/mysql-5.5-errno.patch b/packaging/rpm-uln/mysql-5.5-errno.patch similarity index 100% rename from SPECIFIC-ULN/mysql-5.5-errno.patch rename to packaging/rpm-uln/mysql-5.5-errno.patch diff --git a/SPECIFIC-ULN/mysql-5.5-fix-tests.patch b/packaging/rpm-uln/mysql-5.5-fix-tests.patch similarity index 100% rename from SPECIFIC-ULN/mysql-5.5-fix-tests.patch rename to packaging/rpm-uln/mysql-5.5-fix-tests.patch diff --git a/SPECIFIC-ULN/mysql-5.5-libdir.patch b/packaging/rpm-uln/mysql-5.5-libdir.patch similarity index 100% rename from SPECIFIC-ULN/mysql-5.5-libdir.patch rename to packaging/rpm-uln/mysql-5.5-libdir.patch diff --git a/SPECIFIC-ULN/mysql-5.5-mtr1.patch b/packaging/rpm-uln/mysql-5.5-mtr1.patch similarity index 100% rename from SPECIFIC-ULN/mysql-5.5-mtr1.patch rename to packaging/rpm-uln/mysql-5.5-mtr1.patch diff --git a/SPECIFIC-ULN/mysql-5.5-stack-guard.patch b/packaging/rpm-uln/mysql-5.5-stack-guard.patch similarity index 100% rename from SPECIFIC-ULN/mysql-5.5-stack-guard.patch rename to packaging/rpm-uln/mysql-5.5-stack-guard.patch diff --git a/SPECIFIC-ULN/mysql-5.5-testing.patch b/packaging/rpm-uln/mysql-5.5-testing.patch similarity index 100% rename from SPECIFIC-ULN/mysql-5.5-testing.patch rename to packaging/rpm-uln/mysql-5.5-testing.patch diff --git a/SPECIFIC-ULN/mysql-chain-certs.patch b/packaging/rpm-uln/mysql-chain-certs.patch similarity index 100% rename from SPECIFIC-ULN/mysql-chain-certs.patch rename to packaging/rpm-uln/mysql-chain-certs.patch diff --git a/SPECIFIC-ULN/mysql-embedded-check.c b/packaging/rpm-uln/mysql-embedded-check.c similarity index 100% rename from SPECIFIC-ULN/mysql-embedded-check.c rename to packaging/rpm-uln/mysql-embedded-check.c diff --git a/SPECIFIC-ULN/mysql-expired-certs.patch b/packaging/rpm-uln/mysql-expired-certs.patch similarity index 100% rename from SPECIFIC-ULN/mysql-expired-certs.patch rename to packaging/rpm-uln/mysql-expired-certs.patch diff --git a/SPECIFIC-ULN/mysql-install-test.patch b/packaging/rpm-uln/mysql-install-test.patch similarity index 100% rename from SPECIFIC-ULN/mysql-install-test.patch rename to packaging/rpm-uln/mysql-install-test.patch diff --git a/SPECIFIC-ULN/mysql-strmov.patch b/packaging/rpm-uln/mysql-strmov.patch similarity index 100% rename from SPECIFIC-ULN/mysql-strmov.patch rename to packaging/rpm-uln/mysql-strmov.patch diff --git a/SPECIFIC-ULN/mysql.init b/packaging/rpm-uln/mysql.init similarity index 100% rename from SPECIFIC-ULN/mysql.init rename to packaging/rpm-uln/mysql.init diff --git a/SPECIFIC-ULN/mysql.spec.sh b/packaging/rpm-uln/mysql.spec.sh similarity index 100% rename from SPECIFIC-ULN/mysql.spec.sh rename to packaging/rpm-uln/mysql.spec.sh diff --git a/SPECIFIC-ULN/scriptstub.c b/packaging/rpm-uln/scriptstub.c similarity index 100% rename from SPECIFIC-ULN/scriptstub.c rename to packaging/rpm-uln/scriptstub.c From a4e7094e88d0e8783ee019fc58c41b43e816712b Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Wed, 7 Nov 2012 20:32:54 +0100 Subject: [PATCH 012/324] Make RPMs for ULN build again. A change to "vio/viosslfactories.c" in August, 2012, broke a patch which is to be applied during the build of ULN RPMs. The patch file is "packaging/rpm-uln/mysql-chain-certs.patch" This change bypasses the problem by not trying to apply the patch. This is a regression and must be fixed, not bypassed. --- packaging/rpm-uln/mysql.spec.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packaging/rpm-uln/mysql.spec.sh b/packaging/rpm-uln/mysql.spec.sh index 8b25b160be1..93ba78eb56a 100644 --- a/packaging/rpm-uln/mysql.spec.sh +++ b/packaging/rpm-uln/mysql.spec.sh @@ -244,7 +244,8 @@ Patch13: mysql-expired-certs.patch # Will not be used by MySQL # Patch14: mysql-missing-string-code.patch Undecided, will not work in 5.5 (cmake) # Patch15: mysql-lowercase-bug.patch Fixed in MySQL 5.1.54 and 5.5.9 -Patch16: mysql-chain-certs.patch +# Patch16: mysql-chain-certs.patch Currently, this patch is broken +# by server code changes to "vio/viosslfactories.c" Patch17: mysql-5.5-libdir.patch Patch18: mysql-5.5-fix-tests.patch Patch19: mysql-5.5-mtr1.patch @@ -399,7 +400,8 @@ cd %{src_dir} # read about "%setup -n" # %patch10 -p1 # %patch13 -p1 # %patch14 -p1 -%patch16 -p1 +# %patch16 -p1 Currently, this patch is broken +# by server code changes to "vio/viosslfactories.c" %patch17 -p1 %patch18 -p1 %patch19 -p1 From 078d7a87c9581fb90867197ee7f873fe3bbc3c60 Mon Sep 17 00:00:00 2001 From: Aditya A Date: Thu, 8 Nov 2012 14:19:27 +0530 Subject: [PATCH 013/324] Bug#11751825 - OPTIMIZE PARTITION RECREATES FULL TABLE INSTEAD JUST PARTITION Follow up patch to address the pb2 failures. --- .../parts/r/partition_alter4_innodb.result | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/mysql-test/suite/parts/r/partition_alter4_innodb.result b/mysql-test/suite/parts/r/partition_alter4_innodb.result index 5d3143e35bb..b0f340664b7 100644 --- a/mysql-test/suite/parts/r/partition_alter4_innodb.result +++ b/mysql-test/suite/parts/r/partition_alter4_innodb.result @@ -37566,7 +37566,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -38026,7 +38026,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -38497,7 +38497,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -38969,7 +38969,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -39435,7 +39435,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -39907,7 +39907,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -40384,7 +40384,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -40859,7 +40859,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -41324,7 +41324,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -41784,7 +41784,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -42255,7 +42255,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -42727,7 +42727,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -43193,7 +43193,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -43665,7 +43665,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -44142,7 +44142,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -44617,7 +44617,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION part_1,part_2; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -52582,7 +52582,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -53042,7 +53042,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -53513,7 +53513,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -53985,7 +53985,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -54451,7 +54451,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -54923,7 +54923,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -55400,7 +55400,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template @@ -55875,7 +55875,7 @@ SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template WHERE f_int1 BETWEEN 1 AND @max_row_div2 - 1; ALTER TABLE t1 OPTIMIZE PARTITION ALL; Table Op Msg_type Msg_text -test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize note Table does not support optimize on partitions. All partitions will be rebuilt and analyzed. test.t1 optimize status OK INSERT INTO t1(f_int1,f_int2,f_char1,f_char2,f_charbig) SELECT f_int1,f_int2,f_char1,f_char2,f_charbig FROM t0_template From 7a8c93e6dd879e451b983e0f0b31d1512e516129 Mon Sep 17 00:00:00 2001 From: Aditya A Date: Thu, 8 Nov 2012 15:14:29 +0530 Subject: [PATCH 014/324] Bug#14234028 - CRASH DURING SHUTDOWN WITH BACKGROUND PURGE THREAD Analysis --------- my_stat() calls stat() and if the stat() call fails we try to set the variable my_errno which is actually a thread specific data . We try to get the address of this thread specific data using my_pthread_getspecifc(),but for the purge thread we have not defined any thread specific data so it returns null and when dereferencing null we get a segmentation fault. init_available_charsets() seen in the core stack is invoked through pthread_once() .pthread_once is used for one time initialization.Since free_charsets() is called before innodb plugin shutdown ,purge thread calls init_avaliable_charsets() which leads to the crash. Fix --- Call free_charsets() after the innodb plugin shutdown,since purge threads are still using the charsets. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 11e756381ab..aece8f28533 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1340,7 +1340,6 @@ void clean_up(bool print_message) lex_free(); /* Free some memory */ item_create_cleanup(); set_var_free(); - free_charsets(); if (!opt_noacl) { #ifdef HAVE_DLOPEN @@ -1390,6 +1389,7 @@ void clean_up(bool print_message) #ifdef USE_REGEX my_regex_end(); #endif + free_charsets(); #if defined(ENABLED_DEBUG_SYNC) /* End the debug sync facility. See debug_sync.cc. */ debug_sync_end(); From 7ef879bb81ac898246700012fd55a6a3f302205c Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Thu, 8 Nov 2012 18:09:13 +0530 Subject: [PATCH 015/324] Bug #14669848 CRASH DURING ALTER MAKES ORIGINAL TABLE INACCESSIBLE When a new primary key is added to an InnoDB table, then the following steps are taken by InnoDB plugin: . let t1 be the original table. . a temporary table t1@00231 will be created by cloning t1. . all data will be copied from t1 to t1@00231. . rename t1 to t1@00232. . rename t1@00231 to t1. . drop t1@00232. The rename and drop operations involve file operations. But file operations cannot be rolled back. So in row_merge_rename_tables(), just after doing data dictionary update and before doing any file operations, generate redo logs for file operations and commit the transaction. This will ensure that any crash after this commit, the table is still recoverable by moving .ibd and .frm files. Manual recovery is required. During recovery, the rename file operation redo logs are processed. Previously this was being ignored. rb://1460 approved by Marko Makela. --- storage/innodb_plugin/fil/fil0fil.c | 27 ++++++++++++++++++++++++- storage/innodb_plugin/include/fil0fil.h | 15 ++++++++++++++ storage/innodb_plugin/log/log0recv.c | 15 ++++++++++---- storage/innodb_plugin/row/row0merge.c | 22 ++++++++++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c index 6f2ab938042..d5770baafea 100644 --- a/storage/innodb_plugin/fil/fil0fil.c +++ b/storage/innodb_plugin/fil/fil0fil.c @@ -2619,7 +2619,7 @@ retry: mutex_exit(&fil_system->mutex); #ifndef UNIV_HOTBACKUP - if (success) { + if (success && !recv_recovery_on) { mtr_t mtr; mtr_start(&mtr); @@ -4853,3 +4853,28 @@ fil_close(void) fil_system = NULL; } + +/****************************************************************//** +Generate redo logs for swapping two .ibd files */ +UNIV_INTERN +void +fil_mtr_rename_log( +/*===============*/ + ulint old_space_id, /*!< in: tablespace id of the old + table. */ + const char* old_name, /*!< in: old table name */ + ulint new_space_id, /*!< in: tablespace id of the new + table */ + const char* new_name, /*!< in: new table name */ + const char* tmp_name) /*!< in: temp table name used while + swapping */ +{ + mtr_t mtr; + mtr_start(&mtr); + fil_op_write_log(MLOG_FILE_RENAME, old_space_id, + 0, 0, old_name, tmp_name, &mtr); + fil_op_write_log(MLOG_FILE_RENAME, new_space_id, + 0, 0, new_name, old_name, &mtr); + mtr_commit(&mtr); +} + diff --git a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/include/fil0fil.h index 05217168764..09e6e37b223 100644 --- a/storage/innodb_plugin/include/fil0fil.h +++ b/storage/innodb_plugin/include/fil0fil.h @@ -726,6 +726,21 @@ fil_tablespace_is_being_deleted( /*============================*/ ulint id); /*!< in: space id */ +/****************************************************************//** +Generate redo logs for swapping two .ibd files */ +UNIV_INTERN +void +fil_mtr_rename_log( +/*===============*/ + ulint old_space_id, /*!< in: tablespace id of the old + table. */ + const char* old_name, /*!< in: old table name */ + ulint new_space_id, /*!< in: tablespace id of the new + table */ + const char* new_name, /*!< in: new table name */ + const char* tmp_name); /*!< in: temp table name used while + swapping */ + typedef struct fil_space_struct fil_space_t; #endif diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c index 677ada9fbde..96d63144366 100644 --- a/storage/innodb_plugin/log/log0recv.c +++ b/storage/innodb_plugin/log/log0recv.c @@ -955,8 +955,11 @@ recv_parse_or_apply_log_rec_body( not NULL, then the log record is applied to the page, and the log record should be complete then */ - mtr_t* mtr) /*!< in: mtr or NULL; should be non-NULL + mtr_t* mtr, /*!< in: mtr or NULL; should be non-NULL if and only if block is non-NULL */ + ulint space_id) + /*!< in: tablespace id obtained by + parsing initial log record */ { dict_index_t* index = NULL; page_t* page; @@ -1228,8 +1231,11 @@ recv_parse_or_apply_log_rec_body( ut_ad(!page || page_type != FIL_PAGE_TYPE_ALLOCATED); ptr = mlog_parse_string(ptr, end_ptr, page, page_zip); break; - case MLOG_FILE_CREATE: case MLOG_FILE_RENAME: + ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, + space_id, 0); + break; + case MLOG_FILE_CREATE: case MLOG_FILE_DELETE: case MLOG_FILE_CREATE2: ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0); @@ -1601,7 +1607,8 @@ recv_recover_page_func( recv_parse_or_apply_log_rec_body(recv->type, buf, buf + recv->len, - block, &mtr); + block, &mtr, + recv_addr->space); end_lsn = recv->start_lsn + recv->len; mach_write_ull(FIL_PAGE_LSN + page, end_lsn); @@ -2067,7 +2074,7 @@ recv_parse_log_rec( #endif /* UNIV_LOG_LSN_DEBUG */ new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr, - NULL, NULL); + NULL, NULL, *space); if (UNIV_UNLIKELY(new_ptr == NULL)) { return(0); diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 5da2a4b8534..342d81256f2 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -2418,6 +2418,28 @@ row_merge_rename_tables( goto err_exit; } + /* Generate the redo logs for file operations */ + fil_mtr_rename_log(old_table->space, old_name, + new_table->space, new_table->name, tmp_name); + + /* What if the redo logs are flushed to disk here? This is + tested with following crash point */ + DBUG_EXECUTE_IF("bug14669848_precommit", log_buffer_flush_to_disk(); + DBUG_SUICIDE();); + + /* File operations cannot be rolled back. So, before proceeding + with file operations, commit the dictionary changes.*/ + trx_commit_for_mysql(trx); + + /* If server crashes here, the dictionary in InnoDB and MySQL + will differ. The .ibd files and the .frm files must be swapped + manually by the administrator. No loss of data. */ + DBUG_EXECUTE_IF("bug14669848", DBUG_SUICIDE();); + + /* Ensure that the redo logs are flushed to disk. The config + innodb_flush_log_at_trx_commit must not affect this. */ + log_buffer_flush_to_disk(); + /* The following calls will also rename the .ibd data files if the tables are stored in a single-table tablespace */ From 0f344086c79c731acb2336d9b55006160accc2ad Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Thu, 8 Nov 2012 15:49:28 +0100 Subject: [PATCH 016/324] Building RPMs for ULN: The patch "mysql-chain-certs.patch" needs to be adapted to code changes in "vio/viosslfactories.c" which were done in MySQL 5.5. Then, the patch can be re-enabled in the spec file. --- packaging/rpm-uln/mysql-chain-certs.patch | 26 +++++++++++++---------- packaging/rpm-uln/mysql.spec.sh | 6 ++---- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/packaging/rpm-uln/mysql-chain-certs.patch b/packaging/rpm-uln/mysql-chain-certs.patch index 3b20a28031d..4e26af16cb0 100644 --- a/packaging/rpm-uln/mysql-chain-certs.patch +++ b/packaging/rpm-uln/mysql-chain-certs.patch @@ -9,19 +9,23 @@ Fedora builds, I'm not feeling motivated to try to fix yassl for this. See RH bug #598656. Filed upstream at http://bugs.mysql.com/bug.php?id=54158 + === -diff -Naur mysql-5.1.47.orig/vio/viosslfactories.c mysql-5.1.47/vio/viosslfactories.c ---- mysql-5.1.47.orig/vio/viosslfactories.c 2010-05-06 11:28:07.000000000 -0400 -+++ mysql-5.1.47/vio/viosslfactories.c 2010-05-26 23:23:46.000000000 -0400 -@@ -100,7 +100,7 @@ - (long) ctx, cert_file, key_file)); - if (cert_file) +Joerg Bruehe, MySQL Build Team at Oracle: First patch adapted to code changes in MySQL 5.5 + + +diff -Naur mysql-5.5.29.orig/vio/viosslfactories.c mysql-5.5.29/vio/viosslfactories.c +--- mysql-5.5.29.orig/vio/viosslfactories.c 2010-05-06 11:28:07.000000000 -0400 ++++ mysql-5.5.29/vio/viosslfactories.c 2010-05-26 23:23:46.000000000 -0400 +@@ -106,7 +106,7 @@ + key_file= cert_file; + + if (cert_file && +- SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) ++ SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) { -- if (SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) -+ if (SSL_CTX_use_certificate_chain_file(ctx, cert_file) <= 0) - { - *error= SSL_INITERR_CERT; - DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file)); + *error= SSL_INITERR_CERT; + DBUG_PRINT("error",("%s from file '%s'", sslGetErrString(*error), cert_file)); diff -Naur mysql-5.1.47.orig/extra/yassl/src/ssl.cpp mysql-5.1.47/extra/yassl/src/ssl.cpp --- mysql-5.1.47.orig/extra/yassl/src/ssl.cpp 2010-05-06 11:24:26.000000000 -0400 +++ mysql-5.1.47/extra/yassl/src/ssl.cpp 2010-05-26 23:29:13.000000000 -0400 diff --git a/packaging/rpm-uln/mysql.spec.sh b/packaging/rpm-uln/mysql.spec.sh index 93ba78eb56a..8b25b160be1 100644 --- a/packaging/rpm-uln/mysql.spec.sh +++ b/packaging/rpm-uln/mysql.spec.sh @@ -244,8 +244,7 @@ Patch13: mysql-expired-certs.patch # Will not be used by MySQL # Patch14: mysql-missing-string-code.patch Undecided, will not work in 5.5 (cmake) # Patch15: mysql-lowercase-bug.patch Fixed in MySQL 5.1.54 and 5.5.9 -# Patch16: mysql-chain-certs.patch Currently, this patch is broken -# by server code changes to "vio/viosslfactories.c" +Patch16: mysql-chain-certs.patch Patch17: mysql-5.5-libdir.patch Patch18: mysql-5.5-fix-tests.patch Patch19: mysql-5.5-mtr1.patch @@ -400,8 +399,7 @@ cd %{src_dir} # read about "%setup -n" # %patch10 -p1 # %patch13 -p1 # %patch14 -p1 -# %patch16 -p1 Currently, this patch is broken -# by server code changes to "vio/viosslfactories.c" +%patch16 -p1 %patch17 -p1 %patch18 -p1 %patch19 -p1 From 53455866809feadc88b81f547b96376d15f7a038 Mon Sep 17 00:00:00 2001 From: Thayumanavar Date: Fri, 9 Nov 2012 14:54:35 +0530 Subject: [PATCH 017/324] BUG#14458232 - CRASH IN THD_IS_TRANSACTION_ACTIVE DURING THREAD POOLING STRESS TEST PROBLEM: Connection stress tests which consists of concurrent kill connections interleaved with mysql ping queries cause the mysqld server which uses thread pool scheduler to crash. FIX: Killing a connection involves shutdown and close of client socket and this can cause EPOLLHUP(or EPOLLERR) events to be to be queued and handled after disarming and cleanup of of the connection object (THD) is being done.We disarm the the connection by modifying the epoll mask to zero which ensure no events come and release the ownership of waiting thread that collect events and then do the cleanup of THD. object.As per the linux kernel epoll source code ( http://lxr.linux.no/linux+*/fs/eventpoll.c#L1771), EPOLLHUP (or EPOLLERR) can't be masked even if we set EPOLL mask to zero. So we disarm the connection and thus prevent execution of any query processing handler/queueing to client ctx. queue by removing the client fd from the epoll set via EPOLL_CTL_DEL. Also there is a race condition which involve the following threads: 1) Thread X executing KILL CONNECTION Y and is in THD::awake and using mysys_var (holding LOCK_thd_data). 2) Thread Y in tp_process_event executing and is being killed. 3) Thread Z receives KILL flag internally and possible call the tp_thd_cleanup function which set thread session variable and changing mysys_var. The fix for the above race is to set thread session variable under LOCK_thd_data. We also do not call THD::awake if we found the thread in the thread list that is to be killed but it's KILL_CONNECTION flag set thus avoiding any possible concurrent cleanup. This patch is approved by Mikael Ronstrom via email review. --- include/mysql/thread_pool_priv.h | 1 + sql/sql_class.cc | 12 ++++++++++++ sql/sql_parse.cc | 10 ++++++++-- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/mysql/thread_pool_priv.h b/include/mysql/thread_pool_priv.h index babe0ab6c08..1368c8c52be 100644 --- a/include/mysql/thread_pool_priv.h +++ b/include/mysql/thread_pool_priv.h @@ -61,6 +61,7 @@ uint thd_get_net_read_write(THD *thd); void thd_set_mysys_var(THD *thd, st_my_thread_var *mysys_var); ulong thd_get_net_wait_timeout(THD *thd); my_socket thd_get_fd(THD *thd); +int thd_store_globals(THD* thd); THD *first_global_thread(); THD *next_global_thread(THD *thd); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e32844d06ea..9b0a76bf749 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -468,6 +468,18 @@ my_socket thd_get_fd(THD *thd) return thd->net.vio->sd; } +/** + Set thread specific environment required for thd cleanup in thread pool. + + @param thd THD object + + @retval 1 if thread-specific enviroment could be set else 0 +*/ +int thd_store_globals(THD* thd) +{ + return thd->store_globals(); +} + /** Get thread attributes for connection threads diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ea07bfce0cb..7bbcff4bc2b 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6471,8 +6471,14 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query) if ((thd->security_ctx->master_access & SUPER_ACL) || thd->security_ctx->user_matches(tmp->security_ctx)) { - tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION); - error=0; + /* process the kill only if thread is not already undergoing any kill + connection. + */ + if (tmp->killed != THD::KILL_CONNECTION) + { + tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION); + } + error= 0; } else error=ER_KILL_DENIED_ERROR; From 14dfe6fcc8d4e862484eb5c6e9561c28fbe421df Mon Sep 17 00:00:00 2001 From: Anirudh Mangipudi Date: Fri, 9 Nov 2012 15:15:16 +0530 Subject: [PATCH 018/324] BUG#11762933: MYSQLDUMP WILL SILENTLY SKIP THE `EVENT` TABLE DATA IF DUMPS MYSQL DATABA Problem: If mysqldump is run without --events (or with --skip-events) it will not dump the mysql.event table's data. This behaviour is inconsistent with that of --routines option, which does not affect the dumping of mysql.proc table. According to the Manual, --events (--skip-events) defines, if the Event Scheduler events for the dumped databases should be included in the mysqldump output and this has nothing to do with the mysql.event table itself. Solution: A warning has been added when mysqldump is used without --events (or with --skip-events) and a separate patch with the behavioral change will be prepared for 5.6/trunk. --- client/mysqldump.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 3fda1fafc24..316c0fd174c 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3393,7 +3393,8 @@ static void dump_table(char *table, char *db) if (!opt_events && !my_strcasecmp(&my_charset_latin1, db, "mysql") && !my_strcasecmp(&my_charset_latin1, table, "event")) { - verbose_msg("-- Skipping data table mysql.event, --skip-events was used\n"); + fprintf(stderr, "-- Warning: Skipping the data of table mysql.event." + " Specify the --events option explicitly.\n"); DBUG_VOID_RETURN; } From 2ad007dfd658e250c176e19ae5deabc845bf7ae3 Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Fri, 9 Nov 2012 19:04:01 +0530 Subject: [PATCH 019/324] Bug #14669848 CRASH DURING ALTER MAKES ORIGINAL TABLE INACCESSIBLE When a new primary key is added to an InnoDB table, then the following steps are taken by InnoDB plugin: . let t1 be the original table. . a temporary table t1@00231 will be created by cloning t1. . all data will be copied from t1 to t1@00231. . rename t1 to t1@00232. . rename t1@00231 to t1. . drop t1@00232. The rename and drop operations involve file operations. But file operations cannot be rolled back. So in row_merge_rename_tables(), just after doing data dictionary update and before doing any file operations, generate redo logs for file operations and commit the transaction. This will ensure that any crash after this commit, the table is still recoverable by moving .ibd and .frm files. Manual recovery is required. During recovery, the rename file operation redo logs are processed. Previously this was being ignored. rb://1460 approved by Marko Makela. --- storage/innodb_plugin/fil/fil0fil.c | 27 ++++++++++++++++++++++++- storage/innodb_plugin/include/fil0fil.h | 15 ++++++++++++++ storage/innodb_plugin/log/log0recv.c | 15 ++++++++++---- storage/innodb_plugin/row/row0merge.c | 22 ++++++++++++++++++++ 4 files changed, 74 insertions(+), 5 deletions(-) diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c index 6f2ab938042..d5770baafea 100644 --- a/storage/innodb_plugin/fil/fil0fil.c +++ b/storage/innodb_plugin/fil/fil0fil.c @@ -2619,7 +2619,7 @@ retry: mutex_exit(&fil_system->mutex); #ifndef UNIV_HOTBACKUP - if (success) { + if (success && !recv_recovery_on) { mtr_t mtr; mtr_start(&mtr); @@ -4853,3 +4853,28 @@ fil_close(void) fil_system = NULL; } + +/****************************************************************//** +Generate redo logs for swapping two .ibd files */ +UNIV_INTERN +void +fil_mtr_rename_log( +/*===============*/ + ulint old_space_id, /*!< in: tablespace id of the old + table. */ + const char* old_name, /*!< in: old table name */ + ulint new_space_id, /*!< in: tablespace id of the new + table */ + const char* new_name, /*!< in: new table name */ + const char* tmp_name) /*!< in: temp table name used while + swapping */ +{ + mtr_t mtr; + mtr_start(&mtr); + fil_op_write_log(MLOG_FILE_RENAME, old_space_id, + 0, 0, old_name, tmp_name, &mtr); + fil_op_write_log(MLOG_FILE_RENAME, new_space_id, + 0, 0, new_name, old_name, &mtr); + mtr_commit(&mtr); +} + diff --git a/storage/innodb_plugin/include/fil0fil.h b/storage/innodb_plugin/include/fil0fil.h index 05217168764..09e6e37b223 100644 --- a/storage/innodb_plugin/include/fil0fil.h +++ b/storage/innodb_plugin/include/fil0fil.h @@ -726,6 +726,21 @@ fil_tablespace_is_being_deleted( /*============================*/ ulint id); /*!< in: space id */ +/****************************************************************//** +Generate redo logs for swapping two .ibd files */ +UNIV_INTERN +void +fil_mtr_rename_log( +/*===============*/ + ulint old_space_id, /*!< in: tablespace id of the old + table. */ + const char* old_name, /*!< in: old table name */ + ulint new_space_id, /*!< in: tablespace id of the new + table */ + const char* new_name, /*!< in: new table name */ + const char* tmp_name); /*!< in: temp table name used while + swapping */ + typedef struct fil_space_struct fil_space_t; #endif diff --git a/storage/innodb_plugin/log/log0recv.c b/storage/innodb_plugin/log/log0recv.c index 677ada9fbde..96d63144366 100644 --- a/storage/innodb_plugin/log/log0recv.c +++ b/storage/innodb_plugin/log/log0recv.c @@ -955,8 +955,11 @@ recv_parse_or_apply_log_rec_body( not NULL, then the log record is applied to the page, and the log record should be complete then */ - mtr_t* mtr) /*!< in: mtr or NULL; should be non-NULL + mtr_t* mtr, /*!< in: mtr or NULL; should be non-NULL if and only if block is non-NULL */ + ulint space_id) + /*!< in: tablespace id obtained by + parsing initial log record */ { dict_index_t* index = NULL; page_t* page; @@ -1228,8 +1231,11 @@ recv_parse_or_apply_log_rec_body( ut_ad(!page || page_type != FIL_PAGE_TYPE_ALLOCATED); ptr = mlog_parse_string(ptr, end_ptr, page, page_zip); break; - case MLOG_FILE_CREATE: case MLOG_FILE_RENAME: + ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, + space_id, 0); + break; + case MLOG_FILE_CREATE: case MLOG_FILE_DELETE: case MLOG_FILE_CREATE2: ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0); @@ -1601,7 +1607,8 @@ recv_recover_page_func( recv_parse_or_apply_log_rec_body(recv->type, buf, buf + recv->len, - block, &mtr); + block, &mtr, + recv_addr->space); end_lsn = recv->start_lsn + recv->len; mach_write_ull(FIL_PAGE_LSN + page, end_lsn); @@ -2067,7 +2074,7 @@ recv_parse_log_rec( #endif /* UNIV_LOG_LSN_DEBUG */ new_ptr = recv_parse_or_apply_log_rec_body(*type, new_ptr, end_ptr, - NULL, NULL); + NULL, NULL, *space); if (UNIV_UNLIKELY(new_ptr == NULL)) { return(0); diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 5da2a4b8534..342d81256f2 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -2418,6 +2418,28 @@ row_merge_rename_tables( goto err_exit; } + /* Generate the redo logs for file operations */ + fil_mtr_rename_log(old_table->space, old_name, + new_table->space, new_table->name, tmp_name); + + /* What if the redo logs are flushed to disk here? This is + tested with following crash point */ + DBUG_EXECUTE_IF("bug14669848_precommit", log_buffer_flush_to_disk(); + DBUG_SUICIDE();); + + /* File operations cannot be rolled back. So, before proceeding + with file operations, commit the dictionary changes.*/ + trx_commit_for_mysql(trx); + + /* If server crashes here, the dictionary in InnoDB and MySQL + will differ. The .ibd files and the .frm files must be swapped + manually by the administrator. No loss of data. */ + DBUG_EXECUTE_IF("bug14669848", DBUG_SUICIDE();); + + /* Ensure that the redo logs are flushed to disk. The config + innodb_flush_log_at_trx_commit must not affect this. */ + log_buffer_flush_to_disk(); + /* The following calls will also rename the .ibd data files if the tables are stored in a single-table tablespace */ From 9749b60ee83da745f38f61e479476bd818dce850 Mon Sep 17 00:00:00 2001 From: Venkata Sidagam Date: Fri, 9 Nov 2012 19:19:11 +0530 Subject: [PATCH 020/324] Bug#13556000: CHECK AND REPAIR TABLE SHOULD BE MORE ROBUST[2] Problem description: Corrupt key file for the table. Size of the key is greater than the maximum specified size. This results in the overflow of the key buffer while reading the key from key file. Fix: If size of key is greater than the maximum size it returns an error before writing it into the key buffer. Gives error as corrupt file but no stack overflow. --- storage/myisam/mi_search.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/storage/myisam/mi_search.c b/storage/myisam/mi_search.c index 7526b7c5518..8c656263651 100644 --- a/storage/myisam/mi_search.c +++ b/storage/myisam/mi_search.c @@ -945,9 +945,7 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, ("Found too long binary packed key: %u of %u at 0x%lx", length, keyinfo->maxlength, (long) *page_pos)); DBUG_DUMP("key", *page_pos, 16); - mi_print_error(keyinfo->share, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(0); /* Wrong key */ + goto crashed; /* Wrong key */ } /* Key is packed against prev key, take prefix from prev key. */ from= key; @@ -990,6 +988,8 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, if (from == from_end) { from=page; from_end=page_end; } length+= (uint) ((*key++ = *from++)); } + if (length > keyseg->length) + goto crashed; } else length=keyseg->length; @@ -1029,15 +1029,18 @@ uint _mi_get_binary_pack_key(register MI_KEYDEF *keyinfo, uint nod_flag, if (from_end != page_end) { DBUG_PRINT("error",("Error when unpacking key")); - mi_print_error(keyinfo->share, HA_ERR_CRASHED); - my_errno=HA_ERR_CRASHED; - DBUG_RETURN(0); /* Error */ + goto crashed; /* Error */ } /* Copy data pointer and, if appropriate, key block pointer. */ memcpy((uchar*) key,(uchar*) from,(size_t) length); *page_pos= from+length; } DBUG_RETURN((uint) (key-start_key)+keyseg->length); + + crashed: + mi_print_error(keyinfo->share, HA_ERR_CRASHED); + my_errno= HA_ERR_CRASHED; + DBUG_RETURN(0); } From 858e9ecc877aebdc412b227e41d0cf8e83387dc3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Nov 2012 15:51:28 +0100 Subject: [PATCH 021/324] From 04195c30c1ec09337930e1a7e16e5c9a8333b084 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Mon, 12 Nov 2012 14:24:43 +0200 Subject: [PATCH 022/324] This is a backport of "WL#5674 InnoDB: report all deadlocks (Bug#1784)" from MySQL 5.6 into MySQL 5.5 Will close Bug#14515889 BACKPORT OF INNODB DEADLOCK LOGGING TO 5.5 The original implementation is in vasil.dimov@oracle.com-20101213120811-k2ldtnao2t6zrxfn Approved by: Jimmy (rb:1535) --- .../r/innodb_print_all_deadlocks_basic.result | 22 +++ .../t/innodb_print_all_deadlocks_basic.test | 48 ++++++ storage/innobase/handler/ha_innodb.cc | 6 + storage/innobase/include/srv0srv.h | 3 + storage/innobase/lock/lock0lock.c | 151 ++++++++++++------ storage/innobase/srv/srv0srv.c | 3 + 6 files changed, 186 insertions(+), 47 deletions(-) create mode 100644 mysql-test/suite/sys_vars/r/innodb_print_all_deadlocks_basic.result create mode 100644 mysql-test/suite/sys_vars/t/innodb_print_all_deadlocks_basic.test diff --git a/mysql-test/suite/sys_vars/r/innodb_print_all_deadlocks_basic.result b/mysql-test/suite/sys_vars/r/innodb_print_all_deadlocks_basic.result new file mode 100644 index 00000000000..1bd078dfd7e --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_print_all_deadlocks_basic.result @@ -0,0 +1,22 @@ +SELECT @@innodb_print_all_deadlocks; +@@innodb_print_all_deadlocks +0 +SET GLOBAL innodb_print_all_deadlocks=1; +CREATE TABLE t1 (c1 INT, PRIMARY KEY (c1)) ENGINE=INNODB; +INSERT INTO t1 VALUES (123); +CREATE TABLE t2 (c2 INT, PRIMARY KEY (c2)) ENGINE=INNODB; +INSERT INTO t2 VALUES (456); +BEGIN; +SELECT * FROM t1 FOR UPDATE; +c1 +123 +BEGIN; +SELECT * FROM t2 FOR UPDATE; +c2 +456 +SELECT * FROM t2 FOR UPDATE; +SELECT * FROM t1 FOR UPDATE; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +DROP TABLE t2; +DROP TABLE t1; +SET GLOBAL innodb_print_all_deadlocks=default; diff --git a/mysql-test/suite/sys_vars/t/innodb_print_all_deadlocks_basic.test b/mysql-test/suite/sys_vars/t/innodb_print_all_deadlocks_basic.test new file mode 100644 index 00000000000..5ad0ae485e0 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_print_all_deadlocks_basic.test @@ -0,0 +1,48 @@ +# +# innodb_print_all_deadlocks +# + +-- source include/have_innodb.inc + +SELECT @@innodb_print_all_deadlocks; + +SET GLOBAL innodb_print_all_deadlocks=1; + +CREATE TABLE t1 (c1 INT, PRIMARY KEY (c1)) ENGINE=INNODB; +INSERT INTO t1 VALUES (123); + +CREATE TABLE t2 (c2 INT, PRIMARY KEY (c2)) ENGINE=INNODB; +INSERT INTO t2 VALUES (456); + +-- connect (con1,localhost,root,,) +-- connect (con2,localhost,root,,) + +-- connection con1 +BEGIN; +SELECT * FROM t1 FOR UPDATE; + +-- connection con2 +BEGIN; +SELECT * FROM t2 FOR UPDATE; + +-- connection con1 +-- send +SELECT * FROM t2 FOR UPDATE; + +-- connection con2 +let $wait_condition= +SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.PROCESSLIST +WHERE state = 'Sending data' AND info = 'SELECT * FROM t2 FOR UPDATE'; +-- source include/wait_condition.inc +-- error ER_LOCK_DEADLOCK +SELECT * FROM t1 FOR UPDATE; + +-- connection default + +-- disconnect con1 +-- disconnect con2 + +DROP TABLE t2; +DROP TABLE t1; + +SET GLOBAL innodb_print_all_deadlocks=default; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 2a14fd5c2cc..2de6a30d78d 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11691,6 +11691,11 @@ static MYSQL_SYSVAR_UINT(limit_optimistic_insert_debug, NULL, NULL, 0, 0, UINT_MAX32, 0); #endif /* UNIV_DEBUG */ +static MYSQL_SYSVAR_BOOL(print_all_deadlocks, srv_print_all_deadlocks, + PLUGIN_VAR_OPCMDARG, + "Print all deadlocks to MySQL error log (off by default)", + NULL, NULL, FALSE); + static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(additional_mem_pool_size), MYSQL_SYSVAR(autoextend_increment), @@ -11764,6 +11769,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(trx_rseg_n_slots_debug), MYSQL_SYSVAR(limit_optimistic_insert_debug), #endif /* UNIV_DEBUG */ + MYSQL_SYSVAR(print_all_deadlocks), NULL }; diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 6cbf3e795e6..13510f1ed62 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -333,6 +333,9 @@ extern ulint srv_buf_pool_flushed; reading of a disk page */ extern ulint srv_buf_pool_reads; +/** print all user-level transactions deadlocks to mysqld stderr */ +extern my_bool srv_print_all_deadlocks; + /** Status variables to be passed to MySQL */ typedef struct export_var_struct export_struc; diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 66ec18aeee7..e0c6d698406 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -3261,6 +3261,80 @@ lock_rec_restore_from_page_infimum( /*=========== DEADLOCK CHECKING ======================================*/ +/*********************************************************************//** +rewind(3) the file used for storing the latest detected deadlock and +print a heading message to stderr if printing of all deadlocks to stderr +is enabled. */ +UNIV_INLINE +void +lock_deadlock_start_print() +/*=======================*/ +{ + rewind(lock_latest_err_file); + ut_print_timestamp(lock_latest_err_file); + + if (srv_print_all_deadlocks) { + fprintf(stderr, "InnoDB: transactions deadlock detected, " + "dumping detailed information.\n"); + ut_print_timestamp(stderr); + } +} + +/*********************************************************************//** +Print a message to the deadlock file and possibly to stderr. */ +UNIV_INLINE +void +lock_deadlock_fputs( +/*================*/ + const char* msg) /*!< in: message to print */ +{ + fputs(msg, lock_latest_err_file); + + if (srv_print_all_deadlocks) { + fputs(msg, stderr); + } +} + +/*********************************************************************//** +Print transaction data to the deadlock file and possibly to stderr. */ +UNIV_INLINE +void +lock_deadlock_trx_print( +/*====================*/ + trx_t* trx, /*!< in: transaction */ + ulint max_query_len) /*!< in: max query length to print, or 0 to + use the default max length */ +{ + trx_print(lock_latest_err_file, trx, max_query_len); + + if (srv_print_all_deadlocks) { + trx_print(stderr, trx, max_query_len); + } +} + +/*********************************************************************//** +Print lock data to the deadlock file and possibly to stderr. */ +UNIV_INLINE +void +lock_deadlock_lock_print( +/*=====================*/ + const lock_t* lock) /*!< in: record or table type lock */ +{ + if (lock_get_type_low(lock) == LOCK_REC) { + lock_rec_print(lock_latest_err_file, lock); + + if (srv_print_all_deadlocks) { + lock_rec_print(stderr, lock); + } + } else { + lock_table_print(lock_latest_err_file, lock); + + if (srv_print_all_deadlocks) { + lock_table_print(stderr, lock); + } + } +} + /********************************************************************//** Checks if a lock request results in a deadlock. @return TRUE if a deadlock was detected and we chose trx as a victim; @@ -3304,30 +3378,25 @@ retry: /* If the lock search exceeds the max step or the max depth, the current trx will be the victim. Print its information. */ - rewind(lock_latest_err_file); - ut_print_timestamp(lock_latest_err_file); + lock_deadlock_start_print(); - fputs("TOO DEEP OR LONG SEARCH IN THE LOCK TABLE" - " WAITS-FOR GRAPH, WE WILL ROLL BACK" - " FOLLOWING TRANSACTION \n", - lock_latest_err_file); + lock_deadlock_fputs( + "TOO DEEP OR LONG SEARCH IN THE LOCK TABLE" + " WAITS-FOR GRAPH, WE WILL ROLL BACK" + " FOLLOWING TRANSACTION \n\n" + "*** TRANSACTION:\n"); - fputs("\n*** TRANSACTION:\n", lock_latest_err_file); - trx_print(lock_latest_err_file, trx, 3000); + lock_deadlock_trx_print(trx, 3000); - fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n", - lock_latest_err_file); + lock_deadlock_fputs( + "*** WAITING FOR THIS LOCK TO BE GRANTED:\n"); + + lock_deadlock_lock_print(lock); - if (lock_get_type(lock) == LOCK_REC) { - lock_rec_print(lock_latest_err_file, lock); - } else { - lock_table_print(lock_latest_err_file, lock); - } break; case LOCK_VICTIM_IS_START: - fputs("*** WE ROLL BACK TRANSACTION (2)\n", - lock_latest_err_file); + lock_deadlock_fputs("*** WE ROLL BACK TRANSACTION (2)\n"); break; default: @@ -3442,45 +3511,33 @@ lock_deadlock_recursive( point: a deadlock detected; or we have searched the waits-for graph too long */ - FILE* ef = lock_latest_err_file; + lock_deadlock_start_print(); - rewind(ef); - ut_print_timestamp(ef); + lock_deadlock_fputs("\n*** (1) TRANSACTION:\n"); - fputs("\n*** (1) TRANSACTION:\n", ef); + lock_deadlock_trx_print(wait_lock->trx, 3000); - trx_print(ef, wait_lock->trx, 3000); + lock_deadlock_fputs( + "*** (1) WAITING FOR THIS LOCK" + " TO BE GRANTED:\n"); - fputs("*** (1) WAITING FOR THIS LOCK" - " TO BE GRANTED:\n", ef); + lock_deadlock_lock_print(wait_lock); - if (lock_get_type_low(wait_lock) == LOCK_REC) { - lock_rec_print(ef, wait_lock); - } else { - lock_table_print(ef, wait_lock); - } + lock_deadlock_fputs("*** (2) TRANSACTION:\n"); - fputs("*** (2) TRANSACTION:\n", ef); + lock_deadlock_trx_print(lock->trx, 3000); - trx_print(ef, lock->trx, 3000); + lock_deadlock_fputs( + "*** (2) HOLDS THE LOCK(S):\n"); - fputs("*** (2) HOLDS THE LOCK(S):\n", ef); + lock_deadlock_lock_print(lock); - if (lock_get_type_low(lock) == LOCK_REC) { - lock_rec_print(ef, lock); - } else { - lock_table_print(ef, lock); - } + lock_deadlock_fputs( + "*** (2) WAITING FOR THIS LOCK" + " TO BE GRANTED:\n"); - fputs("*** (2) WAITING FOR THIS LOCK" - " TO BE GRANTED:\n", ef); + lock_deadlock_lock_print(start->wait_lock); - if (lock_get_type_low(start->wait_lock) - == LOCK_REC) { - lock_rec_print(ef, start->wait_lock); - } else { - lock_table_print(ef, start->wait_lock); - } #ifdef UNIV_DEBUG if (lock_print_waits) { fputs("Deadlock detected\n", @@ -3503,8 +3560,8 @@ lock_deadlock_recursive( as a victim to try to avoid deadlocking our recursion starting point transaction */ - fputs("*** WE ROLL BACK TRANSACTION (1)\n", - ef); + lock_deadlock_fputs( + "*** WE ROLL BACK TRANSACTION (1)\n"); wait_lock->trx->was_chosen_as_deadlock_victim = TRUE; diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index a4e51539d81..65d78e28132 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -356,6 +356,9 @@ UNIV_INTERN lint srv_conc_n_threads = 0; InnoDB */ UNIV_INTERN ulint srv_conc_n_waiting_threads = 0; +/* print all user-level transactions deadlocks to mysqld stderr */ +UNIV_INTERN my_bool srv_print_all_deadlocks = FALSE; + typedef struct srv_conc_slot_struct srv_conc_slot_t; struct srv_conc_slot_struct{ os_event_t event; /*!< event to wait */ From 5a7553f36a3eb18ca191607937ce1c67cbfc772d Mon Sep 17 00:00:00 2001 From: Yasufumi Kinoshita Date: Mon, 12 Nov 2012 22:31:30 +0900 Subject: [PATCH 023/324] Bug #14676111 WRONG PAGE_LEVEL WRITTEN FOR UPPER THAN FATHER PAGE AT BTR_LIFT_PAGE_UP() btr_lift_page_up() writes wrong page number (different by -1) for upper than father page. But in almost all of the cases, the father page should be root page, no upper pages. It is very rare path. In addition the leaf page should not be lifted unless the father page is root. Because the branch pages should not become the leaf pages. rb://1336 approved by Marko Makela. --- .../suite/innodb/r/innodb_bug14676111.result | 53 ++++++++ .../suite/innodb/t/innodb_bug14676111.test | 128 ++++++++++++++++++ .../innodb_plugin/r/innodb_bug14676111.result | 53 ++++++++ .../innodb_plugin/t/innodb_bug14676111.test | 128 ++++++++++++++++++ storage/innobase/btr/btr0btr.c | 24 +++- storage/innobase/btr/btr0cur.c | 11 +- storage/innobase/handler/ha_innodb.cc | 10 ++ storage/innobase/include/btr0cur.h | 5 + storage/innobase/include/btr0cur.ic | 13 ++ storage/innobase/include/srv0srv.h | 3 + storage/innobase/include/trx0purge.h | 4 + storage/innobase/srv/srv0srv.c | 32 +++++ storage/innobase/trx/trx0purge.c | 2 + storage/innodb_plugin/btr/btr0btr.c | 38 +++++- storage/innodb_plugin/btr/btr0cur.c | 8 ++ storage/innodb_plugin/handler/ha_innodb.cc | 10 ++ storage/innodb_plugin/include/btr0cur.h | 5 + storage/innodb_plugin/include/btr0cur.ic | 13 ++ storage/innodb_plugin/include/srv0srv.h | 3 + storage/innodb_plugin/include/trx0purge.h | 4 + storage/innodb_plugin/srv/srv0srv.c | 33 +++++ storage/innodb_plugin/trx/trx0purge.c | 2 + 22 files changed, 575 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug14676111.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug14676111.test create mode 100644 mysql-test/suite/innodb_plugin/r/innodb_bug14676111.result create mode 100644 mysql-test/suite/innodb_plugin/t/innodb_bug14676111.test diff --git a/mysql-test/suite/innodb/r/innodb_bug14676111.result b/mysql-test/suite/innodb/r/innodb_bug14676111.result new file mode 100644 index 00000000000..ebecd1d00cb --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug14676111.result @@ -0,0 +1,53 @@ +drop table if exists t1; +CREATE TABLE t1 (a int not null primary key) engine=InnoDB; +set global innodb_limit_optimistic_insert_debug = 2; +insert into t1 values (1); +insert into t1 values (5); +insert into t1 values (4); +insert into t1 values (3); +insert into t1 values (2); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +10.0000 +delete from t1 where a=4; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +8.0000 +delete from t1 where a=5; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +5.0000 +set global innodb_limit_optimistic_insert_debug = 10000; +delete from t1 where a=2; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +3.0000 +insert into t1 values (2); +delete from t1 where a=2; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +2.0000 +insert into t1 values (2); +delete from t1 where a=2; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +1.0000 +drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb_bug14676111.test b/mysql-test/suite/innodb/t/innodb_bug14676111.test new file mode 100644 index 00000000000..fadd111fdc9 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug14676111.test @@ -0,0 +1,128 @@ +# Test for bug #14676111: WRONG PAGE_LEVEL WRITTEN FOR UPPER THAN FATHER PAGE AT BTR_LIFT_PAGE_UP() + +-- source include/have_innodb.inc +-- source include/have_debug.inc + +if (`select count(*)=0 from information_schema.global_variables where variable_name = 'INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG'`) +{ + --skip Test requires InnoDB built with UNIV_DEBUG definition. +} + +--disable_query_log +set @old_innodb_limit_optimistic_insert_debug = @@innodb_limit_optimistic_insert_debug; +--enable_query_log +--disable_warnings +drop table if exists t1; +--enable_warnings + +CREATE TABLE t1 (a int not null primary key) engine=InnoDB; + +let $wait_condition= + SELECT VARIABLE_VALUE < 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS + WHERE VARIABLE_NAME = 'INNODB_PURGE_TRX_ID_AGE'; + +# +# make 4 leveled straight tree +# +set global innodb_limit_optimistic_insert_debug = 2; +insert into t1 values (1); +insert into t1 values (5); +#current tree form +# (1, 5) + +insert into t1 values (4); +#records in a page is limited to 2 artificially. root rise occurs +#current tree form +# (1, 5) +#(1, 4) (5) + +insert into t1 values (3); +#current tree form +# (1, 5) +# (1, 4) (5) +#(1, 3) (4) (5) + +insert into t1 values (2); +#current tree form +# (1, 5) +# (1, 4) (5) +# (1, 3) (4) (5) +#(1, 2) (3) (4) (5) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +delete from t1 where a=4; +--source include/wait_condition.inc +#deleting 1 record of 2 records don't cause merge artificially. +#current tree form +# (1, 5) +# (1) (5) +# (1, 3) (5) +#(1, 2) (3) (5) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +delete from t1 where a=5; +--source include/wait_condition.inc +#deleting 1 record of 2 records don't cause merge artificially. +#current tree form +# (1) +# (1) +# (1, 3) <- lift up this level next, when deleting node ptr +#(1, 2) (3) <- merged next + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +# +# cause merge at level 0 +# + +#disable the artificial limitation of records in a page +set global innodb_limit_optimistic_insert_debug = 10000; +delete from t1 where a=2; +--source include/wait_condition.inc +#merge page occurs. and lift up occurs. +#current tree form +# (1) +# (1) +# (1, 3) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +insert into t1 values (2); +#current tree form +# (1) +# (1) <- lift up this level next, because it is not root +# (1, 2, 3) + +delete from t1 where a=2; +--source include/wait_condition.inc +#current tree form +# (1) +# (1, 3) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +insert into t1 values (2); +#current tree form +# (1) +# (1, 2, 3) <- lift up this level next, because the father is root + +delete from t1 where a=2; +--source include/wait_condition.inc +#current tree form +# (1, 3) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +drop table t1; + +--disable_query_log +set global innodb_limit_optimistic_insert_debug = @old_innodb_limit_optimistic_insert_debug; +--enable_query_log diff --git a/mysql-test/suite/innodb_plugin/r/innodb_bug14676111.result b/mysql-test/suite/innodb_plugin/r/innodb_bug14676111.result new file mode 100644 index 00000000000..ebecd1d00cb --- /dev/null +++ b/mysql-test/suite/innodb_plugin/r/innodb_bug14676111.result @@ -0,0 +1,53 @@ +drop table if exists t1; +CREATE TABLE t1 (a int not null primary key) engine=InnoDB; +set global innodb_limit_optimistic_insert_debug = 2; +insert into t1 values (1); +insert into t1 values (5); +insert into t1 values (4); +insert into t1 values (3); +insert into t1 values (2); +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +10.0000 +delete from t1 where a=4; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +8.0000 +delete from t1 where a=5; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +5.0000 +set global innodb_limit_optimistic_insert_debug = 10000; +delete from t1 where a=2; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +3.0000 +insert into t1 values (2); +delete from t1 where a=2; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +2.0000 +insert into t1 values (2); +delete from t1 where a=2; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status OK +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; +DATA_LENGTH / 16384 +1.0000 +drop table t1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug14676111.test b/mysql-test/suite/innodb_plugin/t/innodb_bug14676111.test new file mode 100644 index 00000000000..ae871e3b63e --- /dev/null +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug14676111.test @@ -0,0 +1,128 @@ +# Test for bug #14676111: WRONG PAGE_LEVEL WRITTEN FOR UPPER THAN FATHER PAGE AT BTR_LIFT_PAGE_UP() + +-- source include/have_innodb_plugin.inc +-- source include/have_debug.inc + +if (`select count(*)=0 from information_schema.global_variables where variable_name = 'INNODB_LIMIT_OPTIMISTIC_INSERT_DEBUG'`) +{ + --skip Test requires InnoDB built with UNIV_DEBUG definition. +} + +--disable_query_log +set @old_innodb_limit_optimistic_insert_debug = @@innodb_limit_optimistic_insert_debug; +--enable_query_log +--disable_warnings +drop table if exists t1; +--enable_warnings + +CREATE TABLE t1 (a int not null primary key) engine=InnoDB; + +let $wait_condition= + SELECT VARIABLE_VALUE < 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS + WHERE VARIABLE_NAME = 'INNODB_PURGE_TRX_ID_AGE'; + +# +# make 4 leveled straight tree +# +set global innodb_limit_optimistic_insert_debug = 2; +insert into t1 values (1); +insert into t1 values (5); +#current tree form +# (1, 5) + +insert into t1 values (4); +#records in a page is limited to 2 artificially. root rise occurs +#current tree form +# (1, 5) +#(1, 4) (5) + +insert into t1 values (3); +#current tree form +# (1, 5) +# (1, 4) (5) +#(1, 3) (4) (5) + +insert into t1 values (2); +#current tree form +# (1, 5) +# (1, 4) (5) +# (1, 3) (4) (5) +#(1, 2) (3) (4) (5) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +delete from t1 where a=4; +--source include/wait_condition.inc +#deleting 1 record of 2 records don't cause merge artificially. +#current tree form +# (1, 5) +# (1) (5) +# (1, 3) (5) +#(1, 2) (3) (5) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +delete from t1 where a=5; +--source include/wait_condition.inc +#deleting 1 record of 2 records don't cause merge artificially. +#current tree form +# (1) +# (1) +# (1, 3) <- lift up this level next, when deleting node ptr +#(1, 2) (3) <- merged next + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +# +# cause merge at level 0 +# + +#disable the artificial limitation of records in a page +set global innodb_limit_optimistic_insert_debug = 10000; +delete from t1 where a=2; +--source include/wait_condition.inc +#merge page occurs. and lift up occurs. +#current tree form +# (1) +# (1) +# (1, 3) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +insert into t1 values (2); +#current tree form +# (1) +# (1) <- lift up this level next, because it is not root +# (1, 2, 3) + +delete from t1 where a=2; +--source include/wait_condition.inc +#current tree form +# (1) +# (1, 3) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +insert into t1 values (2); +#current tree form +# (1) +# (1, 2, 3) <- lift up this level next, because the father is root + +delete from t1 where a=2; +--source include/wait_condition.inc +#current tree form +# (1, 3) + +analyze table t1; +select DATA_LENGTH / 16384 from information_schema.TABLES where TABLE_SCHEMA = 'test' and TABLE_NAME = 't1'; + +drop table t1; + +--disable_query_log +set global innodb_limit_optimistic_insert_debug = @old_innodb_limit_optimistic_insert_debug; +--enable_query_log diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index 5079757272a..fc4e07d7169 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -1973,6 +1973,7 @@ btr_lift_page_up( ulint root_page_no; ulint ancestors; ulint i; + ibool lift_father_up = FALSE; ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL); ut_ad(btr_page_get_next(page, mtr) == FIL_NULL); @@ -2007,6 +2008,27 @@ btr_lift_page_up( pages[ancestors++] = iter_page; } + if (ancestors > 1 && page_level == 0) { + /* The father page also should be the only on its level (not + root). We should lift up the father page at first. + Because the leaf page should be lifted up only for root page. + The freeing page is based on page_level (==0 or !=0) + to choose segment. If the page_level is changed ==0 from !=0, + later freeing of the page doesn't find the page allocation + to be freed.*/ + + lift_father_up = TRUE; + page = father_page; + page_level = btr_page_get_level(page, mtr); + + ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL); + ut_ad(btr_page_get_next(page, mtr) == FIL_NULL); + ut_ad(mtr_memo_contains(mtr, buf_block_align(page), + MTR_MEMO_PAGE_X_FIX)); + + father_page = pages[1]; + } + btr_search_drop_page_hash_index(page); /* Make the father empty */ @@ -2018,7 +2040,7 @@ btr_lift_page_up( lock_update_copy_and_discard(father_page, page); /* Go upward to root page, decreasing levels by one. */ - for (i = 0; i < ancestors; i++) { + for (i = lift_father_up ? 1 : 0; i < ancestors; i++) { iter_page = pages[i]; ut_ad(btr_page_get_level(iter_page, mtr) == (page_level + 1)); diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c index 389e95bcb0a..8dc0a92408b 100644 --- a/storage/innobase/btr/btr0cur.c +++ b/storage/innobase/btr/btr0cur.c @@ -49,6 +49,10 @@ ulint btr_cur_n_sea = 0; ulint btr_cur_n_non_sea_old = 0; ulint btr_cur_n_sea_old = 0; +#ifdef UNIV_DEBUG +uint btr_cur_limit_optimistic_insert_debug = 0; +#endif /* UNIV_DEBUG */ + /* In the optimistic insert, if the insert does not fit, but this much space can be released by page reorganize, then it is reorganized */ @@ -1022,6 +1026,9 @@ calculate_sizes_again: goto calculate_sizes_again; } + LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page), + goto fail); + /* If there have been many consecutive inserts, and we are on the leaf level, check if we have to split the page to reserve enough free space for future updates of records. */ @@ -1034,7 +1041,9 @@ calculate_sizes_again: && (0 == level) && (btr_page_get_split_rec_to_right(cursor, &dummy_rec) || btr_page_get_split_rec_to_left(cursor, &dummy_rec))) { - +#ifdef UNIV_DEBUG +fail: +#endif /* UNIV_DEBUG */ if (big_rec_vec) { dtuple_convert_back_big_rec(index, entry, big_rec_vec); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index bcb903d22bf..28262f02551 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -495,6 +495,10 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_rows_read, SHOW_LONG}, {"rows_updated", (char*) &export_vars.innodb_rows_updated, SHOW_LONG}, +#ifdef UNIV_DEBUG + {"purge_trx_id_age", + (char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG}, +#endif /* UNIV_DEBUG */ {NullS, NullS, SHOW_LONG} }; @@ -9274,6 +9278,11 @@ static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug, PLUGIN_VAR_RQCMDARG, "Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()", NULL, NULL, 0, 0, 1024, 0); + +static MYSQL_SYSVAR_UINT(limit_optimistic_insert_debug, + btr_cur_limit_optimistic_insert_debug, PLUGIN_VAR_RQCMDARG, + "Artificially limit the number of records per B-tree page (0=unlimited).", + NULL, NULL, 0, 0, UINT_MAX32, 0); #endif /* UNIV_DEBUG */ static struct st_mysql_sys_var* innobase_system_variables[]= { @@ -9323,6 +9332,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ #ifdef UNIV_DEBUG MYSQL_SYSVAR(trx_rseg_n_slots_debug), + MYSQL_SYSVAR(limit_optimistic_insert_debug), #endif /* UNIV_DEBUG */ NULL }; diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h index 341d628c6dc..c2b81d0ae91 100644 --- a/storage/innobase/include/btr0cur.h +++ b/storage/innobase/include/btr0cur.h @@ -703,6 +703,11 @@ extern ulint btr_cur_n_sea; extern ulint btr_cur_n_non_sea_old; extern ulint btr_cur_n_sea_old; +#ifdef UNIV_DEBUG +/* Flag to limit optimistic insert records */ +extern uint btr_cur_limit_optimistic_insert_debug; +#endif /* UNIV_DEBUG */ + #ifndef UNIV_NONINL #include "btr0cur.ic" #endif diff --git a/storage/innobase/include/btr0cur.ic b/storage/innobase/include/btr0cur.ic index bd2c46eb734..d894f0546d9 100644 --- a/storage/innobase/include/btr0cur.ic +++ b/storage/innobase/include/btr0cur.ic @@ -8,6 +8,16 @@ Created 10/16/1994 Heikki Tuuri #include "btr0btr.h" +#ifdef UNIV_DEBUG +# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE)\ +if (btr_cur_limit_optimistic_insert_debug\ + && (NREC) >= (ulint)btr_cur_limit_optimistic_insert_debug) {\ + CODE;\ +} +#else +# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE) +#endif /* UNIV_DEBUG */ + /************************************************************* Returns the page cursor component of a tree cursor. */ UNIV_INLINE @@ -100,6 +110,9 @@ btr_cur_compress_recommendation( page = btr_cur_get_page(cursor); + LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page) * 2, + return(FALSE)); + if ((page_get_data_size(page) < BTR_CUR_PAGE_COMPRESS_LIMIT) || ((btr_page_get_next(page, mtr) == FIL_NULL) && (btr_page_get_prev(page, mtr) == FIL_NULL))) { diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index aa6c88e0538..e79d352d1e6 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -569,6 +569,9 @@ struct export_var_struct{ ulint innodb_rows_inserted; ulint innodb_rows_updated; ulint innodb_rows_deleted; +#ifdef UNIV_DEBUG + ulint innodb_purge_trx_id_age; +#endif /* UNIV_DEBUG */ }; /* The server system struct */ diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index fbae7eb9a6d..fc9ff021920 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -133,6 +133,10 @@ struct trx_purge_struct{ than this */ dulint purge_undo_no; /* Purge has advanced past all records whose undo number is less than this */ +#ifdef UNIV_DEBUG + dulint done_trx_no; /* Indicate 'purge pointer' which have + purged already accurately. */ +#endif /* UNIV_DEBUG */ /*-----------------------------*/ ibool next_stored; /* TRUE if the info of the next record to purge is stored below: if yes, then diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 3f6f1982992..46d5b6ad274 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -1913,6 +1913,15 @@ srv_export_innodb_status(void) export_vars.innodb_rows_updated = srv_n_rows_updated; export_vars.innodb_rows_deleted = srv_n_rows_deleted; +#ifdef UNIV_DEBUG + if (ut_dulint_cmp(trx_sys->max_trx_id, purge_sys->done_trx_no) < 0) { + export_vars.innodb_purge_trx_id_age = 0; + } else { + export_vars.innodb_purge_trx_id_age = + ut_dulint_minus(trx_sys->max_trx_id, purge_sys->done_trx_no); + } +#endif /* UNIV_DEBUG */ + mutex_exit(&srv_innodb_monitor_mutex); } @@ -2387,6 +2396,29 @@ loop: + buf_pool->n_pages_written; srv_main_thread_op_info = "sleeping"; +#ifdef UNIV_DEBUG + if (btr_cur_limit_optimistic_insert_debug) { + /* If btr_cur_limit_optimistic_insert_debug is enabled + and no purge_threads, purge opportunity is increased + by x100 (1purge/100msec), to speed up debug scripts + which should wait for purged. */ + + if (!skip_sleep) { + os_thread_sleep(100000); + } + + do { + if (srv_fast_shutdown + && srv_shutdown_state > 0) { + goto background_loop; + } + + srv_main_thread_op_info = "purging"; + n_pages_purged = trx_purge(); + + } while (n_pages_purged); + } else +#endif /* UNIV_DEBUG */ if (!skip_sleep) { os_thread_sleep(1000000); diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index 6fe5855ebfa..e783f14c1ee 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -209,6 +209,7 @@ trx_purge_sys_create(void) purge_sys->purge_trx_no = ut_dulint_zero; purge_sys->purge_undo_no = ut_dulint_zero; purge_sys->next_stored = FALSE; + ut_d(purge_sys->done_trx_no = ut_dulint_zero); rw_lock_create(&purge_sys->latch, SYNC_PURGE_LATCH); @@ -576,6 +577,7 @@ trx_purge_truncate_if_arr_empty(void) ut_ad(mutex_own(&(purge_sys->mutex))); if (purge_sys->arr->n_used == 0) { + ut_d(purge_sys->done_trx_no = purge_sys->purge_trx_no); trx_purge_truncate_history(); diff --git a/storage/innodb_plugin/btr/btr0btr.c b/storage/innodb_plugin/btr/btr0btr.c index 9fef7843f9a..04f3a79866e 100644 --- a/storage/innodb_plugin/btr/btr0btr.c +++ b/storage/innodb_plugin/btr/btr0btr.c @@ -3072,6 +3072,8 @@ btr_lift_page_up( buf_block_t* blocks[BTR_MAX_LEVELS]; ulint n_blocks; /*!< last used index in blocks[] */ ulint i; + ibool lift_father_up = FALSE; + buf_block_t* block_orig = block; ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL); ut_ad(btr_page_get_next(page, mtr) == FIL_NULL); @@ -3082,11 +3084,13 @@ btr_lift_page_up( { btr_cur_t cursor; - mem_heap_t* heap = mem_heap_create(100); - ulint* offsets; + ulint* offsets = NULL; + mem_heap_t* heap = mem_heap_create( + sizeof(*offsets) + * (REC_OFFS_HEADER_SIZE + 1 + 1 + index->n_fields)); buf_block_t* b; - offsets = btr_page_get_father_block(NULL, heap, index, + offsets = btr_page_get_father_block(offsets, heap, index, block, mtr, &cursor); father_block = btr_cur_get_block(&cursor); father_page_zip = buf_block_get_page_zip(father_block); @@ -3110,6 +3114,29 @@ btr_lift_page_up( blocks[n_blocks++] = b = btr_cur_get_block(&cursor); } + if (n_blocks && page_level == 0) { + /* The father page also should be the only on its level (not + root). We should lift up the father page at first. + Because the leaf page should be lifted up only for root page. + The freeing page is based on page_level (==0 or !=0) + to choose segment. If the page_level is changed ==0 from !=0, + later freeing of the page doesn't find the page allocation + to be freed.*/ + + lift_father_up = TRUE; + block = father_block; + page = buf_block_get_frame(block); + page_level = btr_page_get_level(page, mtr); + + ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL); + ut_ad(btr_page_get_next(page, mtr) == FIL_NULL); + ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); + + father_block = blocks[0]; + father_page_zip = buf_block_get_page_zip(father_block); + father_page = buf_block_get_frame(father_block); + } + mem_heap_free(heap); } @@ -3117,6 +3144,7 @@ btr_lift_page_up( /* Make the father empty */ btr_page_empty(father_block, father_page_zip, index, page_level, mtr); + page_level++; /* Copy the records to the father page one by one. */ if (0 @@ -3149,7 +3177,7 @@ btr_lift_page_up( lock_update_copy_and_discard(father_block, block); /* Go upward to root page, decrementing levels by one. */ - for (i = 0; i < n_blocks; i++, page_level++) { + for (i = lift_father_up ? 1 : 0; i < n_blocks; i++, page_level++) { page_t* page = buf_block_get_frame(blocks[i]); page_zip_des_t* page_zip= buf_block_get_page_zip(blocks[i]); @@ -3171,7 +3199,7 @@ btr_lift_page_up( ut_ad(page_validate(father_page, index)); ut_ad(btr_check_node_ptr(index, father_block, mtr)); - return(father_block); + return(lift_father_up ? block_orig : father_block); } /*************************************************************//** diff --git a/storage/innodb_plugin/btr/btr0cur.c b/storage/innodb_plugin/btr/btr0cur.c index 6c67d27ffec..e38b8a9bf53 100644 --- a/storage/innodb_plugin/btr/btr0cur.c +++ b/storage/innodb_plugin/btr/btr0cur.c @@ -86,6 +86,11 @@ srv_refresh_innodb_monitor_stats(). Referenced by srv_printf_innodb_monitor(). */ UNIV_INTERN ulint btr_cur_n_sea_old = 0; +#ifdef UNIV_DEBUG +/* Flag to limit optimistic insert records */ +UNIV_INTERN uint btr_cur_limit_optimistic_insert_debug = 0; +#endif /* UNIV_DEBUG */ + /** In the optimistic insert, if the insert does not fit, but this much space can be released by page reorganize, then it is reorganized */ #define BTR_CUR_PAGE_REORGANIZE_LIMIT (UNIV_PAGE_SIZE / 32) @@ -1171,6 +1176,9 @@ btr_cur_optimistic_insert( } } + LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page), + goto fail); + /* If there have been many consecutive inserts, and we are on the leaf level, check if we have to split the page to reserve enough free space for future updates of records. */ diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index bbdf5680e30..9ed452d9809 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -577,6 +577,10 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_rows_read, SHOW_LONG}, {"rows_updated", (char*) &export_vars.innodb_rows_updated, SHOW_LONG}, +#ifdef UNIV_DEBUG + {"purge_trx_id_age", + (char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG}, +#endif /* UNIV_DEBUG */ {NullS, NullS, SHOW_LONG} }; @@ -11262,6 +11266,11 @@ static MYSQL_SYSVAR_UINT(trx_rseg_n_slots_debug, trx_rseg_n_slots_debug, PLUGIN_VAR_RQCMDARG, "Debug flags for InnoDB to limit TRX_RSEG_N_SLOTS for trx_rsegf_undo_find_free()", NULL, NULL, 0, 0, 1024, 0); + +static MYSQL_SYSVAR_UINT(limit_optimistic_insert_debug, + btr_cur_limit_optimistic_insert_debug, PLUGIN_VAR_RQCMDARG, + "Artificially limit the number of records per B-tree page (0=unlimited).", + NULL, NULL, 0, 0, UINT_MAX32, 0); #endif /* UNIV_DEBUG */ static struct st_mysql_sys_var* innobase_system_variables[]= { @@ -11327,6 +11336,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(io_capacity), #ifdef UNIV_DEBUG MYSQL_SYSVAR(trx_rseg_n_slots_debug), + MYSQL_SYSVAR(limit_optimistic_insert_debug), #endif /* UNIV_DEBUG */ NULL }; diff --git a/storage/innodb_plugin/include/btr0cur.h b/storage/innodb_plugin/include/btr0cur.h index 1c421167828..7744d2d1ee2 100644 --- a/storage/innodb_plugin/include/btr0cur.h +++ b/storage/innodb_plugin/include/btr0cur.h @@ -795,6 +795,11 @@ srv_printf_innodb_monitor(). */ extern ulint btr_cur_n_sea_old; #endif /* !UNIV_HOTBACKUP */ +#ifdef UNIV_DEBUG +/* Flag to limit optimistic insert records */ +extern uint btr_cur_limit_optimistic_insert_debug; +#endif /* UNIV_DEBUG */ + #ifndef UNIV_NONINL #include "btr0cur.ic" #endif diff --git a/storage/innodb_plugin/include/btr0cur.ic b/storage/innodb_plugin/include/btr0cur.ic index e31f77c77eb..5fc4651ca13 100644 --- a/storage/innodb_plugin/include/btr0cur.ic +++ b/storage/innodb_plugin/include/btr0cur.ic @@ -26,6 +26,16 @@ Created 10/16/1994 Heikki Tuuri #ifndef UNIV_HOTBACKUP #include "btr0btr.h" +#ifdef UNIV_DEBUG +# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE)\ +if (btr_cur_limit_optimistic_insert_debug\ + && (NREC) >= (ulint)btr_cur_limit_optimistic_insert_debug) {\ + CODE;\ +} +#else +# define LIMIT_OPTIMISTIC_INSERT_DEBUG(NREC, CODE) +#endif /* UNIV_DEBUG */ + #ifdef UNIV_DEBUG /*********************************************************//** Returns the page cursor component of a tree cursor. @@ -146,6 +156,9 @@ btr_cur_compress_recommendation( page = btr_cur_get_page(cursor); + LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page) * 2, + return(FALSE)); + if ((page_get_data_size(page) < BTR_CUR_PAGE_COMPRESS_LIMIT) || ((btr_page_get_next(page, mtr) == FIL_NULL) && (btr_page_get_prev(page, mtr) == FIL_NULL))) { diff --git a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h index 1a9f54882c5..089a4c1c777 100644 --- a/storage/innodb_plugin/include/srv0srv.h +++ b/storage/innodb_plugin/include/srv0srv.h @@ -650,6 +650,9 @@ struct export_var_struct{ ulint innodb_rows_inserted; /*!< srv_n_rows_inserted */ ulint innodb_rows_updated; /*!< srv_n_rows_updated */ ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */ +#ifdef UNIV_DEBUG + ulint innodb_purge_trx_id_age; /*!< max_trx_id - purged trx_id */ +#endif /* UNIV_DEBUG */ }; /** The server system struct */ diff --git a/storage/innodb_plugin/include/trx0purge.h b/storage/innodb_plugin/include/trx0purge.h index 37d3795efb0..f221a65d076 100644 --- a/storage/innodb_plugin/include/trx0purge.h +++ b/storage/innodb_plugin/include/trx0purge.h @@ -153,6 +153,10 @@ struct trx_purge_struct{ than this */ undo_no_t purge_undo_no; /*!< Purge has advanced past all records whose undo number is less than this */ +#ifdef UNIV_DEBUG + trx_id_t done_trx_no; /* Indicate 'purge pointer' which have + purged already accurately. */ +#endif /* UNIV_DEBUG */ /*-----------------------------*/ ibool next_stored; /*!< TRUE if the info of the next record to purge is stored below: if yes, then diff --git a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c index 8ad4c02e322..2d48fcc6b18 100644 --- a/storage/innodb_plugin/srv/srv0srv.c +++ b/storage/innodb_plugin/srv/srv0srv.c @@ -1964,6 +1964,15 @@ srv_export_innodb_status(void) export_vars.innodb_rows_updated = srv_n_rows_updated; export_vars.innodb_rows_deleted = srv_n_rows_deleted; +#ifdef UNIV_DEBUG + if (ut_dulint_cmp(trx_sys->max_trx_id, purge_sys->done_trx_no) < 0) { + export_vars.innodb_purge_trx_id_age = 0; + } else { + export_vars.innodb_purge_trx_id_age = + ut_dulint_minus(trx_sys->max_trx_id, purge_sys->done_trx_no); + } +#endif /* UNIV_DEBUG */ + mutex_exit(&srv_innodb_monitor_mutex); } @@ -2468,6 +2477,30 @@ loop: srv_main_thread_op_info = "sleeping"; srv_main_1_second_loops++; +#ifdef UNIV_DEBUG + if (btr_cur_limit_optimistic_insert_debug) { + /* If btr_cur_limit_optimistic_insert_debug is enabled + and no purge_threads, purge opportunity is increased + by x100 (1purge/100msec), to speed up debug scripts + which should wait for purged. */ + + if (!skip_sleep) { + os_thread_sleep(100000); + srv_main_sleeps++; + } + + do { + if (srv_fast_shutdown + && srv_shutdown_state > 0) { + goto background_loop; + } + + srv_main_thread_op_info = "purging"; + n_pages_purged = trx_purge(); + + } while (n_pages_purged); + } else +#endif /* UNIV_DEBUG */ if (!skip_sleep) { os_thread_sleep(1000000); diff --git a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c index 56607c9ff93..ea508c1003c 100644 --- a/storage/innodb_plugin/trx/trx0purge.c +++ b/storage/innodb_plugin/trx/trx0purge.c @@ -226,6 +226,7 @@ trx_purge_sys_create(void) purge_sys->purge_trx_no = ut_dulint_zero; purge_sys->purge_undo_no = ut_dulint_zero; purge_sys->next_stored = FALSE; + ut_d(purge_sys->done_trx_no = ut_dulint_zero); rw_lock_create(&purge_sys->latch, SYNC_PURGE_LATCH); @@ -637,6 +638,7 @@ trx_purge_truncate_if_arr_empty(void) ut_ad(mutex_own(&(purge_sys->mutex))); if (purge_sys->arr->n_used == 0) { + ut_d(purge_sys->done_trx_no = purge_sys->purge_trx_no); trx_purge_truncate_history(); From 2f3baa743dc15294764b1aa82f70d04678333259 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 13 Nov 2012 09:21:59 +0100 Subject: [PATCH 024/324] Bug#14845133: The problem is related to the changes made in bug#13025132. get_partition_set can do dynamic pruning which limits the partitions to scan even further. This is not accounted for when setting the correct start of the preallocated record buffer used in the priority queue, thus leading to wrong buffer is used (including wrong preset partitioning id, connected to that buffer). Solution is to fast forward the buffer pointer to point to the correct partition record buffer. --- sql/ha_partition.cc | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 4e6f5984934..69cf5f74df6 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4077,6 +4077,7 @@ bool ha_partition::init_record_priority_queue() { if (bitmap_is_set(&m_part_info->used_partitions, i)) { + DBUG_PRINT("info", ("init rec-buf for part %u", i)); int2store(ptr, i); ptr+= m_rec_length + PARTITION_BYTES_IN_POS; } @@ -4981,11 +4982,27 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) m_top_entry= NO_CURRENT_PART_ID; queue_remove_all(&m_queue); - DBUG_PRINT("info", ("m_part_spec.start_part %d", m_part_spec.start_part)); - for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++) + /* + Position part_rec_buf_ptr to point to the first used partition >= + start_part. There may be partitions marked by used_partitions, + but is before start_part. These partitions has allocated record buffers + but is dynamically pruned, so those buffers must be skipped. + */ + uint first_used_part= bitmap_get_first_set(&m_part_info->used_partitions); + for (; first_used_part < m_part_spec.start_part; first_used_part++) + { + if (bitmap_is_set(&(m_part_info->used_partitions), first_used_part)) + part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS; + } + DBUG_PRINT("info", ("m_part_spec.start_part %u first_used_part %u", + m_part_spec.start_part, first_used_part)); + for (i= first_used_part; i <= m_part_spec.end_part; i++) { if (!(bitmap_is_set(&(m_part_info->used_partitions), i))) continue; + DBUG_PRINT("info", ("reading from part %u (scan_type: %u)", + i, m_index_scan_type)); + DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr)); uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS; int error; handler *file= m_file[i]; From b5ff983ab50549b3c216b4b64806c77fd4712c6e Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Tue, 13 Nov 2012 09:21:59 +0100 Subject: [PATCH 025/324] Bug#14845133: The problem is related to the changes made in bug#13025132. get_partition_set can do dynamic pruning which limits the partitions to scan even further. This is not accounted for when setting the correct start of the preallocated record buffer used in the priority queue, thus leading to wrong buffer is used (including wrong preset partitioning id, connected to that buffer). Solution is to fast forward the buffer pointer to point to the correct partition record buffer. --- sql/ha_partition.cc | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 4e6f5984934..69cf5f74df6 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -4077,6 +4077,7 @@ bool ha_partition::init_record_priority_queue() { if (bitmap_is_set(&m_part_info->used_partitions, i)) { + DBUG_PRINT("info", ("init rec-buf for part %u", i)); int2store(ptr, i); ptr+= m_rec_length + PARTITION_BYTES_IN_POS; } @@ -4981,11 +4982,27 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) m_top_entry= NO_CURRENT_PART_ID; queue_remove_all(&m_queue); - DBUG_PRINT("info", ("m_part_spec.start_part %d", m_part_spec.start_part)); - for (i= m_part_spec.start_part; i <= m_part_spec.end_part; i++) + /* + Position part_rec_buf_ptr to point to the first used partition >= + start_part. There may be partitions marked by used_partitions, + but is before start_part. These partitions has allocated record buffers + but is dynamically pruned, so those buffers must be skipped. + */ + uint first_used_part= bitmap_get_first_set(&m_part_info->used_partitions); + for (; first_used_part < m_part_spec.start_part; first_used_part++) + { + if (bitmap_is_set(&(m_part_info->used_partitions), first_used_part)) + part_rec_buf_ptr+= m_rec_length + PARTITION_BYTES_IN_POS; + } + DBUG_PRINT("info", ("m_part_spec.start_part %u first_used_part %u", + m_part_spec.start_part, first_used_part)); + for (i= first_used_part; i <= m_part_spec.end_part; i++) { if (!(bitmap_is_set(&(m_part_info->used_partitions), i))) continue; + DBUG_PRINT("info", ("reading from part %u (scan_type: %u)", + i, m_index_scan_type)); + DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr)); uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS; int error; handler *file= m_file[i]; From 4885937e85947468a43e809c85280086f2bf045b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Nov 2012 10:40:20 +0530 Subject: [PATCH 026/324] From e42cd2db9107b7f527ffed2adfaa3c5d5b1cb11a Mon Sep 17 00:00:00 2001 From: Jimmy Yang Date: Wed, 14 Nov 2012 17:00:41 +0800 Subject: [PATCH 027/324] Fix Bug #14753402 - FAILING ASSERTION: LEN == IFIELD->FIXED_LEN rb://1411 approved by Marko --- .../suite/innodb/r/innodb_bug14753402.result | 5 +++++ .../suite/innodb/t/innodb_bug14753402.test | 13 +++++++++++ storage/innobase/rem/rem0rec.c | 22 +++++++++++++++++-- storage/innobase/row/row0merge.c | 12 +++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_bug14753402.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug14753402.test diff --git a/mysql-test/suite/innodb/r/innodb_bug14753402.result b/mysql-test/suite/innodb/r/innodb_bug14753402.result new file mode 100644 index 00000000000..032542df59f --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug14753402.result @@ -0,0 +1,5 @@ +CREATE TABLE bug14753402(a34 INT, col8953 NATIONAL CHAR(231) NOT NULL) +ENGINE=INNODB ROW_FORMAT=REDUNDANT; +INSERT INTO bug14753402 VALUES(1, 'aa'); +CREATE INDEX idx1 ON bug14753402(col8953(165)); +DROP TABLE bug14753402; diff --git a/mysql-test/suite/innodb/t/innodb_bug14753402.test b/mysql-test/suite/innodb/t/innodb_bug14753402.test new file mode 100644 index 00000000000..7fa758fc5ad --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug14753402.test @@ -0,0 +1,13 @@ +# +# Test Bug 14753402 - FAILING ASSERTION: LEN == IFIELD->FIXED_LEN +# +-- source include/have_innodb.inc + +CREATE TABLE bug14753402(a34 INT, col8953 NATIONAL CHAR(231) NOT NULL) +ENGINE=INNODB ROW_FORMAT=REDUNDANT; + +INSERT INTO bug14753402 VALUES(1, 'aa'); + +CREATE INDEX idx1 ON bug14753402(col8953(165)); + +DROP TABLE bug14753402; diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c index 30fc28561fa..5cebbf45ac6 100644 --- a/storage/innobase/rem/rem0rec.c +++ b/storage/innobase/rem/rem0rec.c @@ -819,10 +819,19 @@ rec_get_converted_size_comp_prefix( it is 128 or more, or when the field is stored externally. */ if (field->fixed_len) { - ut_ad(len == field->fixed_len); +#ifdef UNIV_DEBUG + ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); + ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); + + ut_ad(len <= field->fixed_len); + + ut_ad(!mbmaxlen || len >= mbminlen + * (field->fixed_len / mbmaxlen)); + /* dict_index_add_col() should guarantee this */ ut_ad(!field->prefix_len || field->fixed_len == field->prefix_len); +#endif /* UNIV_DEBUG */ } else if (dfield_is_ext(&fields[i])) { ut_ad(col->len >= 256 || col->mtype == DATA_BLOB); extra_size += 2; @@ -1169,8 +1178,17 @@ rec_convert_dtuple_to_rec_comp( 0..127. The length will be encoded in two bytes when it is 128 or more, or when the field is stored externally. */ if (fixed_len) { - ut_ad(len == fixed_len); +#ifdef UNIV_DEBUG + ulint mbminlen = DATA_MBMINLEN( + ifield->col->mbminmaxlen); + ulint mbmaxlen = DATA_MBMAXLEN( + ifield->col->mbminmaxlen); + + ut_ad(len <= fixed_len); + ut_ad(!mbmaxlen || len >= mbminlen + * (fixed_len / mbmaxlen)); ut_ad(!dfield_is_ext(field)); +#endif /* UNIV_DEBUG */ } else if (dfield_is_ext(field)) { ut_ad(ifield->col->len >= 256 || ifield->col->mtype == DATA_BLOB); diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c index 57c8f22411a..b5ff91eed1b 100644 --- a/storage/innobase/row/row0merge.c +++ b/storage/innobase/row/row0merge.c @@ -347,8 +347,18 @@ row_merge_buf_add( ut_ad(len <= col->len || col->mtype == DATA_BLOB); if (ifield->fixed_len) { - ut_ad(len == ifield->fixed_len); +#ifdef UNIV_DEBUG + ulint mbminlen = DATA_MBMINLEN(col->mbminmaxlen); + ulint mbmaxlen = DATA_MBMAXLEN(col->mbminmaxlen); + + /* len should be between size calcualted base on + mbmaxlen and mbminlen */ + ut_ad(len <= ifield->fixed_len); + ut_ad(!mbmaxlen || len >= mbminlen + * (ifield->fixed_len / mbmaxlen)); + ut_ad(!dfield_is_ext(field)); +#endif /* UNIV_DEBUG */ } else if (dfield_is_ext(field)) { extra_size += 2; } else if (len < 128 From 1553e0a15e2e172d4c57170bd8adf132c3eb0f23 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Nov 2012 14:57:28 +0530 Subject: [PATCH 028/324] From 2eb5bc95d56cb4b23862fb5f48f7a4f4407ab73d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 14 Nov 2012 16:35:08 +0530 Subject: [PATCH 029/324] From 118b7561980d3069ab12167c689a3beaead26fa4 Mon Sep 17 00:00:00 2001 From: Venkata Sidagam Date: Wed, 14 Nov 2012 17:02:36 +0530 Subject: [PATCH 030/324] BUG#13556107: CHECK AND REPAIR TABLE SHOULD BE MORE ROBUST [3] Problem description: Incorrect key file. Key file is corrupted, while reading the keys from the file. The problem here is that keyseg->start (which should point to the beginning of a field) is pointing beyond total record length. Fix: If keyseg->start is greater than total record length then return error. --- storage/myisam/mi_open.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index 5951aef6d4f..93f70a5d340 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -343,6 +343,12 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) } else if (pos->type == HA_KEYTYPE_BINARY) pos->charset= &my_charset_bin; + if (!(share->keyinfo[i].flag & HA_SPATIAL) && + pos->start > share->base.reclength) + { + my_errno= HA_ERR_CRASHED; + goto err; + } } if (share->keyinfo[i].flag & HA_SPATIAL) { From 16c9c14465aea786b38037d7ad108a5c812b67ae Mon Sep 17 00:00:00 2001 From: Nuno Carvalho Date: Wed, 14 Nov 2012 17:17:14 +0000 Subject: [PATCH 031/324] BUG#12669186: AUTOINC VALUE PERSISTENCY BREAKS CERTAIN REPLICATION SCENARIOS When master and slave have different schemas, in particular different AUTO_INCREMENT columns, INSERT_ID events logged for a given table on master may be applied to a different table on slave on SBR, e.g.: master has one table (t1) with one auto-inc column and another table (t2) without auto-inc column, on slave t1 does not have auto-inc column (despite having the same columns) and t2 has a auto-inc column. The INSERT_ID that is intended for t1, since t1 on slave doesn't have auto-inc column is used on t2, causing consistency problems. To fix this incorrect behaviour, auto-inc interval allocation via INSERT_ID is made effectively terminated at the end of top-level statements on slave and binlog replay. --- sql/sql_class.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9b0a76bf749..ff7f2340ac0 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1693,6 +1693,19 @@ void THD::cleanup_after_query() stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0; auto_inc_intervals_in_cur_stmt_for_binlog.empty(); rand_used= 0; +#ifndef EMBEDDED_LIBRARY + /* + Clean possible unused INSERT_ID events by current statement. + is_update_query() is needed to ignore SET statements: + Statements that don't update anything directly and don't + used stored functions. This is mostly necessary to ignore + statements in binlog between SET INSERT_ID and DML statement + which is intended to consume its event (there can be other + SET statements between them). + */ + if ((rli_slave || rli_fake) && is_update_query(lex->sql_command)) + auto_inc_intervals_forced.empty(); +#endif } if (first_successful_insert_id_in_cur_stmt > 0) { From 51787b41e9609628910527b00e595a7dba456858 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 15 Nov 2012 12:27:05 +0530 Subject: [PATCH 032/324] From bd5c93304db20fd5c82a1f169cfed26daadb2a7d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 15 Nov 2012 15:52:51 +0100 Subject: [PATCH 033/324] remove usage of --skip-ndb from collections - no need to use --skip-ndb in collections files anymore, since long but more clear logic after recent mtr.pl fixes. ndb tests are never run in MySQL Server unless explicitly requested - remove sys_vars.ndb_log_update_as_write_basic.test and sys_vars.ndb_log_updated_only_basic.result since MySQL Server does not have those options. - Only sys_vars.have_ndbcluster_basic left since MySQL Server has that variable hardcoded. --- mysql-test/collections/default.experimental | 5 - mysql-test/collections/default.push | 10 +- mysql-test/collections/default.release.in | 8 +- .../r/ndb_log_update_as_write_basic.result | 14 -- .../r/ndb_log_updated_only_basic.result | 14 -- .../t/ndb_log_update_as_write_basic.test | 216 ------------------ .../t/ndb_log_updated_only_basic.test | 216 ------------------ 7 files changed, 9 insertions(+), 474 deletions(-) delete mode 100644 mysql-test/suite/sys_vars/r/ndb_log_update_as_write_basic.result delete mode 100644 mysql-test/suite/sys_vars/r/ndb_log_updated_only_basic.result delete mode 100644 mysql-test/suite/sys_vars/t/ndb_log_update_as_write_basic.test delete mode 100644 mysql-test/suite/sys_vars/t/ndb_log_updated_only_basic.test diff --git a/mysql-test/collections/default.experimental b/mysql-test/collections/default.experimental index 1f4d29968a5..56b8feb6739 100644 --- a/mysql-test/collections/default.experimental +++ b/mysql-test/collections/default.experimental @@ -18,9 +18,4 @@ rpl.rpl_row_sp011 @solaris # Bug#11753919 2011-07-25 sven Several sys_vars.max_sp_recursion_depth_func @solaris # Bug#11753919 2010-01-20 alik Several test cases fail on Solaris with error Thread stack overrun sys_vars.wait_timeout_func # Bug#11750645 2010-04-26 alik wait_timeout_func fails -# BUG #59055 : All ndb tests should be removed from the repository -# Leaving the sys_vars tests for now. sys_vars.all_vars.test fails on removing ndb tests -sys_vars.ndb_log_update_as_write_basic -sys_vars.have_ndbcluster_basic -sys_vars.ndb_log_updated_only_basic sys_vars.rpl_init_slave_func # Bug#12535301 2011-05-09 andrei sys_vars.rpl_init_slave_func mismatches in daily-5.5 diff --git a/mysql-test/collections/default.push b/mysql-test/collections/default.push index c8402aecd75..13627f68a1e 100644 --- a/mysql-test/collections/default.push +++ b/mysql-test/collections/default.push @@ -1,5 +1,5 @@ -perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list --unit-tests -perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list -perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental --skip-ndb -perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-ndb --skip-test-list=collections/disabled-per-push.list -perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental --skip-ndb +perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list --unit-tests +perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list +perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental +perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list +perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental \ No newline at end of file diff --git a/mysql-test/collections/default.release.in b/mysql-test/collections/default.release.in index 0e3ad30671b..8833086fad9 100644 --- a/mysql-test/collections/default.release.in +++ b/mysql-test/collections/default.release.in @@ -4,14 +4,14 @@ # include default.daily # include default.weekly -perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=debug --vardir=var-debug --skip-ndbcluster --skip-rpl --report-features --debug-server -perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --skip-ndbcluster --report-features -perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=ps --vardir=var-ps --skip-ndbcluster --ps-protocol +perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=debug --vardir=var-debug --skip-rpl --report-features --debug-server +perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features +perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=ps --vardir=var-ps --ps-protocol perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=funcs1+ps --vardir=var-funcs_1_ps --suite=funcs_1 --ps-protocol perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=funcs2 --vardir=var-funcs2 --suite=funcs_2 perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=partitions --vardir=var-parts --suite=parts perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=stress --vardir=var-stress --suite=stress perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=jp --vardir=var-jp --suite=jp -perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-embedded --embedded-server --skip-rpl --skip-ndbcluster +perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=embedded --vardir=var-embedded --embedded-server --skip-rpl perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=nist --vardir=var-nist --suite=nist perl mysql-test-run.pl --force --timer --parallel=auto --experimental=collections/default.experimental --comment=nist+ps --vardir=var-nist_ps --suite=nist --ps-protocol diff --git a/mysql-test/suite/sys_vars/r/ndb_log_update_as_write_basic.result b/mysql-test/suite/sys_vars/r/ndb_log_update_as_write_basic.result deleted file mode 100644 index 6353fba2b7c..00000000000 --- a/mysql-test/suite/sys_vars/r/ndb_log_update_as_write_basic.result +++ /dev/null @@ -1,14 +0,0 @@ -SET @global_start_value = @@global.ndb_log_update_as_write; -ERROR HY000: Unknown system variable 'ndb_log_update_as_write' -SELECT @@global.ndb_log_update_as_write; -ERROR HY000: Unknown system variable 'ndb_log_update_as_write' -'Bug: The value is not a system variable or atleast not supported in version 5.1.22' -'#--------------------FN_DYNVARS_102_01------------------------#' -'#---------------------FN_DYNVARS_102_02-------------------------#' -'#--------------------FN_DYNVARS_102_03------------------------#' -'#--------------------FN_DYNVARS_102_04-------------------------#' -'#-------------------FN_DYNVARS_102_05----------------------------#' -'#----------------------FN_DYNVARS_102_06------------------------#' -'#----------------------FN_DYNVARS_102_07------------------------#' -'#---------------------FN_DYNVARS_102_08-------------------------#' -'#---------------------FN_DYNVARS_102_09----------------------#' diff --git a/mysql-test/suite/sys_vars/r/ndb_log_updated_only_basic.result b/mysql-test/suite/sys_vars/r/ndb_log_updated_only_basic.result deleted file mode 100644 index 38abb7cc263..00000000000 --- a/mysql-test/suite/sys_vars/r/ndb_log_updated_only_basic.result +++ /dev/null @@ -1,14 +0,0 @@ -SET @global_start_value = @@global.ndb_log_updated_only; -ERROR HY000: Unknown system variable 'ndb_log_updated_only' -SELECT @@global.ndb_log_updated_only; -ERROR HY000: Unknown system variable 'ndb_log_updated_only' -'Bug: The value is not a system variable or atleast not supported in version 5.1.22' -'#--------------------FN_DYNVARS_103_01------------------------#' -'#---------------------FN_DYNVARS_103_02-------------------------#' -'#--------------------FN_DYNVARS_103_03------------------------#' -'#--------------------FN_DYNVARS_103_04-------------------------#' -'#-------------------FN_DYNVARS_103_05----------------------------#' -'#----------------------FN_DYNVARS_103_06------------------------#' -'#----------------------FN_DYNVARS_103_07------------------------#' -'#---------------------FN_DYNVARS_103_08-------------------------#' -'#---------------------FN_DYNVARS_103_09----------------------#' diff --git a/mysql-test/suite/sys_vars/t/ndb_log_update_as_write_basic.test b/mysql-test/suite/sys_vars/t/ndb_log_update_as_write_basic.test deleted file mode 100644 index e616a807a38..00000000000 --- a/mysql-test/suite/sys_vars/t/ndb_log_update_as_write_basic.test +++ /dev/null @@ -1,216 +0,0 @@ -############## mysql-test\t\ndb_log_update_as_write_basic.test ############### -# # -# Variable Name: ndb_log_update_as_write # -# Scope: GLOBAL # -# Access Type: Dynamic # -# Data Type: boolean # -# Default Value: # -# Range: # -# # -# # -# Creation Date: 2008-02-07 # -# Author: Rizwan # -# # -# Description: Test Cases of Dynamic System Variable ndb_log_update_as_write # -# that checks the behavior of this variable in the following ways# -# * Default Value # -# * Valid & Invalid values # -# * Scope & Access method # -# * Data Integrity # -# # -# Reference: http://dev.mysql.com/doc/refman/5.1/en/ # -# server-system-variables.html # -# # -############################################################################### -############## mysql-test\t\ndb_log_update_as_write_basic.test ################ -# # -# Variable Name: ndb_log_update_as_write # -# Scope: GLOBAL & SESSION # -# Access Type: Dynamic # -# Data Type: Numeric # -# Default Value: 1 # -# Range: 1 - 65536 # -# # -# # -# Creation Date: 2008-02-07 # -# Author: Rizwan Maredia # -# # -# Description: Test Cases of Dynamic System Variable ndb_log_update_as_write # -# that checks the behavior of this variable in the following ways # -# * Default Value # -# * Valid & Invalid values # -# * Scope & Access method # -# * Data Integrity # -# # -# Reference: http://dev.mysql.com/doc/refman/5.1/en/ # -# server-system-variables.html # -# # -################################################################################ -################# mysql-test\t\ndb_log_update_as_write_basic.test ###### -# # -# # -# Creation Date: 2008-02-07 # -# Author: Rizwan Maredia # -# # -# Description: Test Cases of Dynamic System Variable # -# ndb_log_update_as_write that check behavior of this # -# variable with valid values, invalid values, # -# accessing variable with scope that is # -# allowed and with scope that is now allowed. # -# Scope: Global # -# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-system # -# -variables.html # -# # -######################################################################## - ---source include/load_sysvars.inc - -######################################################################## -# START OF ndb_log_update_as_write TESTS # -######################################################################## - - -################################################################################ -# Saving initial value of ndb_log_update_as_write in a temporary variable # -################################################################################ - - ---Error ER_UNKNOWN_SYSTEM_VARIABLE -SET @global_start_value = @@global.ndb_log_update_as_write; ---Error ER_UNKNOWN_SYSTEM_VARIABLE -SELECT @@global.ndb_log_update_as_write; - ---echo 'Bug: The value is not a system variable or atleast not supported in version 5.1.22' - - ---echo '#--------------------FN_DYNVARS_102_01------------------------#' -######################################################################## -# Display the DEFAULT value of ndb_log_update_as_write # -######################################################################## - -#SET @@ndb_log_update_as_write = 0; -#SET @@ndb_log_update_as_write = DEFAULT; -#SELECT @@ndb_log_update_as_write; -# -#SET @@ndb_log_update_as_write = 1; -#SET @@ndb_log_update_as_write = DEFAULT; -#SELECT @@ndb_log_update_as_write; - - ---echo '#---------------------FN_DYNVARS_102_02-------------------------#' -############################################################################# -# Check if ndb_log_update_as_write can be accessed with and without @@ sign # -############################################################################# - -#SET ndb_log_update_as_write = 1; -#SELECT @@ndb_log_update_as_write; -#--Error ER_UNKNOWN_TABLE -#SELECT global.ndb_log_update_as_write; -# -#SET global ndb_log_update_as_write = 1; -#SELECT @@global.ndb_log_update_as_write; - - ---echo '#--------------------FN_DYNVARS_102_03------------------------#' -######################################################################## -# Change the value of ndb_log_update_as_write to a valid value # -######################################################################## - -#SET @@global.ndb_log_update_as_write = 0; -#SELECT @@global.ndb_log_update_as_write; -#SET @@global.ndb_log_update_as_write = 1; -#SELECT @@global.ndb_log_update_as_write; -## a value of 2 is used to just flush logs and then shutdown cold. -#SET @@global.ndb_log_update_as_write = 2; -#SELECT @@global.ndb_log_update_as_write; - ---echo '#--------------------FN_DYNVARS_102_04-------------------------#' -########################################################################### -# Change the value of ndb_log_update_as_write to invalid value # -########################################################################### - -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = -1; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = TRU; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = TRUE_F; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = FALS; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = OON; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = ONN; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = OOFF; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = 0FF; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = ' 1'; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_update_as_write = "0 "; - - - ---echo '#-------------------FN_DYNVARS_102_05----------------------------#' -########################################################################### -# Test if accessing session ndb_log_update_as_write gives error # -########################################################################### - -#--Error ER_LOCAL_VARIABLE -#SET @@session.ndb_log_update_as_write = 0; -#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR -#SET @@ndb_log_update_as_write = 0; -#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR -#SET @@local.ndb_log_update_as_write = 0; -#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR -#SELECT @@session.ndb_log_update_as_write; -#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR -#SELECT @@local.ndb_log_update_as_write; - ---echo '#----------------------FN_DYNVARS_102_06------------------------#' -######################################################################### -# Check if the value in SESSION Table contains variable value # -######################################################################### - -#SELECT count(VARIABLE_VALUE) AS res_is_0 FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='ndb_log_update_as_write'; - - ---echo '#----------------------FN_DYNVARS_102_07------------------------#' -######################################################################### -# Check if the value in GLOBAL Table matches value in variable # -######################################################################### - -#SELECT @@global.ndb_log_update_as_write = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='ndb_log_update_as_write'; - - ---echo '#---------------------FN_DYNVARS_102_08-------------------------#' -################################################################### -# Check if ON and OFF values can be used on variable # -################################################################### - -#SET @@ndb_log_update_as_write = OFF; -#SELECT @@ndb_log_update_as_write; -#SET @@ndb_log_update_as_write = ON; -#SELECT @@ndb_log_update_as_write; - ---echo '#---------------------FN_DYNVARS_102_09----------------------#' -################################################################### -# Check if TRUE and FALSE values can be used on variable # -################################################################### - -#SET @@ndb_log_update_as_write = TRUE; -#SELECT @@ndb_log_update_as_write; -#SET @@ndb_log_update_as_write = 'FALSE'; -#SELECT @@ndb_log_update_as_write; - -############################## -# Restore initial value # -############################## - -#SET @@ndb_log_update_as_write = @global_start_value; -#SELECT @@ndb_log_update_as_write; - -######################################################################## -# END OF ndb_log_update_as_write TESTS # -######################################################################## diff --git a/mysql-test/suite/sys_vars/t/ndb_log_updated_only_basic.test b/mysql-test/suite/sys_vars/t/ndb_log_updated_only_basic.test deleted file mode 100644 index c00ecf2e2fa..00000000000 --- a/mysql-test/suite/sys_vars/t/ndb_log_updated_only_basic.test +++ /dev/null @@ -1,216 +0,0 @@ -############## mysql-test\t\ndb_log_updated_only_basic.test ############### -# # -# Variable Name: ndb_log_updated_only # -# Scope: GLOBAL # -# Access Type: Dynamic # -# Data Type: boolean # -# Default Value: # -# Range: # -# # -# # -# Creation Date: 2008-02-07 # -# Author: Rizwan # -# # -# Description: Test Cases of Dynamic System Variable ndb_log_updated_only # -# that checks the behavior of this variable in the following ways# -# * Default Value # -# * Valid & Invalid values # -# * Scope & Access method # -# * Data Integrity # -# # -# Reference: http://dev.mysql.com/doc/refman/5.1/en/ # -# server-system-variables.html # -# # -############################################################################### -############## mysql-test\t\ndb_log_updated_only_basic.test ################ -# # -# Variable Name: ndb_log_updated_only # -# Scope: GLOBAL & SESSION # -# Access Type: Dynamic # -# Data Type: Numeric # -# Default Value: 1 # -# Range: 1 - 65536 # -# # -# # -# Creation Date: 2008-02-07 # -# Author: Rizwan Maredia # -# # -# Description: Test Cases of Dynamic System Variable ndb_log_updated_only # -# that checks the behavior of this variable in the following ways # -# * Default Value # -# * Valid & Invalid values # -# * Scope & Access method # -# * Data Integrity # -# # -# Reference: http://dev.mysql.com/doc/refman/5.1/en/ # -# server-system-variables.html # -# # -################################################################################ -################# mysql-test\t\ndb_log_updated_only_basic.test ######### -# # -# # -# Creation Date: 2008-02-07 # -# Author: Rizwan Maredia # -# # -# Description: Test Cases of Dynamic System Variable # -# ndb_log_updated_only that check behavior of this # -# variable with valid values, invalid values, # -# accessing variable with scope that is # -# allowed and with scope that is now allowed. # -# Scope: Global # -# Reference: http://dev.mysql.com/doc/refman/5.1/en/server-system # -# -variables.html # -# # -######################################################################## - ---source include/load_sysvars.inc - -######################################################################## -# START OF ndb_log_updated_only TESTS # -######################################################################## - - -################################################################################ -# Saving initial value of ndb_log_updated_only in a temporary variable # -################################################################################ - - ---Error ER_UNKNOWN_SYSTEM_VARIABLE -SET @global_start_value = @@global.ndb_log_updated_only; ---Error ER_UNKNOWN_SYSTEM_VARIABLE -SELECT @@global.ndb_log_updated_only; - ---echo 'Bug: The value is not a system variable or atleast not supported in version 5.1.22' - - ---echo '#--------------------FN_DYNVARS_103_01------------------------#' -######################################################################## -# Display the DEFAULT value of ndb_log_updated_only # -######################################################################## - -#SET @@ndb_log_updated_only = 0; -#SET @@ndb_log_updated_only = DEFAULT; -#SELECT @@ndb_log_updated_only; -# -#SET @@ndb_log_updated_only = 1; -#SET @@ndb_log_updated_only = DEFAULT; -#SELECT @@ndb_log_updated_only; - - ---echo '#---------------------FN_DYNVARS_103_02-------------------------#' -############################################################################# -# Check if ndb_log_updated_only can be accessed with and without @@ sign # -############################################################################# - -#SET ndb_log_updated_only = 1; -#SELECT @@ndb_log_updated_only; -#--Error ER_UNKNOWN_TABLE -#SELECT global.ndb_log_updated_only; -# -#SET global ndb_log_updated_only = 1; -#SELECT @@global.ndb_log_updated_only; - - ---echo '#--------------------FN_DYNVARS_103_03------------------------#' -######################################################################## -# Change the value of ndb_log_updated_only to a valid value # -######################################################################## - -#SET @@global.ndb_log_updated_only = 0; -#SELECT @@global.ndb_log_updated_only; -#SET @@global.ndb_log_updated_only = 1; -#SELECT @@global.ndb_log_updated_only; -## a value of 2 is used to just flush logs and then shutdown cold. -#SET @@global.ndb_log_updated_only = 2; -#SELECT @@global.ndb_log_updated_only; - ---echo '#--------------------FN_DYNVARS_103_04-------------------------#' -########################################################################### -# Change the value of ndb_log_updated_only to invalid value # -########################################################################### - -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = -1; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = TRU; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = TRUE_F; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = FALS; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = OON; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = ONN; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = OOFF; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = 0FF; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = ' 1'; -#--Error ER_WRONG_VALUE_FOR_VAR -#SET @@global.ndb_log_updated_only = "0 "; - - - ---echo '#-------------------FN_DYNVARS_103_05----------------------------#' -########################################################################### -# Test if accessing session ndb_log_updated_only gives error # -########################################################################### - -#--Error ER_LOCAL_VARIABLE -#SET @@session.ndb_log_updated_only = 0; -#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR -#SET @@ndb_log_updated_only = 0; -#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR -#SET @@local.ndb_log_updated_only = 0; -#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR -#SELECT @@session.ndb_log_updated_only; -#--Error ER_INCORRECT_GLOBAL_LOCAL_VAR -#SELECT @@local.ndb_log_updated_only; - ---echo '#----------------------FN_DYNVARS_103_06------------------------#' -######################################################################### -# Check if the value in SESSION Table contains variable value # -######################################################################### - -#SELECT count(VARIABLE_VALUE) AS res_is_0 FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='ndb_log_updated_only'; - - ---echo '#----------------------FN_DYNVARS_103_07------------------------#' -######################################################################### -# Check if the value in GLOBAL Table matches value in variable # -######################################################################### - -#SELECT @@global.ndb_log_updated_only = VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME='ndb_log_updated_only'; - - ---echo '#---------------------FN_DYNVARS_103_08-------------------------#' -################################################################### -# Check if ON and OFF values can be used on variable # -################################################################### - -#SET @@ndb_log_updated_only = OFF; -#SELECT @@ndb_log_updated_only; -#SET @@ndb_log_updated_only = ON; -#SELECT @@ndb_log_updated_only; - ---echo '#---------------------FN_DYNVARS_103_09----------------------#' -################################################################### -# Check if TRUE and FALSE values can be used on variable # -################################################################### - -#SET @@ndb_log_updated_only = TRUE; -#SELECT @@ndb_log_updated_only; -#SET @@ndb_log_updated_only = 'FALSE'; -#SELECT @@ndb_log_updated_only; - -############################## -# Restore initial value # -############################## - -#SET @@ndb_log_updated_only = @global_start_value; -#SELECT @@ndb_log_updated_only; - -######################################################################## -# END OF ndb_log_updated_only TESTS # -######################################################################## From e5ad41716bf2daf5e270514750e9c8beed165f34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 15 Nov 2012 20:30:36 +0200 Subject: [PATCH 034/324] Bug#15874001 CREATE INDEX ON A UTF8 CHAR COLUMN FAILS WITH ROW_FORMAT=REDUNDANT CHAR(n) in ROW_FORMAT=REDUNDANT tables is always fixed-length (n*mbmaxlen bytes), but in the temporary file it is variable-length (n*mbminlen to n*mbmaxlen bytes) for variable-length character sets, such as UTF-8. The temporary file format used during index creation and online ALTER TABLE is based on ROW_FORMAT=COMPACT. Thus, it should use the variable-length encoding even if the base table is in ROW_FORMAT=REDUNDNAT. dtype_get_fixed_size_low(): Replace an assertion-like check with a debug assertion. rec_init_offsets_comp_ordinary(), rec_convert_dtuple_to_rec_comp(): Make this an inline function. Replace 'ulint extra' with 'bool temp'. rec_get_converted_size_comp_prefix_low(): Renamed from rec_get_converted_size_comp_prefix(), and made inline. Add the parameter 'bool temp'. If temp=true, do not add REC_N_NEW_EXTRA_BYTES. rec_get_converted_size_comp_prefix(): Remove the comment about dict_table_is_comp(). This function is only to be called for other than ROW_FORMAT=REDUNDANT records. rec_get_converted_size_temp(): New function for computing temporary file record size. Omit REC_N_NEW_EXTRA_BYTES from the sizes. rec_init_offsets_temp(), rec_convert_dtuple_to_temp(): New functions, for operating on temporary file records. rb:1559 approved by Jimmy Yang --- storage/innodb_plugin/ChangeLog | 7 + storage/innodb_plugin/include/data0type.ic | 28 +-- storage/innodb_plugin/include/rem0rec.h | 80 +++---- storage/innodb_plugin/rem/rem0rec.c | 237 +++++++++++++++------ storage/innodb_plugin/row/row0merge.c | 44 ++-- 5 files changed, 251 insertions(+), 145 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index f69f9e16904..5387555d24f 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,10 @@ +2012-11-15 The InnoDB Team + + * include/data0type.ic, include/rem0rec.h, + rem/rem0rec.c, row/row0merge.c: + Fix Bug#15874001 CREATE INDEX ON A UTF8 CHAR COLUMN FAILS WITH + ROW_FORMAT=REDUNDANT + 2012-10-18 The InnoDB Team * row/row0sel.c: diff --git a/storage/innodb_plugin/include/data0type.ic b/storage/innodb_plugin/include/data0type.ic index 2bf67a941bd..8a838e32689 100644 --- a/storage/innodb_plugin/include/data0type.ic +++ b/storage/innodb_plugin/include/data0type.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved. +Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. 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 @@ -439,34 +439,16 @@ dtype_get_fixed_size_low( } else if (!comp) { return(len); } else { - /* We play it safe here and ask MySQL for - mbminlen and mbmaxlen. Although - mbminlen and mbmaxlen are - initialized if and only if prtype - is (in one of the 3 functions in this file), - it could be that none of these functions - has been called. */ - +#ifdef UNIV_DEBUG ulint i_mbminlen, i_mbmaxlen; innobase_get_cset_width( dtype_get_charset_coll(prtype), &i_mbminlen, &i_mbmaxlen); - if (UNIV_UNLIKELY(mbminlen != i_mbminlen) - || UNIV_UNLIKELY(mbmaxlen != i_mbmaxlen)) { - - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: " - "mbminlen=%lu, " - "mbmaxlen=%lu, " - "type->mbminlen=%lu, " - "type->mbmaxlen=%lu\n", - (ulong) i_mbminlen, - (ulong) i_mbmaxlen, - (ulong) mbminlen, - (ulong) mbmaxlen); - } + ut_ad(mbminlen == i_mbminlen); + ut_ad(mbmaxlen == i_mbmaxlen); +#endif /* UNIV_DEBUG */ if (mbminlen == mbmaxlen) { return(len); } diff --git a/storage/innodb_plugin/include/rem0rec.h b/storage/innodb_plugin/include/rem0rec.h index 06de23be757..0666c43a026 100644 --- a/storage/innodb_plugin/include/rem0rec.h +++ b/storage/innodb_plugin/include/rem0rec.h @@ -361,24 +361,6 @@ rec_get_offsets_func( #define rec_get_offsets(rec,index,offsets,n,heap) \ rec_get_offsets_func(rec,index,offsets,n,heap,__FILE__,__LINE__) -/******************************************************//** -Determine the offset to each field in a leaf-page record -in ROW_FORMAT=COMPACT. This is a special case of -rec_init_offsets() and rec_get_offsets_func(). */ -UNIV_INTERN -void -rec_init_offsets_comp_ordinary( -/*===========================*/ - const rec_t* rec, /*!< in: physical record in - ROW_FORMAT=COMPACT */ - ulint extra, /*!< in: number of bytes to reserve - between the record header and - the data payload - (usually REC_N_NEW_EXTRA_BYTES) */ - const dict_index_t* index, /*!< in: record descriptor */ - ulint* offsets);/*!< in/out: array of offsets; - in: n=rec_offs_n_fields(offsets) */ - /******************************************************//** The following function determines the offsets to each field in the record. It can reuse a previously allocated array. */ @@ -639,8 +621,48 @@ rec_copy( /*=====*/ void* buf, /*!< in: buffer */ const rec_t* rec, /*!< in: physical record */ - const ulint* offsets);/*!< in: array returned by rec_get_offsets() */ + const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ + __attribute__((nonnull)); #ifndef UNIV_HOTBACKUP +/**********************************************************//** +Determines the size of a data tuple prefix in a temporary file. +@return total size */ +UNIV_INTERN +ulint +rec_get_converted_size_temp( +/*========================*/ + const dict_index_t* index, /*!< in: record descriptor */ + const dfield_t* fields, /*!< in: array of data fields */ + ulint n_fields,/*!< in: number of data fields */ + ulint* extra) /*!< out: extra size */ + __attribute__((warn_unused_result, nonnull)); + +/******************************************************//** +Determine the offset to each field in temporary file. +@see rec_convert_dtuple_to_temp() */ +UNIV_INTERN +void +rec_init_offsets_temp( +/*==================*/ + const rec_t* rec, /*!< in: temporary file record */ + const dict_index_t* index, /*!< in: record descriptor */ + ulint* offsets)/*!< in/out: array of offsets; + in: n=rec_offs_n_fields(offsets) */ + __attribute__((nonnull)); + +/*********************************************************//** +Builds a temporary file record out of a data tuple. +@see rec_init_offsets_temp() */ +UNIV_INTERN +void +rec_convert_dtuple_to_temp( +/*=======================*/ + rec_t* rec, /*!< out: record */ + const dict_index_t* index, /*!< in: record descriptor */ + const dfield_t* fields, /*!< in: array of data fields */ + ulint n_fields) /*!< in: number of fields */ + __attribute__((nonnull)); + /**************************************************************//** Copies the first n fields of a physical record to a new physical record in a buffer. @@ -675,21 +697,6 @@ rec_fold( __attribute__((pure)); #endif /* !UNIV_HOTBACKUP */ /*********************************************************//** -Builds a ROW_FORMAT=COMPACT record out of a data tuple. */ -UNIV_INTERN -void -rec_convert_dtuple_to_rec_comp( -/*===========================*/ - rec_t* rec, /*!< in: origin of record */ - ulint extra, /*!< in: number of bytes to - reserve between the record - header and the data payload - (normally REC_N_NEW_EXTRA_BYTES) */ - const dict_index_t* index, /*!< in: record descriptor */ - ulint status, /*!< in: status bits of the record */ - const dfield_t* fields, /*!< in: array of data fields */ - ulint n_fields);/*!< in: number of data fields */ -/*********************************************************//** Builds a physical record out of a data tuple and stores it into the given buffer. @return pointer to the origin of physical record */ @@ -722,10 +729,7 @@ UNIV_INTERN ulint rec_get_converted_size_comp_prefix( /*===============================*/ - const dict_index_t* index, /*!< in: record descriptor; - dict_table_is_comp() is - assumed to hold, even if - it does not */ + const dict_index_t* index, /*!< in: record descriptor */ const dfield_t* fields, /*!< in: array of data fields */ ulint n_fields,/*!< in: number of data fields */ ulint* extra); /*!< out: extra size */ diff --git a/storage/innodb_plugin/rem/rem0rec.c b/storage/innodb_plugin/rem/rem0rec.c index 9f90d2940dd..70d38262bce 100644 --- a/storage/innodb_plugin/rem/rem0rec.c +++ b/storage/innodb_plugin/rem/rem0rec.c @@ -167,7 +167,6 @@ rec_get_n_extern_new( { const byte* nulls; const byte* lens; - dict_field_t* field; ulint null_mask; ulint n_extern; ulint i; @@ -188,10 +187,13 @@ rec_get_n_extern_new( /* read the lengths of fields 0..n */ do { - ulint len; + const dict_field_t* field + = dict_index_get_nth_field(index, i); + const dict_col_t* col + = dict_field_get_col(field); + ulint len; - field = dict_index_get_nth_field(index, i); - if (!(dict_field_get_col(field)->prtype & DATA_NOT_NULL)) { + if (!(col->prtype & DATA_NOT_NULL)) { /* nullable field => read the null flag */ if (UNIV_UNLIKELY(!(byte) null_mask)) { @@ -209,8 +211,6 @@ rec_get_n_extern_new( if (UNIV_UNLIKELY(!field->fixed_len)) { /* Variable-length field: read the length */ - const dict_col_t* col - = dict_field_get_col(field); len = *lens--; /* If the maximum length of the field is up to 255 bytes, the actual length is always @@ -239,16 +239,15 @@ rec_get_n_extern_new( Determine the offset to each field in a leaf-page record in ROW_FORMAT=COMPACT. This is a special case of rec_init_offsets() and rec_get_offsets_func(). */ -UNIV_INTERN +UNIV_INLINE __attribute__((nonnull)) void rec_init_offsets_comp_ordinary( /*===========================*/ const rec_t* rec, /*!< in: physical record in ROW_FORMAT=COMPACT */ - ulint extra, /*!< in: number of bytes to reserve - between the record header and - the data payload - (usually REC_N_NEW_EXTRA_BYTES) */ + ibool temp, /*!< in: whether to use the + format for temporary files in + index creation */ const dict_index_t* index, /*!< in: record descriptor */ ulint* offsets)/*!< in/out: array of offsets; in: n=rec_offs_n_fields(offsets) */ @@ -256,27 +255,38 @@ rec_init_offsets_comp_ordinary( ulint i = 0; ulint offs = 0; ulint any_ext = 0; - const byte* nulls = rec - (extra + 1); + const byte* nulls = temp + ? rec - 1 + : rec - (1 + REC_N_NEW_EXTRA_BYTES); const byte* lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); - dict_field_t* field; ulint null_mask = 1; #ifdef UNIV_DEBUG - /* We cannot invoke rec_offs_make_valid() here, because it can hold - that extra != REC_N_NEW_EXTRA_BYTES. Similarly, rec_offs_validate() - will fail in that case, because it invokes rec_get_status(). */ + /* We cannot invoke rec_offs_make_valid() here if temp=TRUE. + Similarly, rec_offs_validate() will fail in that case, because + it invokes rec_get_status(). */ offsets[2] = (ulint) rec; offsets[3] = (ulint) index; #endif /* UNIV_DEBUG */ + ut_ad(temp || dict_table_is_comp(index->table)); + + if (temp && dict_table_is_comp(index->table)) { + /* No need to do adjust fixed_len=0. We only need to + adjust it for ROW_FORMAT=REDUNDANT. */ + temp = FALSE; + } + /* read the lengths of fields 0..n */ do { - ulint len; + const dict_field_t* field + = dict_index_get_nth_field(index, i); + const dict_col_t* col + = dict_field_get_col(field); + ulint len; - field = dict_index_get_nth_field(index, i); - if (!(dict_field_get_col(field)->prtype - & DATA_NOT_NULL)) { + if (!(col->prtype & DATA_NOT_NULL)) { /* nullable field => read the null flag */ if (UNIV_UNLIKELY(!(byte) null_mask)) { @@ -296,10 +306,9 @@ rec_init_offsets_comp_ordinary( null_mask <<= 1; } - if (UNIV_UNLIKELY(!field->fixed_len)) { + if (!field->fixed_len + || (temp && !dict_col_get_fixed_size(col, temp))) { /* Variable-length field: read the length */ - const dict_col_t* col - = dict_field_get_col(field); len = *lens--; /* If the maximum length of the field is up to 255 bytes, the actual length is always @@ -393,9 +402,8 @@ rec_init_offsets( = dict_index_get_n_unique_in_tree(index); break; case REC_STATUS_ORDINARY: - rec_init_offsets_comp_ordinary(rec, - REC_N_NEW_EXTRA_BYTES, - index, offsets); + rec_init_offsets_comp_ordinary( + rec, FALSE, index, offsets); return; } @@ -766,17 +774,19 @@ rec_get_nth_field_offs_old( /**********************************************************//** Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. @return total size */ -UNIV_INTERN +UNIV_INLINE __attribute__((warn_unused_result, nonnull(1,2))) ulint -rec_get_converted_size_comp_prefix( -/*===============================*/ +rec_get_converted_size_comp_prefix_low( +/*===================================*/ const dict_index_t* index, /*!< in: record descriptor; dict_table_is_comp() is assumed to hold, even if it does not */ const dfield_t* fields, /*!< in: array of data fields */ ulint n_fields,/*!< in: number of data fields */ - ulint* extra) /*!< out: extra size */ + ulint* extra, /*!< out: extra size */ + ibool temp) /*!< in: whether this is a + temporary file record */ { ulint extra_size; ulint data_size; @@ -785,15 +795,25 @@ rec_get_converted_size_comp_prefix( ut_ad(fields); ut_ad(n_fields > 0); ut_ad(n_fields <= dict_index_get_n_fields(index)); + ut_ad(!temp || extra); - extra_size = REC_N_NEW_EXTRA_BYTES + extra_size = temp + ? UT_BITS_IN_BYTES(index->n_nullable) + : REC_N_NEW_EXTRA_BYTES + UT_BITS_IN_BYTES(index->n_nullable); data_size = 0; + if (temp && dict_table_is_comp(index->table)) { + /* No need to do adjust fixed_len=0. We only need to + adjust it for ROW_FORMAT=REDUNDANT. */ + temp = FALSE; + } + /* read the lengths of fields 0..n */ for (i = 0; i < n_fields; i++) { const dict_field_t* field; ulint len; + ulint fixed_len; const dict_col_t* col; field = dict_index_get_nth_field(index, i); @@ -809,8 +829,14 @@ rec_get_converted_size_comp_prefix( continue; } - ut_ad(len <= col->len || col->mtype == DATA_BLOB); + ut_ad(len <= col->len || col->mtype == DATA_BLOB + || (col->len == 0 && col->mtype == DATA_VARCHAR)); + fixed_len = field->fixed_len; + if (temp && fixed_len + && !dict_col_get_fixed_size(col, temp)) { + fixed_len = 0; + } /* If the maximum length of a variable-length field is up to 255 bytes, the actual length is always stored in one byte. If the maximum length is more than 255 @@ -818,11 +844,11 @@ rec_get_converted_size_comp_prefix( 0..127. The length will be encoded in two bytes when it is 128 or more, or when the field is stored externally. */ - if (field->fixed_len) { - ut_ad(len == field->fixed_len); + if (fixed_len) { + ut_ad(len == fixed_len); /* dict_index_add_col() should guarantee this */ ut_ad(!field->prefix_len - || field->fixed_len == field->prefix_len); + || fixed_len == field->prefix_len); } else if (dfield_is_ext(&fields[i])) { ut_ad(col->len >= 256 || col->mtype == DATA_BLOB); extra_size += 2; @@ -839,13 +865,30 @@ rec_get_converted_size_comp_prefix( data_size += len; } - if (UNIV_LIKELY_NULL(extra)) { + if (extra) { *extra = extra_size; } return(extra_size + data_size); } +/**********************************************************//** +Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. +@return total size */ +UNIV_INTERN +ulint +rec_get_converted_size_comp_prefix( +/*===============================*/ + const dict_index_t* index, /*!< in: record descriptor */ + const dfield_t* fields, /*!< in: array of data fields */ + ulint n_fields,/*!< in: number of data fields */ + ulint* extra) /*!< out: extra size */ +{ + ut_ad(dict_table_is_comp(index->table)); + return(rec_get_converted_size_comp_prefix_low( + index, fields, n_fields, extra, FALSE)); +} + /**********************************************************//** Determines the size of a data tuple in ROW_FORMAT=COMPACT. @return total size */ @@ -890,8 +933,8 @@ rec_get_converted_size_comp( return(ULINT_UNDEFINED); } - return(size + rec_get_converted_size_comp_prefix(index, fields, - n_fields, extra)); + return(size + rec_get_converted_size_comp_prefix_low( + index, fields, n_fields, extra, FALSE)); } /***********************************************************//** @@ -1068,19 +1111,18 @@ rec_convert_dtuple_to_rec_old( /*********************************************************//** Builds a ROW_FORMAT=COMPACT record out of a data tuple. */ -UNIV_INTERN +UNIV_INLINE __attribute__((nonnull)) void rec_convert_dtuple_to_rec_comp( /*===========================*/ rec_t* rec, /*!< in: origin of record */ - ulint extra, /*!< in: number of bytes to - reserve between the record - header and the data payload - (normally REC_N_NEW_EXTRA_BYTES) */ const dict_index_t* index, /*!< in: record descriptor */ - ulint status, /*!< in: status bits of the record */ const dfield_t* fields, /*!< in: array of data fields */ - ulint n_fields)/*!< in: number of data fields */ + ulint n_fields,/*!< in: number of data fields */ + ulint status, /*!< in: status bits of the record */ + ibool temp) /*!< in: whether to use the + format for temporary files in + index creation */ { const dfield_t* field; const dtype_t* type; @@ -1092,31 +1134,44 @@ rec_convert_dtuple_to_rec_comp( ulint n_node_ptr_field; ulint fixed_len; ulint null_mask = 1; - ut_ad(extra == 0 || dict_table_is_comp(index->table)); - ut_ad(extra == 0 || extra == REC_N_NEW_EXTRA_BYTES); + ut_ad(temp || dict_table_is_comp(index->table)); ut_ad(n_fields > 0); - switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) { - case REC_STATUS_ORDINARY: + if (temp) { + ut_ad(status == REC_STATUS_ORDINARY); ut_ad(n_fields <= dict_index_get_n_fields(index)); n_node_ptr_field = ULINT_UNDEFINED; - break; - case REC_STATUS_NODE_PTR: - ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1); - n_node_ptr_field = n_fields - 1; - break; - case REC_STATUS_INFIMUM: - case REC_STATUS_SUPREMUM: - ut_ad(n_fields == 1); - n_node_ptr_field = ULINT_UNDEFINED; - break; - default: - ut_error; - return; + nulls = rec - 1; + if (dict_table_is_comp(index->table)) { + /* No need to do adjust fixed_len=0. We only + need to adjust it for ROW_FORMAT=REDUNDANT. */ + temp = FALSE; + } + } else { + nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); + + switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) { + case REC_STATUS_ORDINARY: + ut_ad(n_fields <= dict_index_get_n_fields(index)); + n_node_ptr_field = ULINT_UNDEFINED; + break; + case REC_STATUS_NODE_PTR: + ut_ad(n_fields + == dict_index_get_n_unique_in_tree(index) + 1); + n_node_ptr_field = n_fields - 1; + break; + case REC_STATUS_INFIMUM: + case REC_STATUS_SUPREMUM: + ut_ad(n_fields == 1); + n_node_ptr_field = ULINT_UNDEFINED; + break; + default: + ut_error; + return; + } } end = rec; - nulls = rec - (extra + 1); lens = nulls - UT_BITS_IN_BYTES(index->n_nullable); /* clear the SQL-null flags */ memset(lens + 1, 0, nulls - lens); @@ -1162,6 +1217,10 @@ rec_convert_dtuple_to_rec_comp( ifield = dict_index_get_nth_field(index, i); fixed_len = ifield->fixed_len; + if (temp && fixed_len + && !dict_col_get_fixed_size(ifield->col, temp)) { + fixed_len = 0; + } /* If the maximum length of a variable-length field is up to 255 bytes, the actual length is always stored in one byte. If the maximum length is more than 255 @@ -1222,8 +1281,7 @@ rec_convert_dtuple_to_rec_new( rec = buf + extra_size; rec_convert_dtuple_to_rec_comp( - rec, REC_N_NEW_EXTRA_BYTES, index, status, - dtuple->fields, dtuple->n_fields); + rec, index, dtuple->fields, dtuple->n_fields, status, FALSE); /* Set the info bits of the record */ rec_set_info_and_status_bits(rec, dtuple_get_info_bits(dtuple)); @@ -1285,6 +1343,54 @@ rec_convert_dtuple_to_rec( return(rec); } +#ifndef UNIV_HOTBACKUP +/**********************************************************//** +Determines the size of a data tuple prefix in ROW_FORMAT=COMPACT. +@return total size */ +UNIV_INTERN +ulint +rec_get_converted_size_temp( +/*========================*/ + const dict_index_t* index, /*!< in: record descriptor */ + const dfield_t* fields, /*!< in: array of data fields */ + ulint n_fields,/*!< in: number of data fields */ + ulint* extra) /*!< out: extra size */ +{ + return(rec_get_converted_size_comp_prefix_low( + index, fields, n_fields, extra, TRUE)); +} + +/******************************************************//** +Determine the offset to each field in temporary file. +@see rec_convert_dtuple_to_temp() */ +UNIV_INTERN +void +rec_init_offsets_temp( +/*==================*/ + const rec_t* rec, /*!< in: temporary file record */ + const dict_index_t* index, /*!< in: record descriptor */ + ulint* offsets)/*!< in/out: array of offsets; + in: n=rec_offs_n_fields(offsets) */ +{ + rec_init_offsets_comp_ordinary(rec, TRUE, index, offsets); +} + +/*********************************************************//** +Builds a temporary file record out of a data tuple. +@see rec_init_offsets_temp() */ +UNIV_INTERN +void +rec_convert_dtuple_to_temp( +/*=======================*/ + rec_t* rec, /*!< out: record */ + const dict_index_t* index, /*!< in: record descriptor */ + const dfield_t* fields, /*!< in: array of data fields */ + ulint n_fields) /*!< in: number of fields */ +{ + rec_convert_dtuple_to_rec_comp(rec, index, fields, n_fields, + REC_STATUS_ORDINARY, TRUE); +} + /**************************************************************//** Copies the first n fields of a physical record to a data tuple. The fields are copied to the memory heap. */ @@ -1495,6 +1601,7 @@ rec_copy_prefix_to_buf( return(*buf + (rec - (lens + 1))); } +#endif /* UNIV_HOTBACKUP */ /***************************************************************//** Validates the consistency of an old-style physical record. diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 342d81256f2..5a8d2de968f 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -291,6 +291,7 @@ row_merge_buf_add( const dict_field_t* ifield; const dict_col_t* col; ulint col_no; + ulint fixed_len; const dfield_t* row_field; ulint len; @@ -340,9 +341,21 @@ row_merge_buf_add( ut_ad(len <= col->len || col->mtype == DATA_BLOB); - if (ifield->fixed_len) { - ut_ad(len == ifield->fixed_len); + fixed_len = ifield->fixed_len; + if (fixed_len && !dict_table_is_comp(index->table) + && col->mbminlen != col->mbmaxlen) { + /* CHAR in ROW_FORMAT=REDUNDANT is always + fixed-length, but in the temporary file it is + variable-length for variable-length character + sets. */ + fixed_len = 0; + } + + if (fixed_len) { + ut_ad(len == fixed_len); ut_ad(!dfield_is_ext(field)); + ut_ad(!col->mbmaxlen || len >= col->mbminlen + * (fixed_len / col->mbmaxlen)); } else if (dfield_is_ext(field)) { extra_size += 2; } else if (len < 128 @@ -363,12 +376,11 @@ row_merge_buf_add( ulint size; ulint extra; - size = rec_get_converted_size_comp(index, - REC_STATUS_ORDINARY, - entry, n_fields, &extra); + size = rec_get_converted_size_temp( + index, entry, n_fields, &extra); - ut_ad(data_size + extra_size + REC_N_NEW_EXTRA_BYTES == size); - ut_ad(extra_size + REC_N_NEW_EXTRA_BYTES == extra); + ut_ad(data_size + extra_size == size); + ut_ad(extra_size == extra); } #endif /* UNIV_DEBUG */ @@ -572,14 +584,9 @@ row_merge_buf_write( ulint extra_size; const dfield_t* entry = buf->tuples[i]; - size = rec_get_converted_size_comp(index, - REC_STATUS_ORDINARY, - entry, n_fields, - &extra_size); + size = rec_get_converted_size_temp( + index, entry, n_fields, &extra_size); ut_ad(size >= extra_size); - ut_ad(extra_size >= REC_N_NEW_EXTRA_BYTES); - extra_size -= REC_N_NEW_EXTRA_BYTES; - size -= REC_N_NEW_EXTRA_BYTES; /* Encode extra_size + 1 */ if (extra_size + 1 < 0x80) { @@ -592,9 +599,8 @@ row_merge_buf_write( ut_ad(b + size < block[1]); - rec_convert_dtuple_to_rec_comp(b + extra_size, 0, index, - REC_STATUS_ORDINARY, - entry, n_fields); + rec_convert_dtuple_to_temp(b + extra_size, index, + entry, n_fields); b += size; @@ -841,7 +847,7 @@ err_exit: *mrec = *buf + extra_size; - rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets); + rec_init_offsets_temp(*mrec, index, offsets); data_size = rec_offs_data_size(offsets); @@ -860,7 +866,7 @@ err_exit: *mrec = b + extra_size; - rec_init_offsets_comp_ordinary(*mrec, 0, index, offsets); + rec_init_offsets_temp(*mrec, index, offsets); data_size = rec_offs_data_size(offsets); ut_ad(extra_size + data_size < sizeof *buf); From e882efe64a17f7e0c0bb45b7b69db6cd24cf04e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 15 Nov 2012 22:05:08 +0200 Subject: [PATCH 035/324] Bug#15872736 FAILING ASSERTION Remove a bogus debug assertion. --- storage/innodb_plugin/handler/handler0alter.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/innodb_plugin/handler/handler0alter.cc b/storage/innodb_plugin/handler/handler0alter.cc index 0422abb0021..b3ecd02f575 100644 --- a/storage/innodb_plugin/handler/handler0alter.cc +++ b/storage/innodb_plugin/handler/handler0alter.cc @@ -98,7 +98,6 @@ innobase_col_to_mysql( case DATA_MYSQL: ut_ad(flen >= len); ut_ad(col->mbmaxlen >= col->mbminlen); - ut_ad(col->mbmaxlen > col->mbminlen || flen == len); memcpy(dest, data, len); break; From a2b10fc59076ad3ea4483cb9cb36369c345852d5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 16 Nov 2012 14:43:10 +0530 Subject: [PATCH 036/324] From a46adb0f9827e8b06c76591b5da3adea4a0b6301 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Fri, 16 Nov 2012 09:02:35 -0500 Subject: [PATCH 037/324] Bug#15859402 INNODB_BUFFER_POOL_READ_AHEAD_EVICTED IS INACCURATE rb://1546 approved by: Sunny Bains and Marko Makela Our dealing of buf_page_t::access_time flag is inaccurate. * If LRU eviction has not started we don't set the access_time * If LRU eviction is started we set it only if the block is not 'too old'. * Not a correctness issue but we hold buf_pool::mutex when setting the flag This patch fixes this by: * Setting flag unconditionally whenever the first page access happens * Use buf_page_t mutex to protect write to the flag --- storage/innodb_plugin/buf/buf0buf.c | 80 +++++++++--------------- storage/innodb_plugin/include/buf0buf.h | 10 +-- storage/innodb_plugin/include/buf0buf.ic | 8 +-- 3 files changed, 37 insertions(+), 61 deletions(-) diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index b49f5288681..755fa947c8f 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -1108,32 +1108,21 @@ buf_page_make_young( } /********************************************************************//** -Sets the time of the first access of a page and moves a page to the -start of the buffer pool LRU list if it is too old. This high-level -function can be used to prevent an important page from slipping -out of the buffer pool. */ +Moves a page to the start of the buffer pool LRU list if it is too old. +This high-level function can be used to prevent an important page from +slipping out of the buffer pool. */ static void -buf_page_set_accessed_make_young( -/*=============================*/ - buf_page_t* bpage, /*!< in/out: buffer block of a +buf_page_make_young_if_needed( +/*==========================*/ + buf_page_t* bpage) /*!< in/out: buffer block of a file page */ - unsigned access_time) /*!< in: bpage->access_time - read under mutex protection, - or 0 if unknown */ { ut_ad(!buf_pool_mutex_own()); ut_a(buf_page_in_file(bpage)); if (buf_page_peek_if_too_old(bpage)) { - buf_pool_mutex_enter(); - buf_LRU_make_block_young(bpage); - buf_pool_mutex_exit(); - } else if (!access_time) { - ulint time_ms = ut_time_ms(); - buf_pool_mutex_enter(); - buf_page_set_accessed(bpage, time_ms); - buf_pool_mutex_exit(); + buf_page_make_young(bpage); } } @@ -1217,7 +1206,6 @@ buf_page_get_zip( buf_page_t* bpage; mutex_t* block_mutex; ibool must_read; - unsigned access_time; #ifndef UNIV_LOG_DEBUG ut_ad(!ibuf_inside()); @@ -1284,13 +1272,14 @@ err_exit: got_block: must_read = buf_page_get_io_fix(bpage) == BUF_IO_READ; - access_time = buf_page_is_accessed(bpage); buf_pool_mutex_exit(); + buf_page_set_accessed(bpage); + mutex_exit(block_mutex); - buf_page_set_accessed_make_young(bpage, access_time); + buf_page_make_young_if_needed(bpage); #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG ut_a(!bpage->file_page_was_freed); @@ -1861,16 +1850,16 @@ wait_until_unfixed: buf_block_buf_fix_inc(block, file, line); - mutex_exit(&block->mutex); - - /* Check if this is the first access to the page */ + buf_pool_mutex_exit(); access_time = buf_page_is_accessed(&block->page); - buf_pool_mutex_exit(); + buf_page_set_accessed(&block->page); + + mutex_exit(&block->mutex); if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL)) { - buf_page_set_accessed_make_young(&block->page, access_time); + buf_page_make_young_if_needed(&block->page); } #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG @@ -1925,7 +1914,7 @@ wait_until_unfixed: mtr_memo_push(mtr, block, fix_type); - if (UNIV_LIKELY(mode != BUF_PEEK_IF_IN_POOL) && !access_time) { + if (mode != BUF_PEEK_IF_IN_POOL && !access_time) { /* In the case of a first access, try to apply linear read-ahead */ @@ -1975,15 +1964,13 @@ buf_page_optimistic_get( buf_block_buf_fix_inc(block, file, line); + access_time = buf_page_is_accessed(&block->page); + + buf_page_set_accessed(&block->page); + mutex_exit(&block->mutex); - /* Check if this is the first access to the page. - We do a dirty read on purpose, to avoid mutex contention. - This field is only used for heuristic purposes; it does not - affect correctness. */ - - access_time = buf_page_is_accessed(&block->page); - buf_page_set_accessed_make_young(&block->page, access_time); + buf_page_make_young_if_needed(&block->page); ut_ad(!ibuf_inside() || ibuf_page(buf_block_get_space(block), @@ -2035,7 +2022,7 @@ buf_page_optimistic_get( #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG ut_a(block->page.file_page_was_freed == FALSE); #endif - if (UNIV_UNLIKELY(!access_time)) { + if (!access_time) { /* In the case of a first access, try to apply linear read-ahead */ @@ -2095,22 +2082,12 @@ buf_page_get_known_nowait( buf_block_buf_fix_inc(block, file, line); + buf_page_set_accessed(&block->page); + mutex_exit(&block->mutex); - if (mode == BUF_MAKE_YOUNG && buf_page_peek_if_too_old(&block->page)) { - buf_pool_mutex_enter(); - buf_LRU_make_block_young(&block->page); - buf_pool_mutex_exit(); - } else if (!buf_page_is_accessed(&block->page)) { - /* Above, we do a dirty read on purpose, to avoid - mutex contention. The field buf_page_t::access_time - is only used for heuristic purposes. Writes to the - field must be protected by mutex, however. */ - ulint time_ms = ut_time_ms(); - - buf_pool_mutex_enter(); - buf_page_set_accessed(&block->page, time_ms); - buf_pool_mutex_exit(); + if (mode == BUF_MAKE_YOUNG) { + buf_page_make_young_if_needed(&block->page); } ut_ad(!ibuf_inside() || (mode == BUF_KEEP_OLD)); @@ -2542,7 +2519,6 @@ buf_page_create( buf_frame_t* frame; buf_block_t* block; buf_block_t* free_block = NULL; - ulint time_ms = ut_time_ms(); ut_ad(mtr); ut_ad(mtr->state == MTR_ACTIVE); @@ -2627,12 +2603,12 @@ buf_page_create( rw_lock_x_unlock(&block->lock); } - buf_page_set_accessed(&block->page, time_ms); - buf_pool_mutex_exit(); mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX); + buf_page_set_accessed(&block->page); + mutex_exit(&block->mutex); /* Delete possible entries for the page from the insert buffer: diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h index fd286f6c26c..b3fcff14f0d 100644 --- a/storage/innodb_plugin/include/buf0buf.h +++ b/storage/innodb_plugin/include/buf0buf.h @@ -927,8 +927,7 @@ UNIV_INLINE void buf_page_set_accessed( /*==================*/ - buf_page_t* bpage, /*!< in/out: control block */ - ulint time_ms) /*!< in: ut_time_ms() */ + buf_page_t* bpage) /*!< in/out: control block */ __attribute__((nonnull)); /*********************************************************************//** Gets the buf_block_t handle of a buffered file block if an uncompressed @@ -1260,10 +1259,11 @@ struct buf_page_struct{ to read this for heuristic purposes without holding any mutex or latch */ - unsigned access_time:32; /*!< time of first access, or - 0 if the block was never accessed - in the buffer pool */ /* @} */ + unsigned access_time; /*!< time of first access, or + 0 if the block was never accessed + in the buffer pool. Protected by + block mutex */ # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG ibool file_page_was_freed; /*!< this is set to TRUE when fsp diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic index 39135a2ece1..098ec379761 100644 --- a/storage/innodb_plugin/include/buf0buf.ic +++ b/storage/innodb_plugin/include/buf0buf.ic @@ -531,15 +531,15 @@ UNIV_INLINE void buf_page_set_accessed( /*==================*/ - buf_page_t* bpage, /*!< in/out: control block */ - ulint time_ms) /*!< in: ut_time_ms() */ + buf_page_t* bpage) /*!< in/out: control block */ { ut_a(buf_page_in_file(bpage)); - ut_ad(buf_pool_mutex_own()); + ut_ad(!buf_pool_mutex_own()); + ut_ad(mutex_own(buf_page_get_mutex(bpage))); if (!bpage->access_time) { /* Make this the time of the first access. */ - bpage->access_time = time_ms; + bpage->access_time = ut_time_ms(); } } From 64dcbd6a498e176d80e9315cc8ec965f6bcb9e5a Mon Sep 17 00:00:00 2001 From: Satya Bodapati Date: Mon, 19 Nov 2012 14:58:51 +0530 Subject: [PATCH 038/324] Bug#14147491 - INFINITE LOOP WHEN OPENING A CORRUPTED TABLE This bug is fixed by Bug#14251529. Only testcase from the contribution is used. --- .../suite/innodb/r/innodb_bug14147491.result | 17 +++++ .../innodb/t/innodb_bug14147491-master.opt | 1 + .../suite/innodb/t/innodb_bug14147491.test | 75 +++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 mysql-test/suite/innodb/r/innodb_bug14147491.result create mode 100644 mysql-test/suite/innodb/t/innodb_bug14147491-master.opt create mode 100644 mysql-test/suite/innodb/t/innodb_bug14147491.test diff --git a/mysql-test/suite/innodb/r/innodb_bug14147491.result b/mysql-test/suite/innodb/r/innodb_bug14147491.result new file mode 100644 index 00000000000..6279f85f676 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_bug14147491.result @@ -0,0 +1,17 @@ +CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts"); +CALL mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); +# Create and populate the table to be corrupted +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB; +INSERT INTO t1 (b) VALUES ('corrupt me'); +INSERT INTO t1 (b) VALUES ('corrupt me'); +# Restart server to flush buffers +# Corrupt the table +Munged a string. +Munged a string. +# Write file to make mysql-test-run.pl expect crash and restart +SELECT * FROM t1; +ERROR HY000: Lost connection to MySQL server during query +# Turn on reconnect +# Wait for server to fully start +# Cleanup +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb_bug14147491-master.opt b/mysql-test/suite/innodb/t/innodb_bug14147491-master.opt new file mode 100644 index 00000000000..6b82baca147 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug14147491-master.opt @@ -0,0 +1 @@ +--innodb_file_per_table=1 --skip-stack-trace --skip-core-file diff --git a/mysql-test/suite/innodb/t/innodb_bug14147491.test b/mysql-test/suite/innodb/t/innodb_bug14147491.test new file mode 100644 index 00000000000..ee3519c53fc --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_bug14147491.test @@ -0,0 +1,75 @@ +# +# Test opening a corrupted table. +# + +# Don't test under valgrind, memory leaks will occur +source include/not_valgrind.inc; +# Avoid CrashReporter popup on Mac +source include/not_crashrep.inc; +# Don't test under embedded +source include/not_embedded.inc; +# Require InnoDB +source include/have_innodb.inc; + +CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts"); +CALL mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); + +--echo # Create and populate the table to be corrupted +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB; +INSERT INTO t1 (b) VALUES ('corrupt me'); +--disable_query_log +--let $i = 10 +while ($i) +{ + INSERT INTO t1 (b) VALUES (REPEAT('abcdefghijklmnopqrstuvwxyz', 100)); + dec $i; +} +--enable_query_log +INSERT INTO t1 (b) VALUES ('corrupt me'); + +--echo # Restart server to flush buffers +source include/restart_mysqld.inc; + +--echo # Corrupt the table +let $MYSQLD_DATADIR=`select @@datadir`; +let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd; + +perl; +use strict; +use warnings; +use Fcntl qw(:DEFAULT :seek); + +my $ibd_file = $ENV{'t1_IBD'}; + +my $chunk; +my $len; + +sysopen IBD_FILE, $ibd_file, O_RDWR || die "Unable to open $ibd_file"; + +while ($len = sysread IBD_FILE, $chunk, 1024) +{ + if ($chunk =~ s/corrupt me/korrupt me/) + { + print "Munged a string.\n"; + sysseek IBD_FILE, -$len, SEEK_CUR; + syswrite IBD_FILE, $chunk, $len; + } +} + +close IBD_FILE; +EOF + +--echo # Write file to make mysql-test-run.pl expect crash and restart +--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect + +--error 2013 +SELECT * FROM t1; + +--echo # Turn on reconnect +--enable_reconnect + +--echo # Wait for server to fully start +--source include/wait_until_connected_again.inc + +--echo # Cleanup +DROP TABLE t1; From 2217a9e38b7c458584bb41c88bd99547329a89c2 Mon Sep 17 00:00:00 2001 From: Vamsikrishna Bhagi Date: Mon, 19 Nov 2012 21:41:35 +0530 Subject: [PATCH 039/324] Bug#14463669 FAILURE TO CORRECTLY PARSE ROUTINES IN MYSQLDUMP OUTPUT Problem: mysqldump when used with option --routines, dumps all the routines of the specified database into output. The statements in this output are written in such a way that they are version safe using C style version commenting (of the format /*! */). If a semicolon is present right before closing of the comment in dump output, it results in a syntax error while importing. Solution: Version comments for dumped routines are specifically to protect the ones older than 5.0. When the import is done on 5.0 or later versions, entire create statement gets executed as all the check conditions at the beginning of the comments are cleared. Since the trade off is between the performance of newer versions which are more in use and protection of very old versions which are no longer supported, it is proposed that these comments be removed altogether to maintain stability of the versions supported. client/mysqldump.c: Bug#14463669 FAILURE TO CORRECTLY PARSE ROUTINES IN MYSQLDUMP OUTPUT Output of mysqldump is derived by getting the queries from show create and appending version comments to them. query_str is the variable used to store the final string. Since it is no longer required, its declaration and manipulations made on it are deleted. At the step where output is printed, query_str is replaced with the original query string derived from 'show create'. --- client/mysqldump.c | 17 ++--------------- mysql-test/r/mysqldump.result | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 765e547004e..65551051953 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2240,7 +2240,6 @@ static uint dump_routines_for_db(char *db) const char *routine_type[]= {"FUNCTION", "PROCEDURE"}; char db_name_buff[NAME_LEN*2+3], name_buff[NAME_LEN*2+3]; char *routine_name; - char *query_str; int i; FILE *sql_file= md_result_file; MYSQL_RES *routine_res, *routine_list_res; @@ -2334,17 +2333,6 @@ static uint dump_routines_for_db(char *db) fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */;\n", routine_type[i], routine_name); - query_str= cover_definer_clause(row[2], strlen(row[2]), - C_STRING_WITH_LEN("50020"), - C_STRING_WITH_LEN("50003"), - C_STRING_WITH_LEN(" FUNCTION")); - - if (!query_str) - query_str= cover_definer_clause(row[2], strlen(row[2]), - C_STRING_WITH_LEN("50020"), - C_STRING_WITH_LEN("50003"), - C_STRING_WITH_LEN(" PROCEDURE")); - if (mysql_num_fields(routine_res) >= 6) { if (switch_db_collation(sql_file, db_name_buff, ";", @@ -2382,9 +2370,9 @@ static uint dump_routines_for_db(char *db) fprintf(sql_file, "DELIMITER ;;\n" - "/*!50003 %s */;;\n" + "%s ;;\n" "DELIMITER ;\n", - (const char *) (query_str != NULL ? query_str : row[2])); + (const char *) row[2]); restore_sql_mode(sql_file, ";"); @@ -2399,7 +2387,6 @@ static uint dump_routines_for_db(char *db) } } - my_free(query_str); } } /* end of routine printing */ mysql_free_result(routine_res); diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 5f3b29f5f7c..2e34bb10a87 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -2706,8 +2706,8 @@ UNLOCK TABLES; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) -RETURN a+b */;; +CREATE DEFINER=`root`@`localhost` FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11) +RETURN a+b ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -2723,11 +2723,11 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1 +CREATE DEFINER=`root`@`localhost` FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1 begin set f1= concat( 'hello', f1 ); return f1; -end */;; +end ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -2743,8 +2743,8 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER="root"@"localhost"*/ /*!50003 PROCEDURE "a'b"() -select 1 */;; +CREATE DEFINER="root"@"localhost" PROCEDURE "a'b"() +select 1 ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -2760,8 +2760,8 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT) -BEGIN SELECT a+b INTO c; end */;; +CREATE DEFINER=`root`@`localhost` PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT) +BEGIN SELECT a+b INTO c; end ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -2777,10 +2777,10 @@ DELIMITER ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc2`(OUT a INT) +CREATE DEFINER=`root`@`localhost` PROCEDURE `bug9056_proc2`(OUT a INT) BEGIN select sum(id) from t1 into a; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -3766,8 +3766,8 @@ create procedure mysqldump_test_db.sp1() select 'hello'; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`user1`@`%`*/ /*!50003 PROCEDURE `sp1`() -select 'hello' */;; +CREATE DEFINER=`user1`@`%` PROCEDURE `sp1`() +select 'hello' ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; From 155b766d9816d7d28a861c9472dc02a2fdfe487a Mon Sep 17 00:00:00 2001 From: Vamsikrishna Bhagi Date: Tue, 20 Nov 2012 11:30:39 +0530 Subject: [PATCH 040/324] Bug#14463669 FAILURE TO CORRECTLY PARSE ROUTINES IN MYSQLDUMP OUTPUT A patch is pushed on this bug. A result mismatch occured for the test main.ddl_i18n_koi8r in x86_64 gcov build of linux in pb2. This commit is to modify ddl_i18n_koi8r.result to match the changes made for the bug. --- mysql-test/r/ddl_i18n_koi8r.result | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/ddl_i18n_koi8r.result b/mysql-test/r/ddl_i18n_koi8r.result index 352f421eda7..af55995bd15 100644 --- a/mysql-test/r/ddl_i18n_koi8r.result +++ b/mysql-test/r/ddl_i18n_koi8r.result @@ -734,7 +734,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p1`( +CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`( INOUT ÐÁÒÁÍ1 CHAR(10), OUT ÐÁÒÁÍ2 CHAR(10)) BEGIN @@ -751,7 +751,7 @@ COLLATION(_utf8 'текÑÑ‚') AS c6, @@character_set_client AS c8; SET ÐÁÒÁÍ1 = 'a'; SET ÐÁÒÁÍ2 = 'b'; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -768,7 +768,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p2`( +CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`( INOUT ÐÁÒÁÍ1 CHAR(10) CHARACTER SET utf8, OUT ÐÁÒÁÍ2 CHAR(10) CHARACTER SET utf8) BEGIN @@ -785,7 +785,7 @@ COLLATION(_utf8 'текÑÑ‚') AS c6, @@character_set_client AS c8; SET ÐÁÒÁÍ1 = 'a'; SET ÐÁÒÁÍ2 = 'b'; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -810,7 +810,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p3`( +CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`( INOUT ÐÁÒÁÍ1 CHAR(10), OUT ÐÁÒÁÍ2 CHAR(10)) BEGIN @@ -827,7 +827,7 @@ COLLATION(_utf8 'текÑÑ‚') AS c6, @@character_set_client AS c8; SET ÐÁÒÁÍ1 = 'a'; SET ÐÁÒÁÍ2 = 'b'; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -844,7 +844,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p4`( +CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`( INOUT ÐÁÒÁÍ1 CHAR(10) CHARACTER SET utf8, OUT ÐÁÒÁÍ2 CHAR(10) CHARACTER SET utf8) BEGIN @@ -861,7 +861,7 @@ COLLATION(_utf8 'текÑÑ‚') AS c6, @@character_set_client AS c8; SET ÐÁÒÁÍ1 = 'a'; SET ÐÁÒÁÍ2 = 'b'; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; From 21345a6aa831067d3d1322f853a04d5cb2aee83e Mon Sep 17 00:00:00 2001 From: Vamsikrishna Bhagi Date: Tue, 20 Nov 2012 11:53:54 +0530 Subject: [PATCH 041/324] Bug#14463669 FAILURE TO CORRECTLY PARSE ROUTINES IN MYSQLDUMP OUTPUT A patch is pushed on this bug. A result mismatch occured for the test main.ddl_i18n_utf8 in x86_64 gcov build of linux in pb2. This commit is to modify ddl_i18n_utf8.result to match the changes made for the bug. --- mysql-test/r/ddl_i18n_utf8.result | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/ddl_i18n_utf8.result b/mysql-test/r/ddl_i18n_utf8.result index 1385612fc32..43e3470e597 100644 --- a/mysql-test/r/ddl_i18n_utf8.result +++ b/mysql-test/r/ddl_i18n_utf8.result @@ -734,7 +734,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p1`( +CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`( INOUT парам1 CHAR(10), OUT парам2 CHAR(10)) BEGIN @@ -751,7 +751,7 @@ COLLATION(_koi8r ' @@character_set_client AS c8; SET парам1 = 'a'; SET парам2 = 'b'; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -768,7 +768,7 @@ ALTER DATABASE `mysqltest1` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p2`( +CREATE DEFINER=`root`@`localhost` PROCEDURE `p2`( INOUT парам1 CHAR(10) CHARACTER SET utf8, OUT парам2 CHAR(10) CHARACTER SET utf8) BEGIN @@ -785,7 +785,7 @@ COLLATION(_koi8r ' @@character_set_client AS c8; SET парам1 = 'a'; SET парам2 = 'b'; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -810,7 +810,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p3`( +CREATE DEFINER=`root`@`localhost` PROCEDURE `p3`( INOUT парам1 CHAR(10), OUT парам2 CHAR(10)) BEGIN @@ -827,7 +827,7 @@ COLLATION(_koi8r ' @@character_set_client AS c8; SET парам1 = 'a'; SET парам2 = 'b'; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; @@ -844,7 +844,7 @@ ALTER DATABASE `mysqltest2` CHARACTER SET utf8 COLLATE utf8_unicode_ci ; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = '' */ ; DELIMITER ;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `p4`( +CREATE DEFINER=`root`@`localhost` PROCEDURE `p4`( INOUT парам1 CHAR(10) CHARACTER SET utf8, OUT парам2 CHAR(10) CHARACTER SET utf8) BEGIN @@ -861,7 +861,7 @@ COLLATION(_koi8r ' @@character_set_client AS c8; SET парам1 = 'a'; SET парам2 = 'b'; -END */;; +END ;; DELIMITER ; /*!50003 SET sql_mode = @saved_sql_mode */ ; /*!50003 SET character_set_client = @saved_cs_client */ ; From fe1bb698622e707b2443758711cba48f81a28d4d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Nov 2012 15:33:45 +0530 Subject: [PATCH 042/324] BUG #15895810 - REQUIRE ADDITIONAL INFORMATION WITH THE --RESULT-FILE OPTION OF MTR --- mysql-test/lib/mtr_report.pm | 12 +++++++++++- mysql-test/mysql-test-run.pl | 8 -------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm index f6b3cf6bda5..af5b32ed939 100644 --- a/mysql-test/lib/mtr_report.pm +++ b/mysql-test/lib/mtr_report.pm @@ -27,7 +27,7 @@ our @EXPORT= qw(report_option mtr_print_line mtr_print_thick_line mtr_warning mtr_error mtr_debug mtr_verbose mtr_verbose_restart mtr_report_test_passed mtr_report_test_skipped mtr_print - mtr_report_test); + mtr_report_test isotime); use mtr_match; use My::Platform; @@ -109,6 +109,8 @@ sub mtr_report_test_passed ($) { $tinfo->{'result'}= 'MTR_RES_PASSED'; mtr_report_test($tinfo); + + resfile_global("endtime ", isotime (time)); } @@ -534,4 +536,12 @@ sub mtr_verbose_restart (@) { } +# Used by --result-file for for formatting times + +sub isotime($) { + my ($sec,$min,$hr,$day,$mon,$yr)= gmtime($_[0]); + return sprintf "%d-%02d-%02dT%02d:%02d:%02dZ", + $yr+1900, $mon+1, $day, $hr, $min, $sec; +} + 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c8589bb50eb..dc8fcf342d5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -335,14 +335,6 @@ my $opt_parallel= $ENV{MTR_PARALLEL} || 1; select(STDOUT); $| = 1; # Automatically flush STDOUT -# Used by --result-file for for formatting times - -sub isotime($) { - my ($sec,$min,$hr,$day,$mon,$yr)= gmtime($_[0]); - return sprintf "%d-%02d-%02dT%02d:%02d:%02dZ", - $yr+1900, $mon+1, $day, $hr, $min, $sec; -} - main(); From fb313032a65a044e18eba0dbcd4a653112500c8c Mon Sep 17 00:00:00 2001 From: Nuno Carvalho Date: Tue, 20 Nov 2012 12:37:23 +0000 Subject: [PATCH 043/324] BUG#15891524: RLI_FAKE MODE IS NOT UNSET AFTER BINLOG REPLAY When a binlog is replayed into a server, e.g.: $ mysqlbinlog binlog.000001 | mysql it sets a pseudo slave mode on the client connection in order to server be able to read binlog events, there is, a format description event is needed to correctly read following events. Also this pseudo slave mode applies to the current connection replication rules that are needed to correctly apply binlog events. If a binlog dump is sourced on a connection, this pseudo slave mode will remains after it, what will apply unexpected rules from customer perspective to following commands. Added a new SET statement to binlog dump that will unset pseudo slave mode at the end of dump file. --- client/mysqlbinlog.cc | 4 + mysql-test/r/mysqlbinlog.result | 32 ++++ mysql-test/r/user_var-binlog.result | 2 + .../suite/binlog/r/binlog_base64_flag.result | 2 + .../suite/binlog/r/binlog_mysqlbinlog2.result | 54 ++++++ .../binlog/r/binlog_mysqlbinlog_row.result | 2 + .../r/binlog_mysqlbinlog_row_innodb.result | 8 + .../r/binlog_mysqlbinlog_row_myisam.result | 8 + .../r/binlog_mysqlbinlog_row_trans.result | 2 + .../binlog/r/binlog_row_ctype_ucs.result | 2 + .../binlog/r/binlog_stm_ctype_ucs.result | 2 + mysql-test/suite/rpl/r/rpl_bug31076.result | 2 + .../suite/rpl/r/rpl_row_mysqlbinlog.result | 10 ++ mysql-test/suite/rpl/r/rpl_sp.result | 2 + mysql-test/suite/rpl/t/rpl_bug31076.test | 2 + .../sys_vars/r/pseudo_slave_mode_basic.result | 119 +++++++++++++ .../sys_vars/t/pseudo_slave_mode_basic.test | 168 ++++++++++++++++++ sql/sql_class.h | 2 + sql/sys_vars.cc | 56 ++++++ 19 files changed, 479 insertions(+) create mode 100644 mysql-test/suite/sys_vars/r/pseudo_slave_mode_basic.result create mode 100644 mysql-test/suite/sys_vars/t/pseudo_slave_mode_basic.test diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index a58aa65207d..461e704a1f8 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -2118,6 +2118,8 @@ int main(int argc, char** argv) else load_processor.init_by_cur_dir(); + fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;\n"); + fprintf(result_file, "/*!40019 SET @@session.max_insert_delayed_threads=0*/;\n"); @@ -2168,6 +2170,8 @@ int main(int argc, char** argv) "/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;\n" "/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\n"); + fprintf(result_file, "/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;\n"); + if (tmpdir.list) free_tmpdir(&tmpdir); if (result_file != stdout) diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 587a4de8a64..68d0a62ca59 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -14,6 +14,7 @@ insert into t1 values ("Alas"); flush logs; --- Local -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -95,8 +96,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Broken LOAD DATA -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -131,8 +134,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- --database -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -186,8 +191,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- --start-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -213,8 +220,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Remote -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -296,8 +305,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Broken LOAD DATA -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -332,8 +343,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- --database -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -387,8 +400,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- --start-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -414,8 +429,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- reading stdin -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -435,6 +452,8 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -453,6 +472,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; drop table t1,t2; flush logs; flush logs; @@ -495,6 +515,7 @@ call p1(); drop procedure p1; call p1(); ERROR 42000: PROCEDURE test.p1 does not exist +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -517,6 +538,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; call p1(); 1 1 @@ -545,6 +567,7 @@ C3BF D0AA drop table t1; flush logs; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -634,6 +657,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; CREATE TABLE t1 (c1 CHAR(10)); FLUSH LOGS; INSERT INTO t1 VALUES ('0123456789'); @@ -721,6 +745,7 @@ RESET MASTER; FLUSH LOGS; # # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified exists +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -772,8 +797,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Test if the 'BEGIN', 'ROLLBACK' and 'COMMIT' are output if the database specified does not exist +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -806,8 +833,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Test if the 'SAVEPOINT', 'ROLLBACK TO' are output if the database specified exists +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -849,8 +878,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Test if the 'SAVEPOINT', 'ROLLBACK TO' are output if the database specified does not exist +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -877,6 +908,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; End of 5.0 tests End of 5.1 tests # Expect deprecation warning. diff --git a/mysql-test/r/user_var-binlog.result b/mysql-test/r/user_var-binlog.result index 68d2364986d..ae4bd68a435 100644 --- a/mysql-test/r/user_var-binlog.result +++ b/mysql-test/r/user_var-binlog.result @@ -18,6 +18,7 @@ master-bin.000001 # User var # # @`var2`=_binary 0x61 COLLATE binary master-bin.000001 # Query # # use `test`; insert into t1 values (@var1),(@var2) master-bin.000001 # Query # # COMMIT flush logs; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -56,4 +57,5 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; drop table t1; diff --git a/mysql-test/suite/binlog/r/binlog_base64_flag.result b/mysql-test/suite/binlog/r/binlog_base64_flag.result index dfca5b2a1e9..6c3135298c6 100644 --- a/mysql-test/suite/binlog/r/binlog_base64_flag.result +++ b/mysql-test/suite/binlog/r/binlog_base64_flag.result @@ -29,6 +29,7 @@ a 1 3 ==== Test --base64-output=never on a binlog with row events ==== +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -51,6 +52,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; ==== Test non-matching FD event and Row event ==== BINLOG ' 4CdYRw8BAAAAYgAAAGYAAAAAAAQANS4xLjE1LW5kYi02LjEuMjQtZGVidWctbG9nAAAAAAAAAAAA diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result index 806cf74479e..b86e715869f 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog2.result @@ -15,6 +15,7 @@ set timestamp=@a+1; insert into t1 values(null, "f"); --- Local -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -85,8 +86,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- offset -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -154,8 +157,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -203,8 +208,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- stop-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -245,8 +252,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start and stop positions --- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -271,8 +280,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start-datetime -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -320,8 +331,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- stop-datetime -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -362,9 +375,11 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Local with 2 binlogs on command line -- flush logs; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -456,8 +471,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- offset -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -546,8 +563,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -616,8 +635,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- stop-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -702,8 +723,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start-datetime -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -772,8 +795,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- stop-datetime -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -814,8 +839,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Remote -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -886,8 +913,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- offset -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -955,8 +984,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1003,8 +1034,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- stop-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1045,8 +1078,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start and stop positions --- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1070,8 +1105,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start-datetime -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1119,8 +1156,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- stop-datetime -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1161,8 +1200,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Remote with 2 binlogs on command line -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1254,8 +1295,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- offset -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1344,8 +1387,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1413,8 +1458,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- stop-position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1498,8 +1545,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- start-datetime -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1568,8 +1617,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- stop-datetime -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1610,8 +1661,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- to-last-log -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1692,6 +1745,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- end of test -- drop table t1; diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result index 84a6d6c3baf..fc22085496d 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result @@ -328,6 +328,7 @@ INSERT INTO t2 SET b=1; UPDATE t1, t2 SET t1.a=10, t2.a=20; DROP TABLE t1,t2; flush logs; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -4135,3 +4136,4 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result index 31d7ee0df98..8e75d203ecc 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_innodb.result @@ -2245,6 +2245,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -3786,6 +3787,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # @@ -3868,6 +3870,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -4077,6 +4080,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # @@ -4235,6 +4239,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -4746,6 +4751,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # @@ -4796,6 +4802,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -4853,6 +4860,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result index c268d20c87d..b4ea8551ca6 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_myisam.result @@ -2245,6 +2245,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -3808,6 +3809,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # @@ -3890,6 +3892,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -4105,6 +4108,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # @@ -4263,6 +4267,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -4784,6 +4789,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # @@ -4834,6 +4840,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -4893,6 +4900,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result index 5d08a1095a9..77e096dd065 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row_trans.result @@ -124,6 +124,7 @@ FLUSH LOGS; # # Call mysqlbinlog to display the log file contents. # +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -463,6 +464,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; # # Cleanup. # diff --git a/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result b/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result index f0519a9d724..f5d19d08a29 100644 --- a/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result +++ b/mysql-test/suite/binlog/r/binlog_row_ctype_ucs.result @@ -10,6 +10,7 @@ master-bin.000001 # Table_map # # table_id: # (test.t2) master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Query # # COMMIT flush logs; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -32,4 +33,5 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; drop table t2; diff --git a/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result b/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result index 3207b9c2180..3a5c3ac4b02 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result +++ b/mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result @@ -10,6 +10,7 @@ master-bin.000001 # User var # # @`v`=_ucs2 0x006100620063 COLLATE ucs2_general_ master-bin.000001 # Query # # use `test`; insert into t2 values (@v) master-bin.000001 # Query # # COMMIT flush logs; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -37,4 +38,5 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; drop table t2; diff --git a/mysql-test/suite/rpl/r/rpl_bug31076.result b/mysql-test/suite/rpl/r/rpl_bug31076.result index 1cf8b87f68d..e09960e848e 100644 --- a/mysql-test/suite/rpl/r/rpl_bug31076.result +++ b/mysql-test/suite/rpl/r/rpl_bug31076.result @@ -35,6 +35,7 @@ KEY `event_id` (`event_id`), KEY `visit_id` (`visit_id`), KEY `data` (`data`) ) ENGINE=MyISAM AUTO_INCREMENT=33900731 DEFAULT CHARSET=latin1; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; BINLOG ' @@ -47,6 +48,7 @@ Bk3vRhe0AQAAWgAAABEMyQkQAJlXFwIAAAEABv/AIE4AvvVDAQZN70YAK0Rvd25sb2Fkcy9NeVNR TC00LjEvbXlzcWwtNC4xLjEyYS13aW4zMi56aXBPaAIC '/*!*/; SET INSERT_ID=21231039/*!*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; use track/*!*/; SET TIMESTAMP=1190087942/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; diff --git a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result index 1a4d5c7574d..1489af830cc 100644 --- a/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result +++ b/mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result @@ -150,6 +150,7 @@ c1 c3 c4 c5 5 2006-02-22 00:00:00 Tested in Texas 11 --- Test 2 position test -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -170,8 +171,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Test 3 First Remote test -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -201,6 +204,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Test 4 Second Remote test -- DROP TABLE t1; @@ -274,6 +278,7 @@ c1 c3 c4 c5 5 2006-02-22 00:00:00 Tested in Texas 11 --- Test 5 LOAD DATA -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -281,8 +286,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Test 6 reading stdin -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -312,8 +319,10 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Test 7 reading stdin w/position -- +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -334,6 +343,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; --- Test 8 switch internal charset -- stop slave; diff --git a/mysql-test/suite/rpl/r/rpl_sp.result b/mysql-test/suite/rpl/r/rpl_sp.result index 8a2a88a8c90..2f5052f0180 100644 --- a/mysql-test/suite/rpl/r/rpl_sp.result +++ b/mysql-test/suite/rpl/r/rpl_sp.result @@ -652,6 +652,7 @@ show function status like '%mysqltestbug36570%'; Db Name Type Definer Modified Created Security_type Comment character_set_client collation_connection Database Collation test mysqltestbug36570_f1 FUNCTION root@localhost t t DEFINER latin1 latin1_swedish_ci latin1_swedish_ci flush logs; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; @@ -1178,6 +1179,7 @@ DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; use test; drop procedure mysqltestbug36570_p1; drop procedure ` mysqltestbug36570_p2`; diff --git a/mysql-test/suite/rpl/t/rpl_bug31076.test b/mysql-test/suite/rpl/t/rpl_bug31076.test index 028ca32636a..4e9517fbf2a 100644 --- a/mysql-test/suite/rpl/t/rpl_bug31076.test +++ b/mysql-test/suite/rpl/t/rpl_bug31076.test @@ -40,6 +40,7 @@ CREATE TABLE `visits_events` ( KEY `data` (`data`) ) ENGINE=MyISAM AUTO_INCREMENT=33900731 DEFAULT CHARSET=latin1; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; --delimiter /*!*/; @@ -119,6 +120,7 @@ SET INSERT_ID=21231039/*!*/; # 9c90ded 2d 63 6f 6e 6e 65 63 74 6f 72 2d 6a 61 76 61 2d |.connector.java.| # 9c90dfd 33 2e 30 2e 31 37 2d 67 61 2e 7a 69 70 |3.0.17.ga.zip| # Query thread_id=28278824 exec_time=0 error_code=0 +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; use track/*!*/; SET TIMESTAMP=1190087942/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1/*!*/; diff --git a/mysql-test/suite/sys_vars/r/pseudo_slave_mode_basic.result b/mysql-test/suite/sys_vars/r/pseudo_slave_mode_basic.result new file mode 100644 index 00000000000..c98dd338909 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/pseudo_slave_mode_basic.result @@ -0,0 +1,119 @@ +SET @session_start_value = @@session.pseudo_slave_mode; +SELECT @session_start_value; +@session_start_value +0 +'#--------------------FN_DYNVARS_156_01------------------------#' +SET @@session.pseudo_slave_mode = 0; +Warnings: +Warning 1231 'pseudo_slave_mode' change was ineffective. +SET @@session.pseudo_slave_mode = DEFAULT; +Warnings: +Warning 1231 'pseudo_slave_mode' change was ineffective. +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +0 +SET @@session.pseudo_slave_mode = 1; +SET @@session.pseudo_slave_mode = DEFAULT; +Warnings: +Warning 1231 Slave applier execution mode not active, statement ineffective. +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +0 +'#---------------------FN_DYNVARS_156_02-------------------------#' +SET pseudo_slave_mode = 1; +SELECT @@pseudo_slave_mode; +@@pseudo_slave_mode +1 +SELECT session.pseudo_slave_mode; +ERROR 42S02: Unknown table 'session' in field list +SELECT local.pseudo_slave_mode; +ERROR 42S02: Unknown table 'local' in field list +SET session pseudo_slave_mode = 0; +Warnings: +Warning 1231 Slave applier execution mode not active, statement ineffective. +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +0 +'#--------------------FN_DYNVARS_156_03------------------------#' +SET @@session.pseudo_slave_mode = 0; +Warnings: +Warning 1231 'pseudo_slave_mode' change was ineffective. +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +0 +SET @@session.pseudo_slave_mode = 1; +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +1 +'#--------------------FN_DYNVARS_156_04-------------------------#' +SET @@session.pseudo_slave_mode = -1; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of '-1' +SET @@session.pseudo_slave_mode = 2; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of '2' +SET @@session.pseudo_slave_mode = "T"; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'T' +SET @@session.pseudo_slave_mode = "Y"; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'Y' +SET @@session.pseudo_slave_mode = TRÜE; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'TRÜE' +SET @@session.pseudo_slave_mode = ÕN; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'ÕN' +SET @@session.pseudo_slave_mode = OF; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'OF' +SET @@session.pseudo_slave_mode = ÓFF; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'ÓFF' +SET @@session.pseudo_slave_mode = '¹'; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of '¹' +SET @@session.pseudo_slave_mode = NO; +ERROR 42000: Variable 'pseudo_slave_mode' can't be set to the value of 'NO' +'#-------------------FN_DYNVARS_156_05----------------------------#' +SET @@global.pseudo_slave_mode = 0; +ERROR HY000: Variable 'pseudo_slave_mode' is a SESSION variable and can't be used with SET GLOBAL +SELECT @@global.pseudo_slave_mode; +ERROR HY000: Variable 'pseudo_slave_mode' is a SESSION variable +'#----------------------FN_DYNVARS_156_06------------------------#' +SELECT count(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='pseudo_slave_mode'; +count(VARIABLE_VALUE) +1 +'#----------------------FN_DYNVARS_156_07------------------------#' +SELECT IF(@@session.pseudo_slave_mode, "ON", "OFF") = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='pseudo_slave_mode'; +IF(@@session.pseudo_slave_mode, "ON", "OFF") = VARIABLE_VALUE +1 +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +1 +SELECT VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='pseudo_slave_mode'; +VARIABLE_VALUE +ON +'#---------------------FN_DYNVARS_156_08-------------------------#' +SET @@session.pseudo_slave_mode = OFF; +Warnings: +Warning 1231 Slave applier execution mode not active, statement ineffective. +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +0 +SET @@session.pseudo_slave_mode = ON; +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +1 +'#---------------------FN_DYNVARS_156_09----------------------#' +SET @@session.pseudo_slave_mode = TRUE; +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +1 +SET @@session.pseudo_slave_mode = FALSE; +Warnings: +Warning 1231 Slave applier execution mode not active, statement ineffective. +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +0 +SET @@session.pseudo_slave_mode = @session_start_value; +Warnings: +Warning 1231 'pseudo_slave_mode' change was ineffective. +SELECT @@session.pseudo_slave_mode; +@@session.pseudo_slave_mode +0 diff --git a/mysql-test/suite/sys_vars/t/pseudo_slave_mode_basic.test b/mysql-test/suite/sys_vars/t/pseudo_slave_mode_basic.test new file mode 100644 index 00000000000..3ef39bb8667 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/pseudo_slave_mode_basic.test @@ -0,0 +1,168 @@ +####################### mysql-test\t\pseudo_slave_mode_basic.test ################### +# # +# Variable Name: pseudo_slave_mode # +# Scope: SESSION # +# Access Type: Dynamic # +# Data Type: boolean # +# Default Value: # +# Valid Values: 0,1 # +# # +# # +# Creation Date: 2012-11-16 # +# # +# Description: Test Cases of Dynamic System Variable pseudo_slave_mode # +# that checks the behavior of this variable in the following ways# +# * Default Value # +# * Valid & Invalid values # +# * Scope & Access method # +# * Data Integrity # +# # +# Reference: http://dev.mysql.com/doc/refman/5.5/en/ # +# server-system-variables.html # +# # +############################################################################### + +--source include/load_sysvars.inc + +######################################################################## +# START OF pseudo_slave_mode TESTS # +######################################################################## + + +############################################################################## +# Saving initial value of pseudo_slave_mode in a temporary variable # +############################################################################## + +SET @session_start_value = @@session.pseudo_slave_mode; +SELECT @session_start_value; + +--echo '#--------------------FN_DYNVARS_156_01------------------------#' +######################################################################## +# Display the DEFAULT value of pseudo_slave_mode # +######################################################################## + +SET @@session.pseudo_slave_mode = 0; +SET @@session.pseudo_slave_mode = DEFAULT; +SELECT @@session.pseudo_slave_mode; + +SET @@session.pseudo_slave_mode = 1; +SET @@session.pseudo_slave_mode = DEFAULT; +SELECT @@session.pseudo_slave_mode; + + +--echo '#---------------------FN_DYNVARS_156_02-------------------------#' +############################################################################# +# Check if pseudo_slave_mode can be accessed with and without @@ sign # +############################################################################# + +SET pseudo_slave_mode = 1; +SELECT @@pseudo_slave_mode; + +--Error ER_UNKNOWN_TABLE +SELECT session.pseudo_slave_mode; + +--Error ER_UNKNOWN_TABLE +SELECT local.pseudo_slave_mode; + +SET session pseudo_slave_mode = 0; +SELECT @@session.pseudo_slave_mode; + + +--echo '#--------------------FN_DYNVARS_156_03------------------------#' +######################################################################## +# change the value of pseudo_slave_mode to a valid value # +######################################################################## + +SET @@session.pseudo_slave_mode = 0; +SELECT @@session.pseudo_slave_mode; +SET @@session.pseudo_slave_mode = 1; +SELECT @@session.pseudo_slave_mode; + + +--echo '#--------------------FN_DYNVARS_156_04-------------------------#' +########################################################################### +# Change the value of pseudo_slave_mode to invalid value # +########################################################################### + +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = -1; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = 2; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = "T"; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = "Y"; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = TRÜE; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = ÕN; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = OF; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = ÓFF; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = '¹'; +--Error ER_WRONG_VALUE_FOR_VAR +SET @@session.pseudo_slave_mode = NO; + + +--echo '#-------------------FN_DYNVARS_156_05----------------------------#' +########################################################################### +# Test if accessing global pseudo_slave_mode gives error # +########################################################################### + +--error ER_LOCAL_VARIABLE +SET @@global.pseudo_slave_mode = 0; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@global.pseudo_slave_mode; + +--echo '#----------------------FN_DYNVARS_156_06------------------------#' +######################################################################### +# Check if the value in SESSION Table contains variable value # +######################################################################### + +SELECT count(VARIABLE_VALUE) FROM INFORMATION_SCHEMA.SESSION_VARIABLES WHERE VARIABLE_NAME='pseudo_slave_mode'; + +--echo '#----------------------FN_DYNVARS_156_07------------------------#' +######################################################################### +# Check if the value in SESSION Table matches value in variable # +######################################################################### + +SELECT IF(@@session.pseudo_slave_mode, "ON", "OFF") = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='pseudo_slave_mode'; +SELECT @@session.pseudo_slave_mode; +SELECT VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='pseudo_slave_mode'; + +--echo '#---------------------FN_DYNVARS_156_08-------------------------#' +################################################################### +# Check if ON and OFF values can be used on variable # +################################################################### + +SET @@session.pseudo_slave_mode = OFF; +SELECT @@session.pseudo_slave_mode; +SET @@session.pseudo_slave_mode = ON; +SELECT @@session.pseudo_slave_mode; + +--echo '#---------------------FN_DYNVARS_156_09----------------------#' +################################################################### +# Check if TRUE and FALSE values can be used on variable # +################################################################### + +SET @@session.pseudo_slave_mode = TRUE; +SELECT @@session.pseudo_slave_mode; +SET @@session.pseudo_slave_mode = FALSE; +SELECT @@session.pseudo_slave_mode; + +############################## +# Restore initial value # +############################## + +SET @@session.pseudo_slave_mode = @session_start_value; +SELECT @@session.pseudo_slave_mode; + +############################################################### +# END OF pseudo_slave_mode TESTS # +############################################################### diff --git a/sql/sql_class.h b/sql/sql_class.h index 4f65aa25796..8140ba4a0f1 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -506,6 +506,8 @@ typedef struct system_variables double long_query_time_double; + my_bool pseudo_slave_mode; + } SV; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 06f97af2ade..5a0d2709a52 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -3270,6 +3270,62 @@ static Sys_var_ulong Sys_sp_cache_size( GLOBAL_VAR(stored_program_cache_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(256, 512 * 1024), DEFAULT(256), BLOCK_SIZE(1)); +static bool check_pseudo_slave_mode(sys_var *self, THD *thd, set_var *var) +{ + longlong previous_val= thd->variables.pseudo_slave_mode; + longlong val= (longlong) var->save_result.ulonglong_value; + bool rli_fake= false; + +#ifndef EMBEDDED_LIBRARY + rli_fake= thd->rli_fake ? true : false; +#endif + + if (rli_fake) + { + if (!val) + { +#ifndef EMBEDDED_LIBRARY + delete thd->rli_fake; + thd->rli_fake= NULL; +#endif + } + else if (previous_val && val) + goto ineffective; + else if (!previous_val && val) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "'pseudo_slave_mode' is already ON."); + } + else + { + if (!previous_val && !val) + goto ineffective; + else if (previous_val && !val) + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "Slave applier execution mode not active, " + "statement ineffective."); + } + goto end; + +ineffective: + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_VAR, + "'pseudo_slave_mode' change was ineffective."); + +end: + return FALSE; +} +static Sys_var_mybool Sys_pseudo_slave_mode( + "pseudo_slave_mode", + "SET pseudo_slave_mode= 0,1 are commands that mysqlbinlog " + "adds to beginning and end of binary log dumps. While zero " + "value indeed disables, the actual enabling of the slave " + "applier execution mode is done implicitly when a " + "Format_description_event is sent through the session.", + SESSION_ONLY(pseudo_slave_mode), NO_CMD_LINE, DEFAULT(FALSE), + NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_pseudo_slave_mode)); + /**************************************************************************** Used templates From 43062dba3ac0d1887a890ddbd364aa81a3a0208f Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Wed, 21 Nov 2012 19:12:20 +0530 Subject: [PATCH 044/324] Bug#15883127: PORT FIX FOR BUG #13904906 TO MYSQL 5.1 Description: Updated yassl to version 2.2.2 --- config/ac-macros/ssl.m4 | 2 +- extra/yassl/README | 11 ++++++++++- extra/yassl/include/lock.hpp | 9 +++++---- extra/yassl/include/openssl/ssl.h | 2 +- extra/yassl/include/yassl_error.hpp | 2 +- extra/yassl/src/cert_wrapper.cpp | 3 +-- extra/yassl/src/lock.cpp | 4 ++-- extra/yassl/src/ssl.cpp | 3 +-- extra/yassl/src/yassl_error.cpp | 7 +------ extra/yassl/taocrypt/include/aes.hpp | 1 - extra/yassl/taocrypt/include/pwdbased.hpp | 4 +++- extra/yassl/taocrypt/src/asn.cpp | 4 +++- extra/yassl/taocrypt/src/coding.cpp | 21 +++++++++++++++++++++ extra/yassl/taocrypt/taocrypt.dsw | 17 ++++++++++++++++- extra/yassl/taocrypt/test/memory.cpp | 2 +- extra/yassl/taocrypt/{ => test}/test.dsp | 14 +++++++------- extra/yassl/yassl.dsw | 5 +---- 17 files changed, 75 insertions(+), 36 deletions(-) rename extra/yassl/taocrypt/{ => test}/test.dsp (90%) diff --git a/config/ac-macros/ssl.m4 b/config/ac-macros/ssl.m4 index fc55f93d8d6..4e785ba0a6f 100644 --- a/config/ac-macros/ssl.m4 +++ b/config/ac-macros/ssl.m4 @@ -42,7 +42,7 @@ AC_DEFUN([MYSQL_USE_BUNDLED_YASSL], [ yassl_thread_cxxflags="" yassl_thread_safe="" if test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no"; then - yassl_thread_cxxflags="-DYASSL_THREAD_SAFE" + yassl_thread_cxxflags="-DMULTI_THREADED" yassl_thread_safe="(thread-safe)" fi AC_SUBST([yassl_thread_cxxflags]) diff --git a/extra/yassl/README b/extra/yassl/README index 7720a9453dd..24bdf32f989 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -12,7 +12,16 @@ before calling SSL_new(); *** end Note *** -yaSSL Release notes, version 2.1.2 (9/2/2011) +yaSSL Release notes, version 2.2.2 (7/5/2012) + + This release of yaSSL contains bug fixes and more security checks around + malicious certificates. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + + +*****************yaSSL Release notes, version 2.1.2 (9/2/2011) This release of yaSSL contains bug fixes, better non-blocking support with SSL_write, and OpenSSL RSA public key format support. diff --git a/extra/yassl/include/lock.hpp b/extra/yassl/include/lock.hpp index ae875001633..487bedfcc70 100644 --- a/extra/yassl/include/lock.hpp +++ b/extra/yassl/include/lock.hpp @@ -27,7 +27,7 @@ Visual Studio Source Annotations header (sourceannotations.h) fails to compile if outside of the global namespace. */ -#ifdef YASSL_THREAD_SAFE +#ifdef MULTI_THREADED #ifdef _WIN32 #include #endif @@ -36,8 +36,9 @@ namespace yaSSL { -#ifdef YASSL_THREAD_SAFE +#ifdef MULTI_THREADED #ifdef _WIN32 + #include class Mutex { CRITICAL_SECTION cs_; @@ -77,7 +78,7 @@ namespace yaSSL { }; #endif // _WIN32 -#else // YASSL_THREAD_SAFE (WE'RE SINGLE) +#else // MULTI_THREADED (WE'RE SINGLE) class Mutex { public: @@ -87,7 +88,7 @@ namespace yaSSL { }; }; -#endif // YASSL_THREAD_SAFE +#endif // MULTI_THREADED diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index 0d99888da88..2fcba67cfdd 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -35,7 +35,7 @@ #include "rsa.h" -#define YASSL_VERSION "2.2.0" +#define YASSL_VERSION "2.2.2" #if defined(__cplusplus) diff --git a/extra/yassl/include/yassl_error.hpp b/extra/yassl/include/yassl_error.hpp index 87bb4c55e96..8efc7f72e87 100644 --- a/extra/yassl/include/yassl_error.hpp +++ b/extra/yassl/include/yassl_error.hpp @@ -65,7 +65,7 @@ enum YasslError { enum Library { yaSSL_Lib = 0, CryptoLib, SocketLib }; enum { MAX_ERROR_SZ = 80 }; -void SetErrorString(unsigned long, char*); +void SetErrorString(YasslError, char*); /* remove for now, if go back to exceptions use this wrapper // Base class for all yaSSL exceptions diff --git a/extra/yassl/src/cert_wrapper.cpp b/extra/yassl/src/cert_wrapper.cpp index 7e73464001a..917cfa1a8fb 100644 --- a/extra/yassl/src/cert_wrapper.cpp +++ b/extra/yassl/src/cert_wrapper.cpp @@ -250,8 +250,7 @@ int CertManager::Validate() TaoCrypt::Source source((*last)->get_buffer(), (*last)->get_length()); TaoCrypt::CertDecoder cert(source, true, &signers_, verifyNone_); - int err = cert.GetError().What(); - if ( err ) + if (int err = cert.GetError().What()) return err; const TaoCrypt::PublicKey& key = cert.GetPublicKey(); diff --git a/extra/yassl/src/lock.cpp b/extra/yassl/src/lock.cpp index 9eb41408ff7..d603440757f 100644 --- a/extra/yassl/src/lock.cpp +++ b/extra/yassl/src/lock.cpp @@ -26,7 +26,7 @@ namespace yaSSL { -#ifdef YASSL_THREAD_SAFE +#ifdef MULTI_THREADED #ifdef _WIN32 Mutex::Mutex() @@ -79,7 +79,7 @@ namespace yaSSL { #endif // _WIN32 -#endif // YASSL_THREAD_SAFE +#endif // MULTI_THREADED diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 3b1fc43bc94..7c264e5a939 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -27,7 +27,6 @@ - /* see man pages for function descriptions */ #include "runtime.hpp" @@ -1014,7 +1013,7 @@ char* ERR_error_string(unsigned long errNumber, char* buffer) static char* msg = (char*)"Please supply a buffer for error string"; if (buffer) { - SetErrorString(errNumber, buffer); + SetErrorString(YasslError(errNumber), buffer); return buffer; } diff --git a/extra/yassl/src/yassl_error.cpp b/extra/yassl/src/yassl_error.cpp index 74735347841..b9fccf782f0 100644 --- a/extra/yassl/src/yassl_error.cpp +++ b/extra/yassl/src/yassl_error.cpp @@ -31,11 +31,6 @@ #pragma warning(disable: 4996) #endif -#ifdef _MSC_VER - // 4996 warning to use MS extensions e.g., strcpy_s instead of strncpy - #pragma warning(disable: 4996) -#endif - namespace yaSSL { @@ -60,7 +55,7 @@ Library Error::get_lib() const */ -void SetErrorString(unsigned long error, char* buffer) +void SetErrorString(YasslError error, char* buffer) { using namespace TaoCrypt; const int max = MAX_ERROR_SZ; // shorthand diff --git a/extra/yassl/taocrypt/include/aes.hpp b/extra/yassl/taocrypt/include/aes.hpp index dc19c98a83a..e2041fc9350 100644 --- a/extra/yassl/taocrypt/include/aes.hpp +++ b/extra/yassl/taocrypt/include/aes.hpp @@ -92,7 +92,6 @@ typedef BlockCipher AES_CBC_Encryption; typedef BlockCipher AES_CBC_Decryption; - } // naemspace #endif // TAO_CRYPT_AES_HPP diff --git a/extra/yassl/taocrypt/include/pwdbased.hpp b/extra/yassl/taocrypt/include/pwdbased.hpp index f40a336e2c3..d050fd8988b 100644 --- a/extra/yassl/taocrypt/include/pwdbased.hpp +++ b/extra/yassl/taocrypt/include/pwdbased.hpp @@ -48,9 +48,11 @@ word32 PBKDF2_HMAC::DeriveKey(byte* derived, word32 dLen, const byte* pwd, word32 pLen, const byte* salt, word32 sLen, word32 iterations) const { - if (dLen > MaxDerivedKeyLength()) + if (dLen > MaxDerivedKeyLength()) return 0; + if (iterations < 0) + return 0; ByteBlock buffer(T::DIGEST_SIZE); HMAC hmac; diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index 5ec4cac1c44..ad054809879 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -154,6 +154,8 @@ word32 GetLength(Source& source) else length = b; + if (source.IsLeft(length) == false) return 0; + return length; } @@ -832,7 +834,7 @@ void CertDecoder::GetName(NameType nt) if (email) { if (!(ptr = AddTag(ptr, buf_end, "/emailAddress=", 14, length))) { source_.SetError(CONTENT_E); - return; + return; } } diff --git a/extra/yassl/taocrypt/src/coding.cpp b/extra/yassl/taocrypt/src/coding.cpp index 8647ea13f20..ba485eea77e 100644 --- a/extra/yassl/taocrypt/src/coding.cpp +++ b/extra/yassl/taocrypt/src/coding.cpp @@ -103,6 +103,16 @@ void HexDecoder::Decode() byte b = coded_.next() - 0x30; // 0 starts at 0x30 byte b2 = coded_.next() - 0x30; + // sanity checks + if (b >= sizeof(hexDecode)/sizeof(hexDecode[0])) { + coded_.SetError(PEM_E); + return; + } + if (b2 >= sizeof(hexDecode)/sizeof(hexDecode[0])) { + coded_.SetError(PEM_E); + return; + } + b = hexDecode[b]; b2 = hexDecode[b2]; @@ -178,6 +188,7 @@ void Base64Decoder::Decode() { word32 bytes = coded_.size(); word32 plainSz = bytes - ((bytes + (pemLineSz - 1)) / pemLineSz); + const byte maxIdx = (byte)sizeof(base64Decode) + 0x2B - 1; plainSz = ((plainSz * 3) / 4) + 3; decoded_.New(plainSz); @@ -200,6 +211,16 @@ void Base64Decoder::Decode() if (e4 == pad) pad4 = true; + if (e1 < 0x2B || e2 < 0x2B || e3 < 0x2B || e4 < 0x2B) { + coded_.SetError(PEM_E); + return; + } + + if (e1 > maxIdx || e2 > maxIdx || e3 > maxIdx || e4 > maxIdx) { + coded_.SetError(PEM_E); + return; + } + e1 = base64Decode[e1 - 0x2B]; e2 = base64Decode[e2 - 0x2B]; e3 = (e3 == pad) ? 0 : base64Decode[e3 - 0x2B]; diff --git a/extra/yassl/taocrypt/taocrypt.dsw b/extra/yassl/taocrypt/taocrypt.dsw index d10d7534c3d..43115069160 100644 --- a/extra/yassl/taocrypt/taocrypt.dsw +++ b/extra/yassl/taocrypt/taocrypt.dsw @@ -3,6 +3,21 @@ Microsoft Developer Studio Workspace File, Format Version 6.00 ############################################################################### +Project: "benchmark"=.\benchmark\benchmark.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name taocrypt + End Project Dependency +}}} + +############################################################################### + Project: "taocrypt"=.\taocrypt.dsp - Package Owner=<4> Package=<5> @@ -15,7 +30,7 @@ Package=<4> ############################################################################### -Project: "test"=.\test.dsp - Package Owner=<4> +Project: "test"=.\test\test.dsp - Package Owner=<4> Package=<5> {{{ diff --git a/extra/yassl/taocrypt/test/memory.cpp b/extra/yassl/taocrypt/test/memory.cpp index ec398a64c45..a9b21f94902 100644 --- a/extra/yassl/taocrypt/test/memory.cpp +++ b/extra/yassl/taocrypt/test/memory.cpp @@ -31,7 +31,7 @@ To use MemoryTracker merely add this file to your project No need to instantiate anything -If your app is multi threaded define YASSL_THREAD_SAFE +If your app is multi threaded define MULTI_THREADED *********************************************************************/ diff --git a/extra/yassl/taocrypt/test.dsp b/extra/yassl/taocrypt/test/test.dsp similarity index 90% rename from extra/yassl/taocrypt/test.dsp rename to extra/yassl/taocrypt/test/test.dsp index 1084f8e06e3..93b369de3d9 100644 --- a/extra/yassl/taocrypt/test.dsp +++ b/extra/yassl/taocrypt/test/test.dsp @@ -37,12 +37,12 @@ RSC=rc.exe # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir "test\Release" -# PROP Intermediate_Dir "test\Release" +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /O2 /I "include" /I "mySTL" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c +# ADD CPP /nologo /MD /W3 /O2 /I "../include" /I "../mySTL" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /c # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe @@ -61,12 +61,12 @@ LINK32=link.exe # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 -# PROP Output_Dir "test\Debug" -# PROP Intermediate_Dir "test\Debug" +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /ZI /Od /I "include" /I "mySTL" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "../include" /I "../mySTL" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /YX /FD /GZ /c # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe @@ -87,7 +87,7 @@ LINK32=link.exe # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File -SOURCE=.\test\test.cpp +SOURCE=.\test.cpp # End Source File # End Group # Begin Group "Header Files" diff --git a/extra/yassl/yassl.dsw b/extra/yassl/yassl.dsw index 288c88dfd5b..8da089fc1fa 100644 --- a/extra/yassl/yassl.dsw +++ b/extra/yassl/yassl.dsw @@ -90,7 +90,7 @@ Package=<4> ############################################################################### -Project: "test"=.\taocrypt\test.dsp - Package Owner=<4> +Project: "test"=.\taocrypt\test\test.dsp - Package Owner=<4> Package=<5> {{{ @@ -113,9 +113,6 @@ Package=<5> Package=<4> {{{ - Begin Project Dependency - Project_Dep_Name taocrypt - End Project Dependency Begin Project Dependency Project_Dep_Name yassl End Project Dependency From c257dbe60cbb64edf64116743cd811cdb3d534e5 Mon Sep 17 00:00:00 2001 From: Yasufumi Kinoshita Date: Mon, 26 Nov 2012 15:57:26 +0900 Subject: [PATCH 045/324] Bug #14676249 : ROW_VERS_IMPL_X_LOCKED_LOW() MIGHT HIT !BPAGE->FILE_PAGE_WAS_FREED ASSERTION trx_undo_prev_version_build() should confirm existence of inherited (not-own) external pages. Bug #14676084 : ROW_UNDO_MOD_UPD_DEL_SEC() DOESN'T NEED UNDO_ROW AND UNDO_EXT INITIALIZED mtr script could hit the assertion error !bpage->file_page_was_freed using this path. So, also fixed rb://1337 approved by Marko Makela. --- storage/innodb_plugin/row/row0umod.c | 3 +++ storage/innodb_plugin/row/row0undo.c | 2 +- storage/innodb_plugin/srv/srv0srv.c | 12 ++++++++++++ storage/innodb_plugin/trx/trx0rec.c | 20 ++++++++++++++++++++ 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/storage/innodb_plugin/row/row0umod.c b/storage/innodb_plugin/row/row0umod.c index 31f7c9f4888..a1c86424625 100644 --- a/storage/innodb_plugin/row/row0umod.c +++ b/storage/innodb_plugin/row/row0umod.c @@ -493,6 +493,7 @@ row_undo_mod_upd_del_sec( ulint err = DB_SUCCESS; ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC); + ut_ad(!node->undo_row); heap = mem_heap_create(1024); while (node->index != NULL) { @@ -546,6 +547,8 @@ row_undo_mod_del_mark_sec( dict_index_t* index; ulint err; + ut_ad(!node->undo_row); + heap = mem_heap_create(1024); while (node->index != NULL) { diff --git a/storage/innodb_plugin/row/row0undo.c b/storage/innodb_plugin/row/row0undo.c index b1606bda5ef..f07d8013919 100644 --- a/storage/innodb_plugin/row/row0undo.c +++ b/storage/innodb_plugin/row/row0undo.c @@ -217,7 +217,7 @@ row_undo_search_clust_to_pcur( node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets, NULL, ext, node->heap); - if (node->update) { + if (node->rec_type == TRX_UNDO_UPD_EXIST_REC) { node->undo_row = dtuple_copy(node->row, node->heap); row_upd_replace(node->undo_row, &node->undo_ext, clust_index, node->update, node->heap); diff --git a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c index 2d48fcc6b18..da5861d8c87 100644 --- a/storage/innodb_plugin/srv/srv0srv.c +++ b/storage/innodb_plugin/srv/srv0srv.c @@ -86,6 +86,14 @@ Created 10/8/1995 Heikki Tuuri #include "trx0i_s.h" #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */ +#ifdef __WIN__ +/* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */ +# define DEBUG_SYNC_C(dummy) ((void) 0) +#else +# include "m_string.h" /* for my_sys.h */ +# include "my_sys.h" /* DEBUG_SYNC_C */ +#endif + /* This is set to TRUE if the MySQL user has set it in MySQL; currently affects only FOREIGN KEY definition parsing */ UNIV_INTERN ibool srv_lower_case_table_names = FALSE; @@ -1474,6 +1482,10 @@ srv_suspend_mysql_thread( trx = thr_get_trx(thr); + if (trx->mysql_thd != 0) { + DEBUG_SYNC_C("srv_suspend_mysql_thread_enter"); + } + os_event_set(srv_lock_timeout_thread_event); mutex_enter(&kernel_mutex); diff --git a/storage/innodb_plugin/trx/trx0rec.c b/storage/innodb_plugin/trx/trx0rec.c index dc55690c9c3..4de0ed8f9b8 100644 --- a/storage/innodb_plugin/trx/trx0rec.c +++ b/storage/innodb_plugin/trx/trx0rec.c @@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri #ifndef UNIV_HOTBACKUP #include "dict0dict.h" #include "ut0mem.h" +#include "read0read.h" #include "row0ext.h" #include "row0upd.h" #include "que0que.h" @@ -1617,6 +1618,25 @@ trx_undo_prev_version_build( if (row_upd_changes_field_size_or_external(index, offsets, update)) { ulint n_ext; + /* We should confirm the existence of disowned external data, + if the previous version record is delete marked. If the trx_id + of the previous record is seen by purge view, we should treat + it as missing history, because the disowned external data + might be purged already. + + The inherited external data (BLOBs) can be freed (purged) + after trx_id was committed, provided that no view was started + before trx_id. If the purge view can see the committed + delete-marked record by trx_id, no transactions need to access + the BLOB. */ + + if ((update->info_bits & REC_INFO_DELETED_FLAG) + && read_view_sees_trx_id(purge_sys->view, trx_id)) { + /* treat as a fresh insert, not to + cause assertion error at the caller. */ + return(DB_SUCCESS); + } + /* We have to set the appropriate extern storage bits in the old version of the record: the extern bits in rec for those fields that update does NOT update, as well as the bits for From 0c587a04afdd12e12d82c7323101b09fc2672bda Mon Sep 17 00:00:00 2001 From: Venkata Sidagam Date: Mon, 26 Nov 2012 15:16:23 +0530 Subject: [PATCH 046/324] Added new line at the end to resolve PB2 per push errors. --- mysql-test/collections/default.push | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/collections/default.push b/mysql-test/collections/default.push index 13627f68a1e..74957d7a901 100644 --- a/mysql-test/collections/default.push +++ b/mysql-test/collections/default.push @@ -2,4 +2,5 @@ perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir= perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list -perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental \ No newline at end of file +perl mysql-test-run.pl --timer --force --parallel=auto --comment=funcs_1 --vardir=var-funcs_1 --suite=funcs_1 --experimental=collections/default.experimental + From 0e01efc036af4c1fea14fe424cfd6e169ba917b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Nov 2012 16:09:18 +0530 Subject: [PATCH 047/324] Bug #14757120 - SAFE_PROCESS.CC/SAFE_PROCESS.PL SHOULD NOT KILL MYSQLD ON SIGSTOP/SIGCONT --- mysql-test/Makefile.am | 3 +- mysql-test/lib/My/SafeProcess/safe_process.cc | 15 +- mysql-test/lib/My/SafeProcess/safe_process.pl | 166 ------------------ 3 files changed, 12 insertions(+), 172 deletions(-) delete mode 100644 mysql-test/lib/My/SafeProcess/safe_process.pl diff --git a/mysql-test/Makefile.am b/mysql-test/Makefile.am index 9d61aa98764..10b1ade81c2 100644 --- a/mysql-test/Makefile.am +++ b/mysql-test/Makefile.am @@ -63,8 +63,7 @@ nobase_test_DATA = \ lib/My/File/Path.pm \ lib/My/SysInfo.pm \ lib/My/CoreDump.pm \ - lib/My/SafeProcess/Base.pm \ - lib/My/SafeProcess/safe_process.pl + lib/My/SafeProcess/Base.pm SUBDIRS = lib/My/SafeProcess diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index 2f906f3763b..3abda6e7f67 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -153,12 +153,19 @@ int main(int argc, char* const argv[] ) pid_t own_pid= getpid(); pid_t parent_pid= getppid(); bool nocore = false; + struct sigaction sa,sa_abort; + sa.sa_handler= handle_signal; + sa.sa_flags= SA_NOCLDSTOP; + sigemptyset(&sa.sa_mask); + + sa_abort.sa_handler= handle_abort; + sigemptyset(&sa_abort.sa_mask); /* Install signal handlers */ - signal(SIGTERM, handle_signal); - signal(SIGINT, handle_signal); - signal(SIGCHLD, handle_signal); - signal(SIGABRT, handle_abort); + sigaction(SIGTERM, &sa,NULL); + sigaction(SIGINT, &sa,NULL); + sigaction(SIGCHLD, &sa,NULL); + sigaction(SIGABRT, &sa_abort,NULL); sprintf(safe_process_name, "safe_process[%ld]", (long) own_pid); diff --git a/mysql-test/lib/My/SafeProcess/safe_process.pl b/mysql-test/lib/My/SafeProcess/safe_process.pl deleted file mode 100644 index 1b3c0aa9a5f..00000000000 --- a/mysql-test/lib/My/SafeProcess/safe_process.pl +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/perl -# -*- cperl -*- - -# Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. -# -# 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. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - -use strict; -use warnings; - -use lib 'lib'; -use My::SafeProcess::Base; -use POSIX qw(WNOHANG); - -########################################################################### -# Util functions -########################################################################### - -# -#Print message to stderr -# -my $verbose= 0; -sub message { - if ($verbose > 0){ - use Time::localtime; - my $tm= localtime(); - my $timestamp= sprintf("%02d%02d%02d %2d:%02d:%02d", - $tm->year % 100, $tm->mon+1, $tm->mday, - $tm->hour, $tm->min, $tm->sec); - print STDERR $timestamp, " monitor[$$]: ", @_, "\n"; - } -} - - -########################################################################### -# Main program -########################################################################### - -my $terminated= 0; - -# Protect against being killed in the middle -# of child creation, just set the terminated flag -# to make sure the child will be killed off -# when program is ready to do that -$SIG{TERM}= sub { message("!Got signal @_"); $terminated= 1; }; -$SIG{INT}= sub { message("!Got signal @_"); $terminated= 1; }; - -my $parent_pid= getppid(); - -my $found_double_dash= 0; -while (my $arg= shift(@ARGV)){ - - if ($arg =~ /^--$/){ - $found_double_dash= 1; - last; - } - elsif ($arg =~ /^--verbose$/){ - $verbose= 1; - } - else { - die "Unknown option: $arg"; - } -} - -my $path= shift(@ARGV); # Executable - -die "usage:\n" . - " safe_process.pl [opts] -- [ [...]]" - unless defined $path || $found_double_dash; - - -message("started"); -#message("path: '$path'"); -message("parent: $parent_pid"); - -# Start process to monitor -my $child_pid= - create_process( - path => $path, - args => \@ARGV, - setpgrp => 1, - ); -message("Started child $child_pid"); - -eval { - sub handle_signal { - $terminated= 1; - message("Got signal @_"); - - # Ignore all signals - foreach my $name (keys %SIG){ - $SIG{$name}= 'IGNORE'; - } - - die "signaled\n"; - }; - local $SIG{TERM}= \&handle_signal; - local $SIG{INT}= \&handle_signal; - local $SIG{CHLD}= sub { - message("Got signal @_"); - kill('KILL', -$child_pid); - my $ret= waitpid($child_pid, 0); - if ($? & 127){ - exit(65); # Killed by signal - } - exit($? >> 8); - }; - - # Monitoring loop - while(!$terminated) { - - # Check if parent is still alive - if (kill(0, $parent_pid) < 1){ - message("Parent is not alive anymore"); - last; - } - - # Wait for child to terminate but wakeup every - # second to also check that parent is still alive - my $ret_pid; - $ret_pid= waitpid($child_pid, &WNOHANG); - if ($ret_pid == $child_pid) { - # Process has exited, collect return status - my $ret_code= $? >> 8; - message("Child exit: $ret_code"); - # Exit with exit status of the child - exit ($ret_code); - } - sleep(1); - } -}; -if ( $@ ) { - # The monitoring loop should have been - # broken by handle_signal - warn "Unexpected: $@" unless ( $@ =~ /signaled/ ); -} - -# Use negative pid in order to kill the whole -# process group -# -my $ret= kill('KILL', -$child_pid); -message("Killed child: $child_pid, ret: $ret"); -if ($ret > 0) { - message("Killed child: $child_pid"); - # Wait blocking for the child to return - my $ret_pid= waitpid($child_pid, 0); - if ($ret_pid != $child_pid){ - message("unexpected pid $ret_pid returned from waitpid($child_pid)"); - } -} - -message("DONE!"); -exit (1); - - From 80fa4f58094affcfb13b454955ee372a2a61ea6c Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Mon, 26 Nov 2012 15:14:26 +0100 Subject: [PATCH 048/324] Reinstate install of mysql-test/lib/My/SafeProcess/Base.pm, removed by mistake --- mysql-test/lib/My/SafeProcess/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/lib/My/SafeProcess/CMakeLists.txt b/mysql-test/lib/My/SafeProcess/CMakeLists.txt index c26256f5a9a..95e23756c30 100644 --- a/mysql-test/lib/My/SafeProcess/CMakeLists.txt +++ b/mysql-test/lib/My/SafeProcess/CMakeLists.txt @@ -29,3 +29,4 @@ INSTALL(TARGETS my_safe_process DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/Safe IF(WIN32) INSTALL(TARGETS my_safe_kill DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test) ENDIF() +INSTALL(FILES Base.pm DESTINATION "${INSTALL_MYSQLTESTDIR}/lib/My/SafeProcess" COMPONENT Test) From 112a93a7c863fe591c8983d15b29c9b4c6aec53b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 28 Nov 2012 09:00:24 +0200 Subject: [PATCH 049/324] Bug#14329288 IS THE CALL TO IBUF_MERGE_OR_DELETE_FOR_PAGE FROM BUF_PAGE_GET_GEN REDUNDANT? buf_page_get_gen(): When decompressing a compressed page that had already been accessed in the buffer pool, do not attempt to merge buffered changes. rb:1602 approved by Inaam Rana --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/buf/buf0buf.c | 20 ++++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 5387555d24f..72f75f39b1d 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2012-11-28 The InnoDB Team + + * buf/buf0buf.c: + Fix Bug#14329288 IS THE CALL TO IBUF_MERGE_OR_DELETE_FOR_PAGE FROM + BUF_PAGE_GET_GEN REDUNDANT? + 2012-11-15 The InnoDB Team * include/data0type.ic, include/rem0rec.h, diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index 755fa947c8f..1222f016c4a 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -1786,14 +1786,26 @@ wait_until_unfixed: buf_page_free_descriptor(bpage); - /* Decompress the page and apply buffered operations - while not holding buf_pool_mutex or block->mutex. */ + /* Decompress the page while not holding + buf_pool_mutex or block->mutex. */ success = buf_zip_decompress(block, srv_use_checksums); ut_a(success); if (UNIV_LIKELY(!recv_no_ibuf_operations)) { - ibuf_merge_or_delete_for_page(block, space, offset, - zip_size, TRUE); + unsigned accessed; + + mutex_enter(&block->mutex); + accessed = buf_page_is_accessed(&block->page); + mutex_exit(&block->mutex); + + if (accessed) { +#ifdef UNIV_IBUF_COUNT_DEBUG + ut_a(ibuf_count_get(space, offset) == 0); +#endif /* UNIV_IBUF_COUNT_DEBUG */ + } else { + ibuf_merge_or_delete_for_page( + block, space, offset, zip_size, TRUE); + } } /* Unfix and unlatch the block. */ From 8dd87e690d15d15be77f41ad2174a0334a8666d6 Mon Sep 17 00:00:00 2001 From: Yasufumi Kinoshita Date: Wed, 28 Nov 2012 17:05:23 +0900 Subject: [PATCH 050/324] Bug#59354 : Bug #12659252 : ASSERT !OTHER_LOCK AT LOCK_REC_ADD_TO_QUEUE DURING A DELETE OPERATION The converted implicit lock should wait for the prior conflicting lock if found. rb://1437 approved by Marko --- storage/innobase/handler/ha_innodb.cc | 10 +++ storage/innobase/include/lock0lock.h | 7 ++ storage/innobase/include/srv0srv.h | 5 ++ storage/innobase/lock/lock0lock.c | 85 +++++++++++++++++---- storage/innobase/row/row0ins.c | 5 +- storage/innobase/srv/srv0srv.c | 18 +++++ storage/innobase/trx/trx0purge.c | 11 +++ storage/innodb_plugin/handler/ha_innodb.cc | 10 +++ storage/innodb_plugin/include/lock0lock.h | 12 ++- storage/innodb_plugin/include/srv0srv.h | 6 ++ storage/innodb_plugin/lock/lock0lock.c | 87 ++++++++++++++++++---- storage/innodb_plugin/row/row0ins.c | 5 +- storage/innodb_plugin/srv/srv0srv.c | 11 +++ storage/innodb_plugin/trx/trx0purge.c | 11 +++ 14 files changed, 250 insertions(+), 33 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 28262f02551..194a7eea795 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -498,6 +498,8 @@ static SHOW_VAR innodb_status_variables[]= { #ifdef UNIV_DEBUG {"purge_trx_id_age", (char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG}, + {"purge_view_trx_id_age", + (char*) &export_vars.innodb_purge_view_trx_id_age, SHOW_LONG}, #endif /* UNIV_DEBUG */ {NullS, NullS, SHOW_LONG} }; @@ -9283,6 +9285,13 @@ static MYSQL_SYSVAR_UINT(limit_optimistic_insert_debug, btr_cur_limit_optimistic_insert_debug, PLUGIN_VAR_RQCMDARG, "Artificially limit the number of records per B-tree page (0=unlimited).", NULL, NULL, 0, 0, UINT_MAX32, 0); + +static MYSQL_SYSVAR_BOOL(trx_purge_view_update_only_debug, + srv_purge_view_update_only_debug, PLUGIN_VAR_NOCMDARG, + "Pause actual purging any delete-marked records, but merely update the purge view. " + "It is to create artificially the situation the purge view have been updated " + "but the each purges were not done yet.", + NULL, NULL, FALSE); #endif /* UNIV_DEBUG */ static struct st_mysql_sys_var* innobase_system_variables[]= { @@ -9333,6 +9342,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { #ifdef UNIV_DEBUG MYSQL_SYSVAR(trx_rseg_n_slots_debug), MYSQL_SYSVAR(limit_optimistic_insert_debug), + MYSQL_SYSVAR(trx_purge_view_update_only_debug), #endif /* UNIV_DEBUG */ NULL }; diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 70b141eafeb..476a2c8accb 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -685,6 +685,13 @@ extern lock_sys_t* lock_sys; remains set when the waiting lock is granted, or if the lock is inherited to a neighboring record */ +#define LOCK_CONV_BY_OTHER 4096 /* this bit is set when the lock is created + by other transaction */ +/* Checks if this is a waiting lock created by lock->trx itself. +@param type_mode lock->type_mode +@return whether it is a waiting lock belonging to lock->trx */ +#define lock_is_wait_not_by_other(type_mode) \ + ((type_mode & (LOCK_CONV_BY_OTHER | LOCK_WAIT)) == LOCK_WAIT) /* When lock bits are reset, the following flags are available: */ #define LOCK_RELEASE_WAIT 1 diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index e79d352d1e6..e1dbc4d11fa 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -176,6 +176,10 @@ extern ulint srv_fatal_semaphore_wait_threshold; #define SRV_SEMAPHORE_WAIT_EXTENSION 7200 extern ulint srv_dml_needed_delay; +#ifdef UNIV_DEBUG +extern my_bool srv_purge_view_update_only_debug; +#endif /* UNIV_DEBUG */ + extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs, query threads, and lock table: we allocate it from dynamic memory to get it to the @@ -571,6 +575,7 @@ struct export_var_struct{ ulint innodb_rows_deleted; #ifdef UNIV_DEBUG ulint innodb_purge_trx_id_age; + ulint innodb_purge_view_trx_id_age; #endif /* UNIV_DEBUG */ }; diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index 57df99fb401..d36e38df4af 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -725,12 +725,16 @@ lock_reset_lock_and_trx_wait( /*=========================*/ lock_t* lock) /* in: record lock */ { - ut_ad((lock->trx)->wait_lock == lock); ut_ad(lock_get_wait(lock)); /* Reset the back pointer in trx to this waiting lock request */ - (lock->trx)->wait_lock = NULL; + if (!(lock->type_mode & LOCK_CONV_BY_OTHER)) { + ut_ad((lock->trx)->wait_lock == lock); + (lock->trx)->wait_lock = NULL; + } else { + ut_ad(lock_get_type(lock) == LOCK_REC); + } lock->type_mode = lock->type_mode & ~LOCK_WAIT; } @@ -1437,9 +1441,9 @@ lock_rec_has_expl( while (lock) { if (lock->trx == trx + && !lock_is_wait_not_by_other(lock->type_mode) && lock_mode_stronger_or_eq(lock_get_mode(lock), precise_mode & LOCK_MODE_MASK) - && !lock_get_wait(lock) && (!lock_rec_get_rec_not_gap(lock) || (precise_mode & LOCK_REC_NOT_GAP) || page_rec_is_supremum(rec)) @@ -1723,7 +1727,7 @@ lock_rec_create( HASH_INSERT(lock_t, hash, lock_sys->rec_hash, lock_rec_fold(space, page_no), lock); - if (type_mode & LOCK_WAIT) { + if (lock_is_wait_not_by_other(type_mode)) { lock_set_lock_and_trx_wait(lock, trx); } @@ -1752,10 +1756,11 @@ lock_rec_enqueue_waiting( lock request is set when performing an insert of an index record */ rec_t* rec, /* in: record */ + lock_t* lock, /* in: lock object; NULL if a new + one should be created. */ dict_index_t* index, /* in: index of record */ que_thr_t* thr) /* in: query thread */ { - lock_t* lock; trx_t* trx; ut_ad(mutex_own(&kernel_mutex)); @@ -1785,8 +1790,16 @@ lock_rec_enqueue_waiting( stderr); } - /* Enqueue the lock request that will wait to be granted */ - lock = lock_rec_create(type_mode | LOCK_WAIT, rec, index, trx); + if (lock == NULL) { + /* Enqueue the lock request that will wait to be granted */ + lock = lock_rec_create(type_mode | LOCK_WAIT, rec, index, trx); + } else { + ut_ad(lock->type_mode & LOCK_WAIT); + ut_ad(lock->type_mode & LOCK_CONV_BY_OTHER); + + lock->type_mode &= ~LOCK_CONV_BY_OTHER; + lock_set_lock_and_trx_wait(lock, trx); + } /* Check if a deadlock occurs: if yes, remove the lock request and return an error code */ @@ -2011,6 +2024,7 @@ lock_rec_lock_slow( que_thr_t* thr) /* in: query thread */ { trx_t* trx; + lock_t* lock; ut_ad(mutex_own(&kernel_mutex)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_S @@ -2025,7 +2039,27 @@ lock_rec_lock_slow( trx = thr_get_trx(thr); - if (lock_rec_has_expl(mode, rec, trx)) { + lock = lock_rec_has_expl(mode, rec, trx); + if (lock) { + if (lock->type_mode & LOCK_CONV_BY_OTHER) { + /* This lock or lock waiting was created by the other + transaction, not by the transaction (trx) itself. + So, the transaction (trx) should treat it collectly + according as whether granted or not. */ + + if (lock->type_mode & LOCK_WAIT) { + /* This lock request was not granted yet. + Should wait for granted. */ + + goto enqueue_waiting; + } else { + /* This lock request was already granted. + Just clearing the flag. */ + + lock->type_mode &= ~LOCK_CONV_BY_OTHER; + } + } + /* The trx already has a strong enough lock on rec: do nothing */ @@ -2035,7 +2069,9 @@ lock_rec_lock_slow( the queue, as this transaction does not have a lock strong enough already granted on the record, we have to wait. */ - return(lock_rec_enqueue_waiting(mode, rec, index, thr)); + ut_ad(lock == NULL); +enqueue_waiting: + return(lock_rec_enqueue_waiting(mode, rec, lock, index, thr)); } else if (!impl) { /* Set the requested lock on the record */ @@ -2171,7 +2207,8 @@ lock_grant( TRX_QUE_LOCK_WAIT state, and there is no need to end the lock wait for it */ - if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) { + if (!(lock->type_mode & LOCK_CONV_BY_OTHER) + && lock->trx->que_state == TRX_QUE_LOCK_WAIT) { trx_end_lock_wait(lock->trx); } } @@ -2188,6 +2225,7 @@ lock_rec_cancel( { ut_ad(mutex_own(&kernel_mutex)); ut_ad(lock_get_type(lock) == LOCK_REC); + ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER)); /* Reset the bit (there can be only one set bit) in the lock bitmap */ lock_rec_reset_nth_bit(lock, lock_rec_find_set_bit(lock)); @@ -2331,8 +2369,12 @@ lock_rec_reset_and_release_wait( lock = lock_rec_get_first(rec); while (lock != NULL) { - if (lock_get_wait(lock)) { + if (lock_is_wait_not_by_other(lock->type_mode)) { lock_rec_cancel(lock); + } else if (lock_get_wait(lock)) { + /* just reset LOCK_WAIT */ + lock_rec_reset_nth_bit(lock, heap_no); + lock_reset_lock_and_trx_wait(lock); } else { lock_rec_reset_nth_bit(lock, heap_no); } @@ -3383,6 +3425,7 @@ lock_table_create( ut_ad(table && trx); ut_ad(mutex_own(&kernel_mutex)); + ut_ad(!(type_mode & LOCK_CONV_BY_OTHER)); if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) { ++table->n_waiting_or_granted_auto_inc_locks; @@ -3900,6 +3943,7 @@ lock_cancel_waiting_and_release( lock_t* lock) /* in: waiting lock request */ { ut_ad(mutex_own(&kernel_mutex)); + ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER)); if (lock_get_type(lock) == LOCK_REC) { @@ -4871,7 +4915,7 @@ lock_rec_insert_check_and_lock( /* Note that we may get DB_SUCCESS also here! */ err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, - next_rec, index, thr); + next_rec, NULL, index, thr); } else { err = DB_SUCCESS; } @@ -4941,10 +4985,23 @@ lock_rec_convert_impl_to_expl( if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, rec, impl_trx)) { + ulint type_mode = (LOCK_REC | LOCK_X + | LOCK_REC_NOT_GAP); + + /* If the delete-marked record was locked already, + we should reserve lock waiting for impl_trx as + implicit lock. Because cannot lock at this moment.*/ + + if (rec_get_deleted_flag(rec, rec_offs_comp(offsets)) + && lock_rec_other_has_conflicting( + LOCK_X | LOCK_REC_NOT_GAP, + rec, impl_trx)) { + + type_mode |= (LOCK_WAIT | LOCK_CONV_BY_OTHER); + } lock_rec_add_to_queue( - LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP, - rec, index, impl_trx); + type_mode, rec, index, impl_trx); } } } diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 785a0426195..678293b492b 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -2195,7 +2195,10 @@ row_ins_index_entry( err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry, ext_vec, n_ext_vec, thr); if (err != DB_FAIL) { - + if (index == dict_table_get_first_index(index->table) + && thr_get_trx(thr)->mysql_thd != 0) { + DEBUG_SYNC_C("row_ins_clust_index_entry_leaf_after"); + } return(err); } diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 46d5b6ad274..3240b7515f8 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -48,6 +48,10 @@ Created 10/8/1995 Heikki Tuuri #include "srv0start.h" #include "row0mysql.h" #include "ha_prototypes.h" +#include "read0read.h" + +#include "m_string.h" /* for my_sys.h */ +#include "my_sys.h" /* DEBUG_SYNC_C */ /* This is set to TRUE if the MySQL user has set it in MySQL; currently affects only FOREIGN KEY definition parsing */ @@ -1435,6 +1439,10 @@ srv_suspend_mysql_thread( trx = thr_get_trx(thr); + if (trx->mysql_thd != 0) { + DEBUG_SYNC_C("srv_suspend_mysql_thread_enter"); + } + os_event_set(srv_lock_timeout_thread_event); mutex_enter(&kernel_mutex); @@ -1920,6 +1928,16 @@ srv_export_innodb_status(void) export_vars.innodb_purge_trx_id_age = ut_dulint_minus(trx_sys->max_trx_id, purge_sys->done_trx_no); } + + if (!purge_sys->view + || ut_dulint_cmp(trx_sys->max_trx_id, + purge_sys->view->up_limit_id) < 0) { + export_vars.innodb_purge_view_trx_id_age = 0; + } else { + export_vars.innodb_purge_view_trx_id_age = + ut_dulint_minus(trx_sys->max_trx_id, + purge_sys->view->up_limit_id); + } #endif /* UNIV_DEBUG */ mutex_exit(&srv_innodb_monitor_mutex); diff --git a/storage/innobase/trx/trx0purge.c b/storage/innobase/trx/trx0purge.c index e783f14c1ee..1e540c96536 100644 --- a/storage/innobase/trx/trx0purge.c +++ b/storage/innobase/trx/trx0purge.c @@ -34,6 +34,10 @@ trx_purge_t* purge_sys = NULL; which needs no purge */ trx_undo_rec_t trx_purge_dummy_rec; +#ifdef UNIV_DEBUG +my_bool srv_purge_view_update_only_debug; +#endif /* UNIV_DEBUG */ + /********************************************************************* Checks if trx_id is >= purge_view: then it is guaranteed that its update undo log still exists in the system. */ @@ -1079,6 +1083,13 @@ trx_purge(void) rw_lock_x_unlock(&(purge_sys->latch)); +#ifdef UNIV_DEBUG + if (srv_purge_view_update_only_debug) { + mutex_exit(&(purge_sys->mutex)); + return(0); + } +#endif + purge_sys->state = TRX_PURGE_ON; /* Handle at most 20 undo log pages in one purge batch */ diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 9ed452d9809..fadcefec023 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -580,6 +580,8 @@ static SHOW_VAR innodb_status_variables[]= { #ifdef UNIV_DEBUG {"purge_trx_id_age", (char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG}, + {"purge_view_trx_id_age", + (char*) &export_vars.innodb_purge_view_trx_id_age, SHOW_LONG}, #endif /* UNIV_DEBUG */ {NullS, NullS, SHOW_LONG} }; @@ -11271,6 +11273,13 @@ static MYSQL_SYSVAR_UINT(limit_optimistic_insert_debug, btr_cur_limit_optimistic_insert_debug, PLUGIN_VAR_RQCMDARG, "Artificially limit the number of records per B-tree page (0=unlimited).", NULL, NULL, 0, 0, UINT_MAX32, 0); + +static MYSQL_SYSVAR_BOOL(trx_purge_view_update_only_debug, + srv_purge_view_update_only_debug, PLUGIN_VAR_NOCMDARG, + "Pause actual purging any delete-marked records, but merely update the purge view. " + "It is to create artificially the situation the purge view have been updated " + "but the each purges were not done yet.", + NULL, NULL, FALSE); #endif /* UNIV_DEBUG */ static struct st_mysql_sys_var* innobase_system_variables[]= { @@ -11337,6 +11346,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { #ifdef UNIV_DEBUG MYSQL_SYSVAR(trx_rseg_n_slots_debug), MYSQL_SYSVAR(limit_optimistic_insert_debug), + MYSQL_SYSVAR(trx_purge_view_update_only_debug), #endif /* UNIV_DEBUG */ NULL }; diff --git a/storage/innodb_plugin/include/lock0lock.h b/storage/innodb_plugin/include/lock0lock.h index b3e1e5c4537..1b472e7b059 100644 --- a/storage/innodb_plugin/include/lock0lock.h +++ b/storage/innodb_plugin/include/lock0lock.h @@ -796,14 +796,22 @@ lock_rec_get_page_no( remains set when the waiting lock is granted, or if the lock is inherited to a neighboring record */ -#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_MODE_MASK +#define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created + by other transaction */ +#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_MODE_MASK # error #endif -#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION)&LOCK_TYPE_MASK +#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK # error #endif /* @} */ +/** Checks if this is a waiting lock created by lock->trx itself. +@param type_mode lock->type_mode +@return whether it is a waiting lock belonging to lock->trx */ +#define lock_is_wait_not_by_other(type_mode) \ + ((type_mode & (LOCK_CONV_BY_OTHER | LOCK_WAIT)) == LOCK_WAIT) + /** Lock operation struct */ typedef struct lock_op_struct lock_op_t; /** Lock operation struct */ diff --git a/storage/innodb_plugin/include/srv0srv.h b/storage/innodb_plugin/include/srv0srv.h index 089a4c1c777..322c15ffe45 100644 --- a/storage/innodb_plugin/include/srv0srv.h +++ b/storage/innodb_plugin/include/srv0srv.h @@ -247,6 +247,10 @@ extern ulint srv_fatal_semaphore_wait_threshold; #define SRV_SEMAPHORE_WAIT_EXTENSION 7200 extern ulint srv_dml_needed_delay; +#ifdef UNIV_DEBUG +extern my_bool srv_purge_view_update_only_debug; +#endif /* UNIV_DEBUG */ + extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs, query threads, and lock table: we allocate it from dynamic memory to get it to the @@ -652,6 +656,8 @@ struct export_var_struct{ ulint innodb_rows_deleted; /*!< srv_n_rows_deleted */ #ifdef UNIV_DEBUG ulint innodb_purge_trx_id_age; /*!< max_trx_id - purged trx_id */ + ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id + - purged view's min trx_id */ #endif /* UNIV_DEBUG */ }; diff --git a/storage/innodb_plugin/lock/lock0lock.c b/storage/innodb_plugin/lock/lock0lock.c index 49f732da175..f302e9b1011 100644 --- a/storage/innodb_plugin/lock/lock0lock.c +++ b/storage/innodb_plugin/lock/lock0lock.c @@ -791,12 +791,16 @@ lock_reset_lock_and_trx_wait( /*=========================*/ lock_t* lock) /*!< in: record lock */ { - ut_ad((lock->trx)->wait_lock == lock); ut_ad(lock_get_wait(lock)); /* Reset the back pointer in trx to this waiting lock request */ - (lock->trx)->wait_lock = NULL; + if (!(lock->type_mode & LOCK_CONV_BY_OTHER)) { + ut_ad((lock->trx)->wait_lock == lock); + (lock->trx)->wait_lock = NULL; + } else { + ut_ad(lock_get_type_low(lock) == LOCK_REC); + } lock->type_mode &= ~LOCK_WAIT; } @@ -1420,9 +1424,9 @@ lock_rec_has_expl( while (lock) { if (lock->trx == trx + && !lock_is_wait_not_by_other(lock->type_mode) && lock_mode_stronger_or_eq(lock_get_mode(lock), precise_mode & LOCK_MODE_MASK) - && !lock_get_wait(lock) && (!lock_rec_get_rec_not_gap(lock) || (precise_mode & LOCK_REC_NOT_GAP) || heap_no == PAGE_HEAP_NO_SUPREMUM) @@ -1721,7 +1725,7 @@ lock_rec_create( HASH_INSERT(lock_t, hash, lock_sys->rec_hash, lock_rec_fold(space, page_no), lock); - if (UNIV_UNLIKELY(type_mode & LOCK_WAIT)) { + if (lock_is_wait_not_by_other(type_mode)) { lock_set_lock_and_trx_wait(lock, trx); } @@ -1752,10 +1756,11 @@ lock_rec_enqueue_waiting( const buf_block_t* block, /*!< in: buffer block containing the record */ ulint heap_no,/*!< in: heap number of the record */ + lock_t* lock, /*!< in: lock object; NULL if a new + one should be created. */ dict_index_t* index, /*!< in: index of record */ que_thr_t* thr) /*!< in: query thread */ { - lock_t* lock; trx_t* trx; ut_ad(mutex_own(&kernel_mutex)); @@ -1789,9 +1794,17 @@ lock_rec_enqueue_waiting( stderr); } - /* Enqueue the lock request that will wait to be granted */ - lock = lock_rec_create(type_mode | LOCK_WAIT, - block, heap_no, index, trx); + if (lock == NULL) { + /* Enqueue the lock request that will wait to be granted */ + lock = lock_rec_create(type_mode | LOCK_WAIT, + block, heap_no, index, trx); + } else { + ut_ad(lock->type_mode & LOCK_WAIT); + ut_ad(lock->type_mode & LOCK_CONV_BY_OTHER); + + lock->type_mode &= ~LOCK_CONV_BY_OTHER; + lock_set_lock_and_trx_wait(lock, trx); + } /* Check if a deadlock occurs: if yes, remove the lock request and return an error code */ @@ -2036,6 +2049,7 @@ lock_rec_lock_slow( que_thr_t* thr) /*!< in: query thread */ { trx_t* trx; + lock_t* lock; ut_ad(mutex_own(&kernel_mutex)); ut_ad((LOCK_MODE_MASK & mode) != LOCK_S @@ -2050,7 +2064,27 @@ lock_rec_lock_slow( trx = thr_get_trx(thr); - if (lock_rec_has_expl(mode, block, heap_no, trx)) { + lock = lock_rec_has_expl(mode, block, heap_no, trx); + if (lock) { + if (lock->type_mode & LOCK_CONV_BY_OTHER) { + /* This lock or lock waiting was created by the other + transaction, not by the transaction (trx) itself. + So, the transaction (trx) should treat it collectly + according as whether granted or not. */ + + if (lock->type_mode & LOCK_WAIT) { + /* This lock request was not granted yet. + Should wait for granted. */ + + goto enqueue_waiting; + } else { + /* This lock request was already granted. + Just clearing the flag. */ + + lock->type_mode &= ~LOCK_CONV_BY_OTHER; + } + } + /* The trx already has a strong enough lock on rec: do nothing */ @@ -2060,8 +2094,10 @@ lock_rec_lock_slow( the queue, as this transaction does not have a lock strong enough already granted on the record, we have to wait. */ + ut_ad(lock == NULL); +enqueue_waiting: return(lock_rec_enqueue_waiting(mode, block, heap_no, - index, thr)); + lock, index, thr)); } else if (!impl) { /* Set the requested lock on the record */ @@ -2203,7 +2239,8 @@ lock_grant( TRX_QUE_LOCK_WAIT state, and there is no need to end the lock wait for it */ - if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) { + if (!(lock->type_mode & LOCK_CONV_BY_OTHER) + && lock->trx->que_state == TRX_QUE_LOCK_WAIT) { trx_end_lock_wait(lock->trx); } } @@ -2220,6 +2257,7 @@ lock_rec_cancel( { ut_ad(mutex_own(&kernel_mutex)); ut_ad(lock_get_type_low(lock) == LOCK_REC); + ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER)); /* Reset the bit (there can be only one set bit) in the lock bitmap */ lock_rec_reset_nth_bit(lock, lock_rec_find_set_bit(lock)); @@ -2362,8 +2400,12 @@ lock_rec_reset_and_release_wait( lock = lock_rec_get_first(block, heap_no); while (lock != NULL) { - if (lock_get_wait(lock)) { + if (lock_is_wait_not_by_other(lock->type_mode)) { lock_rec_cancel(lock); + } else if (lock_get_wait(lock)) { + /* just reset LOCK_WAIT */ + lock_rec_reset_nth_bit(lock, heap_no); + lock_reset_lock_and_trx_wait(lock); } else { lock_rec_reset_nth_bit(lock, heap_no); } @@ -3588,6 +3630,7 @@ lock_table_create( ut_ad(table && trx); ut_ad(mutex_own(&kernel_mutex)); + ut_ad(!(type_mode & LOCK_CONV_BY_OTHER)); if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) { ++table->n_waiting_or_granted_auto_inc_locks; @@ -4139,6 +4182,7 @@ lock_cancel_waiting_and_release( lock_t* lock) /*!< in: waiting lock request */ { ut_ad(mutex_own(&kernel_mutex)); + ut_ad(!(lock->type_mode & LOCK_CONV_BY_OTHER)); if (lock_get_type_low(lock) == LOCK_REC) { @@ -5153,7 +5197,7 @@ lock_rec_insert_check_and_lock( err = lock_rec_enqueue_waiting(LOCK_X | LOCK_GAP | LOCK_INSERT_INTENTION, block, next_rec_heap_no, - index, thr); + NULL, index, thr); } else { err = DB_SUCCESS; } @@ -5229,10 +5273,23 @@ lock_rec_convert_impl_to_expl( if (!lock_rec_has_expl(LOCK_X | LOCK_REC_NOT_GAP, block, heap_no, impl_trx)) { + ulint type_mode = (LOCK_REC | LOCK_X + | LOCK_REC_NOT_GAP); + + /* If the delete-marked record was locked already, + we should reserve lock waiting for impl_trx as + implicit lock. Because cannot lock at this moment.*/ + + if (rec_get_deleted_flag(rec, rec_offs_comp(offsets)) + && lock_rec_other_has_conflicting( + LOCK_X | LOCK_REC_NOT_GAP, block, + heap_no, impl_trx)) { + + type_mode |= (LOCK_WAIT | LOCK_CONV_BY_OTHER); + } lock_rec_add_to_queue( - LOCK_REC | LOCK_X | LOCK_REC_NOT_GAP, - block, heap_no, index, impl_trx); + type_mode, block, heap_no, index, impl_trx); } } } diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c index 92ce04774ea..7e81cf6ab2c 100644 --- a/storage/innodb_plugin/row/row0ins.c +++ b/storage/innodb_plugin/row/row0ins.c @@ -2265,7 +2265,10 @@ row_ins_index_entry( err = row_ins_index_entry_low(BTR_MODIFY_LEAF, index, entry, n_ext, thr); if (err != DB_FAIL) { - + if (index == dict_table_get_first_index(index->table) + && thr_get_trx(thr)->mysql_thd != 0) { + DEBUG_SYNC_C("row_ins_clust_index_entry_leaf_after"); + } return(err); } diff --git a/storage/innodb_plugin/srv/srv0srv.c b/storage/innodb_plugin/srv/srv0srv.c index da5861d8c87..4ddd0a4603d 100644 --- a/storage/innodb_plugin/srv/srv0srv.c +++ b/storage/innodb_plugin/srv/srv0srv.c @@ -85,6 +85,7 @@ Created 10/8/1995 Heikki Tuuri #include "ha_prototypes.h" #include "trx0i_s.h" #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */ +#include "read0read.h" #ifdef __WIN__ /* error LNK2001: unresolved external symbol _debug_sync_C_callback_ptr */ @@ -1983,6 +1984,16 @@ srv_export_innodb_status(void) export_vars.innodb_purge_trx_id_age = ut_dulint_minus(trx_sys->max_trx_id, purge_sys->done_trx_no); } + + if (!purge_sys->view + || ut_dulint_cmp(trx_sys->max_trx_id, + purge_sys->view->up_limit_id) < 0) { + export_vars.innodb_purge_view_trx_id_age = 0; + } else { + export_vars.innodb_purge_view_trx_id_age = + ut_dulint_minus(trx_sys->max_trx_id, + purge_sys->view->up_limit_id); + } #endif /* UNIV_DEBUG */ mutex_exit(&srv_innodb_monitor_mutex); diff --git a/storage/innodb_plugin/trx/trx0purge.c b/storage/innodb_plugin/trx/trx0purge.c index ea508c1003c..4e79187b5c5 100644 --- a/storage/innodb_plugin/trx/trx0purge.c +++ b/storage/innodb_plugin/trx/trx0purge.c @@ -51,6 +51,10 @@ UNIV_INTERN trx_purge_t* purge_sys = NULL; which needs no purge */ UNIV_INTERN trx_undo_rec_t trx_purge_dummy_rec; +#ifdef UNIV_DEBUG +UNIV_INTERN my_bool srv_purge_view_update_only_debug; +#endif /* UNIV_DEBUG */ + /*****************************************************************//** Checks if trx_id is >= purge_view: then it is guaranteed that its update undo log still exists in the system. @@ -1142,6 +1146,13 @@ trx_purge(void) rw_lock_x_unlock(&(purge_sys->latch)); +#ifdef UNIV_DEBUG + if (srv_purge_view_update_only_debug) { + mutex_exit(&(purge_sys->mutex)); + return(0); + } +#endif + purge_sys->state = TRX_PURGE_ON; /* Handle at most 20 undo log pages in one purge batch */ From 92f7dc41b50ff1451bdc0f7f4deac354d2bee7c1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Nov 2012 19:01:59 +0530 Subject: [PATCH 051/324] From c1f9f122d52c4497387f3b86d87a35000b3e5f54 Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Thu, 29 Nov 2012 17:23:23 +0530 Subject: [PATCH 052/324] Bug#15912213: BUFFER OVERFLOW IN ACL_GET() Description: A very large database name causes buffer overflow in functions acl_get() and check_grant_db() in sql_acl.cc. It happens due to an unguarded string copy operation. This puts required sanity checks before copying db string to destination buffer. --- sql/sql_acl.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index e07f668b1cf..80662832140 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1356,10 +1356,19 @@ ulong acl_get(const char *host, const char *ip, { ulong host_access= ~(ulong)0, db_access= 0; uint i; - size_t key_length; + size_t key_length, copy_length; char key[ACL_KEY_LENGTH],*tmp_db,*end; acl_entry *entry; DBUG_ENTER("acl_get"); + + copy_length= (size_t) (strlen(ip ? ip : "") + + strlen(user ? user : "") + + strlen(db ? db : "")); + /* + Make sure that strmov() operations do not result in buffer overflow. + */ + if (copy_length >= ACL_KEY_LENGTH) + DBUG_RETURN(0); VOID(pthread_mutex_lock(&acl_cache->lock)); end=strmov((tmp_db=strmov(strmov(key, ip ? ip : "")+1,user)+1),db); @@ -4340,6 +4349,16 @@ bool check_grant_db(THD *thd,const char *db) char helping [NAME_LEN+USERNAME_LENGTH+2]; uint len; bool error= TRUE; + size_t copy_length; + + copy_length= (size_t) (strlen(sctx->priv_user ? sctx->priv_user : "") + + strlen(db ? db : "")); + + /* + Make sure that strmov() operations do not result in buffer overflow. + */ + if (copy_length >= (NAME_LEN+USERNAME_LENGTH+2)) + return 1; len= (uint) (strmov(strmov(helping, sctx->priv_user) + 1, db) - helping) + 1; From fe4fe4e1cc8c65ace419764fc07594456b900510 Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Thu, 29 Nov 2012 17:33:06 +0530 Subject: [PATCH 053/324] BUG#15888454: SLAVE CRASHES WHEN DML REQUIRES CONVERSION & TABLE HAS LESS COLUMNS THAN MASTER Problem: ======== If DML operation requires a converstion at slave and if slave contains less number of columns than master, slave is crashing. Fix: ==== When Slave applies any DML operation, it sees if any of the columns requires conversion. If yes, it creates conversion table. While creating the coversion table, it should look into the actual number of columns required to create the table instead of getting the number of columns from Master (size()). Columns would have dropped or added at Slave. So the value should be min(columns@master, columns@slave) sql/rpl_utility.cc: loop through only correct number of columns --- sql/rpl_utility.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 627bad741e8..8efb376b5b6 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -878,8 +878,13 @@ TABLE *table_def::create_conversion_table(THD *thd, Relay_log_info *rli, TABLE * DBUG_ENTER("table_def::create_conversion_table"); List field_list; - - for (uint col= 0 ; col < size() ; ++col) + /* + At slave, columns may differ. So we should create + min(columns@master, columns@slave) columns in the + conversion table. + */ + uint const cols_to_create= min(target_table->s->fields, size()); + for (uint col= 0 ; col < cols_to_create; ++col) { Create_field *field_def= (Create_field*) alloc_root(thd->mem_root, sizeof(Create_field)); From 6cbbe2392fa58a7e58d3e9800da9909bfa99c179 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Thu, 29 Nov 2012 17:21:36 +0100 Subject: [PATCH 054/324] Bug#11754279 SIGNIFICANT INACCURACY IN DECIMAL MULTIPLICATION CALCULATIONS frac is the number of decimal digits after the point For each multiplication in the expression, decimal_mul() does this: to->frac= from1->frac + from2->frac; /* store size in digits */ which will eventually overflow. The code for handling the overflow, will truncate the two digits in "1.75" to "1" Solution: Truncate to 31 significant fractional digits, when doing decimal multiplication. --- strings/decimal.c | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/strings/decimal.c b/strings/decimal.c index 3a170728546..4790ed70f42 100644 --- a/strings/decimal.c +++ b/strings/decimal.c @@ -1989,44 +1989,45 @@ int decimal_mul(const decimal_t *from1, const decimal_t *from2, decimal_t *to) int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg), frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac), intg0=ROUND_UP(from1->intg+from2->intg), - frac0=frac1+frac2, error, i, j, d_to_move; + frac0=frac1+frac2, error, iii, jjj, d_to_move; dec1 *buf1=from1->buf+intg1, *buf2=from2->buf+intg2, *buf0, *start2, *stop2, *stop1, *start0, carry; sanity(to); - i=intg0; /* save 'ideal' values */ - j=frac0; + iii= intg0; /* save 'ideal' values */ + jjj= frac0; FIX_INTG_FRAC_ERROR(to->len, intg0, frac0, error); /* bound size */ - to->sign=from1->sign != from2->sign; - to->frac=from1->frac+from2->frac; /* store size in digits */ + to->sign= from1->sign != from2->sign; + to->frac= from1->frac + from2->frac; /* store size in digits */ + set_if_smaller(to->frac, NOT_FIXED_DEC); to->intg=intg0*DIG_PER_DEC1; if (unlikely(error)) { set_if_smaller(to->frac, frac0*DIG_PER_DEC1); set_if_smaller(to->intg, intg0*DIG_PER_DEC1); - if (unlikely(i > intg0)) /* bounded integer-part */ + if (unlikely(iii > intg0)) /* bounded integer-part */ { - i-=intg0; - j=i >> 1; - intg1-= j; - intg2-=i-j; + iii-=intg0; + jjj= iii >> 1; + intg1-= jjj; + intg2-=iii-jjj; frac1=frac2=0; /* frac0 is already 0 here */ } else /* bounded fract part */ { - j-=frac0; - i=j >> 1; + jjj-=frac0; + iii=jjj >> 1; if (frac1 <= frac2) { - frac1-= i; - frac2-=j-i; + frac1-= iii; + frac2-=jjj-iii; } else { - frac2-= i; - frac1-=j-i; + frac2-= iii; + frac1-=jjj-iii; } } } From 07ffa9c767a7b2633b7dd21dcca8d7f89dada601 Mon Sep 17 00:00:00 2001 From: Shivji Kumar Jha Date: Fri, 30 Nov 2012 12:12:33 +0530 Subject: [PATCH 055/324] BUG#12359942 - REPLICATION TEST FROM ENGINE SUITE RPL_ROW_UNTIL TIMES OUT === Problem === The test is dependent on binlog positions and checks to see if the command 'START SLAVE' functions correctly with the 'UNTIL' clause added to it. The 'UNTIL' clause is added to specify that the slave should start and run until the SQL thread reaches a given point in the master binary log or in the slave relay log. The test uses hard coded values for MASTER_LOG_POS and RELAY_LOG_POS, instead of extracting it using query_get_value() function. There is a test 'rpl.rpl_row_until' which does the similar thing but uses query_get_value() function to set the values of MASTER_LOG_POS/ RELAY_LOG_POS. To be precise, rpl.rpl_row_until is a modified version of engines/func.rpl_row_until.test. The use of hard coded values may lead the slave to stop at a position which may differ from the expected position in the binlog file, an example being the failure of engines/funcs.rpl_row_until in mysql-5.1 given as: "query 'select * from t2' failed. Table 'test.t2' doesn't exist". In this case, the slave actually ran a couple of extra commands as a result of which the slave first deleted the table and then ran a select query on table, leading to the above mentioned failure. === Fix === 1) Fixed the code for failure seen in rpl.rpl_row_until. This test was also failing although the symptoms of failure were different. 2) Copied the contents from rpl.rpl_row_until into into engines/funcs.rpl.rpl_row_until. 3) Updated engines/funcs.rpl_row_until.result accordingly. mysql-test/suite/engines/funcs/r/rpl_row_until.result: modified to accomodate the changes in corresponding test file. mysql-test/suite/engines/funcs/t/disabled.def: removed from the list of disabled tests. mysql-test/suite/engines/funcs/t/rpl_row_until.test: fixed rpl.rpl_row_until and copied its content to engines/funcs.rpl_row_until. The reason being both are same tests but rpl.rpl_row_until is an updated version. mysql-test/suite/rpl/t/disabled.def: removed from the list of disabled tests. sql/sql_repl.cc: Added a check to catch an improper combination of arguements passed to 'START SLAVE UNTIL'. Earlier, START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=561, RELAY_LOG_POS=12; passed. It is now detected and an error is reported. --- .../engines/funcs/r/rpl_row_until.result | 242 ++++-------------- mysql-test/suite/engines/funcs/t/disabled.def | 1 - .../suite/engines/funcs/t/rpl_row_until.test | 166 +++++++----- mysql-test/suite/rpl/t/disabled.def | 1 - sql/sql_repl.cc | 4 + 5 files changed, 154 insertions(+), 260 deletions(-) diff --git a/mysql-test/suite/engines/funcs/r/rpl_row_until.result b/mysql-test/suite/engines/funcs/r/rpl_row_until.result index 5091a9f6468..5629f5c8cdd 100644 --- a/mysql-test/suite/engines/funcs/r/rpl_row_until.result +++ b/mysql-test/suite/engines/funcs/r/rpl_row_until.result @@ -1,204 +1,60 @@ -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; -stop slave; -create table t1(n int not null auto_increment primary key); -insert into t1 values (1),(2),(3),(4); -drop table t1; -create table t2(n int not null auto_increment primary key); -insert into t2 values (1),(2); -insert into t2 values (3),(4); -drop table t2; -start slave until master_log_file='master-bin.000001', master_log_pos=311; -select * from t1; +include/master-slave.inc +[connection master] +CREATE TABLE t1(n INT NOT NULL AUTO_INCREMENT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3),(4); +DROP TABLE t1; +CREATE TABLE t2(n INT NOT NULL AUTO_INCREMENT PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2); +INSERT INTO t2 VALUES (3),(4); +DROP TABLE t2; +include/stop_slave.inc +RESET SLAVE; +START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=master_pos_drop_t1 +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t1; n 1 2 3 4 -show slave status; -Slave_IO_State # -Master_Host 127.0.0.1 -Master_User root -Master_Port MASTER_MYPORT -Connect_Retry 1 -Master_Log_File master-bin.000001 -Read_Master_Log_Pos # -Relay_Log_File slave-relay-bin.000004 -Relay_Log_Pos # -Relay_Master_Log_File master-bin.000001 -Slave_IO_Running # -Slave_SQL_Running No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 0 -Last_Error -Skip_Counter 0 -Exec_Master_Log_Pos # -Relay_Log_Space # -Until_Condition Master -Until_Log_File master-bin.000001 -Until_Log_Pos 311 -Master_SSL_Allowed No -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 No -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 0 -Last_SQL_Error -start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; -select * from t1; -n 1 -n 2 -n 3 -n 4 -show slave status; -Slave_IO_State # -Master_Host 127.0.0.1 -Master_User root -Master_Port MASTER_MYPORT -Connect_Retry 1 -Master_Log_File master-bin.000001 -Read_Master_Log_Pos # -Relay_Log_File slave-relay-bin.000004 -Relay_Log_Pos # -Relay_Master_Log_File master-bin.000001 -Slave_IO_Running # -Slave_SQL_Running No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 0 -Last_Error -Skip_Counter 0 -Exec_Master_Log_Pos # -Relay_Log_Space # -Until_Condition Master -Until_Log_File master-no-such-bin.000001 -Until_Log_Pos 291 -Master_SSL_Allowed No -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 No -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 0 -Last_SQL_Error -start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; -select * from t2; -show slave status; -Slave_IO_State # -Master_Host 127.0.0.1 -Master_User root -Master_Port MASTER_MYPORT -Connect_Retry 1 -Master_Log_File master-bin.000001 -Read_Master_Log_Pos # -Relay_Log_File slave-relay-bin.000004 -Relay_Log_Pos # -Relay_Master_Log_File master-bin.000001 -Slave_IO_Running # -Slave_SQL_Running No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 0 -Last_Error -Skip_Counter 0 -Exec_Master_Log_Pos # -Relay_Log_Space # -Until_Condition Relay -Until_Log_File slave-relay-bin.000004 -Until_Log_Pos 728 -Master_SSL_Allowed No -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 No -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 0 -Last_SQL_Error -start slave; -stop slave; -start slave until master_log_file='master-bin.000001', master_log_pos=740; -show slave status; -Slave_IO_State # -Master_Host 127.0.0.1 -Master_User root -Master_Port MASTER_MYPORT -Connect_Retry 1 -Master_Log_File master-bin.000001 -Read_Master_Log_Pos # -Relay_Log_File slave-relay-bin.000004 -Relay_Log_Pos # -Relay_Master_Log_File master-bin.000001 -Slave_IO_Running Yes -Slave_SQL_Running No -Replicate_Do_DB -Replicate_Ignore_DB -Replicate_Do_Table -Replicate_Ignore_Table -Replicate_Wild_Do_Table -Replicate_Wild_Ignore_Table -Last_Errno 0 -Last_Error -Skip_Counter 0 -Exec_Master_Log_Pos # -Relay_Log_Space # -Until_Condition Master -Until_Log_File master-bin.000001 -Until_Log_Pos 740 -Master_SSL_Allowed No -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 No -Last_IO_Errno 0 -Last_IO_Error -Last_SQL_Errno 0 -Last_SQL_Error -start slave until master_log_file='master-bin', master_log_pos=561; +include/check_slave_param.inc [Exec_Master_Log_Pos] +START SLAVE UNTIL MASTER_LOG_FILE='master-no-such-bin.000001', MASTER_LOG_POS=MASTER_LOG_POS; +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t1; +n +1 +2 +3 +4 +include/check_slave_param.inc [Exec_Master_Log_Pos] +START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=relay_pos_insert1_t2 +include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t2; +n +1 +2 +include/check_slave_param.inc [Exec_Master_Log_Pos] +START SLAVE; +include/wait_for_slave_to_start.inc +include/stop_slave.inc +START SLAVE SQL_THREAD UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=master_pos_create_t2 +include/wait_for_slave_param.inc [Until_Log_Pos] +include/wait_for_slave_sql_to_stop.inc +include/check_slave_param.inc [Exec_Master_Log_Pos] +START SLAVE UNTIL MASTER_LOG_FILE='master-bin', MASTER_LOG_POS=MASTER_LOG_POS; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL -start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; +START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=MASTER_LOG_POS, RELAY_LOG_POS=RELAY_LOG_POS; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL -start slave until master_log_file='master-bin.000001'; +START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001'; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL -start slave until relay_log_file='slave-relay-bin.000002'; +START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000009'; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL -start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561; +START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', MASTER_LOG_POS=MASTER_LOG_POS; ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL -start slave sql_thread; -start slave until master_log_file='master-bin.000001', master_log_pos=740; +START SLAVE; +START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=MASTER_LOG_POS; Warnings: -Level Note -Code 1254 -Message Slave is already running +Note 1254 Slave is already running +include/stop_slave.inc +RESET SLAVE; +include/rpl_end.inc diff --git a/mysql-test/suite/engines/funcs/t/disabled.def b/mysql-test/suite/engines/funcs/t/disabled.def index 5b6e3f6a281..586abe7171f 100644 --- a/mysql-test/suite/engines/funcs/t/disabled.def +++ b/mysql-test/suite/engines/funcs/t/disabled.def @@ -72,7 +72,6 @@ rpl000017 : Result Difference Due to Change in .inc file rpl_skip_error : Result Difference Due to Change in .inc file rpl_sp : Result Difference Due to Change in .inc file -rpl_row_until : Test Present in rpl suite as well . Test Fails with table t2 not found. rpl_loaddata_s : Test Present in rpl suite as well . Test Fails due to bin log truncation. rpl_log_pos : Test Present in rpl suite as well . Test Fails due to bin log truncation. rpl_row_NOW : Result Difference Due to Change in .inc file diff --git a/mysql-test/suite/engines/funcs/t/rpl_row_until.test b/mysql-test/suite/engines/funcs/t/rpl_row_until.test index ccd9ce11637..bf38bd487ea 100644 --- a/mysql-test/suite/engines/funcs/t/rpl_row_until.test +++ b/mysql-test/suite/engines/funcs/t/rpl_row_until.test @@ -2,90 +2,126 @@ -- source include/have_binlog_format_row.inc -- source include/master-slave.inc -# Test is dependent on binlog positions +# Note: The test is dependent on binlog positions -# prepare version for substitutions -let $VERSION=`select version()`; - -# stop slave before he will start replication also sync with master -# for avoiding undetermenistic behaviour +# Create some events on master +connection master; +CREATE TABLE t1(n INT NOT NULL AUTO_INCREMENT PRIMARY KEY); +INSERT INTO t1 VALUES (1),(2),(3),(4); +DROP TABLE t1; +# Save master log position for query DROP TABLE t1 save_master_pos; -connection slave; -sync_with_master; -stop slave; +let $master_pos_drop_t1= query_get_value(SHOW BINLOG EVENTS, Pos, 7); +let $master_log_file= query_get_value(SHOW BINLOG EVENTS, Log_name, 7); + +CREATE TABLE t2(n INT NOT NULL AUTO_INCREMENT PRIMARY KEY); +# Save master log position for query CREATE TABLE t2 +save_master_pos; +let $master_pos_create_t2= query_get_value(SHOW BINLOG EVENTS, Pos, 8); + +INSERT INTO t2 VALUES (1),(2); +save_master_pos; +# Save master log position for query INSERT INTO t2 VALUES (1),(2); +let $master_pos_insert1_t2= query_get_value(SHOW BINLOG EVENTS, End_log_pos, 12); +sync_slave_with_master; + +# Save relay log position for query INSERT INTO t2 VALUES (1),(2); +let $relay_pos_insert1_t2= query_get_value(show slave status, Relay_Log_Pos, 1); connection master; -# create some events on master -create table t1(n int not null auto_increment primary key); -insert into t1 values (1),(2),(3),(4); -drop table t1; -create table t2(n int not null auto_increment primary key); -insert into t2 values (1),(2); -insert into t2 values (3),(4); -drop table t2; +INSERT INTO t2 VALUES (3),(4); +DROP TABLE t2; +# Save master log position for query INSERT INTO t2 VALUES (1),(2); +let $master_pos_drop_t2= query_get_value(SHOW BINLOG EVENTS, End_log_pos, 17); +sync_slave_with_master; -# try to replicate all queries until drop of t1 +--source include/stop_slave.inc +# Reset slave. +RESET SLAVE; +--disable_query_log +eval CHANGE MASTER TO MASTER_USER='root', MASTER_CONNECT_RETRY=1, MASTER_HOST='127.0.0.1', MASTER_PORT=$MASTER_MYPORT; +--enable_query_log + +# Try to replicate all queries until drop of t1 connection slave; -start slave until master_log_file='master-bin.000001', master_log_pos=311; -sleep 2; -wait_for_slave_to_stop; -# here table should be still not deleted -select * from t1; ---vertical_results ---replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 7 # 9 # 11 # 22 # 23 # 33 # -show slave status; +echo START SLAVE UNTIL MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=master_pos_drop_t1; +--disable_query_log +eval START SLAVE UNTIL MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=$master_pos_drop_t1; +--enable_query_log +--source include/wait_for_slave_sql_to_stop.inc -# this should fail right after start -start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; +# Here table should be still not deleted +SELECT * FROM t1; +--let $slave_param= Exec_Master_Log_Pos +--let $slave_param_value= $master_pos_drop_t1 +--source include/check_slave_param.inc + +# This should fail right after start +--replace_result 291 MASTER_LOG_POS +START SLAVE UNTIL MASTER_LOG_FILE='master-no-such-bin.000001', MASTER_LOG_POS=291; +--source include/wait_for_slave_sql_to_stop.inc # again this table should be still not deleted -select * from t1; -sleep 2; -wait_for_slave_to_stop; ---vertical_results ---replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 7 # 9 # 11 # 22 # 23 # 33 # -show slave status; +SELECT * FROM t1; -# try replicate all up to and not including the second insert to t2; -start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=728; -sleep 2; -wait_for_slave_to_stop; -select * from t2; ---vertical_results ---replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 7 # 9 # 11 # 22 # 23 # 33 # -show slave status; +--let $slave_param= Exec_Master_Log_Pos +--let $slave_param_value= $master_pos_drop_t1 +--source include/check_slave_param.inc + +# Try replicate all up to and not including the second insert to t2; +echo START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=relay_pos_insert1_t2; +--disable_query_log +eval START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=$relay_pos_insert1_t2; +--enable_query_log +--source include/wait_for_slave_sql_to_stop.inc +SELECT * FROM t2; + +--let $slave_param= Exec_Master_Log_Pos +--let $slave_param_value= $master_pos_insert1_t2 +--source include/check_slave_param.inc # clean up -start slave; +START SLAVE; +--source include/wait_for_slave_to_start.inc connection master; -save_master_pos; -connection slave; -sync_with_master; -stop slave; +sync_slave_with_master; +--source include/stop_slave.inc -# this should stop immediately as we are already there -start slave until master_log_file='master-bin.000001', master_log_pos=740; -sleep 2; -wait_for_slave_to_stop; +# This should stop immediately as we are already there +echo START SLAVE SQL_THREAD UNTIL MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=master_pos_create_t2; +--disable_query_log +eval START SLAVE SQL_THREAD UNTIL MASTER_LOG_FILE='$master_log_file', MASTER_LOG_POS=$master_pos_create_t2; +--enable_query_log +let $slave_param= Until_Log_Pos; +let $slave_param_value= $master_pos_create_t2; +--source include/wait_for_slave_param.inc +--source include/wait_for_slave_sql_to_stop.inc # here the sql slave thread should be stopped ---vertical_results ---replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004 ---replace_column 1 # 7 # 9 # 22 # 23 # 33 # -show slave status; +--let $slave_param= Exec_Master_Log_Pos +--let $slave_param_value= $master_pos_drop_t2 +--source include/check_slave_param.inc #testing various error conditions +--replace_result 561 MASTER_LOG_POS --error 1277 -start slave until master_log_file='master-bin', master_log_pos=561; +START SLAVE UNTIL MASTER_LOG_FILE='master-bin', MASTER_LOG_POS=561; +--replace_result 561 MASTER_LOG_POS 12 RELAY_LOG_POS --error 1277 -start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12; +START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=561, RELAY_LOG_POS=12; --error 1277 -start slave until master_log_file='master-bin.000001'; +START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001'; --error 1277 -start slave until relay_log_file='slave-relay-bin.000002'; +START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000009'; +--replace_result 561 MASTER_LOG_POS --error 1277 -start slave until relay_log_file='slave-relay-bin.000002', master_log_pos=561; +START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', MASTER_LOG_POS=561; # Warning should be given for second command -start slave sql_thread; -start slave until master_log_file='master-bin.000001', master_log_pos=740; +START SLAVE; +--replace_result 740 MASTER_LOG_POS +START SLAVE UNTIL MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=740; + +--source include/stop_slave.inc +# Clear slave IO error. +RESET SLAVE; + +--let $rpl_only_running_threads= 1 +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 0a8f3cb2a50..808dfc268a9 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -12,5 +12,4 @@ rpl_row_create_table : Bug#11759274 Feb 27 2010 andrei failed different way than earlier with bug#45576 rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock -rpl_row_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out rpl_stm_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 7aa8176ae62..c15382c669e 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -869,6 +869,8 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) if (thd->lex->mi.pos) { + if (thd->lex->mi.relay_log_pos) + slave_errno=ER_BAD_SLAVE_UNTIL_COND; mi->rli.until_condition= Relay_log_info::UNTIL_MASTER_POS; mi->rli.until_log_pos= thd->lex->mi.pos; /* @@ -880,6 +882,8 @@ int start_slave(THD* thd , Master_info* mi, bool net_report) } else if (thd->lex->mi.relay_log_pos) { + if (thd->lex->mi.pos) + slave_errno=ER_BAD_SLAVE_UNTIL_COND; mi->rli.until_condition= Relay_log_info::UNTIL_RELAY_POS; mi->rli.until_log_pos= thd->lex->mi.relay_log_pos; strmake(mi->rli.until_log_name, thd->lex->mi.relay_log_name, From 60fff18d774518fbca00961c9511f3ea1bd177f2 Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Fri, 30 Nov 2012 16:19:30 +0500 Subject: [PATCH 056/324] Reverting fix for bug#14329288 revid that is being reverted: marko.makela@oracle.com-20121128070024-hb56t41limja8edz --- storage/innodb_plugin/ChangeLog | 6 ------ storage/innodb_plugin/buf/buf0buf.c | 20 ++++---------------- 2 files changed, 4 insertions(+), 22 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 72f75f39b1d..5387555d24f 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,9 +1,3 @@ -2012-11-28 The InnoDB Team - - * buf/buf0buf.c: - Fix Bug#14329288 IS THE CALL TO IBUF_MERGE_OR_DELETE_FOR_PAGE FROM - BUF_PAGE_GET_GEN REDUNDANT? - 2012-11-15 The InnoDB Team * include/data0type.ic, include/rem0rec.h, diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index 1222f016c4a..755fa947c8f 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -1786,26 +1786,14 @@ wait_until_unfixed: buf_page_free_descriptor(bpage); - /* Decompress the page while not holding - buf_pool_mutex or block->mutex. */ + /* Decompress the page and apply buffered operations + while not holding buf_pool_mutex or block->mutex. */ success = buf_zip_decompress(block, srv_use_checksums); ut_a(success); if (UNIV_LIKELY(!recv_no_ibuf_operations)) { - unsigned accessed; - - mutex_enter(&block->mutex); - accessed = buf_page_is_accessed(&block->page); - mutex_exit(&block->mutex); - - if (accessed) { -#ifdef UNIV_IBUF_COUNT_DEBUG - ut_a(ibuf_count_get(space, offset) == 0); -#endif /* UNIV_IBUF_COUNT_DEBUG */ - } else { - ibuf_merge_or_delete_for_page( - block, space, offset, zip_size, TRUE); - } + ibuf_merge_or_delete_for_page(block, space, offset, + zip_size, TRUE); } /* Unfix and unlatch the block. */ From 17076f8cd3e6068049a34071910ef45d0c3f6efa Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Fri, 30 Nov 2012 16:17:38 +0100 Subject: [PATCH 057/324] bug#14589559: ASSERTION `FILE_ENTRY_BUF[2] == 0' FAILED IN DEACTIVATE_DDL_LOG_ENTRY Update of comments according to reviewers request. --- sql/sql_table.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index cf725a5261d..e9f6022aca4 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -823,6 +823,7 @@ static void set_ddl_log_entry_from_buf(uint read_entry, { uint inx; uchar single_char; + DBUG_ENTER("set_ddl_log_entry_from_buf"); ddl_log_entry->entry_pos= read_entry; single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]; ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char; @@ -835,6 +836,7 @@ static void set_ddl_log_entry_from_buf(uint read_entry, ddl_log_entry->from_name= (char*) &file_entry_buf[inx]; inx+= global_ddl_log.name_len; ddl_log_entry->handler_name= (char*) &file_entry_buf[inx]; + DBUG_VOID_RETURN; } @@ -1396,7 +1398,7 @@ bool execute_ddl_log_entry(THD *thd, uint first_entry) { if (read_ddl_log_file_entry(file_entry_buf, read_entry, IO_SIZE)) { - /* Write to error log and continue with next log entry */ + /* Print the error to the log and continue with next log entry */ sql_print_error("Failed to read entry = %u from ddl log", read_entry); break; @@ -1407,7 +1409,7 @@ bool execute_ddl_log_entry(THD *thd, uint first_entry) if (execute_ddl_log_action(thd, &ddl_log_entry)) { - /* Write to error log and continue with next log entry */ + /* Print the error to the log and continue with next log entry */ sql_print_error("Failed to execute action for entry = %u from ddl log", read_entry); break; From bdfc4dc6c6927d4dc46e3cd0c4ff2a1595c174a3 Mon Sep 17 00:00:00 2001 From: Libing Song Date: Sat, 1 Dec 2012 08:04:33 +0800 Subject: [PATCH 058/324] Bug#11764602 ASSERTION IN FORMAT_DESCRIPTION_LOG_EVENT::CALC_SERVER_VERSION_SPLIT Problem: When reading a Format_description_log_event, it supposes MySQL version is always valid and DBUG_ASSERTION is used check the version number. However, user may give a wrong binlog offset, even give a faked binary event which includes an invalid MySQL version. This will cause server crash. Fix: The assertions are removed and an error will be reported if MySQL version in Format_description_log_event is invalid. --- sql/log_event.cc | 18 ++++++++++++++---- sql/log_event.h | 18 ++++++++++++++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 58de0d310d7..63770e340b0 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4205,7 +4205,6 @@ Format_description_log_event::do_shall_skip(Relay_log_info *rli) into 'server_version_split': X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z} X.Yabc -> {X,Y,0} - Xabc -> {X,0,0} 'server_version_split' is then used for lookups to find if the server which created this event has some known bug. */ @@ -4216,10 +4215,21 @@ void Format_description_log_event::calc_server_version_split() for (uint i= 0; i<=2; i++) { number= strtoul(p, &r, 10); - server_version_split[i]= (uchar)number; - DBUG_ASSERT(number < 256); // fit in uchar + /* + It is an invalid version if any version number greater than 255 or + first number is not followed by '.'. + */ + if (number < 256 && (*r == '.' || i != 0)) + server_version_split[i]= (uchar)number; + else + { + server_version_split[0]= 0; + server_version_split[1]= 0; + server_version_split[2]= 0; + break; + } + p= r; - DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice if (*r == '.') p++; // skip the dot } diff --git a/sql/log_event.h b/sql/log_event.h index c36564fcde8..4c8580eb2fd 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -969,7 +969,7 @@ public: return thd ? thd->db : 0; } #else - Log_event() : temp_buf(0) {} + Log_event() : temp_buf(0), flags(0) {} /* avoid having to link mysqlbinlog against libpthread */ static Log_event* read_log_event(IO_CACHE* file, const Format_description_log_event @@ -2244,12 +2244,26 @@ public: #ifndef MYSQL_CLIENT bool write(IO_CACHE* file); #endif - bool is_valid() const + bool header_is_valid() const { return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN : LOG_EVENT_MINIMAL_HEADER_LEN)) && (post_header_len != NULL)); } + + bool version_is_valid() const + { + /* It is invalid only when all version numbers are 0 */ + return !(server_version_split[0] == 0 && + server_version_split[1] == 0 && + server_version_split[2] == 0); + } + + bool is_valid() const + { + return header_is_valid() && version_is_valid(); + } + int get_data_size() { /* From 859ff1ec36cac3fae7862b738a4d58f50ca7d44a Mon Sep 17 00:00:00 2001 From: Yasufumi Kinoshita Date: Tue, 4 Dec 2012 12:32:58 +0900 Subject: [PATCH 059/324] UNIV_DEBUG build of some environments needs #include "read0read.h" for srv0srv.c and trx0rec.c. This is only for mysql-5.5 --- storage/innobase/srv/srv0srv.c | 1 + storage/innobase/trx/trx0rec.c | 1 + 2 files changed, 2 insertions(+) diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 3b493e4e115..398c544bc5b 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -85,6 +85,7 @@ Created 10/8/1995 Heikki Tuuri #include "ha_prototypes.h" #include "trx0i_s.h" #include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */ +#include "read0read.h" #include "mysql/plugin.h" #include "mysql/service_thd_wait.h" diff --git a/storage/innobase/trx/trx0rec.c b/storage/innobase/trx/trx0rec.c index 9dd8cc7ba09..f80f58493aa 100644 --- a/storage/innobase/trx/trx0rec.c +++ b/storage/innobase/trx/trx0rec.c @@ -36,6 +36,7 @@ Created 3/26/1996 Heikki Tuuri #ifndef UNIV_HOTBACKUP #include "dict0dict.h" #include "ut0mem.h" +#include "read0read.h" #include "row0ext.h" #include "row0upd.h" #include "que0que.h" From 14b18b27854dcbbb732a3c23af64cb9eddff0ea7 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Tue, 4 Dec 2012 18:14:01 +0530 Subject: [PATCH 060/324] BUG#13812374 - RPL.RPL_REPORT_PORT FAILS OCCASIONALLY ON PB2 Problem: The problem with the test is that the slave returns from start_slave.inc call too early before the list is actually actualised. This caused the slave stale data to be reported. Fix: Added a wait in the test till the slave's IO status is changed to "Waiting for master to send event" which which ensures the list is correctly updated. --- mysql-test/suite/rpl/r/rpl_report_port.result | 2 ++ mysql-test/suite/rpl/t/rpl_report_port.test | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/mysql-test/suite/rpl/r/rpl_report_port.result b/mysql-test/suite/rpl/r/rpl_report_port.result index 6a9ac341780..2f422c8b577 100644 --- a/mysql-test/suite/rpl/r/rpl_report_port.result +++ b/mysql-test/suite/rpl/r/rpl_report_port.result @@ -2,10 +2,12 @@ include/master-slave.inc [connection master] include/rpl_restart_server.inc [server_number=2 parameters: --report-port=9000] include/start_slave.inc +include/wait_for_slave_param.inc [Slave_IO_State] [Slave restarted with the report-port set to some value] include/assert.inc [The value shown for the slave's port number is user specified port number which is the value set for report-port.] include/rpl_restart_server.inc [server_number=2] include/start_slave.inc +include/wait_for_slave_param.inc [Slave_IO_State] [Slave restarted with the report-port set to the value of slave's port number] include/assert.inc [The default value shown for the slave's port number is the actual port number of the slave.] include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_report_port.test b/mysql-test/suite/rpl/t/rpl_report_port.test index 12c34ce01b1..6e728a678ad 100644 --- a/mysql-test/suite/rpl/t/rpl_report_port.test +++ b/mysql-test/suite/rpl/t/rpl_report_port.test @@ -32,6 +32,9 @@ connection master; connection slave; --source include/start_slave.inc +--let $slave_param= Slave_IO_State +--let $slave_param_value= Waiting for master to send event +--source include/wait_for_slave_param.inc --echo [Slave restarted with the report-port set to some value] connection master; @@ -52,6 +55,9 @@ connection master; connection slave; --source include/start_slave.inc +--let $slave_param= Slave_IO_State +--let $slave_param_value= Waiting for master to send event +--source include/wait_for_slave_param.inc connection master; sync_slave_with_master; From 86718b969ca8a461de315f34d66b5b513288982e Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Tue, 4 Dec 2012 16:09:48 +0000 Subject: [PATCH 061/324] Bug#13545447 RPL_ROTATE_LOGS FAILS DUE TO CONCURRENCY ISSUES IN REP. CODE RPL_ROTATE_LOGS has been failing sporadically in what seems a problem related to routines that update the coordinates. However, the test lacks proper assert statments and because of this the debug information upon failure simply points to the content mismatch between the test and the result file. Not as a solution, but as a improvement to the test to better debug this failure, new assert statments were added to the test. @rpl_rotate_logs.test Added new assert statments reducing the dependency on the result file. @rpl_rotate_logs.result Added new content to the result file to match the test changes --- mysql-test/suite/rpl/r/rpl_rotate_logs.result | 34 ++++------- mysql-test/suite/rpl/t/rpl_rotate_logs.test | 59 ++++++++++++++++--- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_rotate_logs.result b/mysql-test/suite/rpl/r/rpl_rotate_logs.result index ef95103c7bc..256ed4eaad2 100644 --- a/mysql-test/suite/rpl/r/rpl_rotate_logs.result +++ b/mysql-test/suite/rpl/r/rpl_rotate_logs.result @@ -17,10 +17,8 @@ insert into t1 values('Could not break slave'),('Tried hard'); Master_Log_File = 'master-bin.000001' Relay_Master_Log_File = 'master-bin.000001' include/check_slave_is_running.inc -select * from t1; -s -Could not break slave -Tried hard +include/assert.inc [Table t1 should contain the first inserted line] +include/assert.inc [Table t1 should contain the second inserted line] flush logs; create table t2(m int not null auto_increment primary key); insert into t2 values (34),(67),(123); @@ -31,9 +29,7 @@ master-bin.000001 # master-bin.000002 # master-bin.000003 # create table t3 select * from temp_table; -select * from t3; -a -testing temporary tables +include/assert.inc [Data in t3 should be equal to temp_table] drop table temp_table, t3; insert into t2 values(1234); set insert_id=1234; @@ -60,19 +56,15 @@ insert into t2 values (65); Master_Log_File = 'master-bin.000003' Relay_Master_Log_File = 'master-bin.000003' include/check_slave_is_running.inc -select * from t2; -m -34 -65 -67 -123 -1234 +include/assert.inc [Table t2 should still contain the first inserted line after creation] +include/assert.inc [Table t2 should contain the line inserted after the purge] +include/assert.inc [Table t2 should still contain the second insert line after creation] +include/assert.inc [Table t2 should still contain the third inserted line after creation] +include/assert.inc [Table t2 should still contain the line from the duplicated key test] create temporary table temp_table (a char(80) not null); insert into temp_table values ("testing temporary tables part 2"); create table t3 (n int); -select count(*) from t3 where n >= 4; -count(*) -100 +include/assert.inc [Table t3 should contain 100 lines on the master] create table t4 select * from temp_table; show binary logs; Log_name File_size @@ -85,16 +77,12 @@ master-bin.000008 # show master status; File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000008 # -select * from t4; -a -testing temporary tables part 2 +include/assert.inc [Data in t4 should be equal to temp_table] Master_Log_File = 'master-bin.000008' Relay_Master_Log_File = 'master-bin.000008' include/check_slave_is_running.inc lock tables t3 read; -select count(*) from t3 where n >= 4; -count(*) -100 +include/assert.inc [Table t3 should contain 100 lines on the slave] unlock tables; drop table if exists t1,t2,t3,t4; End of 4.1 tests diff --git a/mysql-test/suite/rpl/t/rpl_rotate_logs.test b/mysql-test/suite/rpl/t/rpl_rotate_logs.test index 67079b9bea1..dc158d7ef92 100644 --- a/mysql-test/suite/rpl/t/rpl_rotate_logs.test +++ b/mysql-test/suite/rpl/t/rpl_rotate_logs.test @@ -66,7 +66,17 @@ sync_slave_with_master; let $status_items= Master_Log_File, Relay_Master_Log_File; source include/show_slave_status.inc; source include/check_slave_is_running.inc; -select * from t1; + +--let $assert_text= Table t1 should contain the first inserted line +--let $query_result= query_get_value(select * from t1, "s", 1) +--let $assert_cond= "$query_result" = "Could not break slave" +--source include/assert.inc + +--let $assert_text= Table t1 should contain the second inserted line +--let $query_result= query_get_value(select * from t1, "s", 2) +--let $assert_cond= "$query_result" = "Tried hard" +--source include/assert.inc + connection master; flush logs; create table t2(m int not null auto_increment primary key); @@ -77,7 +87,11 @@ create table t3 select * from temp_table; sync_slave_with_master; -select * from t3; +--let $query_result= query_get_value(select * from t3, "a", 1) +--let $assert_text= Data in t3 should be equal to temp_table +--let $assert_cond= "$query_result" = "testing temporary tables" +--source include/assert.inc + connection master; drop table temp_table, t3; @@ -136,11 +150,30 @@ insert into t2 values (65); sync_slave_with_master; source include/show_slave_status.inc; source include/check_slave_is_running.inc; -select * from t2; + +--let $assert_text= Table t2 should still contain the first inserted line after creation +--let $assert_cond= [select * from t2,"m",1] = 34 +--source include/assert.inc + +--let $assert_text= Table t2 should contain the line inserted after the purge +--let $assert_cond= [select * from t2,"m",2] = 65 +--source include/assert.inc + +--let $assert_text= Table t2 should still contain the second insert line after creation +--let $assert_cond= [select * from t2,"m",3] = 67 +--source include/assert.inc + +--let $assert_text= Table t2 should still contain the third inserted line after creation +--let $assert_cond= [select * from t2,"m",4] = 123 +--source include/assert.inc + +--let $assert_text= Table t2 should still contain the line from the duplicated key test +--let $assert_cond= [select * from t2,"m",5] = 1234 +--source include/assert.inc # # Test forcing the replication log to rotate -# +# connection master; create temporary table temp_table (a char(80) not null); @@ -156,19 +189,31 @@ while ($1) dec $1; } enable_query_log; -select count(*) from t3 where n >= 4; + +--let $assert_text= Table t3 should contain 100 lines on the master +--let $assert_cond= [select count(*) from t3 where n >= 4,"count(*)",1] = 100 +--source include/assert.inc + create table t4 select * from temp_table; source include/show_binary_logs.inc; source include/show_master_status.inc; sync_slave_with_master; -select * from t4; + +--let $query_result= query_get_value(select * from t4, "a", 1) +--let $assert_text= Data in t4 should be equal to temp_table +--let $assert_cond= "$query_result" = "testing temporary tables part 2" +--source include/assert.inc source include/show_slave_status.inc; source include/check_slave_is_running.inc; # because of concurrent insert, the table may not be up to date # if we do not lock lock tables t3 read; -select count(*) from t3 where n >= 4; + +--let $assert_text= Table t3 should contain 100 lines on the slave +--let $assert_cond= [select count(*) from t3 where n >= 4,"count(*)",1] = 100 +--source include/assert.inc + unlock tables; #clean up connection master; From 70cb820e2d0bd0a1d1970a312591e87edf3b38ae Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Wed, 5 Dec 2012 16:53:33 +0400 Subject: [PATCH 062/324] Bug #15948123: SERVER WORKS INCORRECT WITH LONG TABLE ALIASES Code in MDL subsystem assumes that identifiers of objects can't be longer than NAME_LEN characters. This assumption was broken when one tried to construct MDL_key based on table alias, which can have arbitrary length. Since MDL_key's (and MDL locks) are not really used for table aliases this patch changes code to not initialize MDL_key object for table list element representing aliases. --- sql/mdl.h | 2 ++ sql/sql_parse.cc | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/sql/mdl.h b/sql/mdl.h index d30d30ac2fa..6d29ad968c6 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -246,6 +246,8 @@ public: } void mdl_key_init(const MDL_key *rhs) { + DBUG_ASSERT(rhs->m_length <= NAME_LEN); + DBUG_ASSERT(rhs->m_db_name_length <= NAME_LEN); memcpy(m_ptr, rhs->m_ptr, rhs->m_length); m_length= rhs->m_length; m_db_name_length= rhs->m_db_name_length; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7bbcff4bc2b..534c4cee4c7 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6000,8 +6000,13 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->next_name_resolution_table= NULL; /* Link table in global list (all used tables) */ lex->add_to_query_tables(ptr); - ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, mdl_type, - MDL_TRANSACTION); + + // Pure table aliases do not need to be locked: + if (!test(table_options & TL_OPTION_ALIAS)) + { + ptr->mdl_request.init(MDL_key::TABLE, ptr->db, ptr->table_name, mdl_type, + MDL_TRANSACTION); + } DBUG_RETURN(ptr); } From 997748e850095610b0516262ebe2482b51df9652 Mon Sep 17 00:00:00 2001 From: Bjorn Munch Date: Wed, 5 Dec 2012 15:14:08 +0100 Subject: [PATCH 063/324] Remove moot --unit-test option for mtr in collections --- mysql-test/collections/default.daily | 2 +- mysql-test/collections/default.push | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/collections/default.daily b/mysql-test/collections/default.daily index e8b15acb34d..665da0d152c 100644 --- a/mysql-test/collections/default.daily +++ b/mysql-test/collections/default.daily @@ -1,5 +1,5 @@ -perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features --skip-test-list=collections/disabled-daily.list --unit-tests +perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=normal --vardir=var-normal --report-features --skip-test-list=collections/disabled-daily.list perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --skip-test-list=collections/disabled-daily.list perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=row --vardir=var-row --mysqld=--binlog-format=row --skip-test-list=collections/disabled-daily.list perl mysql-test-run.pl --force --timer --debug-server --parallel=auto --experimental=collections/default.experimental --comment=ps_row --vardir=var-ps_row --mysqld=--binlog-format=row --ps-protocol --skip-test-list=collections/disabled-daily.list diff --git a/mysql-test/collections/default.push b/mysql-test/collections/default.push index 74957d7a901..e1781d5082c 100644 --- a/mysql-test/collections/default.push +++ b/mysql-test/collections/default.push @@ -1,4 +1,4 @@ -perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list --unit-tests +perl mysql-test-run.pl --timer --force --parallel=auto --comment=n_mix --vardir=var-n_mix --mysqld=--binlog-format=mixed --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list perl mysql-test-run.pl --timer --force --parallel=auto --comment=ps_row --vardir=var-ps_row --ps-protocol --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list perl mysql-test-run.pl --timer --force --parallel=auto --comment=embedded --vardir=var-emebbed --embedded --experimental=collections/default.experimental perl mysql-test-run.pl --timer --force --parallel=auto --comment=rpl_binlog_row --vardir=var-rpl_binlog_row --suite=rpl,binlog --mysqld=--binlog-format=row --experimental=collections/default.experimental --skip-test-list=collections/disabled-per-push.list From 2c64d0a58db9980608b61b5593033694379f1566 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 5 Dec 2012 16:16:32 +0100 Subject: [PATCH 064/324] From 095e8271b768ca50df05557e9833b7c8f9d5636a Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Wed, 5 Dec 2012 19:26:56 +0400 Subject: [PATCH 065/324] Bug #15954896 "SP, MULTI-TABLE DELETE AND LONG ALIAS". Using too long table aliases in stored routines might have caused server crashes. Code in sp_head::merge_table_list() which is responsible for collecting information about tables used in stored routine was not aware of the fact that table alias might have arbitrary length. I.e. it assumed that table alias can't be longer than NAME_LEN bytes and allocated buffer for a key identifying table accordingly. This patch fixes the issue by ensuring that we use dynamically allocated buffer for table key when table alias is too long. By default stack based buffer is used in which NAME_LEN bytes are reserved for table alias. --- sql/sp_head.cc | 48 +++++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 7eef9f5ab28..054fc5e223e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3839,8 +3839,6 @@ typedef struct st_sp_table Multi-set key: db_name\0table_name\0alias\0 - for normal tables db_name\0table_name\0 - for temporary tables - Note that in both cases we don't take last '\0' into account when - we count length of key. */ LEX_STRING qname; uint db_length, table_name_length; @@ -3897,19 +3895,26 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) for (; table ; table= table->next_global) if (!table->derived && !table->schema_table) { - char tname[(NAME_LEN + 1) * 3]; // db\0table\0alias\0 - uint tlen, alen; + /* + Structure of key for the multi-set is "db\0table\0alias\0". + Since "alias" part can have arbitrary length we use String + object to construct the key. By default String will use + buffer allocated on stack with NAME_LEN bytes reserved for + alias, since in most cases it is going to be smaller than + NAME_LEN bytes. + */ + char tname_buff[(NAME_LEN + 1) * 3]; + String tname(tname_buff, sizeof(tname_buff), &my_charset_bin); + uint temp_table_key_length; - tlen= table->db_length; - memcpy(tname, table->db, tlen); - tname[tlen++]= '\0'; - memcpy(tname+tlen, table->table_name, table->table_name_length); - tlen+= table->table_name_length; - tname[tlen++]= '\0'; - alen= strlen(table->alias); - memcpy(tname+tlen, table->alias, alen); - tlen+= alen; - tname[tlen]= '\0'; + tname.length(0); + tname.append(table->db, table->db_length); + tname.append('\0'); + tname.append(table->table_name, table->table_name_length); + tname.append('\0'); + temp_table_key_length= tname.length(); + tname.append(table->alias); + tname.append('\0'); /* Upgrade the lock type because this table list will be used @@ -3924,9 +3929,10 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) (and therefore should not be prelocked). Otherwise we will erroneously treat table with same name but with different alias as non-temporary. */ - if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname, tlen)) || - ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname, - tlen - alen - 1)) && + if ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname.ptr(), + tname.length())) || + ((tab= (SP_TABLE *)hash_search(&m_sptabs, (uchar *)tname.ptr(), + temp_table_key_length)) && tab->temp)) { if (tab->lock_type < table->lock_type) @@ -3945,11 +3951,11 @@ sp_head::merge_table_list(THD *thd, TABLE_LIST *table, LEX *lex_for_tmp_check) lex_for_tmp_check->create_info.options & HA_LEX_CREATE_TMP_TABLE) { tab->temp= TRUE; - tab->qname.length= tlen - alen - 1; + tab->qname.length= temp_table_key_length; } else - tab->qname.length= tlen; - tab->qname.str= (char*) thd->memdup(tname, tab->qname.length + 1); + tab->qname.length= tname.length(); + tab->qname.str= (char*) thd->memdup(tname.ptr(), tab->qname.length); if (!tab->qname.str) return FALSE; tab->table_name_length= table->table_name_length; @@ -4018,7 +4024,7 @@ sp_head::add_used_tables_to_table_list(THD *thd, if (!(tab_buff= (char *)thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST)) * stab->lock_count)) || !(key_buff= (char*)thd->memdup(stab->qname.str, - stab->qname.length + 1))) + stab->qname.length))) DBUG_RETURN(FALSE); for (uint j= 0; j < stab->lock_count; j++) From 46cfbf35f86a6ff63bdfcd85297bd8269efc2826 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Wed, 5 Dec 2012 20:41:29 +0400 Subject: [PATCH 066/324] Bug #15948123: SERVER WORKS INCORRECT WITH LONG TABLE ALIASES Post-push cleanup: removal of unneeded assertions. --- sql/mdl.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sql/mdl.h b/sql/mdl.h index 6d29ad968c6..d30d30ac2fa 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -246,8 +246,6 @@ public: } void mdl_key_init(const MDL_key *rhs) { - DBUG_ASSERT(rhs->m_length <= NAME_LEN); - DBUG_ASSERT(rhs->m_db_name_length <= NAME_LEN); memcpy(m_ptr, rhs->m_ptr, rhs->m_length); m_length= rhs->m_length; m_db_name_length= rhs->m_db_name_length; From 54769c281ec9cf7d52740ed5ca503c5d81ed1744 Mon Sep 17 00:00:00 2001 From: Dmitry Shulga Date: Thu, 6 Dec 2012 15:59:15 +0600 Subject: [PATCH 067/324] This patch fixes bug#14729757 - MY_HASH_SEARCH(&XID_CACHE, XID_STATE->XID.KEY(), XID_STATE->XID.KEY_LENGTH())==0 This bug is a regression of bug#11759534 - 51855: RACE CONDITION IN XA START. The reason for regression is that the changes that fixes the original bug wasn't merged from mysql-5.1 into mysql-5.5 and mysql-trunk. Only null-merge was done for the patch changeset. To incorporate lost changes the manual merge have been done. Additionally the call of trans_rolback() was added into trans_xa_start() in case if xid_cache_insert is failed() after transaction has been started. If we don't call trans_rollback() we would never reset the flag SERVER_STATUS_IN_TRANS in THD::server_status and therefore all subsequent attempts to execute XA START in the connection where the error was occurred will be failed since thd->in_active_multi_stmt_transaction() will return the true every time when trans_xa_start is called. The latest changes were absent in patch for mysql-5.1 --- sql/sql_class.cc | 11 ++++++++--- sql/transaction.cc | 20 +++++++++++++++++--- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index ff7f2340ac0..6e47dcb5795 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4024,9 +4024,14 @@ bool xid_cache_insert(XID *xid, enum xa_states xa_state) bool xid_cache_insert(XID_STATE *xid_state) { mysql_mutex_lock(&LOCK_xid_cache); - DBUG_ASSERT(my_hash_search(&xid_cache, xid_state->xid.key(), - xid_state->xid.key_length())==0); - my_bool res=my_hash_insert(&xid_cache, (uchar*)xid_state); + if (my_hash_search(&xid_cache, xid_state->xid.key(), + xid_state->xid.key_length())) + { + mysql_mutex_unlock(&LOCK_xid_cache); + my_error(ER_XAER_DUPID, MYF(0)); + return true; + } + bool res= my_hash_insert(&xid_cache, (uchar*)xid_state); mysql_mutex_unlock(&LOCK_xid_cache); return res; } diff --git a/sql/transaction.cc b/sql/transaction.cc index 3359decbcd5..1623cd57d77 100644 --- a/sql/transaction.cc +++ b/sql/transaction.cc @@ -567,15 +567,19 @@ bool trans_xa_start(THD *thd) my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]); else if (thd->locked_tables_mode || thd->in_active_multi_stmt_transaction()) my_error(ER_XAER_OUTSIDE, MYF(0)); - else if (xid_cache_search(thd->lex->xid)) - my_error(ER_XAER_DUPID, MYF(0)); else if (!trans_begin(thd)) { DBUG_ASSERT(thd->transaction.xid_state.xid.is_null()); thd->transaction.xid_state.xa_state= XA_ACTIVE; thd->transaction.xid_state.rm_error= 0; thd->transaction.xid_state.xid.set(thd->lex->xid); - xid_cache_insert(&thd->transaction.xid_state); + if (xid_cache_insert(&thd->transaction.xid_state)) + { + thd->transaction.xid_state.xa_state= XA_NOTR; + thd->transaction.xid_state.xid.null(); + trans_rollback(thd); + DBUG_RETURN(true); + } DBUG_RETURN(FALSE); } @@ -661,6 +665,16 @@ bool trans_xa_commit(THD *thd) if (!thd->transaction.xid_state.xid.eq(thd->lex->xid)) { + /* + xid_state.in_thd is always true beside of xa recovery procedure. + Note, that there is no race condition here between xid_cache_search + and xid_cache_delete, since we always delete our own XID + (thd->lex->xid == thd->transaction.xid_state.xid). + The only case when thd->lex->xid != thd->transaction.xid_state.xid + and xid_state->in_thd == 0 is in the function + xa_cache_insert(XID, xa_states), which is called before starting + client connections, and thus is always single-threaded. + */ XID_STATE *xs= xid_cache_search(thd->lex->xid); res= !xs || xs->in_thd; if (res) From aec9ca5da4ca2201d62932096d4f55929909596e Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Thu, 6 Dec 2012 16:53:02 +0530 Subject: [PATCH 068/324] Bug#15912213: BUFFER OVERFLOW IN ACL_GET() Description: A very large database name causes buffer overflow in functions acl_get() and check_grant_db() in sql_acl.cc. It happens due to an unguarded string copy operation. This puts required sanity checks before copying db string to destination buffer. --- sql/sql_acl.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index d99ca3ceb99..fdd9b107bf2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1581,11 +1581,20 @@ ulong acl_get(const char *host, const char *ip, { ulong host_access= ~(ulong)0, db_access= 0; uint i; - size_t key_length; + size_t key_length, copy_length; char key[ACL_KEY_LENGTH],*tmp_db,*end; acl_entry *entry; DBUG_ENTER("acl_get"); + copy_length= (size_t) (strlen(ip ? ip : "") + + strlen(user ? user : "") + + strlen(db ? db : "")); + /* + Make sure that strmov() operations do not result in buffer overflow. + */ + if (copy_length >= ACL_KEY_LENGTH) + DBUG_RETURN(0); + mysql_mutex_lock(&acl_cache->lock); end=strmov((tmp_db=strmov(strmov(key, ip ? ip : "")+1,user)+1),db); if (lower_case_table_names) @@ -4942,6 +4951,16 @@ bool check_grant_db(THD *thd,const char *db) char helping [NAME_LEN+USERNAME_LENGTH+2]; uint len; bool error= TRUE; + size_t copy_length; + + copy_length= (size_t) (strlen(sctx->priv_user ? sctx->priv_user : "") + + strlen(db ? db : "")); + + /* + Make sure that strmov() operations do not result in buffer overflow. + */ + if (copy_length >= (NAME_LEN+USERNAME_LENGTH+2)) + return 1; len= (uint) (strmov(strmov(helping, sctx->priv_user) + 1, db) - helping) + 1; From b3b59f75d225bfe3c7459e714c5cc713339f92df Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 7 Dec 2012 15:41:49 +0530 Subject: [PATCH 069/324] From b74a229c23dd1d67c1f108cfec261e7756c86537 Mon Sep 17 00:00:00 2001 From: Akhila Maddukuri Date: Fri, 7 Dec 2012 18:26:02 +0530 Subject: [PATCH 070/324] Bug #15930494 MYSQLDUMP TEST SOMETIMES FAILS DUE TO MIXING STDOUT AND STDERR Fix: Added a destination file to mysqldump. --- mysql-test/r/mysqldump.result | 27 ++++++++++++++++----------- mysql-test/t/mysqldump.test | 11 +++++++++-- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 2e34bb10a87..96ab16f113f 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -5115,15 +5115,12 @@ INSERT INTO b12809202_db.t2 VALUES (1), (2), (3); # Note : In the following dump the transaction # should start only after the logs are # flushed, as 'flush logs' causes implicit -# commit starting 5.5. +# commit starting 5.5.Also, as stderr is +# unbuffered, it is redirected to a different +# file to avoid diffs due to bad stdout/stderr +# order in the output. #### Dump starts here #### --- Connecting to localhost... --- main : logs flushed successfully! --- Starting transaction... --- Retrieving table structure for table t1... --- Sending SELECT query... --- Retrieving rows... -- -- Host: localhost Database: b12809202_db -- ------------------------------------------------------ @@ -5158,9 +5155,6 @@ CREATE TABLE `t1` ( LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; INSERT INTO `t1` VALUES (1),(2),(3); --- Retrieving table structure for table t2... --- Sending SELECT query... --- Retrieving rows... /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; @@ -5185,7 +5179,6 @@ LOCK TABLES `t2` WRITE; INSERT INTO `t2` VALUES (1),(2),(3); /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; --- Disconnecting from localhost... /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -5197,6 +5190,18 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed +## stderr ## +-- Connecting to localhost... +-- main : logs flushed successfully! +-- Starting transaction... +-- Retrieving table structure for table t1... +-- Sending SELECT query... +-- Retrieving rows... +-- Retrieving table structure for table t2... +-- Sending SELECT query... +-- Retrieving rows... +-- Disconnecting from localhost... + #### Dump ends here #### DROP TABLE b12809202_db.t1; DROP TABLE b12809202_db.t2; diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 6d136c0f00a..b6af97c6f41 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -2347,11 +2347,17 @@ INSERT INTO b12809202_db.t2 VALUES (1), (2), (3); --echo # Note : In the following dump the transaction --echo # should start only after the logs are --echo # flushed, as 'flush logs' causes implicit ---echo # commit starting 5.5. +--echo # commit starting 5.5.Also, as stderr is +--echo # unbuffered, it is redirected to a different +--echo # file to avoid diffs due to bad stdout/stderr +--echo # order in the output. --echo --echo #### Dump starts here #### --replace_regex /-- Server version.*// /-- MySQL dump .*// /-- Dump completed on .*/-- Dump completed/ ---exec $MYSQL_DUMP --verbose --single-transaction --flush-log b12809202_db 2>&1 +--exec $MYSQL_DUMP --verbose --single-transaction --flush-log b12809202_db 2>$MYSQLTEST_VARDIR/tmp/b12809202_stderr.sql +--echo +--echo ## stderr ## +--cat_file $MYSQLTEST_VARDIR/tmp/b12809202_stderr.sql --echo --echo #### Dump ends here #### @@ -2359,6 +2365,7 @@ INSERT INTO b12809202_db.t2 VALUES (1), (2), (3); DROP TABLE b12809202_db.t1; DROP TABLE b12809202_db.t2; DROP DATABASE b12809202_db; +--remove_file $MYSQLTEST_VARDIR/tmp/b12809202_stderr.sql --echo # --echo # Delete all existing binary logs. From 51d43baa66ff77b045390ea82aa8b20898c9244f Mon Sep 17 00:00:00 2001 From: Shivji Kumar Jha Date: Sun, 9 Dec 2012 15:50:32 +0530 Subject: [PATCH 071/324] BUG#12359942 - REPLICATION TEST FROM ENGINE SUITE RPL_ROW_UNTIL TIMES OUT patch to fix post push falures in pb2 mysql-test/suite/rpl/r/rpl_row_until.result: changes to account for the changes made in corresponding test file. mysql-test/suite/rpl/t/disabled.def: disabled test in macosx mysql-test/suite/rpl/t/rpl_row_until.test: replaced static relayy log file by an mtr variable which saves the name of relay log file. --- mysql-test/suite/rpl/r/rpl_row_until.result | 1 - mysql-test/suite/rpl/t/disabled.def | 1 + mysql-test/suite/rpl/t/rpl_row_until.test | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/rpl/r/rpl_row_until.result b/mysql-test/suite/rpl/r/rpl_row_until.result index 5629f5c8cdd..be8f17c6f01 100644 --- a/mysql-test/suite/rpl/r/rpl_row_until.result +++ b/mysql-test/suite/rpl/r/rpl_row_until.result @@ -27,7 +27,6 @@ n 3 4 include/check_slave_param.inc [Exec_Master_Log_Pos] -START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=relay_pos_insert1_t2 include/wait_for_slave_sql_to_stop.inc SELECT * FROM t2; n diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index 808dfc268a9..d33f85091ff 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -13,3 +13,4 @@ rpl_row_create_table : Bug#11759274 Feb 27 2010 andrei failed different way than earlier with bug#45576 rpl_get_master_version_and_clock : Bug#11766137 Jan 05 2011 joro Valgrind warnings rpl_get_master_version_and_clock rpl_stm_until : BUG#59543 Jan 26 2011 alfranio Replication test from eits suite rpl_row_until times out +rpl_row_until @macosx : BUG#15965353 RPL.RPL_ROW_UNTIL FAILS ON PB2 , PLATFORM= MACOSX10.6 X86_64 MAX diff --git a/mysql-test/suite/rpl/t/rpl_row_until.test b/mysql-test/suite/rpl/t/rpl_row_until.test index bf38bd487ea..eaa99c29694 100644 --- a/mysql-test/suite/rpl/t/rpl_row_until.test +++ b/mysql-test/suite/rpl/t/rpl_row_until.test @@ -26,6 +26,7 @@ let $master_pos_insert1_t2= query_get_value(SHOW BINLOG EVENTS, End_log_pos, 12) sync_slave_with_master; # Save relay log position for query INSERT INTO t2 VALUES (1),(2); +let $relay_log_file= query_get_value(show slave status, Relay_Log_File,1); let $relay_pos_insert1_t2= query_get_value(show slave status, Relay_Log_Pos, 1); connection master; @@ -68,9 +69,8 @@ SELECT * FROM t1; --source include/check_slave_param.inc # Try replicate all up to and not including the second insert to t2; -echo START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=relay_pos_insert1_t2; --disable_query_log -eval START SLAVE UNTIL RELAY_LOG_FILE='slave-relay-bin.000002', RELAY_LOG_POS=$relay_pos_insert1_t2; +eval START SLAVE UNTIL RELAY_LOG_FILE='$relay_log_file', RELAY_LOG_POS=$relay_pos_insert1_t2; --enable_query_log --source include/wait_for_slave_sql_to_stop.inc SELECT * FROM t2; From 0a925f7317d8140f6541f1bef36bf2df0c6d1daa Mon Sep 17 00:00:00 2001 From: Joerg Bruehe Date: Mon, 10 Dec 2012 09:42:18 +0100 Subject: [PATCH 072/324] RPMs for ULN do not build in MySQL 5.6: Patches + libmysqld.so Bug #15972480 This is the change for 5.5: a cleanup in the way "libmysqld.so" is created. (Patches were adapted for 5.5 previously.) Originally, the ".so" was created by taking all modules in "libmysqld.a", after removing some few which caused unresolved references. This is no good idea, rather "ld" should be used to follow all references from some few start modules. At the same time, the ".so" version needed to be corrected: The original "0.0.1" is both wrong and risky. Rather, the server version is used to identify the ".so" file, but for linkage the first two levels are sufficient (so upgrades are possible without re-building the embedded application). --- packaging/rpm-uln/mysql.spec.sh | 37 +++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/packaging/rpm-uln/mysql.spec.sh b/packaging/rpm-uln/mysql.spec.sh index 8b25b160be1..3e2c5c3f11c 100644 --- a/packaging/rpm-uln/mysql.spec.sh +++ b/packaging/rpm-uln/mysql.spec.sh @@ -508,21 +508,28 @@ mkdir release # TODO / FIXME: Do we need "scriptstub"? gcc $CFLAGS $LDFLAGS -o scriptstub "-DLIBDIR=\"%{_libdir}/mysql\"" %{SOURCE4} -# TODO / FIXME: "libmysqld.so" should have been produced above - WORK in PROGRESS +# TODO / FIXME: "libmysqld.so" should have been produced above # regular build will make libmysqld.a but not libmysqld.so :-( cd release mkdir libmysqld/work cd libmysqld/work -ar -x ../libmysqld.a -rm rpl_utility.cc.o sql_binlog.cc.o # Try-and-Error: These modules cause unresolved references -gcc $CFLAGS $LDFLAGS -shared -Wl,-soname,libmysqld.so.0 -o libmysqld.so.0.0.1 \ - *.o \ +# "libmysqld" provides the same ABI as "libmysqlclient", but it implements the server: +# The shared object is identified by the full version, +# for linkage selection the first two levels are sufficient so that upgrades are possible +# (see "man ld", option "-soname"). +SO_FULL='%{mysql_version}' +SO_USE=`echo $SO_FULL | sed -e 's/\([0-9]\.[0-9]\)\.[0-9]*/\1/'` +# These two modules should pull everything else which is needed: +ar -x ../libmysqld.a client.c.o signal_handler.cc.o +gcc $CFLAGS $LDFLAGS -shared -Wl,-soname,libmysqld.so.$SO_USE -o libmysqld.so.$SO_FULL \ + *.o ../libmysqld.a \ -lpthread -lcrypt -laio -lnsl -lssl -lcrypto -lz -lrt -lstdc++ -lm -lc # this is to check that we built a complete library cp %{SOURCE9} . -ln -s libmysqld.so.0.0.1 libmysqld.so.0 -gcc -I../../include -I../../../%{src_dir}/include $CFLAGS mysql-embedded-check.c libmysqld.so.0 -LD_LIBRARY_PATH=. ldd ./a.out +PROGNAME=`basename %{SOURCE9} .c` +ln -s libmysqld.so.$SO_FULL libmysqld.so.$SO_USE +gcc -I../../include -I../../../%{src_dir}/include $CFLAGS -o $PROGNAME %{SOURCE9} libmysqld.so.$SO_USE +LD_LIBRARY_PATH=. ldd $PROGNAME cd ../.. cd .. @@ -618,9 +625,11 @@ mv ${RPM_BUILD_ROOT}%{_bindir}/mysql_config ${RPM_BUILD_ROOT}%{_libdir}/mysql/my install -m 0755 scriptstub ${RPM_BUILD_ROOT}%{_bindir}/mysql_config rm -f ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.a -install -m 0755 release/libmysqld/work/libmysqld.so.0.0.1 ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.0.0.1 -ln -s libmysqld.so.0.0.1 ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.0 -ln -s libmysqld.so.0 ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so +SO_FULL='%{mysql_version}' +SO_USE=`echo $SO_FULL | sed -e 's/\([0-9]\.[0-9]\)\.[0-9]*/\1/'` +install -m 0755 release/libmysqld/work/libmysqld.so.$SO_FULL ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.$SO_FULL +ln -s libmysqld.so.$SO_FULL ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so.$SO_USE +ln -s libmysqld.so.$SO_USE ${RPM_BUILD_ROOT}%{_libdir}/mysql/libmysqld.so rm -f ${RPM_BUILD_ROOT}%{_bindir}/comp_err rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/comp_err.1* @@ -964,6 +973,12 @@ fi %{_mandir}/man1/mysql_client_test.1* %changelog +* Thu Dec 7 2012 Joerg Bruehe +- Change the way in which "libmysqld.so" is created: Using all object modules + was wrong, gcc / ld can resolve the dependencies from "libmysqld.a". + Also, identify the ".so" version from the MySQL version, "0.0.1" was wrong. + Bug#15972480 + * Tue Sep 18 2012 Joerg Bruehe - Restrict the vendor check to Oracle: There is no history here which we have to allow for. From fc311cc623193ee936b73f487568ae86f1f9a95c Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Wed, 12 Dec 2012 22:31:03 +0530 Subject: [PATCH 073/324] Bug#13639125 DELIMITER STRIPS THE NEXT NEW LINE IN A SQL STATEMENT While processing each lines entered at the prompt, mysql client appends a '\n' to all the lines except for delimiter commands. However the same logic must not apply if 'delimiter' is part of a string or a comment, for which a '\n' should be added. Fixed by adding appropriate checks. Added a test case. --- client/mysql.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/client/mysql.cc b/client/mysql.cc index b772fe67cc4..edbfd532de3 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2283,17 +2283,19 @@ static bool add_line(String &buffer,char *line,char *in_string, { uint length=(uint) (out-line); - if (!truncated && - (length < 9 || - my_strnncoll (charset_info, - (uchar *)line, 9, (const uchar *) "delimiter", 9))) + if (!truncated && (length < 9 || + my_strnncoll (charset_info, (uchar *)line, 9, + (const uchar *) "delimiter", 9) || + (*in_string || *ml_comment))) { /* Don't add a new line in case there's a DELIMITER command to be added to the glob buffer (e.g. on processing a line like ";DELIMITER ") : similar to how a new line is not added in the case when the DELIMITER is the first command - entered with an empty glob buffer. + entered with an empty glob buffer. However, if the delimiter is + part of a string or a comment, the new line should be added. (e.g. + SELECT '\ndelimiter\n';\n) */ *out++='\n'; length++; From c85f51f92ab5c28baad9d2ff72dcf9778f9bea4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 13 Dec 2012 17:12:21 +0200 Subject: [PATCH 074/324] Follow-up fix to Bug#14628410: Remove the Windows InnoDB Plugin specific implementation of innobase_mysql_tmpfile() from MySQL 5.5 onwards. --- storage/innobase/handler/ha_innodb.cc | 97 --------------------------- 1 file changed, 97 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 67b0382b348..aece93bac74 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1248,102 +1248,6 @@ innobase_get_lower_case_table_names(void) return(lower_case_table_names); } -#if defined (__WIN__) -extern MYSQL_PLUGIN_IMPORT MY_TMPDIR mysql_tmpdir_list; -/*******************************************************************//** -Map an OS error to an errno value. The OS error number is stored in -_doserrno and the mapped value is stored in errno) */ -extern "C" -void __cdecl -_dosmaperr( - unsigned long); /*!< in: OS error value */ - -/*********************************************************************//** -Creates a temporary file. -@return temporary file descriptor, or < 0 on error */ -extern "C" UNIV_INTERN -int -innobase_mysql_tmpfile(void) -/*========================*/ -{ - int fd; /* handle of opened file */ - HANDLE osfh; /* OS handle of opened file */ - char* tmpdir; /* point to the directory - where to create file */ - TCHAR path_buf[MAX_PATH - 14]; /* buffer for tmp file path. - The length cannot be longer - than MAX_PATH - 14, or - GetTempFileName will fail. */ - char filename[MAX_PATH]; /* name of the tmpfile */ - DWORD fileaccess = GENERIC_READ /* OS file access */ - | GENERIC_WRITE - | DELETE; - DWORD fileshare = FILE_SHARE_READ /* OS file sharing mode */ - | FILE_SHARE_WRITE - | FILE_SHARE_DELETE; - DWORD filecreate = CREATE_ALWAYS; /* OS method of open/create */ - DWORD fileattrib = /* OS file attribute flags */ - FILE_ATTRIBUTE_NORMAL - | FILE_FLAG_DELETE_ON_CLOSE - | FILE_ATTRIBUTE_TEMPORARY - | FILE_FLAG_SEQUENTIAL_SCAN; - - DBUG_ENTER("innobase_mysql_tmpfile"); - - DBUG_EXECUTE_IF("innobase_tmpfile_creation_failure", return(-1);); - - tmpdir = my_tmpdir(&mysql_tmpdir_list); - - /* The tmpdir parameter can not be NULL for GetTempFileName. */ - if (!tmpdir) { - uint ret; - - /* Use GetTempPath to determine path for temporary files. */ - ret = GetTempPath(sizeof(path_buf), path_buf); - if (ret > sizeof(path_buf) || (ret == 0)) { - - _dosmaperr(GetLastError()); /* map error */ - DBUG_RETURN(-1); - } - - tmpdir = path_buf; - } - - /* Use GetTempFileName to generate a unique filename. */ - if (!GetTempFileName(tmpdir, "ib", 0, filename)) { - - _dosmaperr(GetLastError()); /* map error */ - DBUG_RETURN(-1); - } - - DBUG_PRINT("info", ("filename: %s", filename)); - - /* Open/Create the file. */ - osfh = CreateFile(filename, fileaccess, fileshare, NULL, - filecreate, fileattrib, NULL); - if (osfh == INVALID_HANDLE_VALUE) { - - /* open/create file failed! */ - _dosmaperr(GetLastError()); /* map error */ - DBUG_RETURN(-1); - } - - do { - /* Associates a CRT file descriptor with the OS file handle. */ - fd = _open_osfhandle((intptr_t) osfh, 0); - } while (fd == -1 && errno == EINTR); - - if (fd == -1) { - /* Open failed, close the file handle. */ - - _dosmaperr(GetLastError()); /* map error */ - CloseHandle(osfh); /* no need to check if - CloseHandle fails */ - } - - DBUG_RETURN(fd); -} -#else /*********************************************************************//** Creates a temporary file. @return temporary file descriptor, or < 0 on error */ @@ -1400,7 +1304,6 @@ innobase_mysql_tmpfile(void) } return(fd2); } -#endif /* defined (__WIN__) */ /*********************************************************************//** Wrapper around MySQL's copy_and_convert function. From c3e918ea90764e233e1cdefbde3745740dc569a3 Mon Sep 17 00:00:00 2001 From: Bill Qu Date: Mon, 17 Dec 2012 23:13:46 +0800 Subject: [PATCH 075/324] Approved by Jimmy and Inaam. rb#1576 --- storage/innobase/buf/buf0buf.c | 42 ++++++++++++++++++++++----- storage/innobase/buf/buf0flu.c | 24 +++++++++++++++ storage/innobase/buf/buf0lru.c | 42 +++++++++++++++++++++++++-- storage/innobase/handler/ha_innodb.cc | 4 +++ storage/innobase/include/buf0buf.h | 19 ++++++++++++ storage/innobase/include/buf0lru.h | 5 +++- storage/innobase/include/srv0srv.h | 2 ++ storage/innobase/srv/srv0srv.c | 15 +++++++--- 8 files changed, 138 insertions(+), 15 deletions(-) diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index ffd91637b0a..2406980196e 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -369,6 +369,33 @@ buf_get_total_list_len( } } +/********************************************************************//** +Get total list size in bytes from all buffer pools. */ +UNIV_INTERN +void +buf_get_total_list_size_in_bytes( +/*=============================*/ + buf_pools_list_size_t* buf_pools_list_size) /*!< out: list sizes + in all buffer pools */ +{ + ulint i; + ut_ad(buf_pools_list_size); + memset(buf_pools_list_size, 0, sizeof(*buf_pools_list_size)); + + for (i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool; + + buf_pool = buf_pool_from_array(i); + /* We don't need mutex protection since this is + for statistics purpose */ + buf_pools_list_size->LRU_bytes += buf_pool->stat.LRU_bytes; + buf_pools_list_size->unzip_LRU_bytes += + UT_LIST_GET_LEN(buf_pool->unzip_LRU) * UNIV_PAGE_SIZE; + buf_pools_list_size->flush_list_bytes += + buf_pool->stat.flush_list_bytes; + } +} + /********************************************************************//** Get total buffer pool statistics. */ UNIV_INTERN @@ -2951,6 +2978,7 @@ buf_page_init( ulint offset, /*!< in: offset of the page within space in units of a page */ ulint fold, /*!< in: buf_page_address_fold(space,offset) */ + ulint zip_size,/*!< in: compressed page size, or 0 */ buf_block_t* block) /*!< in/out: block to init */ { buf_page_t* hash_page; @@ -3013,6 +3041,9 @@ buf_page_init( ut_d(block->page.in_page_hash = TRUE); HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold, &block->page); + if (zip_size) { + page_zip_set_size(&block->page.zip, zip_size); + } } /********************************************************************//** @@ -3114,7 +3145,7 @@ err_exit: ut_ad(buf_pool_from_bpage(bpage) == buf_pool); - buf_page_init(buf_pool, space, offset, fold, block); + buf_page_init(buf_pool, space, offset, fold, zip_size, block); /* The block must be put to the LRU list, to the old blocks */ buf_LRU_add_block(bpage, TRUE/* to old blocks */); @@ -3132,8 +3163,6 @@ err_exit: buf_page_set_io_fix(bpage, BUF_IO_READ); if (UNIV_UNLIKELY(zip_size)) { - page_zip_set_size(&block->page.zip, zip_size); - /* buf_pool->mutex may be released and reacquired by buf_buddy_alloc(). Thus, we must release block->mutex in order not to @@ -3226,7 +3255,8 @@ err_exit: HASH_INSERT(buf_page_t, hash, buf_pool->page_hash, fold, bpage); - /* The block must be put to the LRU list, to the old blocks */ + /* The block must be put to the LRU list, to the old blocks + The zip_size is already set into the page zip */ buf_LRU_add_block(bpage, TRUE/* to old blocks */); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG buf_LRU_insert_zip_clean(bpage); @@ -3317,7 +3347,7 @@ buf_page_create( mutex_enter(&block->mutex); - buf_page_init(buf_pool, space, offset, fold, block); + buf_page_init(buf_pool, space, offset, fold, zip_size, block); /* The block must be put to the LRU list */ buf_LRU_add_block(&block->page, FALSE); @@ -3335,8 +3365,6 @@ buf_page_create( buf_page_set_io_fix(&block->page, BUF_IO_READ); rw_lock_x_lock(&block->lock); - - page_zip_set_size(&block->page.zip, zip_size); mutex_exit(&block->mutex); /* buf_pool->mutex may be released and reacquired by buf_buddy_alloc(). Thus, we must release block->mutex diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c index 7cd09d6675e..c385dc793ab 100644 --- a/storage/innobase/buf/buf0flu.c +++ b/storage/innobase/buf/buf0flu.c @@ -79,6 +79,23 @@ static ulint buf_lru_flush_page_count = 0; /* @} */ +/******************************************************************//** +Increases flush_list size in bytes with zip_size for compressed page, +UNIV_PAGE_SIZE for uncompressed page in inline function */ +static inline +void +incr_flush_list_size_in_bytes( +/*==========================*/ + buf_block_t* block, /*!< in: control block */ + buf_pool_t* buf_pool) /*!< in: buffer pool instance */ +{ + ulint zip_size; + ut_ad(buf_flush_list_mutex_own(buf_pool)); + zip_size = page_zip_get_size(&block->page.zip); + buf_pool->stat.flush_list_bytes += zip_size ? zip_size : UNIV_PAGE_SIZE; + ut_ad(buf_pool->stat.flush_list_bytes <= buf_pool->curr_pool_size); +} + #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /******************************************************************//** Validates the flush list. @@ -308,6 +325,7 @@ buf_flush_insert_into_flush_list( ut_d(block->page.in_flush_list = TRUE); block->page.oldest_modification = lsn; UT_LIST_ADD_FIRST(list, buf_pool->flush_list, &block->page); + incr_flush_list_size_in_bytes(block, buf_pool); #ifdef UNIV_DEBUG_VALGRIND { @@ -412,6 +430,8 @@ buf_flush_insert_sorted_into_flush_list( prev_b, &block->page); } + incr_flush_list_size_in_bytes(block, buf_pool); + #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG ut_a(buf_flush_validate_low(buf_pool)); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ @@ -504,6 +524,7 @@ buf_flush_remove( buf_page_t* bpage) /*!< in: pointer to the block in question */ { buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + ulint zip_size; ut_ad(buf_pool_mutex_own(buf_pool)); ut_ad(mutex_own(buf_page_get_mutex(bpage))); @@ -542,6 +563,9 @@ buf_flush_remove( because we assert on in_flush_list in comparison function. */ ut_d(bpage->in_flush_list = FALSE); + zip_size = page_zip_get_size(&bpage->zip); + buf_pool->stat.flush_list_bytes -= zip_size ? zip_size : UNIV_PAGE_SIZE; + bpage->oldest_modification = 0; #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index 60894cae6ad..b3e282d24b2 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -150,6 +150,23 @@ buf_LRU_block_free_hashed_page( buf_block_t* block); /*!< in: block, must contain a file page and be in a state where it can be freed */ +/******************************************************************//** +Increases LRU size in bytes with zip_size for compressed page, +UNIV_PAGE_SIZE for uncompressed page in inline function */ +static inline +void +incr_LRU_size_in_bytes( +/*===================*/ + buf_page_t* bpage, /*!< in: control block */ + buf_pool_t* buf_pool) /*!< in: buffer pool instance */ +{ + ulint zip_size; + ut_ad(buf_pool_mutex_own(buf_pool)); + zip_size = page_zip_get_size(&bpage->zip); + buf_pool->stat.LRU_bytes += zip_size ? zip_size : UNIV_PAGE_SIZE; + ut_ad(buf_pool->stat.LRU_bytes <= buf_pool->curr_pool_size); +} + /******************************************************************//** Determines if the unzip_LRU list should be used for evicting a victim instead of the general LRU list. @@ -1356,6 +1373,7 @@ buf_LRU_remove_block( buf_page_t* bpage) /*!< in: control block */ { buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + ulint zip_size; ut_ad(buf_pool); ut_ad(bpage); @@ -1391,6 +1409,9 @@ buf_LRU_remove_block( UT_LIST_REMOVE(LRU, buf_pool->LRU, bpage); ut_d(bpage->in_LRU_list = FALSE); + zip_size = page_zip_get_size(&bpage->zip); + buf_pool->stat.LRU_bytes -= zip_size ? zip_size : UNIV_PAGE_SIZE; + buf_unzip_LRU_remove_block_if_needed(bpage); /* If the LRU list is so short that LRU_old is not defined, @@ -1451,7 +1472,10 @@ buf_unzip_LRU_add_block( } /******************************************************************//** -Adds a block to the LRU list end. */ +Adds a block to the LRU list end. Please make sure that the zip_size is +already set into the page zip when invoking the function, so that we +can get correct zip_size from the buffer page when adding a block +into LRU */ UNIV_INLINE void buf_LRU_add_block_to_end_low( @@ -1470,6 +1494,8 @@ buf_LRU_add_block_to_end_low( UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage); ut_d(bpage->in_LRU_list = TRUE); + incr_LRU_size_in_bytes(bpage, buf_pool); + if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) { ut_ad(buf_pool->LRU_old); @@ -1498,7 +1524,10 @@ buf_LRU_add_block_to_end_low( } /******************************************************************//** -Adds a block to the LRU list. */ +Adds a block to the LRU list. Please make sure that the zip_size is +already set into the page zip when invoking the function, so that we +can get correct zip_size from the buffer page when adding a block +into LRU */ UNIV_INLINE void buf_LRU_add_block_low( @@ -1540,6 +1569,8 @@ buf_LRU_add_block_low( ut_d(bpage->in_LRU_list = TRUE); + incr_LRU_size_in_bytes(bpage, buf_pool); + if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) { ut_ad(buf_pool->LRU_old); @@ -1567,7 +1598,10 @@ buf_LRU_add_block_low( } /******************************************************************//** -Adds a block to the LRU list. */ +Adds a block to the LRU list. Please make sure that the zip_size is +already set into the page zip when invoking the function, so that we +can get correct zip_size from the buffer page when adding a block +into LRU */ UNIV_INTERN void buf_LRU_add_block( @@ -1753,6 +1787,8 @@ alloc: UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, prev_b, b); + incr_LRU_size_in_bytes(b, buf_pool); + if (buf_page_is_old(b)) { buf_pool->LRU_old_len++; if (UNIV_UNLIKELY diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index aece93bac74..9c8640b9442 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -601,8 +601,12 @@ innobase_commit_low( static SHOW_VAR innodb_status_variables[]= { {"buffer_pool_pages_data", (char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG}, + {"buffer_pool_bytes_data", + (char*) &export_vars.innodb_buffer_pool_bytes_data, SHOW_LONG}, {"buffer_pool_pages_dirty", (char*) &export_vars.innodb_buffer_pool_pages_dirty, SHOW_LONG}, + {"buffer_pool_bytes_dirty", + (char*) &export_vars.innodb_buffer_pool_bytes_dirty, SHOW_LONG}, {"buffer_pool_pages_flushed", (char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG}, {"buffer_pool_pages_free", diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 9c8051ad867..b7f6eae3f09 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -198,6 +198,15 @@ struct buf_pool_info_struct{ typedef struct buf_pool_info_struct buf_pool_info_t; +/** The occupied bytes of lists in all buffer pools */ +struct buf_pools_list_size_struct { + ulint LRU_bytes; /*!< LRU size in bytes */ + ulint unzip_LRU_bytes; /*!< unzip_LRU size in bytes */ + ulint flush_list_bytes; /*!< flush_list size in bytes */ +}; + +typedef struct buf_pools_list_size_struct buf_pools_list_size_t; + #ifndef UNIV_HOTBACKUP /********************************************************************//** Acquire mutex on all buffer pool instances */ @@ -1333,6 +1342,14 @@ buf_get_total_list_len( ulint* free_len, /*!< out: length of all free lists */ ulint* flush_list_len);/*!< out: length of all flush lists */ /********************************************************************//** +Get total list size in bytes from all buffer pools. */ +UNIV_INTERN +void +buf_get_total_list_size_in_bytes( +/*=============================*/ + buf_pools_list_size_t* buf_pools_list_size); /*!< out: list sizes + in all buffer pools */ +/********************************************************************//** Get total buffer pool statistics. */ UNIV_INTERN void @@ -1685,6 +1702,8 @@ struct buf_pool_stat_struct{ young because the first access was not long enough ago, in buf_page_peek_if_too_old() */ + ulint LRU_bytes; /*!< LRU size in bytes */ + ulint flush_list_bytes;/*!< flush_list size in bytes */ }; /** Statistics of buddy blocks of a given size. */ diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index 9ecb9de2afe..0e08f455800 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -149,7 +149,10 @@ buf_LRU_block_free_non_file_page( /*=============================*/ buf_block_t* block); /*!< in: block, must not contain a file page */ /******************************************************************//** -Adds a block to the LRU list. */ +Adds a block to the LRU list. Please make sure that the zip_size is +already set into the page zip when invoking the function, so that we +can get correct zip_size from the buffer page when adding a block +into LRU */ UNIV_INTERN void buf_LRU_add_block( diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 7d934365fb6..e2d061969f3 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -707,7 +707,9 @@ struct export_var_struct{ ulint innodb_data_reads; /*!< I/O read requests */ ulint innodb_buffer_pool_pages_total; /*!< Buffer pool size */ ulint innodb_buffer_pool_pages_data; /*!< Data pages */ + ulint innodb_buffer_pool_bytes_data; /*!< File bytes used */ ulint innodb_buffer_pool_pages_dirty; /*!< Dirty data pages */ + ulint innodb_buffer_pool_bytes_dirty; /*!< File bytes modified */ ulint innodb_buffer_pool_pages_misc; /*!< Miscellanous pages */ ulint innodb_buffer_pool_pages_free; /*!< Free pages */ #ifdef UNIV_DEBUG diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c index 398c544bc5b..5872ff2c437 100644 --- a/storage/innobase/srv/srv0srv.c +++ b/storage/innobase/srv/srv0srv.c @@ -2016,13 +2016,15 @@ void srv_export_innodb_status(void) /*==========================*/ { - buf_pool_stat_t stat; - ulint LRU_len; - ulint free_len; - ulint flush_list_len; + buf_pool_stat_t stat; + buf_pools_list_size_t buf_pools_list_size; + ulint LRU_len; + ulint free_len; + ulint flush_list_len; buf_get_total_stat(&stat); buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len); + buf_get_total_list_size_in_bytes(&buf_pools_list_size); mutex_enter(&srv_innodb_monitor_mutex); @@ -2051,7 +2053,12 @@ srv_export_innodb_status(void) export_vars.innodb_buffer_pool_read_ahead_evicted = stat.n_ra_pages_evicted; export_vars.innodb_buffer_pool_pages_data = LRU_len; + export_vars.innodb_buffer_pool_bytes_data = + buf_pools_list_size.LRU_bytes + + buf_pools_list_size.unzip_LRU_bytes; export_vars.innodb_buffer_pool_pages_dirty = flush_list_len; + export_vars.innodb_buffer_pool_bytes_dirty = + buf_pools_list_size.flush_list_bytes; export_vars.innodb_buffer_pool_pages_free = free_len; #ifdef UNIV_DEBUG export_vars.innodb_buffer_pool_pages_latched From 8cd60993716707a6c9af4fcc9d6d6d26b9b155e3 Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Mon, 10 Dec 2012 09:55:08 +0100 Subject: [PATCH 076/324] Bug#15960005 VALGRIND WARNINGS IN PROCESS_ARGS Both and can be specified as numbers or '*'. If an asterisk is used, an argument of type int is consumed. --- include/mysql/service_my_snprintf.h | 1 + strings/my_vsnprintf.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h index fd55944ed67..c7a03893d2e 100644 --- a/include/mysql/service_my_snprintf.h +++ b/include/mysql/service_my_snprintf.h @@ -49,6 +49,7 @@ string will be quoted according to MySQL identifier quoting rules. Both and can be specified as numbers or '*'. + If an asterisk is used, an argument of type int is consumed. can be 'l', 'll', or 'z'. diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 73cbf02f148..b0fd83451a6 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -343,6 +343,7 @@ start: print_arr[idx].length--; DBUG_ASSERT(*fmt == '$' && print_arr[idx].length < MAX_ARGS); args_arr[print_arr[idx].length].arg_type= 'd'; + args_arr[print_arr[idx].length].have_longlong= 0; print_arr[idx].flags|= LENGTH_ARG; arg_count= max(arg_count, print_arr[idx].length + 1); fmt++; @@ -361,6 +362,7 @@ start: print_arr[idx].width--; DBUG_ASSERT(*fmt == '$' && print_arr[idx].width < MAX_ARGS); args_arr[print_arr[idx].width].arg_type= 'd'; + args_arr[print_arr[idx].width].have_longlong= 0; print_arr[idx].flags|= WIDTH_ARG; arg_count= max(arg_count, print_arr[idx].width + 1); fmt++; From d426504b9e3e9e92b0c948e912f2b6ffdc89e2d7 Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Tue, 11 Dec 2012 10:11:24 +0530 Subject: [PATCH 077/324] Bug #14200010 NEWLY CREATED TABLE DOESN'T ALLOW FOR LOOSE INDEX SCANS Problem: Before the ALTER TABLE statement, the array dict_index_t::stat_n_diff_key_vals had proper values calculated and updated. But after the ALTER TABLE statement, all the values of this array is 0. Because of this statistics returned by innodb_rec_per_key() is different before and after the ALTER TABLE statement. Running the ANALYZE TABLE command populates the statistics correctly. Solution: After ALTER TABLE statement, set the flag dict_table_t::stat_initialized correctly so that the table statistics will be recalculated properly when the table is next loaded. But note that we still don't choose the loose index scans. This fix only ensures that an ALTER TABLE does not change the optimizer plan. rb://1639 approved by Marko and Jimmy. --- mysql-test/suite/innodb_plugin/r/innodb-index.result | 2 +- mysql-test/suite/innodb_plugin/r/innodb_mysql.result | 2 +- storage/innodb_plugin/row/row0mysql.c | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb_plugin/r/innodb-index.result b/mysql-test/suite/innodb_plugin/r/innodb-index.result index bf7c382327b..df853fac078 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-index.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-index.result @@ -963,7 +963,7 @@ Table Op Msg_type Msg_text test.t1 check status OK explain select * from t1 where b like 'adfd%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL b NULL NULL NULL 15 Using where +1 SIMPLE t1 range b b 769 NULL 7 Using where create table t2(a int, b varchar(255), primary key(a,b)) engine=innodb; insert into t2 select a,left(b,255) from t1; drop table t1; diff --git a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result index ebaa52d3b4d..02a3b340057 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb_mysql.result +++ b/mysql-test/suite/innodb_plugin/r/innodb_mysql.result @@ -343,7 +343,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index; Using temporary explain select distinct f1, f2 from t1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary +1 SIMPLE t1 index NULL PRIMARY 5 NULL 4 Using index drop table t1; CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), INDEX (name)); diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 137a164c4cd..9379912a218 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -4083,6 +4083,13 @@ end: trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, NULL); trx->error_state = DB_SUCCESS; + } else { + if (old_is_tmp && !new_is_tmp) { + /* After ALTER TABLE the table statistics + needs to be rebuilt. It will be rebuilt + when the table is loaded again. */ + table->stat_initialized = FALSE; + } } } From a172c2126577423fdcd9e1b442a299255b9f89f6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 11 Dec 2012 18:34:04 +0530 Subject: [PATCH 078/324] Bug #14737171: MTR DOES NOT PRESERVE TEST CASE LOGS ON RETRY-FAIL --- mysql-test/mysql-test-run.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 674abe7e102..44aac7e007e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -616,6 +616,8 @@ sub run_test_server ($$$) { else { mtr_report("\nRetrying test $tname, ". "attempt($retries/$opt_retry)...\n"); + my $log_file_name= $opt_vardir."/log/".$result->{shortname}.".log"; + rename $log_file_name,$log_file_name.".failed"; delete($result->{result}); $result->{retries}= $retries+1; $result->write_test($sock, 'TESTCASE'); From 2e10e7c38eb6ccef3319f3fc5267224c171628da Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Tue, 11 Dec 2012 22:00:51 +0400 Subject: [PATCH 079/324] Bug #15954872 "MAKE MDL SUBSYSTEM AND TABLE DEFINITION CACHE ROBUST AGAINST BUGS IN CALLERS". Both MDL subsystems and Table Definition Cache code assume that callers ensure that names of objects passed to them are not longer than NAME_LEN bytes. Unfortunately due to bugs in callers this assumption might be broken in some cases. As result we get nasty bugs causing buffer overruns when we construct MDL key or TDC key from object names. This patch makes TDC code more robust against such bugs by ensuring that we always checking size of result buffer when constructing TDC keys. This doesn't free its callers from ensuring that both db and table names are shorter than NAME_LEN bytes. But at least this steps prevents buffer overruns in case of bug in caller, replacing them with less harmful behavior. This is 5.1-only version of patch. This patch introduces new version of create_table_def_key() helper function which constructs TDC key without risk of result buffer overrun. Places in code that construct TDC keys were changed to use this function. Also changed rm_temporary_table() and open_new_frm() functions to avoid use of "unsafe" strmov() and strxmov() functions and use safer strnxmov() instead. --- sql/mysql_priv.h | 27 ++++++++++++++++++++++++++- sql/sql_base.cc | 46 ++++++++++++++++++++++++++++------------------ sql/sql_cache.cc | 13 +++++++------ sql/sql_trigger.cc | 4 +--- 4 files changed, 62 insertions(+), 28 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 4741562cab3..903fbcf019c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1296,6 +1296,31 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok); bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create); uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list, bool tmp_table); + +/** + Create a table cache key for non-temporary table. + + @param key Buffer for key (must be at least NAME_LEN*2+2 bytes). + @param db Database name. + @param table_name Table name. + + @return Length of key. + + @sa create_table_def_key(thd, char *, table_list, bool) +*/ + +inline uint +create_table_def_key(char *key, const char *db, const char *table_name) +{ + /* + In theory caller should ensure that both db and table_name are + not longer than NAME_LEN bytes. In practice we play safe to avoid + buffer overruns. + */ + return (uint)(strmake(strmake(key, db, NAME_LEN) + 1, table_name, + NAME_LEN) - key + 1); +} + TABLE_SHARE *get_table_share(THD *thd, TABLE_LIST *table_list, char *key, uint key_length, uint db_flags, int *error); void release_table_share(TABLE_SHARE *share, enum release_type type); @@ -1593,7 +1618,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint counter, bool *need_reopen); int decide_logging_format(THD *thd, TABLE_LIST *tables); TABLE *open_temporary_table(THD *thd, const char *path, const char *db, const char *table_name, bool link_in_list); -bool rm_temporary_table(handlerton *base, char *path); +bool rm_temporary_table(handlerton *base, const char *path); void free_io_cache(TABLE *entry); void intern_close_table(TABLE *entry); bool close_thread_table(THD *thd, TABLE **table_ptr); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c7513f45983..b191e9592ff 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -242,8 +242,9 @@ static void check_unused(void) uint create_table_def_key(THD *thd, char *key, TABLE_LIST *table_list, bool tmp_table) { - uint key_length= (uint) (strmov(strmov(key, table_list->db)+1, - table_list->table_name)-key)+1; + uint key_length= create_table_def_key(key, table_list->db, + table_list->table_name); + if (tmp_table) { int4store(key + key_length, thd->server_id); @@ -619,13 +620,10 @@ void release_table_share(TABLE_SHARE *share, enum release_type type) TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) { char key[NAME_LEN*2+2]; - TABLE_LIST table_list; uint key_length; safe_mutex_assert_owner(&LOCK_open); - table_list.db= (char*) db; - table_list.table_name= (char*) table_name; - key_length= create_table_def_key((THD*) 0, key, &table_list, 0); + key_length= create_table_def_key(key, db, table_name); return (TABLE_SHARE*) hash_search(&table_def_cache,(uchar*) key, key_length); } @@ -2419,7 +2417,7 @@ bool lock_table_name_if_not_cached(THD *thd, const char *db, uint key_length; DBUG_ENTER("lock_table_name_if_not_cached"); - key_length= (uint)(strmov(strmov(key, db) + 1, table_name) - key) + 1; + key_length= create_table_def_key(key, db, table_name); VOID(pthread_mutex_lock(&LOCK_open)); if (hash_search(&open_cache, (uchar *)key, key_length)) @@ -3025,7 +3023,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, TABLE *find_locked_table(THD *thd, const char *db,const char *table_name) { char key[MAX_DBKEY_LENGTH]; - uint key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; + uint key_length= create_table_def_key(key, db, table_name); for (TABLE *table=thd->open_tables; table ; table=table->next) { @@ -5737,17 +5735,27 @@ TABLE *open_temporary_table(THD *thd, const char *path, const char *db, } -bool rm_temporary_table(handlerton *base, char *path) +/** + Delete a temporary table. + + @param base Handlerton for table to be deleted. + @param path Path to the table to be deleted (i.e. path + to its .frm without an extension). + + @retval false - success. + @retval true - failure. +*/ + +bool rm_temporary_table(handlerton *base, const char *path) { bool error=0; handler *file; - char *ext; + char frm_path[FN_REFLEN + 1]; DBUG_ENTER("rm_temporary_table"); - strmov(ext= strend(path), reg_ext); - if (my_delete(path,MYF(0))) + strxnmov(frm_path, sizeof(frm_path) - 1, path, reg_ext, NullS); + if (my_delete(frm_path, MYF(0))) error=1; /* purecov: inspected */ - *ext= 0; // remove extension file= get_new_handler((TABLE_SHARE*) 0, current_thd->mem_root, base); if (file && file->ha_delete_table(path)) { @@ -8633,7 +8641,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, DBUG_ENTER("remove_table_from_cache"); DBUG_PRINT("enter", ("table: '%s'.'%s' flags: %u", db, table_name, flags)); - key_length=(uint) (strmov(strmov(key,db)+1,table_name)-key)+1; + key_length= create_table_def_key(key, db, table_name); for (;;) { HASH_SEARCH_STATE state; @@ -8831,12 +8839,14 @@ open_new_frm(THD *thd, TABLE_SHARE *share, const char *alias, { LEX_STRING pathstr; File_parser *parser; - char path[FN_REFLEN]; + char path[FN_REFLEN+1]; DBUG_ENTER("open_new_frm"); /* Create path with extension */ - pathstr.length= (uint) (strxmov(path, share->normalized_path.str, reg_ext, - NullS)- path); + pathstr.length= (uint) (strxnmov(path, sizeof(path) - 1, + share->normalized_path.str, + reg_ext, + NullS) - path); pathstr.str= path; if ((parser= sql_parse_prepare(&pathstr, mem_root, 1))) @@ -8977,7 +8987,7 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table TABLE *table; DBUG_ENTER("mysql_wait_completed_table"); - key_length=(uint) (strmov(strmov(key,lpt->db)+1,lpt->table_name)-key)+1; + key_length= create_table_def_key(key, lpt->db, lpt->table_name); VOID(pthread_mutex_lock(&LOCK_open)); HASH_SEARCH_STATE state; for (table= (TABLE*) hash_first(&open_cache,(uchar*) key,key_length, diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 901ff2d8744..8056ca6b49f 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2708,8 +2708,8 @@ void Query_cache::invalidate_table(THD *thd, TABLE_LIST *table_list) char key[MAX_DBKEY_LENGTH]; uint key_length; - key_length=(uint) (strmov(strmov(key,table_list->db)+1, - table_list->table_name) -key)+ 1; + key_length= create_table_def_key(key, table_list->db, + table_list->table_name); // We don't store temporary tables => no key_length+=4 ... invalidate_table(thd, (uchar *)key, key_length); @@ -2830,8 +2830,8 @@ Query_cache::register_tables_from_list(TABLE_LIST *tables_used, DBUG_PRINT("qcache", ("view: %s db: %s", tables_used->view_name.str, tables_used->view_db.str)); - key_length= (uint) (strmov(strmov(key, tables_used->view_db.str) + 1, - tables_used->view_name.str) - key) + 1; + key_length= create_table_def_key(key, tables_used->view_db.str, + tables_used->view_name.str); /* There are not callback function for for VIEWs */ @@ -4062,8 +4062,9 @@ uint Query_cache::filename_2_table_key (char *key, const char *path, *db_length= (filename - dbname) - 1; DBUG_PRINT("qcache", ("table '%-.*s.%s'", *db_length, dbname, filename)); - DBUG_RETURN((uint) (strmov(strmake(key, dbname, *db_length) + 1, - filename) -key) + 1); + DBUG_RETURN((uint) (strmake(strmake(key, dbname, + min(*db_length, NAME_LEN)) + 1, + filename, NAME_LEN) - key) + 1); } /**************************************************************************** diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 4e056739d96..3ad956cb3fe 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1988,9 +1988,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, */ #ifndef DBUG_OFF uchar key[MAX_DBKEY_LENGTH]; - uint key_length= (uint) (strmov(strmov((char*)&key[0], db)+1, - old_table)-(char*)&key[0])+1; - + uint key_length= create_table_def_key((char *)key, db, old_table); if (!is_table_name_exclusively_locked_by_this_thread(thd, key, key_length)) safe_mutex_assert_owner(&LOCK_open); #endif From 72343da4b6f1e31b0a940ac941196e202c720d71 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 12 Dec 2012 15:09:31 +0530 Subject: [PATCH 080/324] Bug #14737171:MTR DOES NOT PRESERVE TEST CASE LOGS ON RETRY-FAIL --- mysql-test/mysql-test-run.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 44aac7e007e..2f545b05c3c 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -616,7 +616,9 @@ sub run_test_server ($$$) { else { mtr_report("\nRetrying test $tname, ". "attempt($retries/$opt_retry)...\n"); - my $log_file_name= $opt_vardir."/log/".$result->{shortname}.".log"; + #saving the log file as filename.failed in case of retry + my $worker_logdir= $result->{savedir}; + my $log_file_name=dirname($worker_logdir)."/".$result->{shortname}.".log"; rename $log_file_name,$log_file_name.".failed"; delete($result->{result}); $result->{retries}= $retries+1; From cbc9373f363b7fa86562f587a527b6e8d8688a4e Mon Sep 17 00:00:00 2001 From: Harin Vadodaria Date: Thu, 13 Dec 2012 10:17:26 +0530 Subject: [PATCH 081/324] Bug#15965288: BUFFER OVERFLOW IN YASSL FUNCTION DOPROCESSREPLY() Description: Function DoProcessReply() calls function decrypt_message() in a while loop without performing a check on available buffer space. This can cause buffer overflow and crash the server. This patch is fix provided by Sawtooth to resolve the issue. --- extra/yassl/src/handshake.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/extra/yassl/src/handshake.cpp b/extra/yassl/src/handshake.cpp index c1ee61d043e..c7dbaf86071 100644 --- a/extra/yassl/src/handshake.cpp +++ b/extra/yassl/src/handshake.cpp @@ -767,8 +767,14 @@ int DoProcessReply(SSL& ssl) while (buffer.get_current() < hdr.length_ + RECORD_HEADER + offset) { // each message in record, can be more than 1 if not encrypted - if (ssl.getSecurity().get_parms().pending_ == false) // cipher on + if (ssl.getSecurity().get_parms().pending_ == false) { // cipher on + // sanity check for malicious/corrupted/illegal input + if (buffer.get_remaining() < hdr.length_) { + ssl.SetError(bad_input); + return 0; + } decrypt_message(ssl, buffer, hdr.length_); + } mySTL::auto_ptr msg(mf.CreateObject(hdr.type_)); if (!msg.get()) { From b0213a2b3ae26ca38347355aa17f84828124eafe Mon Sep 17 00:00:00 2001 From: Satya Bodapati Date: Thu, 13 Dec 2012 18:53:16 +0530 Subject: [PATCH 082/324] Bug#14628410 - ASSERTION `! IS_SET()' FAILED IN DIAGNOSTICS_AREA::SET_OK_STATUS The error code returned from Merge file/Temp file creation functions are ignored. Use the return codes of the row_merge_file_create() and innobase_mysql_tmpfile() to return the error to caller if file creation fails. Approved by Marko. rb#1618 --- storage/innodb_plugin/handler/ha_innodb.cc | 7 ++++++ storage/innodb_plugin/row/row0merge.c | 26 +++++++++++++++++----- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index fadcefec023..340e7cccd97 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -929,6 +929,8 @@ convert_error_code_to_mysql( #endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */ case DB_UNSUPPORTED: return(HA_ERR_UNSUPPORTED); + case DB_OUT_OF_MEMORY: + return(HA_ERR_OUT_OF_MEM); } } @@ -1138,6 +1140,8 @@ innobase_mysql_tmpfile(void) DBUG_ENTER("innobase_mysql_tmpfile"); + DBUG_EXECUTE_IF("innobase_tmpfile_creation_failure", return(-1);); + tmpdir = my_tmpdir(&mysql_tmpdir_list); /* The tmpdir parameter can not be NULL for GetTempFileName. */ @@ -1200,6 +1204,9 @@ innobase_mysql_tmpfile(void) { int fd2 = -1; File fd = mysql_tmpfile("ib"); + + DBUG_EXECUTE_IF("innobase_tmpfile_creation_failure", return(-1);); + if (fd >= 0) { /* Copy the file descriptor, so that the additional resources allocated by create_temp_file() can be freed by invoking diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 5a8d2de968f..204fecbba75 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -702,6 +702,8 @@ row_merge_read( ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof *buf; ibool success; + DBUG_EXECUTE_IF("row_merge_read_failure", return(FALSE);); + #ifdef UNIV_DEBUG if (row_merge_print_block_read) { fprintf(stderr, "row_merge_read fd=%d ofs=%lu\n", @@ -738,6 +740,8 @@ row_merge_write( ib_uint64_t ofs = ((ib_uint64_t) offset) * sizeof(row_merge_block_t); + DBUG_EXECUTE_IF("row_merge_write_failure", return(FALSE);); + #ifdef UNIV_DEBUG if (row_merge_print_block_write) { fprintf(stderr, "row_merge_write fd=%d ofs=%lu\n", @@ -2189,9 +2193,10 @@ row_merge_drop_temp_indexes(void) } /*********************************************************************//** -Create a merge file. */ -static -void +Create a merge file. +@return file descriptor, or -1 on failure */ +static __attribute__((nonnull, warn_unused_result)) +int row_merge_file_create( /*==================*/ merge_file_t* merge_file) /*!< out: merge file structure */ @@ -2199,6 +2204,7 @@ row_merge_file_create( merge_file->fd = innobase_mysql_tmpfile(); merge_file->offset = 0; merge_file->n_rec = 0; + return(merge_file->fd); } /*********************************************************************//** @@ -2619,7 +2625,7 @@ row_merge_build_indexes( ulint block_size; ulint i; ulint error; - int tmpfd; + int tmpfd = -1; ut_ad(trx); ut_ad(old_table); @@ -2638,11 +2644,21 @@ row_merge_build_indexes( for (i = 0; i < n_indexes; i++) { - row_merge_file_create(&merge_files[i]); + if (row_merge_file_create(&merge_files[i]) < 0) + { + error = DB_OUT_OF_MEMORY; + goto func_exit; + } } tmpfd = innobase_mysql_tmpfile(); + if (tmpfd < 0) + { + error = DB_OUT_OF_MEMORY; + goto func_exit; + } + /* Reset the MySQL row buffer that is used when reporting duplicate keys. */ innobase_rec_reset(table); From 2d16c5bd4b6a0fb9f3cd325d0ae8c3805c1ac62c Mon Sep 17 00:00:00 2001 From: Ravinder Thakur Date: Thu, 13 Dec 2012 20:33:44 +0530 Subject: [PATCH 083/324] bug#11761752: DO NOT ALLOW USE OF ALTERNATE DATA STREAMS ON NTFS FILESYSTEM. File names with colon are being disallowed because of the Alternate Data Stream (ADS) feature of NTFS that could be misused. ADS allows data to be written to alternate streams of a normal file. The data in alternate streams cannot be seen by normal tools on Windows (explorer, cmd.exe). As a result someone can use this feature to hide large amount of data in alternate streams and admins will have no easy way of figuring out the files that are using that disk space. The fix also disallows ADS in the scenarios where file name is passed as some dynamic variable. An important thing about the fix is that it DOES NOT disallow ADS file names if they are not dynamic (i.e. if the file is created by using some option that needs local access to the MySQL server, for example error log file). The reasoning is that if some MySQL option related to files requires access to the local machine (it is not dynamic), then user can very well create data in ADS by some other means. This fixes only those scenarios which can allow users to create data in ADS over the wire. File names with colon are being disallowed only on Windows. UNIX (Linux in particular) supports NTFS, but it will not be a common scenario for someone to configure a NTFS file system to store MySQL data on Linux. Changes in file bug11761752-master.opt are needed due to bug number 15937938. --- include/my_sys.h | 1 + mysys/my_access.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++ mysys/my_fopen.c | 5 ++++ mysys/my_open.c | 7 ++++++ sql/set_var.cc | 3 +++ 5 files changed, 77 insertions(+) diff --git a/include/my_sys.h b/include/my_sys.h index f6cd9dada99..6bdb95e9707 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -649,6 +649,7 @@ extern File my_sopen(const char *path, int oflag, int shflag, int pmode); #endif extern int check_if_legal_filename(const char *path); extern int check_if_legal_tablename(const char *path); +extern my_bool is_filename_allowed(const char *name, size_t length); #if defined(__WIN__) && defined(__NT__) extern int nt_share_delete(const char *name,myf MyFlags); diff --git a/mysys/my_access.c b/mysys/my_access.c index 43917da7f98..4734fbac8ba 100644 --- a/mysys/my_access.c +++ b/mysys/my_access.c @@ -156,6 +156,67 @@ int check_if_legal_tablename(const char *name) } +#ifdef __WIN__ +/** + Checks if the drive letter supplied is valid or not. Valid drive + letters are A to Z, both lower case and upper case. + + @param drive_letter : The drive letter to validate. + + @return TRUE if the drive exists, FALSE otherwise. +*/ +static my_bool does_drive_exists(char drive_letter) +{ + DWORD drive_mask= GetLogicalDrives(); + drive_letter= toupper(drive_letter); + + return (drive_letter >= 'A' && drive_letter <= 'Z') && + (drive_mask & (0x1 << (drive_letter - 'A'))); +} +#endif + +/** + Verifies if the file name supplied is allowed or not. On Windows + file names with a colon (:) are not allowed because such file names + store data in Alternate Data Streams which can be used to hide + the data. + + @param name contains the file name with or without path + @param length contains the length of file name + + @return TRUE if the file name is allowed, FALSE otherwise. +*/ +my_bool is_filename_allowed(const char *name __attribute__((unused)), + size_t length __attribute__((unused))) +{ +#ifdef __WIN__ + /* + For Windows, check if the file name contains : character. + Start from end of path and search if the file name contains : + */ + const char* ch = NULL; + for(ch= name + length - 1; ch >= name; --ch) + { + if (FN_LIBCHAR == *ch || '/' == *ch) + break; + else if (':' == *ch) + { + /* + File names like C:foobar.txt are allowed since the syntax means + file foobar.txt in current directory of C drive. However file + names likes CC:foobar are not allowed since this syntax means ADS + foobar in file CC. + */ + return ((ch - name == 1) && does_drive_exists(*name)); + } + } + return TRUE; +#else + /* For other platforms, file names can contain colon : */ + return TRUE; +#endif +} /* is_filename_allowed */ + #if defined(__WIN__) || defined(__EMX__) diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index 72991490d75..75c5ec6ff8b 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -56,6 +56,11 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) errno= EACCES; fd= 0; } + else if (!is_filename_allowed(filename, strlen(filename))) + { + errno= EINVAL; + fd= 0; + } else #endif { diff --git a/mysys/my_open.c b/mysys/my_open.c index fe7f65c450b..9060bb404e8 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -218,6 +218,13 @@ File my_sopen(const char *path, int oflag, int shflag, int pmode) DWORD fileattrib; /* OS file attribute flags */ SECURITY_ATTRIBUTES SecurityAttributes; + if (!is_filename_allowed(path, strlen(path))) + { + errno= EINVAL; + _doserrno= 0L; /* not an OS error */ + return -1; + } + SecurityAttributes.nLength= sizeof(SecurityAttributes); SecurityAttributes.lpSecurityDescriptor= NULL; SecurityAttributes.bInheritHandle= !(oflag & _O_NOINHERIT); diff --git a/sql/set_var.cc b/sql/set_var.cc index bbc47c2d7e8..269eea844aa 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2502,6 +2502,9 @@ static int sys_check_log_path(THD *thd, set_var *var) goto err; } + if (!is_filename_allowed(log_file_str, strlen(log_file_str))) + goto err; + if (my_stat(path, &f_stat, MYF(0))) { /* From 117e2d1b6b13998d1aa19f4192813bd97488bafb Mon Sep 17 00:00:00 2001 From: Inaam Rana Date: Fri, 14 Dec 2012 11:24:57 +0500 Subject: [PATCH 084/324] Bug#14329288 IS THE CALL TO IBUF_MERGE_OR_DELETE_FOR_PAGE FROM BUF_PAGE_GET_GEN REDUNDANT? rb://1711 approved by: Marko Makela When decompressing a compressed page that had already been accessed in the buffer pool, do not attempt to merge buffered changes. --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/buf/buf0buf.c | 21 ++++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 5387555d24f..a8e54f6dc30 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2012-12-13 The InnoDB Team + + * buf/buf0buf.c: + Fix Bug#14329288 IS THE CALL TO IBUF_MERGE_OR_DELETE_FOR_PAGE FROM + BUF_PAGE_GET_GEN REDUNDANT? + 2012-11-15 The InnoDB Team * include/data0type.ic, include/rem0rec.h, diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index 755fa947c8f..e7e60fb2b2a 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -1778,22 +1778,29 @@ wait_until_unfixed: UNIV_MEM_INVALID(bpage, sizeof *bpage); + buf_pool->n_pend_unzip++; + buf_pool_mutex_exit(); + + access_time = buf_page_is_accessed(&block->page); mutex_exit(&block->mutex); mutex_exit(&buf_pool_zip_mutex); - buf_pool->n_pend_unzip++; - - buf_pool_mutex_exit(); buf_page_free_descriptor(bpage); - /* Decompress the page and apply buffered operations - while not holding buf_pool_mutex or block->mutex. */ + /* Decompress the page while not holding + buf_pool_mutex or block->mutex. */ success = buf_zip_decompress(block, srv_use_checksums); ut_a(success); if (UNIV_LIKELY(!recv_no_ibuf_operations)) { - ibuf_merge_or_delete_for_page(block, space, offset, - zip_size, TRUE); + if (access_time) { +#ifdef UNIV_IBUF_COUNT_DEBUG + ut_a(ibuf_count_get(space, offset) == 0); +#endif /* UNIV_IBUF_COUNT_DEBUG */ + } else { + ibuf_merge_or_delete_for_page( + block, space, offset, zip_size, TRUE); + } } /* Unfix and unlatch the block. */ From 0fa867fd9105dc6ccce8437df0ce7f03b89bec92 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Fri, 14 Dec 2012 13:55:30 +0400 Subject: [PATCH 085/324] Fix for BUG#15948580 UPDATE_XML() CRASHES THE SERVER. Problem: tag's buffer overflow leads to a problem. Fix: bound check added. sql/item_xmlfunc.cc: Fix for BUG#15948580 UPDATE_XML() CRASHES THE SERVER. - XML tag/attribute level shouldn't exceed MAX_LEVEL as we use a static buffer to store them in the MY_XML_USER_DATA. --- sql/item_xmlfunc.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 751c975b48e..4140fcfb11c 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -2669,8 +2669,12 @@ int xml_enter(MY_XML_PARSER *st,const char *attr, size_t len) node.parent= data->parent; // Set parent for the new node to old parent data->parent= numnodes; // Remember current node as new parent + DBUG_ASSERT(data->level <= MAX_LEVEL); data->pos[data->level]= numnodes; - node.level= data->level++; + if (data->level < MAX_LEVEL) + node.level= data->level++; + else + return MY_XML_ERROR; node.type= st->current_node_type; // TAG or ATTR node.beg= attr; node.end= attr + len; From 7bdd8b481c9456091a6ad4cd4deeccf8d5001bd1 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 18 Dec 2012 16:51:41 +0200 Subject: [PATCH 086/324] Fix Bug#13463493 INNODB PLUGIN WERE CHANGED, BUT STILL USE THE SAME VERSION NUMBER 1.0.17 Now that InnoDB/InnoDB Plugin is no longer separately developed and distributed from the MySQL server it does not need its own version number. Thus use the MySQL version instead. "Removing" the version altogether is not feasible because the config variable 'innodb_version' cannot be removed in GA branches. Reviewed by: Marko (rb#1751) --- storage/innodb_plugin/ChangeLog | 6 ++++++ storage/innodb_plugin/include/univ.i | 18 +++++++----------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index a8e54f6dc30..e9c86a85d29 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,3 +1,9 @@ +2012-12-18 The InnoDB Team + + * include/univ.i: + Fix Bug#Bug#13463493 INNODB PLUGIN WERE CHANGED, BUT STILL USE THE + SAME VERSION NUMBER 1.0.17 + 2012-12-13 The InnoDB Team * buf/buf0buf.c: diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index a25b2e6585c..ff3a0a6686c 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -43,9 +43,12 @@ Created 1/20/1994 Heikki Tuuri #include "hb_univ.i" #endif /* UNIV_HOTBACKUP */ -#define INNODB_VERSION_MAJOR 1 -#define INNODB_VERSION_MINOR 0 -#define INNODB_VERSION_BUGFIX 17 +#include + +/* Set InnoDB Plugin version to be the same as the MySQL server version. +MYSQL_VERSION_ID is something like 50168. */ +#define INNODB_VERSION_MAJOR (MYSQL_VERSION_ID / 10000) +#define INNODB_VERSION_MINOR (MYSQL_VERSION_ID / 100 % 100) /* The following is the InnoDB version as shown in SELECT plugin_version FROM information_schema.plugins; @@ -56,14 +59,7 @@ component, i.e. we show M.N.P as M.N */ #define INNODB_VERSION_SHORT \ (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) -/* auxiliary macros to help creating the version as string */ -#define __INNODB_VERSION(a, b, c) (#a "." #b "." #c) -#define _INNODB_VERSION(a, b, c) __INNODB_VERSION(a, b, c) - -#define INNODB_VERSION_STR \ - _INNODB_VERSION(INNODB_VERSION_MAJOR, \ - INNODB_VERSION_MINOR, \ - INNODB_VERSION_BUGFIX) +#define INNODB_VERSION_STR MYSQL_SERVER_VERSION #define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/" From febe03c2dbc3b9cab4f7e083274619f6bb96ec4a Mon Sep 17 00:00:00 2001 From: Ahmad Abdullateef Date: Tue, 18 Dec 2012 22:12:56 +0530 Subject: [PATCH 087/324] BUG#14727815 - CRASH IN PTHREAD_RWLOCK_WRLOCK/SRW_UNLOCK IN QUERY CACHE CODE DESCRIPTION: MySQL Server crashes sporadically when Query Caching is on and the server has high contention among clients. ANALYSIS : Scenario 1: In Query_cache::move_by_type() when handling RESULT or its related blocks, Write Lock is acquired on its parent Query block. However the next and prev pointers are cached in local variables before lock acquisition. In an extremely high contention scenario there exists a possibility that Query_cache::append_result_data() is operating on the same query block and as a consequence might append a new Result block to the end of Result blocks Linked List of the Query. This would manipulate the next, prev pointers of the Block being processed in move_by_type(), however the local pointers still point to previous nodes there by causing Data Corruption leading to crash. FIX : Scenario 1: The next, prev pointers are now accessed only after Lock acquisition in Query_cache::move_by_type(). --- sql/sql_cache.cc | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 8056ca6b49f..cba7c876a4c 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -3892,15 +3892,14 @@ my_bool Query_cache::move_by_type(uchar **border, case Query_cache_block::RES_CONT: case Query_cache_block::RESULT: { - DBUG_PRINT("qcache", ("block 0x%lx RES* (%d)", (ulong) block, - (int) block->type)); - if (*border == 0) - break; - Query_cache_block *query_block = block->result()->parent(), - *next = block->next, - *prev = block->prev; - Query_cache_block::block_type type = block->type; - BLOCK_LOCK_WR(query_block); + DBUG_PRINT("qcache", ("block 0x%lx RES* (%d)", (ulong) block, + (int) block->type)); + if (*border == 0) + break; + Query_cache_block *query_block= block->result()->parent(); + BLOCK_LOCK_WR(query_block); + Query_cache_block *next= block->next, *prev= block->prev; + Query_cache_block::block_type type= block->type; ulong len = block->length, used = block->used; Query_cache_block *pprev = block->pprev, *pnext = block->pnext, From 0dd066cb6f462cd4d76184e4176aefbf7d874440 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Tue, 18 Dec 2012 20:55:30 +0200 Subject: [PATCH 088/324] Fix Bug#16000909 MEMORY LEAK, MYSQL_INPLACE_ALTER_TABLE This is a followup to the fix of Bug#14628410 ASSERTION `! IS_SET()' FAILED IN DIAGNOSTICS_AREA::SET_OK_STATUS (satya.bodapati@oracle.com-20121213132316-5joz4phltx9yhjs7) In innobase_mysql_tmpfile(): allocate/open the file after the return(-1); statement. --- storage/innodb_plugin/handler/ha_innodb.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 340e7cccd97..e15c84c8346 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -1140,7 +1140,10 @@ innobase_mysql_tmpfile(void) DBUG_ENTER("innobase_mysql_tmpfile"); - DBUG_EXECUTE_IF("innobase_tmpfile_creation_failure", return(-1);); + DBUG_EXECUTE_IF( + "innobase_tmpfile_creation_failure", + return(-1); + ); tmpdir = my_tmpdir(&mysql_tmpdir_list); @@ -1203,9 +1206,14 @@ innobase_mysql_tmpfile(void) /*========================*/ { int fd2 = -1; - File fd = mysql_tmpfile("ib"); + File fd; - DBUG_EXECUTE_IF("innobase_tmpfile_creation_failure", return(-1);); + DBUG_EXECUTE_IF( + "innobase_tmpfile_creation_failure", + return(-1); + ); + + fd = mysql_tmpfile("ib"); if (fd >= 0) { /* Copy the file descriptor, so that the additional resources From d485482a5f7d4b6ba15159b01be48c5da59db273 Mon Sep 17 00:00:00 2001 From: Vasil Dimov Date: Wed, 19 Dec 2012 13:46:00 +0200 Subject: [PATCH 089/324] Fix Bug#16021177 DICT_LOAD_FOREIGNS() PASSES UNALIGNED MEMORY TO DTUPLE_CREATE_FROM_MEM() Align to word-size the memory occupied by tuple_buf[] memory chunk. I confirm that this change fixes the SIGBUS on Solaris. Approved by: Marko (via IM) --- storage/innobase/dict/dict0load.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c index f8df2310d83..b36042e7f7a 100644 --- a/storage/innobase/dict/dict0load.c +++ b/storage/innobase/dict/dict0load.c @@ -2328,7 +2328,8 @@ dict_load_foreigns( ibool check_charsets) /*!< in: TRUE=check charset compatibility */ { - char tuple_buf[DTUPLE_EST_ALLOC(1)]; + ulint tuple_buf[(DTUPLE_EST_ALLOC(1) + sizeof(ulint) - 1) + / sizeof(ulint)]; btr_pcur_t pcur; dtuple_t* tuple; dfield_t* dfield; From c7fd61814f6014e90d90f4919ea4024f77c7e14c Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Thu, 20 Dec 2012 11:59:36 +0530 Subject: [PATCH 090/324] Bug #14556349 RENAME OF COMPRESSED TABLE AND INSERT BUFFER MERGE CAUSE HANG Problem Statement: When the operation RENAME TABLE is about rename the tablespace of the table, it will stop all i/o operations on the tablespace temporarily. For this the fil_space_t::stop_ios member is used. Once the fil_space_t::stop_ios member is set to TRUE in the RENAME TABLE operation, it is expected that no new i/o operation will be done on the tablespace and all pending i/o operation can be completed on the tablespace. If the pending i/o operations initiate any new i/o operations then there will be deadlock. The RENAME TABLE operation will be waiting for pending i/o on the tablespace to be completed, and the pending i/o operations will be waiting on the RENAME TABLE operation to set the file_space_t::stop_ios flag to be set to FALSE. But in the given scenario the pending i/o operations did not initiate new i/o. But they where still unnecessarily checking the fil_space_t::stop_ios flag. This resulted in deadlock. Solution: I noticed that this deadlock happens in fil_space_get_size() and fil_space_get_zip_size() in the i/o threads. These functions check the stop_ios flag even when no i/o will be initiated. I modified these functions to ensure that they check the stop_ios flag only when they will be initiating an i/o operation. This solves the problem. rb://1635 (mysql-5.5) rb://1660 (mysql-trunk) approved by Inaam, Jimmy, and ima. --- storage/innobase/fil/fil0fil.c | 38 ++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 0e817942908..2f875663039 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -1466,7 +1466,7 @@ fil_space_get_size( ut_ad(fil_system); - fil_mutex_enter_and_prepare_for_io(id); + mutex_enter(&fil_system->mutex); space = fil_space_get_by_id(id); @@ -1481,6 +1481,23 @@ fil_space_get_size( ut_a(1 == UT_LIST_GET_LEN(space->chain)); + mutex_exit(&fil_system->mutex); + + /* It is possible that the space gets evicted at this point + before the fil_mutex_enter_and_prepare_for_io() acquires + the fil_system->mutex. Check for this after completing the + call to fil_mutex_enter_and_prepare_for_io(). */ + fil_mutex_enter_and_prepare_for_io(id); + + /* We are still holding the fil_system->mutex. Check if + the space is still in memory cache. */ + space = fil_space_get_by_id(id); + + if (space == NULL) { + mutex_exit(&fil_system->mutex); + return(0); + } + node = UT_LIST_GET_FIRST(space->chain); /* It must be a single-table tablespace and we have not opened @@ -1518,7 +1535,7 @@ fil_space_get_flags( return(0); } - fil_mutex_enter_and_prepare_for_io(id); + mutex_enter(&fil_system->mutex); space = fil_space_get_by_id(id); @@ -1533,6 +1550,23 @@ fil_space_get_flags( ut_a(1 == UT_LIST_GET_LEN(space->chain)); + mutex_exit(&fil_system->mutex); + + /* It is possible that the space gets evicted at this point + before the fil_mutex_enter_and_prepare_for_io() acquires + the fil_system->mutex. Check for this after completing the + call to fil_mutex_enter_and_prepare_for_io(). */ + fil_mutex_enter_and_prepare_for_io(id); + + /* We are still holding the fil_system->mutex. Check if + the space is still in memory cache. */ + space = fil_space_get_by_id(id); + + if (space == NULL) { + mutex_exit(&fil_system->mutex); + return(0); + } + node = UT_LIST_GET_FIRST(space->chain); /* It must be a single-table tablespace and we have not opened From 4a35c6d44b7c400e8b89cdff99a628cc2a903ebd Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Thu, 20 Dec 2012 10:56:09 +0100 Subject: [PATCH 091/324] Bug#16027468 ADDRESSSANITIZER BUG IN MYSQLTEST DBUG_ENTER and DBUG_LEAVE must *always* match, otherwise all subsequent DBUG_ENTER calls will be poking into undefined stack frames. --- client/mysqltest.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 89fcb56825e..23978579cdb 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1168,7 +1168,7 @@ void close_files() void free_used_memory() { uint i; - DBUG_ENTER("free_used_memory"); + // Do not use DBUG_ENTER("free_used_memory"); here, see below. if (connections) close_connections(); @@ -1206,7 +1206,6 @@ void free_used_memory() mysql_server_end(); /* Don't use DBUG after mysql_server_end() */ - DBUG_VIOLATION_HELPER_LEAVE; return; } From c162202ac06c4659e43fad96f9fe0b2907bef13a Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Thu, 20 Dec 2012 19:26:20 +0530 Subject: [PATCH 092/324] Bug #13819630 ARCHIVE TABLE WITH 1000+ PARTITIONS CRASHES SERVER ON "DROP TABLE" In the function ha_archive::write_row(), there is an error code path that exits the function without releasing the mutex that was acquired earlier. rb#1743 approved by ramil. --- storage/archive/ha_archive.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 0e186cb8513..164c59f2426 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -898,10 +898,11 @@ int ha_archive::write_row(uchar *buf) table->timestamp_field->set_time(); mysql_mutex_lock(&share->mutex); - if (!share->archive_write_open) - if (init_archive_writer()) - DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); - + if (!share->archive_write_open && init_archive_writer()) + { + rc= HA_ERR_CRASHED_ON_USAGE; + goto error; + } if (table->next_number_field && record == table->record[0]) { @@ -980,8 +981,8 @@ int ha_archive::write_row(uchar *buf) rc= real_write_row(buf, &(share->archive_write)); error: mysql_mutex_unlock(&share->mutex); - my_free(read_buf); - + if (read_buf) + my_free(read_buf); DBUG_RETURN(rc); } From 98aaf18bc7ff64cbb616b4ce94998218704112b6 Mon Sep 17 00:00:00 2001 From: prabakaran thirumalai Date: Fri, 21 Dec 2012 11:04:49 +0530 Subject: [PATCH 093/324] Bug#14627287 THREAD CACHE - BYPASSES PRIVILEGES Analysis: When thread cache is enabled, it does not properly initialize thd->start_utime when a thread is picked from the thread cache. This breaks the quota management mechanism. THD::time_out_user_resource_limits() resets m_user_connect->conn_per_hour to 0 based on thd->start_utime Fix: Initialize start_utime when cached thread is reused. Notes: Enabled back tests which were disabled because of this issue. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index aece8f28533..cb1bc6bed12 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1969,7 +1969,7 @@ static bool cache_thread() this thread for handling of new THD object/connection. */ thd->mysys_var->abort= 0; - thd->thr_create_utime= my_micro_time(); + thd->thr_create_utime= thd->start_utime= my_micro_time(); threads.append(thd); return(1); } From 96c373c51a2a6f3d0c2190bbc2f641c455f67319 Mon Sep 17 00:00:00 2001 From: Roy Lyseng Date: Fri, 21 Dec 2012 09:53:42 +0100 Subject: [PATCH 094/324] Bug#15972635: Incorrect results returned in 32 table join with HAVING The problem is a shift operation that is not 64-bit safe. The consequence is that used tables information for a join with 32 tables or more will be incorrect. Fixed by adding a type cast in Item_sum::update_used_tables(). Also used the opportunity to fix some other potential bugs by adding an explicit type-cast to an integer in a left-shift operation. Some of them were quite harmless, but was fixed in order to get the same signed-ness as the other operand of the operation it was used in. sql/item_cmpfunc.cc Adjusted signed-ness for some integers in left-shift. sql/item_subselect.cc Added type-cast to nesting_map (which is a 32/64 bit type, so potential bug for deeply nested queries). sql/item_sum.cc Added type-cast to nesting_map (32/64-bit type) and table_map (64-bit type). sql/opt_range.cc Added type-cast to ulonglong (which is a 64-bit type). sql/sql_base.cc Added type-cast to nesting_map (which is a 32/64-bit type). sql/sql_select.cc Added type-cast to nesting_map (32/64-bit type) and key_part_map (64-bit type). sql/strfunc.cc Changed type-cast from longlong to ulonglong, to preserve signed-ness. --- sql/item_cmpfunc.cc | 22 +++++++++++----------- sql/item_subselect.cc | 3 ++- sql/item_sum.cc | 15 +++++++++------ sql/opt_range.cc | 2 +- sql/sql_base.cc | 3 ++- sql/sql_select.cc | 35 +++++++++++++++++++---------------- sql/strfunc.cc | 2 +- 7 files changed, 45 insertions(+), 37 deletions(-) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 47e576e7fdf..4dc41d29794 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -220,15 +220,15 @@ static uint collect_cmp_types(Item **items, uint nitems, bool skip_nulls= FALSE) items[i]->result_type() == ROW_RESULT) && cmp_row_type(items[0], items[i])) return 0; - found_types|= 1<< (uint)item_cmp_type(left_result, - items[i]->result_type()); + found_types|= 1U << (uint)item_cmp_type(left_result, + items[i]->result_type()); } /* Even if all right-hand items are NULLs and we are skipping them all, we need at least one type bit in the found_type bitmask. */ if (skip_nulls && !found_types) - found_types= 1 << (uint)left_result; + found_types= 1U << (uint)left_result; return found_types; } @@ -2897,12 +2897,12 @@ Item *Item_func_case::find_item(String *str) cmp_type= item_cmp_type(left_result_type, args[i]->result_type()); DBUG_ASSERT(cmp_type != ROW_RESULT); DBUG_ASSERT(cmp_items[(uint)cmp_type]); - if (!(value_added_map & (1<<(uint)cmp_type))) + if (!(value_added_map & (1U << (uint)cmp_type))) { cmp_items[(uint)cmp_type]->store_value(args[first_expr_num]); if ((null_value=args[first_expr_num]->null_value)) return else_expr_num != -1 ? args[else_expr_num] : 0; - value_added_map|= 1<<(uint)cmp_type; + value_added_map|= 1U << (uint)cmp_type; } if (!cmp_items[(uint)cmp_type]->cmp(args[i]) && !args[i]->null_value) return args[i + 1]; @@ -3107,7 +3107,7 @@ void Item_func_case::fix_length_and_dec() nagg++; if (!(found_types= collect_cmp_types(agg, nagg))) return; - if (found_types & (1 << STRING_RESULT)) + if (found_types & (1U << STRING_RESULT)) { /* If we'll do string comparison, we also need to aggregate @@ -3147,7 +3147,7 @@ void Item_func_case::fix_length_and_dec() } for (i= 0; i <= (uint)DECIMAL_RESULT; i++) { - if (found_types & (1 << i) && !cmp_items[i]) + if (found_types & (1U << i) && !cmp_items[i]) { DBUG_ASSERT((Item_result)i != ROW_RESULT); if (!(cmp_items[i]= @@ -3956,7 +3956,7 @@ void Item_func_in::fix_length_and_dec() } for (i= 0; i <= (uint)DECIMAL_RESULT; i++) { - if (found_types & 1 << i) + if (found_types & (1U << i)) { (type_cnt)++; cmp_type= (Item_result) i; @@ -4139,7 +4139,7 @@ void Item_func_in::fix_length_and_dec() { for (i= 0; i <= (uint) DECIMAL_RESULT; i++) { - if (found_types & (1 << i) && !cmp_items[i]) + if (found_types & (1U << i) && !cmp_items[i]) { if ((Item_result)i == STRING_RESULT && agg_arg_charsets_for_comparison(cmp_collation, args, arg_count)) @@ -4229,12 +4229,12 @@ longlong Item_func_in::val_int() Item_result cmp_type= item_cmp_type(left_result_type, args[i]->result_type()); in_item= cmp_items[(uint)cmp_type]; DBUG_ASSERT(in_item); - if (!(value_added_map & (1 << (uint)cmp_type))) + if (!(value_added_map & (1U << (uint)cmp_type))) { in_item->store_value(args[0]); if ((null_value= args[0]->null_value)) return 0; - value_added_map|= 1 << (uint)cmp_type; + value_added_map|= 1U << (uint)cmp_type; } if (!in_item->cmp(args[i]) && !args[i]->null_value) return (longlong) (!negated); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index d3b06f5983a..dd6257db30a 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1042,7 +1042,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, } save_allow_sum_func= thd->lex->allow_sum_func; - thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; + thd->lex->allow_sum_func|= + (nesting_map)1 << thd->lex->current_select->nest_level; /* Item_sum_(max|min) can't substitute other item => we can use 0 as reference, also Item_sum_(max|min) can't be fixed after creation, so diff --git a/sql/item_sum.cc b/sql/item_sum.cc index d9e634f8c16..75aec7918fa 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -151,9 +151,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) If it is there under a construct where it is not allowed we report an error. */ - invalid= !(allow_sum_func & (1 << max_arg_level)); + invalid= !(allow_sum_func & ((nesting_map)1 << max_arg_level)); } - else if (max_arg_level >= 0 || !(allow_sum_func & (1 << nest_level))) + else if (max_arg_level >= 0 || + !(allow_sum_func & ((nesting_map)1 << nest_level))) { /* The set function can be aggregated only in outer subqueries. @@ -162,7 +163,8 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) */ if (register_sum_func(thd, ref)) return TRUE; - invalid= aggr_level < 0 && !(allow_sum_func & (1 << nest_level)); + invalid= aggr_level < 0 && + !(allow_sum_func & ((nesting_map)1 << nest_level)); if (!invalid && thd->variables.sql_mode & MODE_ANSI) invalid= aggr_level < 0 && max_arg_level < nest_level; } @@ -310,14 +312,15 @@ bool Item_sum::register_sum_func(THD *thd, Item **ref) sl && sl->nest_level > max_arg_level; sl= sl->master_unit()->outer_select() ) { - if (aggr_level < 0 && (allow_sum_func & (1 << sl->nest_level))) + if (aggr_level < 0 && + (allow_sum_func & ((nesting_map)1 << sl->nest_level))) { /* Found the most nested subquery where the function can be aggregated */ aggr_level= sl->nest_level; aggr_sel= sl; } } - if (sl && (allow_sum_func & (1 << sl->nest_level))) + if (sl && (allow_sum_func & ((nesting_map)1 << sl->nest_level))) { /* We reached the subquery of level max_arg_level and checked @@ -542,7 +545,7 @@ void Item_sum::update_used_tables () used_tables_cache&= PSEUDO_TABLE_BITS; /* the aggregate function is aggregated into its local context */ - used_tables_cache |= (1 << aggr_sel->join->tables) - 1; + used_tables_cache|= ((table_map)1 << aggr_sel->join->tables) - 1; } } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ce87bdd5381..96a27899db0 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -9705,7 +9705,7 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) cur_parts have bits set for only used keyparts. */ ulonglong all_parts, cur_parts; - all_parts= (1<> 1; if (all_parts != cur_parts) goto next_index; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1a9cc580d27..9f40eb6b937 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7891,7 +7891,8 @@ bool setup_fields(THD *thd, Item **ref_pointer_array, thd->mark_used_columns= mark_used_columns; DBUG_PRINT("info", ("thd->mark_used_columns: %d", thd->mark_used_columns)); if (allow_sum_func) - thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; + thd->lex->allow_sum_func|= + (nesting_map)1 << thd->lex->current_select->nest_level; thd->where= THD::DEFAULT_WHERE; save_is_item_list_lookup= thd->lex->current_select->is_item_list_lookup; thd->lex->current_select->is_item_list_lookup= 0; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 97ccf16ddd3..6908d313ee8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -453,25 +453,25 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, ORDER *group, bool *hidden_group_fields) { int res; - nesting_map save_allow_sum_func=thd->lex->allow_sum_func ; + st_select_lex *const select= thd->lex->current_select; + nesting_map save_allow_sum_func= thd->lex->allow_sum_func; /* Need to save the value, so we can turn off only any new non_agg_field_used additions coming from the WHERE */ - const bool saved_non_agg_field_used= - thd->lex->current_select->non_agg_field_used(); + const bool saved_non_agg_field_used= select->non_agg_field_used(); DBUG_ENTER("setup_without_group"); - thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); + thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level); res= setup_conds(thd, tables, leaves, conds); /* it's not wrong to have non-aggregated columns in a WHERE */ - thd->lex->current_select->set_non_agg_field_used(saved_non_agg_field_used); + select->set_non_agg_field_used(saved_non_agg_field_used); - thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; + thd->lex->allow_sum_func|= (nesting_map)1 << select->nest_level; res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, order); - thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); + thd->lex->allow_sum_func&= ~((nesting_map)1 << select->nest_level); res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields, group, hidden_group_fields); thd->lex->allow_sum_func= save_allow_sum_func; @@ -559,7 +559,7 @@ JOIN::prepare(Item ***rref_pointer_array, { nesting_map save_allow_sum_func= thd->lex->allow_sum_func; thd->where="having clause"; - thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level; + thd->lex->allow_sum_func|= (nesting_map)1 << select_lex_arg->nest_level; select_lex->having_fix_field= 1; bool having_fix_rc= (!having->fixed && (having->fix_fields(thd, &having) || @@ -4547,7 +4547,8 @@ best_access_path(JOIN *join, in ReuseRangeEstimateForRef-3. */ if (table->quick_keys.is_set(key) && - (const_part & ((1 << table->quick_key_parts[key])-1)) == + (const_part & + (((key_part_map)1 << table->quick_key_parts[key])-1)) == (((key_part_map)1 << table->quick_key_parts[key])-1) && table->quick_n_ranges[key] == 1 && records > (double) table->quick_rows[key]) @@ -4714,7 +4715,8 @@ best_access_path(JOIN *join, */ if (table->quick_keys.is_set(key) && table->quick_key_parts[key] <= max_key_part && - const_part & (1 << table->quick_key_parts[key]) && + const_part & + ((key_part_map)1 << table->quick_key_parts[key]) && table->quick_n_ranges[key] == 1 + test(ref_or_null_part & const_part) && records > (double) table->quick_rows[key]) @@ -5950,7 +5952,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, j->ref.items[i]=keyuse->val; // Save for cond removal j->ref.cond_guards[i]= keyuse->cond_guard; if (keyuse->null_rejecting) - j->ref.null_rejecting |= 1 << i; + j->ref.null_rejecting|= (key_part_map)1 << i; keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; if (!keyuse->used_tables && !(join->select_options & SELECT_DESCRIBE)) @@ -6234,7 +6236,7 @@ static void add_not_null_conds(JOIN *join) { for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++) { - if (tab->ref.null_rejecting & (1 << keypart)) + if (tab->ref.null_rejecting & ((key_part_map)1 << keypart)) { Item *item= tab->ref.items[keypart]; Item *notnull; @@ -10672,11 +10674,11 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, } else { - recinfo->null_bit= 1 << (null_count & 7); + recinfo->null_bit= (uint8)1 << (null_count & 7); recinfo->null_pos= null_count/8; } field->move_field(pos,null_flags+null_count/8, - 1 << (null_count & 7)); + (uint8)1 << (null_count & 7)); null_count++; } else @@ -11035,7 +11037,7 @@ TABLE *create_virtual_tmp_table(THD *thd, List &field_list) { cur_field->move_field(field_pos, (uchar*) null_pos, null_bit); null_bit<<= 1; - if (null_bit == (1 << 8)) + if (null_bit == (uint)1 << 8) { ++null_pos; null_bit= 1; @@ -12386,7 +12388,8 @@ join_read_always_key(JOIN_TAB *tab) /* Perform "Late NULLs Filtering" (see internals manual for explanations) */ for (uint i= 0 ; i < tab->ref.key_parts ; i++) { - if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null()) + if ((tab->ref.null_rejecting & ((key_part_map)1 << i)) && + tab->ref.items[i]->is_null()) return -1; } diff --git a/sql/strfunc.cc b/sql/strfunc.cc index 0c0742b3805..f39901a6ca5 100644 --- a/sql/strfunc.cc +++ b/sql/strfunc.cc @@ -85,7 +85,7 @@ ulonglong find_set(TYPELIB *lib, const char *str, uint length, CHARSET_INFO *cs, *set_warning= 1; } else - found|= ((longlong) 1 << (find - 1)); + found|= 1ULL << (find - 1); if (pos >= end) break; start= pos + mblen; From 259a5a301cc3cbc14a9d70b837e7ab2b39d50288 Mon Sep 17 00:00:00 2001 From: Chaithra Gopalareddy Date: Mon, 24 Dec 2012 06:39:54 +0530 Subject: [PATCH 095/324] Bug#11757005: UNION CONVERTS UNSIGNED MEDIUMINT AND BIGINT TO SIGNED Problem: When we are joining types (of fields) in case of a union, we usually upgrade the datatypes to the largest present in the query. In case of mediumint, it is not happening. Analysis: When joined with types LONG and LONGLONG, mediumint should get upgraded to LONG and LONGLONG respectively. W.r.t the given query, constant '1' will be created as a LONGLONG internally and SIGNED flag is enabled. As a result, while combining types for the field, LONGLONG along with MEDIUMINT gets converted to LONG first. LONG with MEDIUMINT(of the third select) gets converted to MEDIUMINT. SIGNED FLAG would be that of the first field's. As a result, the final result would be SIGNED MEDIUMINT. Fix: While joining types, MEDIUMINT with LONGLONG and MEDIUMINT with LONG is converted to LONGLONG and LONG respectively. Also, made some changes for FLOAT and DOUBLE. sql/field.cc: Changed merge types for MEDIUMINT. --- sql/field.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index ff631edd8d4..90029c12f0b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -184,7 +184,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP MYSQL_TYPE_LONG, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 - MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, + MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONG, //MYSQL_TYPE_DATE MYSQL_TYPE_TIME MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR @@ -215,7 +215,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP MYSQL_TYPE_FLOAT, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 - MYSQL_TYPE_FLOAT, MYSQL_TYPE_INT24, + MYSQL_TYPE_FLOAT, MYSQL_TYPE_FLOAT, //MYSQL_TYPE_DATE MYSQL_TYPE_TIME MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR @@ -246,7 +246,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP MYSQL_TYPE_DOUBLE, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 - MYSQL_TYPE_DOUBLE, MYSQL_TYPE_INT24, + MYSQL_TYPE_DOUBLE, MYSQL_TYPE_DOUBLE, //MYSQL_TYPE_DATE MYSQL_TYPE_TIME MYSQL_TYPE_VARCHAR, MYSQL_TYPE_VARCHAR, //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR @@ -277,7 +277,7 @@ static enum_field_types field_types_merge_rules [FIELDTYPE_NUM][FIELDTYPE_NUM]= //MYSQL_TYPE_NULL MYSQL_TYPE_TIMESTAMP MYSQL_TYPE_NULL, MYSQL_TYPE_TIMESTAMP, //MYSQL_TYPE_LONGLONG MYSQL_TYPE_INT24 - MYSQL_TYPE_LONGLONG, MYSQL_TYPE_INT24, + MYSQL_TYPE_LONGLONG, MYSQL_TYPE_LONGLONG, //MYSQL_TYPE_DATE MYSQL_TYPE_TIME MYSQL_TYPE_NEWDATE, MYSQL_TYPE_TIME, //MYSQL_TYPE_DATETIME MYSQL_TYPE_YEAR From 76059a4a1d185186d6f382c84067806cf5582dd6 Mon Sep 17 00:00:00 2001 From: Annamalai Gurusami Date: Mon, 24 Dec 2012 16:49:42 +0530 Subject: [PATCH 096/324] Fixing a pb2 issue. There is some difference in the output in my local machine and pb2 machines in the explain output. --- mysql-test/suite/innodb_plugin/r/innodb-index.result | 2 +- mysql-test/suite/innodb_plugin/t/innodb-index.test | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb_plugin/r/innodb-index.result b/mysql-test/suite/innodb_plugin/r/innodb-index.result index df853fac078..1200215fca4 100644 --- a/mysql-test/suite/innodb_plugin/r/innodb-index.result +++ b/mysql-test/suite/innodb_plugin/r/innodb-index.result @@ -963,7 +963,7 @@ Table Op Msg_type Msg_text test.t1 check status OK explain select * from t1 where b like 'adfd%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range b b 769 NULL 7 Using where +1 SIMPLE t1 range b b 769 NULL # Using where create table t2(a int, b varchar(255), primary key(a,b)) engine=innodb; insert into t2 select a,left(b,255) from t1; drop table t1; diff --git a/mysql-test/suite/innodb_plugin/t/innodb-index.test b/mysql-test/suite/innodb_plugin/t/innodb-index.test index d4310093bfd..fa47087903e 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb-index.test +++ b/mysql-test/suite/innodb_plugin/t/innodb-index.test @@ -420,6 +420,10 @@ select a, length(b),b=left(repeat(d,100*a),65535),length(c),c=repeat(d,20*a),d from t1; show create table t1; check table t1; + +# In my local machine and in pb2 machine only the key_len field is differing. +# So masking this problematic output. +--replace_column 9 # explain select * from t1 where b like 'adfd%'; # From fa61c0499a714541e363abd20c75c7adae1780d7 Mon Sep 17 00:00:00 2001 From: Chaithra Gopalareddy Date: Wed, 26 Dec 2012 20:21:19 +0530 Subject: [PATCH 097/324] Bug#12347040: MEMORY LEAK IN CONVERT_TZ COULD POSSIBLY CAUSE DOS ATTACKS Problem: For detailed description, see Bug#42502. This bug is a duplicate of Bug#42502. The complete fix for Bug#42502 was not made as proposed. Hence the bug still persists. Fix: Make the changes as proposed originally for the bugfix of 42502. Which is to remove the allocation of the memory before we actually check for any errors. sql/tztime.cc: Remove the double allocation for tz_info --- sql/tztime.cc | 21 +++------------------ 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/sql/tztime.cc b/sql/tztime.cc index 922cfd1fad6..81a80686de2 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1808,7 +1808,7 @@ static Time_zone* tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) { TABLE *table= 0; - TIME_ZONE_INFO *tz_info; + TIME_ZONE_INFO *tz_info= NULL; Tz_names_entry *tmp_tzname; Time_zone *return_val= 0; int res; @@ -1816,7 +1816,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) my_time_t ttime; char buff[MAX_FIELD_WIDTH]; String abbr(buff, sizeof(buff), &my_charset_latin1); - char *alloc_buff, *tz_name_buff; + char *alloc_buff= NULL; + char *tz_name_buff= NULL; /* Temporary arrays that are used for loading of data for filling TIME_ZONE_INFO structure @@ -1836,22 +1837,6 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) DBUG_ENTER("tz_load_from_open_tables"); - /* Prepare tz_info for loading also let us make copy of time zone name */ - if (!(alloc_buff= (char*) alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) + - tz_name->length() + 1))) - { - sql_print_error("Out of memory while loading time zone description"); - return 0; - } - tz_info= (TIME_ZONE_INFO *)alloc_buff; - bzero(tz_info, sizeof(TIME_ZONE_INFO)); - tz_name_buff= alloc_buff + sizeof(TIME_ZONE_INFO); - /* - By writing zero to the end we guarantee that we can call ptr() - instead of c_ptr() for time zone name. - */ - strmake(tz_name_buff, tz_name->ptr(), tz_name->length()); - /* Let us find out time zone id by its name (there is only one index and it is specifically for this purpose). From 6b7182d9a3a073a7e2d586b3182c27de154aad08 Mon Sep 17 00:00:00 2001 From: Mattias Jonsson Date: Thu, 27 Dec 2012 02:27:00 +0100 Subject: [PATCH 098/324] Bug#14589559 Post push fix for valgrind warnings. --- sql/sql_table.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4ed3b5fc84e..134ea5b4284 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 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 @@ -1105,6 +1105,7 @@ bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry, { DBUG_RETURN(TRUE); } + memset(file_entry_buf, 0, sizeof(file_entry_buf)); file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_ENTRY_CODE; file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= @@ -1199,6 +1200,7 @@ bool write_execute_ddl_log_entry(uint first_entry, { DBUG_RETURN(TRUE); } + memset(file_entry_buf, 0, sizeof(file_entry_buf)); if (!complete) { /* @@ -1212,12 +1214,7 @@ bool write_execute_ddl_log_entry(uint first_entry, } else file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE; - file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */ - file_entry_buf[DDL_LOG_PHASE_POS]= 0; int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry); - file_entry_buf[DDL_LOG_NAME_POS]= 0; - file_entry_buf[DDL_LOG_NAME_POS + global_ddl_log.name_len]= 0; - file_entry_buf[DDL_LOG_NAME_POS + 2*global_ddl_log.name_len]= 0; if (!(*active_entry)) { if (get_free_ddl_log_entry(active_entry, &write_header)) From 825459b8cda4f97a3ef1f3affb4889d7807a0f3a Mon Sep 17 00:00:00 2001 From: Nirbhay Choubey Date: Thu, 27 Dec 2012 17:33:34 +0530 Subject: [PATCH 099/324] Bug#16046140 BIN/MYSQLD_SAFE: TEST: ARGUMENT EXPECTED Some shell interpreters do not support '-e' test primary to construct conditions. man test 1 (on S10) ...skip... -e file True if file exists. (Not available in sh.) ...skip... Hence, check for the existence of a file using '-e' might result in a syntax error on such shell programs. Fixed by replacing it by '-f'. --- scripts/mysqld_safe.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh index 75589a2d004..48c98f2fde3 100644 --- a/scripts/mysqld_safe.sh +++ b/scripts/mysqld_safe.sh @@ -393,7 +393,7 @@ then log_notice "Logging to '$err_log'." logging=file - if [ ! -e "$err_log" ]; then # if error log already exists, + if [ ! -f "$err_log" ]; then # if error log already exists, touch "$err_log" # we just append. otherwise, chmod "$fmode" "$err_log" # fix the permissions here! fi @@ -599,7 +599,7 @@ do eval_log_error "$cmd" - if [ $want_syslog -eq 0 -a ! -e "$err_log" ]; then + if [ $want_syslog -eq 0 -a ! -f "$err_log" ]; then touch "$err_log" # hypothetical: log was renamed but not chown $user "$err_log" # flushed yet. we'd recreate it with chmod "$fmode" "$err_log" # wrong owner next time we log, so set From ec70b93e7b529dbd0da0eaab317fe0edf9ea1c24 Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Fri, 28 Dec 2012 16:13:48 +0530 Subject: [PATCH 100/324] BUG#14726272- BACKPORT FIX FOR BUG 11746142 TO 5.5 AND 5.1 Details of BUG#11746142: CALLING MYSQLD WHILE ANOTHER INSTANCE IS RUNNING, REMOVES PID FILE Fix: Before removing the pid file, ensure it was created by the same process, leave it intact otherwise. sql/mysqld.cc: delete_pid_file() introduced, which checks that the pid file belongs to the process before removing it --- sql/mysqld.cc | 46 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index cb1bc6bed12..12b52a87adc 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -867,6 +867,7 @@ static void clean_up(bool print_message); static int test_if_case_insensitive(const char *dir_name); #ifndef EMBEDDED_LIBRARY +static bool pid_file_created= false; static void usage(void); static void start_signal_handler(void); static void close_server_sock(); @@ -875,6 +876,7 @@ static void wait_for_signal_thread_to_end(void); static void create_pid_file(); static void end_ssl(); #endif +static void delete_pid_file(myf flags); #ifndef EMBEDDED_LIBRARY @@ -1395,10 +1397,7 @@ void clean_up(bool print_message) debug_sync_end(); #endif /* defined(ENABLED_DEBUG_SYNC) */ -#if !defined(EMBEDDED_LIBRARY) - if (!opt_bootstrap) - (void) my_delete(pidfile_name,MYF(0)); // This may not always exist -#endif + delete_pid_file(MYF(0)); if (print_message && errmesg && server_start_time) sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); thread_scheduler.end(); @@ -4387,9 +4386,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL); #endif /* __NETWARE__ */ - if (!opt_bootstrap) - (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore - + delete_pid_file(MYF(MY_WME)); if (unix_sock != INVALID_SOCKET) unlink(mysqld_unix_port); exit(1); @@ -9098,12 +9095,13 @@ static void create_pid_file() if ((file = my_create(pidfile_name,0664, O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0) { - char buff[21], *end; + char buff[MAX_BIGINT_WIDTH + 1], *end; end= int10_to_str((long) getpid(), buff, 10); *end++= '\n'; if (!my_write(file, (uchar*) buff, (uint) (end-buff), MYF(MY_WME | MY_NABP))) { (void) my_close(file, MYF(0)); + pid_file_created= true; return; } (void) my_close(file, MYF(0)); @@ -9113,6 +9111,38 @@ static void create_pid_file() } #endif /* EMBEDDED_LIBRARY */ + +/** + Remove the process' pid file. + + @param flags file operation flags +*/ + +static void delete_pid_file(myf flags) +{ +#ifndef EMBEDDED_LIBRARY + File file; + if (opt_bootstrap || + !pid_file_created || + !(file= my_open(pidfile_name, O_RDONLY, flags))) + return; + + /* Make sure that the pid file was created by the same process. */ + uchar buff[MAX_BIGINT_WIDTH + 1]; + size_t error= my_read(file, buff, sizeof(buff), flags); + my_close(file, flags); + buff[sizeof(buff) - 1]= '\0'; + if (error != MY_FILE_ERROR && + atol((char *) buff) == (long) getpid()) + { + my_delete(pidfile_name, flags); + pid_file_created= false; + } +#endif /* EMBEDDED_LIBRARY */ + return; +} + + /** Clear most status variables. */ void refresh_status(THD *thd) { From 2fb1b2d74ce6d54e53838db822c12e433751a7c5 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Dec 2012 23:46:31 +0530 Subject: [PATCH 101/324] From 10f8266d50ec134e72d9562e29d676c00249d9bb Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Tue, 1 Jan 2013 03:33:40 +0100 Subject: [PATCH 102/324] Updated README and client executables copyright year to 2013 --- README | 2 +- include/welcome_copyright_notice.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README b/README index c97663ccefc..c8299d9c946 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ For the avoidance of doubt, this particular copy of the software is released under the version 2 of the GNU General Public License. MySQL is brought to you by Oracle. -Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. +Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. License information can be found in the COPYING file. diff --git a/include/welcome_copyright_notice.h b/include/welcome_copyright_notice.h index ef4b08d4c0d..15d11bf3664 100644 --- a/include/welcome_copyright_notice.h +++ b/include/welcome_copyright_notice.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 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 @@ -16,7 +16,7 @@ #ifndef _welcome_copyright_notice_h_ #define _welcome_copyright_notice_h_ -#define COPYRIGHT_NOTICE_CURRENT_YEAR "2012" +#define COPYRIGHT_NOTICE_CURRENT_YEAR "2013" /* This define specifies copyright notice which is displayed by every MySQL From 5ff0148e3983ca30deeaca5495ace3b7218c880f Mon Sep 17 00:00:00 2001 From: Kent Boortz Date: Wed, 2 Jan 2013 06:18:27 +0100 Subject: [PATCH 103/324] Updated Windows MSI package copyright year to 2013 --- packaging/WiX/custom_ui.wxs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/WiX/custom_ui.wxs b/packaging/WiX/custom_ui.wxs index 568053f4cf5..6e243832e12 100644 --- a/packaging/WiX/custom_ui.wxs +++ b/packaging/WiX/custom_ui.wxs @@ -2,7 +2,7 @@ xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"> client 2 handler t1 open; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option --> client 1 drop table t1; create table t1 (a int); diff --git a/mysql-test/suite/handler/heap.result b/mysql-test/suite/handler/heap.result index 8b526335024..55f9fd41c7a 100644 --- a/mysql-test/suite/handler/heap.result +++ b/mysql-test/suite/handler/heap.result @@ -586,7 +586,7 @@ Note 1051 Unknown table 't1' create table t1 (a int not null) ENGINE=csv; --> client 2 handler t1 open; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option --> client 1 drop table t1; create table t1 (a int); @@ -1728,9 +1728,9 @@ a b 4 40 5 50 HANDLER t1 READ a FIRST; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 READ a LAST; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 READ b FIRST LIMIT 2; a b 1 10 @@ -1781,11 +1781,11 @@ create table t1 (f1 integer not null, key (f1)) engine=Memory; insert into t1 values (1); HANDLER t1 OPEN; HANDLER t1 READ f1 NEXT; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 READ f1 NEXT; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 READ f1 NEXT; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option HANDLER t1 CLOSE; DROP TABLE t1; End of 5.3 tests diff --git a/mysql-test/suite/handler/innodb.result b/mysql-test/suite/handler/innodb.result index db36640ea39..d4103ddd6ff 100644 --- a/mysql-test/suite/handler/innodb.result +++ b/mysql-test/suite/handler/innodb.result @@ -587,7 +587,7 @@ Note 1051 Unknown table 't1' create table t1 (a int not null) ENGINE=csv; --> client 2 handler t1 open; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option --> client 1 drop table t1; create table t1 (a int); diff --git a/mysql-test/suite/handler/interface.result b/mysql-test/suite/handler/interface.result index 96d21e7373a..cebbc2784df 100644 --- a/mysql-test/suite/handler/interface.result +++ b/mysql-test/suite/handler/interface.result @@ -269,7 +269,7 @@ handler t1 open; lock table t1 write; alter table t1 engine=csv; handler t1 read a next; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option handler t1 close; unlock tables; drop table t1; diff --git a/mysql-test/suite/handler/myisam.result b/mysql-test/suite/handler/myisam.result index e8abe8047cd..980b87768da 100644 --- a/mysql-test/suite/handler/myisam.result +++ b/mysql-test/suite/handler/myisam.result @@ -586,7 +586,7 @@ Note 1051 Unknown table 't1' create table t1 (a int not null) ENGINE=csv; --> client 2 handler t1 open; -ERROR HY000: Table storage engine for 't1' doesn't have this option +ERROR HY000: Storage engine CSV of the table `test`.`t1` doesn't have this option --> client 1 drop table t1; create table t1 (a int); diff --git a/mysql-test/suite/innodb/r/innodb-create-options.result b/mysql-test/suite/innodb/r/innodb-create-options.result index c73baa60d42..c32af26c22d 100644 --- a/mysql-test/suite/innodb/r/innodb-create-options.result +++ b/mysql-test/suite/innodb/r/innodb-create-options.result @@ -10,11 +10,11 @@ Note 1051 Unknown table 't1' # 'FIXED' is sent to InnoDB since it is used by MyISAM. # But it is an invalid mode in InnoDB CREATE TABLE t1 ( i INT ) ROW_FORMAT=FIXED; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: invalid ROW_FORMAT specifier. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message @@ -46,11 +46,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Compact ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: invalid ROW_FORMAT specifier. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Compact @@ -58,23 +58,23 @@ t1 Compact # KEY_BLOCK_SIZE is incompatible with COMPACT, REDUNDANT, & DYNAMIC DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=1; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=2; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; SHOW WARNINGS; Level Code Message @@ -104,29 +104,29 @@ t1 Compressed key_block_size=16 DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: invalid ROW_FORMAT specifier. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; SHOW WARNINGS; Level Code Message @@ -146,11 +146,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Compact row_format=COMPACT ALTER TABLE t1 KEY_BLOCK_SIZE=2; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=REDUNDANT; SHOW WARNINGS; Level Code Message @@ -158,11 +158,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Redundant row_format=REDUNDANT ALTER TABLE t1 KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC; SHOW WARNINGS; Level Code Message @@ -170,11 +170,11 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME ROW_FORMAT CREATE_OPTIONS t1 Dynamic row_format=DYNAMIC ALTER TABLE t1 KEY_BLOCK_SIZE=8; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; Level Code Message @@ -212,23 +212,23 @@ t1 CREATE TABLE `t1` ( `f1` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 KEY_BLOCK_SIZE=2 ALTER TABLE t1 ROW_FORMAT=COMPACT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=REDUNDANT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; Level Code Message @@ -250,11 +250,11 @@ t1 Compact row_format=COMPACT # Test 6) StrictMode=ON, CREATE with an invalid KEY_BLOCK_SIZE. DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=9; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") # Test 7) StrictMode=ON, Make sure ROW_FORMAT= COMPRESSED & DYNAMIC and # and a valid non-zero KEY_BLOCK_SIZE are rejected with Antelope # and that they can be set to default values during strict mode. @@ -263,23 +263,23 @@ DROP TABLE IF EXISTS t1; Warnings: Note 1051 Unknown table 't1' CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=4; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; SHOW WARNINGS; Level Code Message @@ -298,34 +298,34 @@ CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; SHOW WARNINGS; Level Code Message ALTER TABLE t1 KEY_BLOCK_SIZE=8; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPRESSED; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SET GLOBAL innodb_file_format=Barracuda; DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_format=Antelope; ALTER TABLE t1 ADD COLUMN f1 INT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message @@ -340,23 +340,23 @@ SET GLOBAL innodb_file_format=Barracuda; SET GLOBAL innodb_file_per_table=OFF; DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=16; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") CREATE TABLE t1 ( i INT ) ROW_FORMAT=REDUNDANT; SHOW WARNINGS; Level Code Message @@ -375,23 +375,23 @@ CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; SHOW WARNINGS; Level Code Message ALTER TABLE t1 KEY_BLOCK_SIZE=1; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPRESSED; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DYNAMIC; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=COMPACT; SHOW WARNINGS; Level Code Message @@ -415,12 +415,12 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_per_table=OFF; ALTER TABLE t1 ADD COLUMN f1 INT; -ERROR HY000: Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") SHOW WARNINGS; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table '#sql-temporary' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; Level Code Message diff --git a/mysql-test/suite/innodb/r/innodb-index.result b/mysql-test/suite/innodb/r/innodb-index.result index 4b032ebabb5..9130b3a4ef2 100644 --- a/mysql-test/suite/innodb/r/innodb-index.result +++ b/mysql-test/suite/innodb/r/innodb-index.result @@ -545,7 +545,7 @@ t4 CREATE TABLE `t4` ( CONSTRAINT `dc` FOREIGN KEY (`a`) REFERENCES `t1` (`a`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 alter table t3 add constraint dc foreign key (a) references t1(a); -ERROR HY000: Can't create table '#sql-temporary' (errno: 121 "Duplicate key on write or update") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 121 "Duplicate key on write or update") show create table t3; Table Create Table t3 CREATE TABLE `t3` ( @@ -1146,17 +1146,17 @@ PRIMARY KEY (c1) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1); -ERROR HY000: Can't create table '#sql-temporary' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); -ERROR HY000: Can't create table '#sql-temporary' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1); -ERROR HY000: Can't create table '#sql-temporary' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL; ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); -ERROR HY000: Can't create table '#sql-temporary' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 150 "Foreign key constraint is incorrectly formed") ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1); SHOW CREATE TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-zip.result b/mysql-test/suite/innodb/r/innodb-zip.result index f794ae7470f..5bb97e785a2 100644 --- a/mysql-test/suite/innodb/r/innodb-zip.result +++ b/mysql-test/suite/innodb/r/innodb-zip.result @@ -193,11 +193,11 @@ drop table t1; set innodb_strict_mode = on; create table t1 (id int primary key) engine = innodb key_block_size = 0; create table t2 (id int primary key) engine = innodb key_block_size = 9; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t3 (id int primary key) engine = innodb key_block_size = 1; create table t4 (id int primary key) engine = innodb key_block_size = 2; create table t5 (id int primary key) engine = innodb key_block_size = 4; @@ -225,25 +225,25 @@ create table t1 (id int primary key) engine = innodb key_block_size = 8 row_format = compressed; create table t2 (id int primary key) engine = innodb key_block_size = 8 row_format = redundant; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t3 (id int primary key) engine = innodb key_block_size = 8 row_format = compact; -ERROR HY000: Can't create table 'test.t3' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t3' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t3` (errno: 140 "Wrong create options") create table t4 (id int primary key) engine = innodb key_block_size = 8 row_format = dynamic; -ERROR HY000: Can't create table 'test.t4' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t4` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t4' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t4` (errno: 140 "Wrong create options") create table t5 (id int primary key) engine = innodb key_block_size = 8 row_format = default; SELECT table_schema, table_name, row_format, data_length, index_length @@ -254,74 +254,74 @@ test t5 Compressed 8192 0 drop table t1, t5; create table t1 (id int primary key) engine = innodb key_block_size = 9 row_format = redundant; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Warning 140 InnoDB: cannot specify ROW_FORMAT = REDUNDANT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") create table t2 (id int primary key) engine = innodb key_block_size = 9 row_format = compact; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Warning 140 InnoDB: cannot specify ROW_FORMAT = COMPACT with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t2 (id int primary key) engine = innodb key_block_size = 9 row_format = dynamic; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: invalid KEY_BLOCK_SIZE = 9. Valid values are [1, 2, 4, 8, 16] Warning 140 InnoDB: cannot specify ROW_FORMAT = DYNAMIC with KEY_BLOCK_SIZE. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") SELECT table_schema, table_name, row_format, data_length, index_length FROM information_schema.tables WHERE engine='innodb'; table_schema table_name row_format data_length index_length set global innodb_file_per_table = off; create table t1 (id int primary key) engine = innodb key_block_size = 1; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") create table t2 (id int primary key) engine = innodb key_block_size = 2; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t3 (id int primary key) engine = innodb key_block_size = 4; -ERROR HY000: Can't create table 'test.t3' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t3' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t3` (errno: 140 "Wrong create options") create table t4 (id int primary key) engine = innodb key_block_size = 8; -ERROR HY000: Can't create table 'test.t4' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t4` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t4' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t4` (errno: 140 "Wrong create options") create table t5 (id int primary key) engine = innodb key_block_size = 16; -ERROR HY000: Can't create table 'test.t5' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t5` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_per_table. -Error 1005 Can't create table 'test.t5' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t5` (errno: 140 "Wrong create options") create table t6 (id int primary key) engine = innodb row_format = compressed; -ERROR HY000: Can't create table 'test.t6' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t6` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_per_table. -Error 1005 Can't create table 'test.t6' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t6` (errno: 140 "Wrong create options") create table t7 (id int primary key) engine = innodb row_format = dynamic; -ERROR HY000: Can't create table 'test.t7' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t7` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_per_table. -Error 1005 Can't create table 'test.t7' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t7` (errno: 140 "Wrong create options") create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; SELECT table_schema, table_name, row_format, data_length, index_length @@ -333,47 +333,47 @@ drop table t8, t9; set global innodb_file_per_table = on; set global innodb_file_format = `0`; create table t1 (id int primary key) engine = innodb key_block_size = 1; -ERROR HY000: Can't create table 'test.t1' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t1' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") create table t2 (id int primary key) engine = innodb key_block_size = 2; -ERROR HY000: Can't create table 'test.t2' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t2` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t2' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t2` (errno: 140 "Wrong create options") create table t3 (id int primary key) engine = innodb key_block_size = 4; -ERROR HY000: Can't create table 'test.t3' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t3' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t3` (errno: 140 "Wrong create options") create table t4 (id int primary key) engine = innodb key_block_size = 8; -ERROR HY000: Can't create table 'test.t4' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t4` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t4' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t4` (errno: 140 "Wrong create options") create table t5 (id int primary key) engine = innodb key_block_size = 16; -ERROR HY000: Can't create table 'test.t5' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t5` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: KEY_BLOCK_SIZE requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t5' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t5` (errno: 140 "Wrong create options") create table t6 (id int primary key) engine = innodb row_format = compressed; -ERROR HY000: Can't create table 'test.t6' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t6` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: ROW_FORMAT=COMPRESSED requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t6' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t6` (errno: 140 "Wrong create options") create table t7 (id int primary key) engine = innodb row_format = dynamic; -ERROR HY000: Can't create table 'test.t7' (errno: 140 "Wrong create options") +ERROR HY000: Can't create table `test`.`t7` (errno: 140 "Wrong create options") show warnings; Level Code Message Warning 140 InnoDB: ROW_FORMAT=DYNAMIC requires innodb_file_format > Antelope. -Error 1005 Can't create table 'test.t7' (errno: 140 "Wrong create options") +Error 1005 Can't create table `test`.`t7` (errno: 140 "Wrong create options") create table t8 (id int primary key) engine = innodb row_format = compact; create table t9 (id int primary key) engine = innodb row_format = redundant; SELECT table_schema, table_name, row_format, data_length, index_length diff --git a/mysql-test/suite/innodb/r/innodb.result b/mysql-test/suite/innodb/r/innodb.result index 7307ce9dc24..96ce3d477c9 100644 --- a/mysql-test/suite/innodb/r/innodb.result +++ b/mysql-test/suite/innodb/r/innodb.result @@ -1600,7 +1600,7 @@ concat(a, b) drop table t1; CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); -ERROR HY000: The used table type doesn't support FULLTEXT indexes +ERROR HY000: The storage engine InnoDB doesn't support FULLTEXT indexes DROP TABLE t1; CREATE TABLE t1 (a_id tinyint(4) NOT NULL default '0', PRIMARY KEY (a_id)) ENGINE=InnoDB DEFAULT CHARSET=latin1; INSERT INTO t1 VALUES (1),(2),(3); @@ -2525,13 +2525,13 @@ drop table t1; set foreign_key_checks=0; create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb; create table t1(a char(10) primary key, b varchar(20)) engine = innodb; -ERROR HY000: Can't create table 'test.t1' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t1` (errno: 150 "Foreign key constraint is incorrectly formed") set foreign_key_checks=1; drop table t2; set foreign_key_checks=0; create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1; create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8; -ERROR HY000: Can't create table 'test.t2' (errno: 150 "Foreign key constraint is incorrectly formed") +ERROR HY000: Can't create table `test`.`t2` (errno: 150 "Foreign key constraint is incorrectly formed") set foreign_key_checks=1; drop table t1; set foreign_key_checks=0; diff --git a/mysql-test/suite/innodb/r/innodb_bug12400341.result b/mysql-test/suite/innodb/r/innodb_bug12400341.result index 02d609d8092..eced0895e3a 100644 --- a/mysql-test/suite/innodb/r/innodb_bug12400341.result +++ b/mysql-test/suite/innodb/r/innodb_bug12400341.result @@ -15,7 +15,7 @@ select count(*) from information_schema.processlist; count(*) 33 CREATE TABLE mysqltest.testtable (id int unsigned not null primary key) ENGINE=InnoDB; -ERROR HY000: Can't create table 'mysqltest.testtable' (errno: 177 "Too many active concurrent transactions") +ERROR HY000: Can't create table `mysqltest`.`testtable` (errno: 177 "Too many active concurrent transactions") select count(*) from information_schema.processlist; count(*) 33 diff --git a/mysql-test/suite/innodb/r/innodb_bug46000.result b/mysql-test/suite/innodb/r/innodb_bug46000.result index 9ee0c935d71..f3dff71539b 100644 --- a/mysql-test/suite/innodb/r/innodb_bug46000.result +++ b/mysql-test/suite/innodb/r/innodb_bug46000.result @@ -6,7 +6,7 @@ show warnings; Level Code Message Warning 1280 Cannot Create Index with name 'GEN_CLUST_INDEX'. The name is reserved for the system default primary index. Error 1280 Incorrect index name 'GEN_CLUST_INDEX' -Error 1005 Can't create table 'test.bug46000' (errno: -1 "Internal error < 0 (Not system error)") +Error 1005 Can't create table `test`.`bug46000` (errno: -1 "Internal error < 0 (Not system error)") create table bug46000(id int) engine=innodb; create index GEN_CLUST_INDEX on bug46000(id); ERROR 42000: Incorrect index name 'GEN_CLUST_INDEX' diff --git a/mysql-test/suite/innodb/r/innodb_gis.result b/mysql-test/suite/innodb/r/innodb_gis.result index 36b37e4ccd8..21c1234d7d3 100644 --- a/mysql-test/suite/innodb/r/innodb_gis.result +++ b/mysql-test/suite/innodb/r/innodb_gis.result @@ -598,4 +598,4 @@ create table t1 (a int not null, b linestring not null, unique key b (b(12))); create unique index a on t1(a); drop table t1; create table t1 (g geometry not null, spatial gk(g)) engine=innodb; -ERROR HY000: The used table type doesn't support SPATIAL indexes +ERROR HY000: The storage engine InnoDB doesn't support SPATIAL indexes diff --git a/mysql-test/suite/innodb/t/innodb-create-options.test b/mysql-test/suite/innodb/t/innodb-create-options.test index 12c24820031..0f8e6f8dda2 100644 --- a/mysql-test/suite/innodb/t/innodb-create-options.test +++ b/mysql-test/suite/innodb/t/innodb-create-options.test @@ -96,10 +96,10 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=0; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; @@ -141,25 +141,25 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE --echo # Test 3) StrictMode=ON, ALTER with each ROW_FORMAT & a valid non-zero KEY_BLOCK_SIZE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ); ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=FIXED KEY_BLOCK_SIZE=1; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=COMPACT KEY_BLOCK_SIZE=2; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=DYNAMIC KEY_BLOCK_SIZE=4; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=REDUNDANT KEY_BLOCK_SIZE=8; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=16; SHOW WARNINGS; @@ -173,26 +173,26 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPACT; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=2; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=REDUNDANT; SHOW WARNINGS; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=4; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=DYNAMIC; SHOW WARNINGS; SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE TABLE_NAME = 't1'; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=8; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; @@ -213,20 +213,20 @@ CREATE TABLE t1 ( i INT ) KEY_BLOCK_SIZE=2; SHOW CREATE TABLE t1; ALTER TABLE t1 ADD COLUMN f1 INT; SHOW CREATE TABLE t1; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=COMPACT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=REDUNDANT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=COMPRESSED; SHOW WARNINGS; @@ -276,29 +276,29 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=8; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=COMPRESSED; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; SET GLOBAL innodb_file_format=Barracuda; DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_format=Antelope; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ADD COLUMN f1 INT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; @@ -337,20 +337,20 @@ SELECT TABLE_NAME,ROW_FORMAT,CREATE_OPTIONS FROM information_schema.tables WHERE DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=DEFAULT; SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 KEY_BLOCK_SIZE=1; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=COMPRESSED; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ROW_FORMAT=DYNAMIC; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=COMPACT; SHOW WARNINGS; @@ -365,10 +365,10 @@ SET GLOBAL innodb_file_per_table=ON; DROP TABLE IF EXISTS t1; CREATE TABLE t1 ( i INT ) ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; SET GLOBAL innodb_file_per_table=OFF; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t1 ADD COLUMN f1 INT; ---replace_regex /'[^']*test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ / - .*[0-9]*)/)/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ SHOW WARNINGS; ALTER TABLE t1 ROW_FORMAT=DEFAULT KEY_BLOCK_SIZE=0; SHOW WARNINGS; diff --git a/mysql-test/suite/innodb/t/innodb-index.test b/mysql-test/suite/innodb/t/innodb-index.test index cea9055b873..a8ef524c3e9 100644 --- a/mysql-test/suite/innodb/t/innodb-index.test +++ b/mysql-test/suite/innodb/t/innodb-index.test @@ -250,7 +250,7 @@ insert into t2 values (1,1,1,1,1); commit; alter table t4 add constraint dc foreign key (a) references t1(a); show create table t4; ---replace_regex /'test\.#sql-[0-9a-f_]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ # a foreign key 'test/dc' already exists --error ER_CANT_CREATE_TABLE alter table t3 add constraint dc foreign key (a) references t1(a); @@ -620,20 +620,20 @@ CREATE TABLE t2( PRIMARY KEY (c1) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; ---replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1); ---replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); ---replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1); ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL; ---replace_regex /'test\.#sql-[0-9_a-f-]*'/'#sql-temporary'/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ --error ER_CANT_CREATE_TABLE ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2); diff --git a/mysql-test/suite/maria/maria.result b/mysql-test/suite/maria/maria.result index a7e038675a9..ddd0adade57 100644 --- a/mysql-test/suite/maria/maria.result +++ b/mysql-test/suite/maria/maria.result @@ -653,7 +653,7 @@ t1 1 a 1 a A 1000 NULL NULL YES BTREE alter table t1 engine=heap; alter table t1 disable keys; Warnings: -Note 1031 Table storage engine for 't1' doesn't have this option +Note 1031 Storage engine MEMORY of the table `test`.`t1` doesn't have this option show keys from t1; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment t1 1 a 1 a NULL 500 NULL NULL YES HASH diff --git a/mysql-test/suite/maria/maria3.result b/mysql-test/suite/maria/maria3.result index 27d72b75930..b502d71e772 100644 --- a/mysql-test/suite/maria/maria3.result +++ b/mysql-test/suite/maria/maria3.result @@ -359,7 +359,7 @@ NULL NULL 0 NULL 0 0 alter table t1 add column d char(0) not null, add key (d); -ERROR 42000: The used storage engine can't index column 'd' +ERROR 42000: The storage engine Aria can't index column `d` drop table t1; CREATE TABLE t1 (a bit(3)); insert into t1 values (NULL),(0),(1),(2),(3),(4),(5),(6),(7); diff --git a/mysql-test/suite/percona/percona_innodb_fake_changes.result b/mysql-test/suite/percona/percona_innodb_fake_changes.result index 5540c76f2e5..434b7283146 100644 --- a/mysql-test/suite/percona/percona_innodb_fake_changes.result +++ b/mysql-test/suite/percona/percona_innodb_fake_changes.result @@ -43,7 +43,7 @@ SET autocommit=0; SET innodb_fake_changes=1; BEGIN; CREATE TABLE t2 (a INT) ENGINE=InnoDB; -ERROR HY000: Can't create table 'test.t2' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t2` (errno: 131 "Command not supported by database") DROP TABLE t1; ERROR 42S02: Unknown table 't1' TRUNCATE TABLE t1; diff --git a/mysql-test/suite/perfschema/r/misc.result b/mysql-test/suite/perfschema/r/misc.result index 1dbde982328..3b088496b0a 100644 --- a/mysql-test/suite/perfschema/r/misc.result +++ b/mysql-test/suite/perfschema/r/misc.result @@ -6,9 +6,9 @@ AND EVENT_NAME IN WHERE NAME LIKE "wait/synch/%") LIMIT 1; create table test.t1(a int) engine=performance_schema; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table performance_schema.t1(a int); ERROR 42000: CREATE command denied to user 'root'@'localhost' for table 't1' drop table if exists test.ghost; diff --git a/mysql-test/suite/perfschema/r/privilege.result b/mysql-test/suite/perfschema/r/privilege.result index 019d8964523..32a502db34b 100644 --- a/mysql-test/suite/perfschema/r/privilege.result +++ b/mysql-test/suite/perfschema/r/privilege.result @@ -152,13 +152,13 @@ before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'root'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.file_instances; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'root'@'localhost' for table 'setup_instruments' @@ -250,13 +250,13 @@ before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_1'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.file_instances; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_1'@'localhost' for table 'setup_instruments' @@ -348,13 +348,13 @@ before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_2'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.file_instances; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_2'@'localhost' for table 'setup_instruments' @@ -446,13 +446,13 @@ before insert on performance_schema.file_instances for each row begin end; ERROR 42000: Access denied for user 'pfs_user_3'@'localhost' to database 'performance_schema' create table test.t1(a int) engine=PERFORMANCE_SCHEMA; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.setup_instruments; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.events_waits_current; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") create table test.t1 like performance_schema.file_instances; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") insert into performance_schema.setup_instruments set name="foo"; ERROR 42000: INSERT command denied to user 'pfs_user_3'@'localhost' for table 'setup_instruments' diff --git a/mysql-test/t/partition_not_windows.test b/mysql-test/t/partition_not_windows.test index 333e12e2b16..429329c79bb 100644 --- a/mysql-test/t/partition_not_windows.test +++ b/mysql-test/t/partition_not_windows.test @@ -199,7 +199,7 @@ DROP TABLE example; --rmdir $MYSQLTEST_VARDIR/p2Index --rmdir $MYSQLTEST_VARDIR/p3Index ---error ER_CANT_CREATE_TABLE,1 +--error 1 CREATE TABLE `example` ( `ID_EXAMPLE` int(10) unsigned NOT NULL AUTO_INCREMENT, `DESCRIPTION` varchar(30) NOT NULL, diff --git a/sql/discover.cc b/sql/discover.cc index b5bccf7dcb0..4224e8ce0b0 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -132,7 +132,7 @@ int writefrm(const char *path, const char *db, const char *table, if (my_errno == ENOENT) my_error(ER_BAD_DB_ERROR, MYF(0), db); else - my_error(ER_CANT_CREATE_TABLE, MYF(0), table, my_errno); + my_error(ER_CANT_CREATE_TABLE, MYF(0), db, table, my_errno); } else { diff --git a/sql/handler.cc b/sql/handler.cc index f890c2c8324..f094ff7bebb 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1138,7 +1138,8 @@ int ha_prepare(THD *thd) else { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), + ER_GET_ERRNO, ER(ER_GET_ERRNO), + HA_ERR_WRONG_COMMAND, ha_resolve_storage_engine_name(ht)); } } @@ -2004,7 +2005,7 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv) } if ((err= ht->savepoint_set(ht, thd, (uchar *)(sv+1)+ht->savepoint_offset))) { // cannot happen - my_error(ER_GET_ERRNO, MYF(0), err); + my_error(ER_GET_ERRNO, MYF(0), err, hton_name(ht)->str); error=1; } status_var_increment(thd->status_var.ha_savepoint_count); @@ -2035,7 +2036,7 @@ int ha_release_savepoint(THD *thd, SAVEPOINT *sv) if ((err= ht->savepoint_release(ht, thd, (uchar *)(sv+1) + ht->savepoint_offset))) { // cannot happen - my_error(ER_GET_ERRNO, MYF(0), err); + my_error(ER_GET_ERRNO, MYF(0), err, hton_name(ht)->str); error=1; } } @@ -2971,7 +2972,7 @@ void handler::print_error(int error, myf errflag) DBUG_ENTER("handler::print_error"); DBUG_PRINT("enter",("error: %d",error)); - int textno=ER_GET_ERRNO; + int textno= -1; // impossible value switch (error) { case EACCES: textno=ER_OPEN_AS_READONLY; @@ -3100,7 +3101,9 @@ void handler::print_error(int error, myf errflag) textno=ER_OUT_OF_RESOURCES; break; case HA_ERR_WRONG_COMMAND: - textno=ER_ILLEGAL_HA; + my_error(ER_ILLEGAL_HA, MYF(0), table_type(), table_share->db.str, + table_share->table_name.str); + DBUG_VOID_RETURN; break; case HA_ERR_OLD_FILE: textno=ER_OLD_KEYFILE; @@ -3219,10 +3222,11 @@ void handler::print_error(int error, myf errflag) } } else - my_error(ER_GET_ERRNO,errflag,error); + my_error(ER_GET_ERRNO, errflag, error, table_type()); DBUG_VOID_RETURN; } } + DBUG_ASSERT(textno > 0); if (fatal_error) { /* Ensure this becomes a true error */ @@ -4181,10 +4185,8 @@ int ha_create_table(THD *thd, const char *path, (void) closefrm(&table, 0); if (error) - { - strxmov(name_buff, db, ".", table_name, NullS); - my_error(ER_CANT_CREATE_TABLE, MYF(ME_BELL+ME_WAITTANG), name_buff, error); - } + my_error(ER_CANT_CREATE_TABLE, MYF(0), db, table_name, error); + err: free_table_share(&share); DBUG_RETURN(error != 0); @@ -4326,7 +4328,7 @@ static my_bool discover_handlerton(THD *thd, plugin_ref plugin, if (error) { DBUG_ASSERT(share->error); // MUST be always set for get_cached_table_share to work - my_error(ER_GET_ERRNO, MYF(0), error); + my_error(ER_GET_ERRNO, MYF(0), error, plugin_name(plugin)->str); share->db_plugin= 0; } else @@ -5116,7 +5118,7 @@ bool ha_show_status(THD *thd, handlerton *db_type, enum ha_stat_type stat) if (!result && !thd->is_error()) my_eof(thd); else if (!thd->is_error()) - my_error(ER_GET_ERRNO, MYF(0), errno); + my_error(ER_GET_ERRNO, MYF(0), errno, hton_name(db_type)->str); return result; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 108943541c9..2d27876df0b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6143,7 +6143,7 @@ bool Item_func_match::fix_fields(THD *thd, Item **ref) table=((Item_field *)item)->field->table; if (!(table->file->ha_table_flags() & HA_CAN_FULLTEXT)) { - my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0), table->file->table_type()); return 1; } table->fulltext_searched=1; diff --git a/sql/lock.cc b/sql/lock.cc index 3a1a6d41ce3..5bb42185d90 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -93,7 +93,7 @@ extern HASH open_cache; static int lock_external(THD *thd, TABLE **table,uint count); static int unlock_external(THD *thd, TABLE **table,uint count); -static void print_lock_error(int error, const char *); +static void print_lock_error(int error, TABLE *); /* Map the return value of thr_lock to an error from errmsg.txt */ static int thr_lock_errno_to_mysql[]= @@ -358,7 +358,7 @@ static int lock_external(THD *thd, TABLE **tables, uint count) if ((error=(*tables)->file->ha_external_lock(thd,lock_type))) { - print_lock_error(error, (*tables)->file->table_type()); + print_lock_error(error, *tables); while (--i) { tables--; @@ -673,7 +673,7 @@ static int unlock_external(THD *thd, TABLE **table,uint count) if ((error=(*table)->file->ha_external_lock(thd, F_UNLCK))) { error_code=error; - print_lock_error(error_code, (*table)->file->table_type()); + print_lock_error(error_code, *table); } } table++; @@ -895,7 +895,7 @@ bool lock_object_name(THD *thd, MDL_key::enum_mdl_namespace mdl_type, } -static void print_lock_error(int error, const char *table) +static void print_lock_error(int error, TABLE *table) { int textno; DBUG_ENTER("print_lock_error"); @@ -911,17 +911,15 @@ static void print_lock_error(int error, const char *table) textno=ER_LOCK_DEADLOCK; break; case HA_ERR_WRONG_COMMAND: - textno=ER_ILLEGAL_HA; - break; + my_error(ER_ILLEGAL_HA, MYF(0), table->file->table_type(), + table->s->db.str, table->s->table_name.str); + DBUG_VOID_RETURN; default: textno=ER_CANT_LOCK; break; } - if ( textno == ER_ILLEGAL_HA ) - my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), table); - else - my_error(textno, MYF(ME_BELL+ME_OLDWIN+ME_WAITTANG), error); + my_error(textno, MYF(0), error); DBUG_VOID_RETURN; } diff --git a/sql/share/errmsg-utf8.txt b/sql/share/errmsg-utf8.txt index 6a7eafc5fc4..e0b16b7a1ed 100644 --- a/sql/share/errmsg-utf8.txt +++ b/sql/share/errmsg-utf8.txt @@ -75,30 +75,30 @@ ER_CANT_CREATE_FILE swe "Kan inte skapa filen '%-.200s' (Felkod: %M)" ukr "Ðе можу Ñтворити файл '%-.200s' (помилка: %M)" ER_CANT_CREATE_TABLE - cze "Nemohu vytvo-BÅ™it tabulku '%-.200s' (chybový kód: %M)" - dan "Kan ikke oprette tabellen '%-.200s' (Fejlkode: %M)" - nla "Kan tabel '%-.200s' niet aanmaken (Errcode: %M)" - eng "Can't create table '%-.200s' (errno: %M)" - jps "'%-.200s' テーブルãŒä½œã‚Œã¾ã›ã‚“.(errno: %M)", - est "Ei suuda luua tabelit '%-.200s' (veakood: %M)" - fre "Ne peut créer la table '%-.200s' (Errcode: %M)" - ger "Kann Tabelle '%-.200s' nicht erzeugen (Fehler: %M)" - greek "ΑδÏνατη η δημιουÏγία του πίνακα '%-.200s' (κωδικός λάθους: %M)" - hun "A '%-.200s' tabla nem hozhato letre (hibakod: %M)" - ita "Impossibile creare la tabella '%-.200s' (errno: %M)" - jpn "'%-.200s' テーブルãŒä½œã‚Œã¾ã›ã‚“.(errno: %M)" - kor "í…Œì´ë¸” '%-.200s'를 만들지 못했습니다. (ì—러번호: %M)" - nor "Kan ikke opprette tabellen '%-.200s' (Feilkode: %M)" - norwegian-ny "Kan ikkje opprette tabellen '%-.200s' (Feilkode: %M)" - pol "Nie można stworzyć tabeli '%-.200s' (Kod błędu: %M)" - por "Não pode criar a tabela '%-.200s' (erro no. %M)" - rum "Nu pot sa creez tabla '%-.200s' (Eroare: %M)" - rus "Ðевозможно Ñоздать таблицу '%-.200s' (ошибка: %M)" - serbian "Ne mogu da kreiram tabelu '%-.200s' (errno: %M)" - slo "Nemôžem vytvoriÅ¥ tabuľku '%-.200s' (chybový kód: %M)" - spa "No puedo crear tabla '%-.200s' (Error: %M)" - swe "Kan inte skapa tabellen '%-.200s' (Felkod: %M)" - ukr "Ðе можу Ñтворити таблицю '%-.200s' (помилка: %M)" + cze "Nemohu vytvo-BÅ™it tabulku %`s.%`s (chybový kód: %M)" + dan "Kan ikke oprette tabellen %`s.%`s (Fejlkode: %M)" + nla "Kan tabel %`s.%`s niet aanmaken (Errcode: %M)" + eng "Can't create table %`s.%`s (errno: %M)" + jps "%`s.%`s テーブルãŒä½œã‚Œã¾ã›ã‚“.(errno: %M)", + est "Ei suuda luua tabelit %`s.%`s (veakood: %M)" + fre "Ne peut créer la table %`s.%`s (Errcode: %M)" + ger "Kann Tabelle %`s.%`s nicht erzeugen (Fehler: %M)" + greek "ΑδÏνατη η δημιουÏγία του πίνακα %`s.%`s (κωδικός λάθους: %M)" + hun "A %`s.%`s tabla nem hozhato letre (hibakod: %M)" + ita "Impossibile creare la tabella %`s.%`s (errno: %M)" + jpn "%`s.%`s テーブルãŒä½œã‚Œã¾ã›ã‚“.(errno: %M)" + kor "í…Œì´ë¸” %`s.%`s를 만들지 못했습니다. (ì—러번호: %M)" + nor "Kan ikke opprette tabellen %`s.%`s (Feilkode: %M)" + norwegian-ny "Kan ikkje opprette tabellen %`s.%`s (Feilkode: %M)" + pol "Nie można stworzyć tabeli %`s.%`s (Kod błędu: %M)" + por "Não pode criar a tabela %`s.%`s (erro no. %M)" + rum "Nu pot sa creez tabla %`s.%`s (Eroare: %M)" + rus "Ðевозможно Ñоздать таблицу %`s.%`s (ошибка: %M)" + serbian "Ne mogu da kreiram tabelu %`s.%`s (errno: %M)" + slo "Nemôžem vytvoriÅ¥ tabuľku %`s.%`s (chybový kód: %M)" + spa "No puedo crear tabla %`s.%`s (Error: %M)" + swe "Kan inte skapa tabellen %`s.%`s (Felkod: %M)" + ukr "Ðе можу Ñтворити таблицю %`s.%`s (помилка: %M)" ER_CANT_CREATE_DB cze "Nemohu vytvo-BÅ™it databázi '%-.192s' (chybový kód: %M)" dan "Kan ikke oprette databasen '%-.192s' (Fejlkode: %M)" @@ -696,53 +696,26 @@ ER_FORM_NOT_FOUND swe "Formulär '%-.192s' finns inte i '%-.192s'" ukr "ВиглÑд '%-.192s' не Ñ–Ñнує Ð´Ð»Ñ '%-.192s'" ER_GET_ERRNO - cze "Obsluha tabulky vr-Bátila chybu %M" - dan "Modtog fejl %M fra tabel hÃ¥ndteringen" - nla "Fout %M van tabel handler" - eng "Got error %M from storage engine" - est "Tabeli handler tagastas vea %M" - fre "Reçu l'erreur %M du handler de la table" - ger "Fehler %M (Speicher-Engine)" - greek "Ελήφθη μήνυμα λάθους %M από τον χειÏιστή πίνακα (table handler)" - hun "%M hibajelzes a tablakezelotol" - ita "Rilevato l'errore %M dal gestore delle tabelle" - jpn "Got error %M from table handler" - kor "í…Œì´ë¸” handlerì—서 %M ì—러가 ë°œìƒ í•˜ì˜€ìŠµë‹ˆë‹¤." - nor "Mottok feil %M fra tabell hÃ¥ndterer" - norwegian-ny "Mottok feil %M fra tabell handterar" - pol "Otrzymano bÅ‚?d %M z obsÅ‚ugi tabeli" - por "Obteve erro %M no manipulador de tabelas" - rum "Eroarea %M obtinuta din handlerul tabelei" - rus "Получена ошибка %M от обработчика таблиц" - serbian "Handler tabela je vratio greÅ¡ku %M" - slo "Obsluha tabuľky vrátila chybu %M" - spa "Error %M desde el manejador de la tabla" - swe "Fick felkod %M frÃ¥n databashanteraren" - ukr "Отримано помилку %M від деÑкриптора таблиці" + nla "Fout %M van tabel handler %s" + eng "Got error %M from storage engine %s" + fre "Reçu l'erreur %M du handler de la table %s" + ger "Fehler %M von Speicher-Engine %s" + greek "Ελήφθη μήνυμα λάθους %M από τον χειÏιστή πίνακα (table handler) %s" + ita "Rilevato l'errore %M dal gestore delle tabelle %s" + nor "Mottok feil %M fra tabell hÃ¥ndterer %s" + norwegian-ny "Mottok feil %M fra tabell handterar %s" + pol "Otrzymano bÅ‚?d %M z obsÅ‚ugi tabeli %s" + por "Obteve erro %M no manipulador de tabelas %s" + rum "Eroarea %M obtinuta din handlerul tabelei %s" + rus "Получена ошибка %M от обработчика таблиц %s" + spa "Error %M desde el manejador de la tabla %s" + swe "Fick felkod %M frÃ¥n databashanteraren %s" + ukr "Отримано помилку %M від деÑкриптора таблиці %s" ER_ILLEGAL_HA - cze "Obsluha tabulky '%-.192s' nem-Bá tento parametr" - dan "Denne mulighed eksisterer ikke for tabeltypen '%-.192s'" - nla "Tabel handler voor '%-.192s' heeft deze optie niet" - eng "Table storage engine for '%-.192s' doesn't have this option" - est "Tabeli '%-.192s' handler ei toeta antud operatsiooni" - fre "Le handler de la table '%-.192s' n'a pas cette option" - ger "Diese Option gibt es nicht (Speicher-Engine für '%-.192s')" - greek "Ο χειÏιστής πίνακα (table handler) για '%-.192s' δεν διαθέτει αυτή την επιλογή" - hun "A(z) '%-.192s' tablakezelonek nincs ilyen opcioja" - ita "Il gestore delle tabelle per '%-.192s' non ha questa opzione" - jpn "Table handler for '%-.192s' doesn't have this option" - kor "'%-.192s'ì˜ í…Œì´ë¸” handler는 ì´ëŸ¬í•œ ì˜µì…˜ì„ ì œê³µí•˜ì§€ 않ì니다." - nor "Tabell hÃ¥ndtereren for '%-.192s' har ikke denne muligheten" - norwegian-ny "Tabell hÃ¥ndteraren for '%-.192s' har ikkje denne moglegheita" - pol "ObsÅ‚uga tabeli '%-.192s' nie posiada tej opcji" - por "Manipulador de tabela para '%-.192s' não tem esta opção" - rum "Handlerul tabelei pentru '%-.192s' nu are aceasta optiune" - rus "Обработчик таблицы '%-.192s' не поддерживает Ñту возможноÑть" - serbian "Handler tabela za '%-.192s' nema ovu opciju" - slo "Obsluha tabuľky '%-.192s' nemá tento parameter" - spa "El manejador de la tabla de '%-.192s' no tiene esta opcion" - swe "Tabellhanteraren for tabell '%-.192s' stödjer ej detta" - ukr "ДеÑкриптор таблиці '%-.192s' не має цієї влаÑтивоÑті" + eng "Storage engine %s of the table %`s.%`s doesn't have this option" + ger "Diese Option gibt es nicht in Speicher-Engine %s für %`s.%`s" + rus "Обработчик %s таблицы %`s.%`s не поддерживает Ñту возможноÑть" + ukr "ДеÑкриптор %s таблиці %`s.%`s не має цієї влаÑтивоÑті" ER_KEY_NOT_FOUND cze "Nemohu naj-Bít záznam v '%-.192s'" dan "Kan ikke finde posten i '%-.192s'" @@ -1750,28 +1723,10 @@ ER_KEY_COLUMN_DOES_NOT_EXITS 42000 S1009 swe "Nyckelkolumn '%-.192s' finns inte" ukr "Ключовий Ñтовбець '%-.192s' не Ñ–Ñнує у таблиці" ER_BLOB_USED_AS_KEY 42000 S1009 - cze "Blob sloupec '%-.192s' nem-Bůže být použit jako klíÄ" - dan "BLOB feltet '%-.192s' kan ikke bruges ved specifikation af indeks" - nla "BLOB kolom '%-.192s' kan niet gebruikt worden bij zoeksleutel specificatie" - eng "BLOB column '%-.192s' can't be used in key specification with the used table type" - est "BLOB-tüüpi tulpa '%-.192s' ei saa kasutada võtmena" - fre "Champ BLOB '%-.192s' ne peut être utilisé dans une clé" - ger "BLOB-Feld '%-.192s' kann beim verwendeten Tabellentyp nicht als Schlüssel verwendet werden" - greek "Πεδίο Ï„Ïπου Blob '%-.192s' δεν μποÏεί να χÏησιμοποιηθεί στον οÏισμό ενός ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï (key specification)" - hun "Blob objektum '%-.192s' nem hasznalhato kulcskent" - ita "La colonna BLOB '%-.192s' non puo` essere usata nella specifica della chiave" - kor "BLOB 칼럼 '%-.192s'는 키 ì •ì˜ì—서 ì‚¬ìš©ë  ìˆ˜ 없습니다." - nor "Blob felt '%-.192s' kan ikke brukes ved spesifikasjon av nøkler" - norwegian-ny "Blob kolonne '%-.192s' kan ikkje brukast ved spesifikasjon av nyklar" - pol "Kolumna typu Blob '%-.192s' nie może być użyta w specyfikacji klucza" - por "Coluna BLOB '%-.192s' não pode ser utilizada na especificação de chave para o tipo de tabela usado" - rum "Coloana de tip BLOB '%-.192s' nu poate fi folosita in specificarea cheii cu tipul de tabla folosit" - rus "Столбец типа BLOB '%-.192s' не может быть иÑпользован как значение ключа в таблице такого типа" - serbian "BLOB kolona '%-.192s' ne može biti upotrebljena za navoÄ‘enje kljuÄa sa tipom tabele koji se trenutno koristi" - slo "Blob pole '%-.192s' nemôže byÅ¥ použité ako kľúÄ" - spa "La columna Blob '%-.192s' no puede ser usada en una declaracion de clave" - swe "En BLOB '%-.192s' kan inte vara nyckel med den använda tabelltypen" - ukr "BLOB Ñтовбець '%-.192s' не може бути викориÑтаний у визначенні ключа в цьому типі таблиці" + eng "BLOB column %`s can't be used in key specification in the %s table" + ger "BLOB-Feld %`s kann beim %s Tabellen nicht als Schlüssel verwendet werden" + rus "Столбец типа BLOB %`s не может быть иÑпользован как значение ключа в %s таблице" + ukr "BLOB Ñтовбець %`s не може бути викориÑтаний у визначенні ключа в %s таблиці" ER_TOO_BIG_FIELDLENGTH 42000 S1009 cze "P-BříliÅ¡ velká délka sloupce '%-.192s' (nejvíce %lu). Použijte BLOB" dan "For stor feltlængde for kolonne '%-.192s' (maks = %lu). Brug BLOB i stedet" @@ -3691,39 +3646,39 @@ ER_TOO_LONG_STRING 42000 swe "Resultatsträngen är längre än max_allowed_packet" ukr "Строка результату довша ніж max_allowed_packet" ER_TABLE_CANT_HANDLE_BLOB 42000 - cze "Typ pou-Bžité tabulky nepodporuje BLOB/TEXT sloupce" - dan "Denne tabeltype understøtter ikke brug af BLOB og TEXT kolonner" - nla "Het gebruikte tabel type ondersteunt geen BLOB/TEXT kolommen" - eng "The used table type doesn't support BLOB/TEXT columns" - est "Valitud tabelitüüp ei toeta BLOB/TEXT tüüpi välju" - fre "Ce type de table ne supporte pas les colonnes BLOB/TEXT" - ger "Der verwendete Tabellentyp unterstützt keine BLOB- und TEXT-Felder" - hun "A hasznalt tabla tipus nem tamogatja a BLOB/TEXT mezoket" - ita "Il tipo di tabella usata non supporta colonne di tipo BLOB/TEXT" - por "Tipo de tabela usado não permite colunas BLOB/TEXT" - rum "Tipul de tabela folosit nu suporta coloane de tip BLOB/TEXT" - rus "ИÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° не поддерживает типы BLOB/TEXT" - serbian "IskoriÅ¡teni tip tabele ne podržava kolone tipa 'BLOB' odnosno 'TEXT'" - spa "El tipo de tabla usada no permite soporte para columnas BLOB/TEXT" - swe "Den använda tabelltypen kan inte hantera BLOB/TEXT-kolumner" - ukr "ВикориÑтаний тип таблиці не підтримує BLOB/TEXT Ñтовбці" + cze "Typ pou-Bžité tabulky (%s) nepodporuje BLOB/TEXT sloupce" + dan "Denne tabeltype (%s) understøtter ikke brug af BLOB og TEXT kolonner" + nla "Het gebruikte tabel type (%s) ondersteunt geen BLOB/TEXT kolommen" + eng "Storage engine %s doesn't support BLOB/TEXT columns" + est "Valitud tabelitüüp (%s) ei toeta BLOB/TEXT tüüpi välju" + fre "Ce type de table (%s) ne supporte pas les colonnes BLOB/TEXT" + ger "Der verwendete Tabellentyp (%s) unterstützt keine BLOB- und TEXT-Felder" + hun "A hasznalt tabla tipus (%s) nem tamogatja a BLOB/TEXT mezoket" + ita "Il tipo di tabella usata (%s) non supporta colonne di tipo BLOB/TEXT" + por "Tipo de tabela usado (%s) não permite colunas BLOB/TEXT" + rum "Tipul de tabela folosit (%s) nu suporta coloane de tip BLOB/TEXT" + rus "%s таблицы не поддерживают типы BLOB/TEXT" + serbian "IskoriÅ¡teni tip tabele (%s) ne podržava kolone tipa 'BLOB' odnosno 'TEXT'" + spa "El tipo de tabla usada (%s) no permite soporte para columnas BLOB/TEXT" + swe "Den använda tabelltypen (%s) kan inte hantera BLOB/TEXT-kolumner" + ukr "%s таблиці не підтримують BLOB/TEXT Ñтовбці" ER_TABLE_CANT_HANDLE_AUTO_INCREMENT 42000 - cze "Typ pou-Bžité tabulky nepodporuje AUTO_INCREMENT sloupce" - dan "Denne tabeltype understøtter ikke brug af AUTO_INCREMENT kolonner" - nla "Het gebruikte tabel type ondersteunt geen AUTO_INCREMENT kolommen" - eng "The used table type doesn't support AUTO_INCREMENT columns" - est "Valitud tabelitüüp ei toeta AUTO_INCREMENT tüüpi välju" - fre "Ce type de table ne supporte pas les colonnes AUTO_INCREMENT" - ger "Der verwendete Tabellentyp unterstützt keine AUTO_INCREMENT-Felder" - hun "A hasznalt tabla tipus nem tamogatja az AUTO_INCREMENT tipusu mezoket" - ita "Il tipo di tabella usata non supporta colonne di tipo AUTO_INCREMENT" - por "Tipo de tabela usado não permite colunas AUTO_INCREMENT" - rum "Tipul de tabela folosit nu suporta coloane de tip AUTO_INCREMENT" - rus "ИÑÐ¿Ð¾Ð»ÑŒÐ·ÑƒÐµÐ¼Ð°Ñ Ñ‚Ð°Ð±Ð»Ð¸Ñ†Ð° не поддерживает автоинкрементные Ñтолбцы" - serbian "IskoriÅ¡teni tip tabele ne podržava kolone tipa 'AUTO_INCREMENT'" - spa "El tipo de tabla usada no permite soporte para columnas AUTO_INCREMENT" - swe "Den använda tabelltypen kan inte hantera AUTO_INCREMENT-kolumner" - ukr "ВикориÑтаний тип таблиці не підтримує AUTO_INCREMENT Ñтовбці" + cze "Typ pou-Bžité tabulky (%s) nepodporuje AUTO_INCREMENT sloupce" + dan "Denne tabeltype understøtter (%s) ikke brug af AUTO_INCREMENT kolonner" + nla "Het gebruikte tabel type (%s) ondersteunt geen AUTO_INCREMENT kolommen" + eng "Storage engine %s doesn't support AUTO_INCREMENT columns" + est "Valitud tabelitüüp (%s) ei toeta AUTO_INCREMENT tüüpi välju" + fre "Ce type de table (%s) ne supporte pas les colonnes AUTO_INCREMENT" + ger "Der verwendete Tabellentyp (%s) unterstützt keine AUTO_INCREMENT-Felder" + hun "A hasznalt tabla tipus (%s) nem tamogatja az AUTO_INCREMENT tipusu mezoket" + ita "Il tipo di tabella usata (%s) non supporta colonne di tipo AUTO_INCREMENT" + por "Tipo de tabela usado (%s) não permite colunas AUTO_INCREMENT" + rum "Tipul de tabela folosit (%s) nu suporta coloane de tip AUTO_INCREMENT" + rus "%s таблицы не поддерживают автоинкрементные Ñтолбцы" + serbian "IskoriÅ¡teni tip tabele (%s) ne podržava kolone tipa 'AUTO_INCREMENT'" + spa "El tipo de tabla usada (%s) no permite soporte para columnas AUTO_INCREMENT" + swe "Den använda tabelltypen (%s) kan inte hantera AUTO_INCREMENT-kolumner" + ukr "%s таблиці не підтримують AUTO_INCREMENT Ñтовбці" ER_DELAYED_INSERT_TABLE_LOCKED cze "INSERT DELAYED nen-Bí možno s tabulkou '%-.192s' použít, protože je zamÄená pomocí LOCK TABLES" dan "INSERT DELAYED kan ikke bruges med tabellen '%-.192s', fordi tabellen er lÃ¥st med LOCK TABLES" @@ -3766,29 +3721,10 @@ ER_WRONG_COLUMN_NAME 42000 swe "Felaktigt kolumnnamn '%-.100s'" ukr "Ðевірне ім'Ñ ÑÑ‚Ð¾Ð²Ð±Ñ†Ñ '%-.100s'" ER_WRONG_KEY_COLUMN 42000 - cze "Handler pou-Bžité tabulky neumí indexovat sloupce '%-.192s'" - dan "Den brugte tabeltype kan ikke indeksere kolonnen '%-.192s'" - nla "De gebruikte tabel 'handler' kan kolom '%-.192s' niet indexeren" - eng "The used storage engine can't index column '%-.192s'" - est "Tabelihandler ei oska indekseerida tulpa '%-.192s'" - fre "Le handler de la table ne peut indexé la colonne '%-.192s'" - ger "Die verwendete Speicher-Engine kann die Spalte '%-.192s' nicht indizieren" - greek "The used table handler can't index column '%-.192s'" - hun "A hasznalt tablakezelo nem tudja a '%-.192s' mezot indexelni" - ita "Il gestore delle tabelle non puo` indicizzare la colonna '%-.192s'" - jpn "The used table handler can't index column '%-.192s'" - kor "The used table handler can't index column '%-.192s'" - nor "The used table handler can't index column '%-.192s'" - norwegian-ny "The used table handler can't index column '%-.192s'" - pol "The used table handler can't index column '%-.192s'" - por "O manipulador de tabela usado não pode indexar a coluna '%-.192s'" - rum "Handler-ul tabelei folosite nu poate indexa coloana '%-.192s'" - rus "ИÑпользованный обработчик таблицы не может проиндекÑировать Ñтолбец '%-.192s'" - serbian "Handler tabele ne može da indeksira kolonu '%-.192s'" - slo "The used table handler can't index column '%-.192s'" - spa "El manipulador de tabla usado no puede indexar columna '%-.192s'" - swe "Den använda tabelltypen kan inte indexera kolumn '%-.192s'" - ukr "ВикориÑтаний вказівник таблиці не може індекÑувати Ñтовбець '%-.192s'" + eng "The storage engine %s can't index column %`s" + ger "Die Speicher-Engine %s kann die Spalte %`s nicht indizieren" + rus "Обработчик таблиц %s не может проиндекÑировать Ñтолбец %`s" + ukr "Вказівник таблиц %s не може індекÑувати Ñтовбець %`s" ER_WRONG_MRG_TABLE cze "V-BÅ¡echny tabulky v MERGE tabulce nejsou definovány stejnÄ›" dan "Tabellerne i MERGE er ikke defineret ens" @@ -4088,22 +4024,8 @@ ER_NEW_ABORTING_CONNECTION 08S01 spa "Abortada conexión %ld para db: '%-.192s' usuario: '%-.48s' servidor: '%-.64s' (%-.64s)" swe "Avbröt länken för trÃ¥d %ld till db '%-.192s', användare '%-.48s', host '%-.64s' (%-.64s)" ukr "Перервано з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ %ld до бази данних: '%-.192s' кориÑтувач: '%-.48s' хоÑÑ‚: '%-.64s' (%-.64s)" -ER_DUMP_NOT_IMPLEMENTED - cze "Handler tabulky nepodporuje bin-Bární dump" - dan "Denne tabeltype unserstøtter ikke binært tabeldump" - nla "De 'handler' voor de tabel ondersteund geen binaire tabel dump" - eng "The storage engine for the table does not support binary table dump" - fre "Ce type de table ne supporte pas les copies binaires" - ger "Die Speicher-Engine für die Tabelle unterstützt keinen binären Tabellen-Dump" - ita "Il gestore per la tabella non supporta il dump binario" - jpn "The handler for the table does not support binary table dump" - por "O manipulador de tabela não suporta 'dump' binário de tabela" - rum "The handler for the table does not support binary table dump" - rus "Обработчик Ñтой таблицы не поддерживает двоичного ÑÐ¾Ñ…Ñ€Ð°Ð½ÐµÐ½Ð¸Ñ Ð¾Ð±Ñ€Ð°Ð·Ð° таблицы (dump)" - serbian "Handler tabele ne podržava binarni dump tabele" - spa "El manipulador de tabla no soporta dump para tabla binaria" - swe "Tabellhanteraren klarar inte en binär kopiering av tabellen" - ukr "Цей тип таблиці не підтримує бінарну передачу таблиці" +ER_unused_2 + eng "You should never see it" ER_FLUSH_MASTER_BINLOG_CLOSED eng "Binlog closed, cannot RESET MASTER" ger "Binlog geschlossen. Kann RESET MASTER nicht ausführen" @@ -4477,18 +4399,18 @@ ER_LOCK_DEADLOCK 40001 spa "Encontrado deadlock cuando tentando obtener el bloqueo; Tente recomenzar la transición" swe "Fick 'DEADLOCK' vid lÃ¥sförsök av block/rad. Försök att starta om transaktionen" ER_TABLE_CANT_HANDLE_FT - nla "Het gebruikte tabel type ondersteund geen FULLTEXT indexen" - eng "The used table type doesn't support FULLTEXT indexes" - est "Antud tabelitüüp ei toeta FULLTEXT indekseid" - fre "Le type de table utilisé ne supporte pas les index FULLTEXT" - ger "Der verwendete Tabellentyp unterstützt keine FULLTEXT-Indizes" - ita "La tabella usata non supporta gli indici FULLTEXT" - por "O tipo de tabela utilizado não suporta índices de texto completo (fulltext indexes)" - rus "ИÑпользуемый тип таблиц не поддерживает полнотекÑтовых индекÑов" - serbian "Upotrebljeni tip tabele ne podržava 'FULLTEXT' indekse" - spa "El tipo de tabla usada no soporta índices FULLTEXT" - swe "Tabelltypen har inte hantering av FULLTEXT-index" - ukr "ВикориÑтаний тип таблиці не підтримує FULLTEXT індекÑів" + nla "Het gebruikte tabel type (%s) ondersteund geen FULLTEXT indexen" + eng "The storage engine %s doesn't support FULLTEXT indexes" + est "Antud tabelitüüp (%s) ei toeta FULLTEXT indekseid" + fre "Le type de table utilisé (%s) ne supporte pas les index FULLTEXT" + ger "Der verwendete Tabellentyp (%s) unterstützt keine FULLTEXT-Indizes" + ita "La tabella usata (%s) non supporta gli indici FULLTEXT" + por "O tipo de tabela utilizado (%s) não suporta índices de texto completo (fulltext indexes)" + rus "ИÑпользуемый тип таблиц (%s) не поддерживает полнотекÑтовых индекÑов" + serbian "Upotrebljeni tip tabele (%s) ne podržava 'FULLTEXT' indekse" + spa "El tipo de tabla usada (%s) no soporta índices FULLTEXT" + swe "Tabelltypen (%s) har inte hantering av FULLTEXT-index" + ukr "ВикориÑтаний тип таблиці (%s) не підтримує FULLTEXT індекÑів" ER_CANNOT_ADD_FOREIGN nla "Kan foreign key beperking niet toevoegen" eng "Cannot add foreign key constraint" @@ -5622,8 +5544,8 @@ ER_NON_GROUPING_FIELD_USED 42000 eng "Non-grouping field '%-.192s' is used in %-.64s clause" ger "In der %-.192s-Klausel wird das die Nicht-Gruppierungsspalte '%-.64s' verwendet" ER_TABLE_CANT_HANDLE_SPKEYS - eng "The used table type doesn't support SPATIAL indexes" - ger "Der verwendete Tabellentyp unterstützt keine SPATIAL-Indizes" + eng "The storage engine %s doesn't support SPATIAL indexes" + ger "Der verwendete Tabellentyp (%s) unterstützt keine SPATIAL-Indizes" ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA eng "Triggers can not be created on system tables" ger "Trigger können nicht auf Systemtabellen erzeugt werden" @@ -6017,8 +5939,8 @@ ER_ONLY_INTEGERS_ALLOWED eng "Only integers allowed as number here" ger "An dieser Stelle sind nur Ganzzahlen zulässig" ER_UNSUPORTED_LOG_ENGINE - eng "This storage engine cannot be used for log tables" - ger "Diese Speicher-Engine kann für Logtabellen nicht verwendet werden" + eng "Storage engine %s cannot be used for log tables" + ger "Speicher-Engine %s kann für Logtabellen nicht verwendet werden" ER_BAD_LOG_STATEMENT eng "You cannot '%s' a log table if logging is enabled" ger "Sie können eine Logtabelle nicht '%s', wenn Loggen angeschaltet ist" @@ -6498,7 +6420,7 @@ ER_BINLOG_UNSAFE_INSERT_TWO_KEYS ER_TABLE_IN_FK_CHECK eng "Table is being used in foreign key check." -ER_UNUSED_1 +ER_unused_1 eng "You should never see it" ER_BINLOG_UNSAFE_AUTOINC_NOT_FIRST diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 1c93a59904c..d1e5d731183 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -304,7 +304,8 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) /* There can be only one table in '*tables'. */ if (! (table->file->ha_table_flags() & HA_CAN_SQL_HANDLER)) { - my_error(ER_ILLEGAL_HA, MYF(0), tables->alias); + my_error(ER_ILLEGAL_HA, MYF(0), table->file->table_type(), + table->s->db.str, table->s->table_name.str); goto err; } @@ -901,7 +902,8 @@ retry: break; } default: - my_message(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0)); + my_error(ER_ILLEGAL_HA, MYF(0), table->file->table_type(), + table->s->db.str, table->s->table_name.str); goto err; } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index d6a64b38446..2f9bcf92f6d 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1764,7 +1764,7 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) mysql_mutex_unlock(&LOCK_plugin); } if (error > 0) - sql_print_error(ER(ER_GET_ERRNO), my_errno); + sql_print_error(ER(ER_GET_ERRNO), my_errno, table->file->table_type()); end_read_record(&read_record_info); table->m_needs_reopen= TRUE; // Force close to free memory close_mysql_tables(new_thd); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index eb02e9f2baf..dd00d921b6e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -963,7 +963,7 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) plugin_ref plugin= ha_resolve_by_name(thd, &handler_name); if (!plugin) { - my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name); + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), ddl_log_entry->handler_name); goto error; } hton= plugin_data(plugin, handlerton*); @@ -3255,15 +3255,13 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, if (auto_increment && (file->ha_table_flags() & HA_NO_AUTO_INCREMENT)) { - my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, - ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT, MYF(0), file->table_type()); DBUG_RETURN(TRUE); } if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS)) { - my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB), - MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_BLOB, MYF(0), file->table_type()); DBUG_RETURN(TRUE); } @@ -3439,8 +3437,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->ha_table_flags() & HA_CAN_FULLTEXT)) { - my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT), - MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0), file->table_type()); DBUG_RETURN(TRUE); } } @@ -3457,8 +3454,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->ha_table_flags() & HA_CAN_RTREEKEYS)) { - my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS), - MYF(0)); + my_error(ER_TABLE_CANT_HANDLE_SPKEYS, MYF(0), file->table_type()); DBUG_RETURN(TRUE); } if (key_info->key_parts != 1) @@ -3573,7 +3569,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, { if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS)) { - my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str); + my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str, + file->table_type()); DBUG_RETURN(TRUE); } if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type == @@ -3695,7 +3692,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } else if (length == 0 && (sql_field->flags & NOT_NULL_FLAG)) { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str); + my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), + column->field_name.str); DBUG_RETURN(TRUE); } if (length > file->max_key_part_length() && key->type != Key::FULLTEXT) @@ -4394,7 +4392,7 @@ bool mysql_create_table_no_lock(THD *thd, if (!hton->discover_table_structure) { - my_error(ER_ILLEGAL_HA, MYF(0), table_name); + my_error(ER_ILLEGAL_HA, MYF(0), hton_name(hton)->str, db, table_name); goto err; } @@ -4414,7 +4412,7 @@ bool mysql_create_table_no_lock(THD *thd, if (ha_err) { - my_error(ER_GET_ERRNO, MYF(0), ha_err); + my_error(ER_GET_ERRNO, MYF(0), ha_err, hton_name(hton)->str); goto err; } } @@ -5417,6 +5415,7 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, switch (keys_onoff) { case ENABLE: + DEBUG_SYNC(table->in_use, "alter_table_enable_indexes"); error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); break; case LEAVE_AS_IS: @@ -5431,7 +5430,8 @@ bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled, { push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->s->table_name.str); + table->file->table_type(), + table->s->db.str, table->s->table_name.str); error= 0; } else if (error) table->file->print_error(error, MYF(0)); @@ -6051,7 +6051,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, (!create_info->db_type || /* unknown engine */ !(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES))) { - my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0)); + my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0), + hton_name(create_info->db_type)->str); DBUG_RETURN(TRUE); } @@ -6267,11 +6268,19 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, DBUG_PRINT("info", ("old type: %s new type: %s", ha_resolve_storage_engine_name(old_db_type), ha_resolve_storage_engine_name(new_db_type))); - if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) || - ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED)) + if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED)) { DBUG_PRINT("info", ("doesn't support alter")); - my_error(ER_ILLEGAL_HA, MYF(0), table_name); + my_error(ER_ILLEGAL_HA, MYF(0), hton_name(old_db_type)->str, + db, table_name); + goto err; + } + + if (ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED)) + { + DBUG_PRINT("info", ("doesn't support alter")); + my_error(ER_ILLEGAL_HA, MYF(0), hton_name(new_db_type)->str, + new_db, new_name); goto err; } @@ -6279,35 +6288,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) && !table->s->tmp_table) // no need to touch frm { - switch (alter_info->keys_onoff) { - case LEAVE_AS_IS: - break; - case ENABLE: - if (wait_while_table_is_used(thd, table, extra_func, - TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)) - goto err; - DEBUG_SYNC(thd,"alter_table_enable_indexes"); - error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); - table->s->allow_access_to_protected_table(); - break; - case DISABLE: - if (wait_while_table_is_used(thd, table, extra_func, - TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)) - goto err; - error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); - table->s->allow_access_to_protected_table(); - break; - default: - DBUG_ASSERT(FALSE); - error= 0; - break; - } - if (error == HA_ERR_WRONG_COMMAND) + if (alter_info->keys_onoff != LEAVE_AS_IS) { - error= 0; - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, - ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->alias.c_ptr()); + if (wait_while_table_is_used(thd, table, extra_func, + TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)) + goto err; + error= alter_table_manage_keys(table, 0, alter_info->keys_onoff); + table->s->allow_access_to_protected_table(); } if (!error && (new_name != table_name || new_db != db)) @@ -6365,7 +6352,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, error= 0; push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), - table->alias.c_ptr()); + table->file->table_type(), + table->s->db.str, table->s->table_name.str); } if (!error) diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index cdd5078c262..3f61fbb3302 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -311,6 +311,7 @@ innobase_check_index_keys( } my_error(ER_WRONG_KEY_COLUMN, MYF(0), + field->table->file->table_type(), field->field_name); return(ER_WRONG_KEY_COLUMN); } @@ -325,6 +326,7 @@ innobase_check_index_keys( } my_error(ER_WRONG_KEY_COLUMN, MYF(0), + field->table->file->table_type(), key_part1.field->field_name); return(ER_WRONG_KEY_COLUMN); } diff --git a/storage/pbxt/src/discover_xt.cc b/storage/pbxt/src/discover_xt.cc index 05891bdf19d..23941374fb1 100644 --- a/storage/pbxt/src/discover_xt.cc +++ b/storage/pbxt/src/discover_xt.cc @@ -1196,7 +1196,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } else if (length == 0) { - my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name); + my_error(ER_WRONG_KEY_COLUMN, MYF(0), file->table_type(), + column->field_name); DBUG_RETURN(TRUE); } if (length > file->max_key_part_length() && key->type != Key::FULLTEXT) diff --git a/storage/sequence/mysql-test/sequence/simple.result b/storage/sequence/mysql-test/sequence/simple.result index 102f17498fe..b14fde2cfef 100644 --- a/storage/sequence/mysql-test/sequence/simple.result +++ b/storage/sequence/mysql-test/sequence/simple.result @@ -39,7 +39,7 @@ ERROR 42S02: Table 'test.seq_' doesn't exist show create table se; ERROR 42S02: Table 'test.se' doesn't exist show create table seq_1_to_15_step_0; -ERROR HY000: Got error 140 "Wrong create options" from storage engine +ERROR HY000: Got error 140 "Wrong create options" from storage engine SEQUENCE select * from seq_1_to_15_step_2; seq 1 diff --git a/storage/sphinx/ha_sphinx.cc b/storage/sphinx/ha_sphinx.cc index 94940e0b82f..23bf21b6cbe 100644 --- a/storage/sphinx/ha_sphinx.cc +++ b/storage/sphinx/ha_sphinx.cc @@ -3424,7 +3424,8 @@ int ha_sphinx::create ( const char * name, TABLE * table, HA_CREATE_INFO * ) // report and bail if ( sError[0] ) { - my_error ( ER_CANT_CREATE_TABLE, MYF(0), sError, -1 ); + my_error ( ER_CANT_CREATE_TABLE, MYF(0), + table->s->db.str, table->s->table_name, sError ); SPH_RET(-1); } diff --git a/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result index c2b9160f7c3..4fee0a983ed 100644 --- a/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result +++ b/storage/test_sql_discovery/mysql-test/sql_discovery/simple.result @@ -4,7 +4,7 @@ test_sql_discovery_statement test_sql_discovery_write_frm ON set sql_quote_show_create=0; create table t1 (a int) engine=test_sql_discovery; -ERROR HY000: Can't create table 'test.t1' (errno: 131 "Command not supported by database") +ERROR HY000: Can't create table `test`.`t1` (errno: 131 "Command not supported by database") select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist set @@test_sql_discovery_statement='t1:foobar bwa-ha-ha'; @@ -16,7 +16,7 @@ show warnings; Level Code Message Error 1064 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'foobar bwa-ha-ha' at line 1 Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:select 1'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -24,7 +24,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'select 1' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int primary key) partition by hash(id) partitions 2'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -32,7 +32,7 @@ show warnings; Level Code Message Error 1290 The MariaDB server is running with the --skip-partition option so it cannot execute this statement Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int) union=(t3,t4)'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -40,7 +40,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) union=(t3,t4)' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 like t2'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -48,7 +48,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 like t2' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 select * from t2'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -56,7 +56,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 select * from t2' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int) index directory="/tmp"'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -64,7 +64,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) index directory="/tmp"' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int) data directory="/tmp"'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -72,7 +72,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) data directory="/tmp"' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int) engine=myisam'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -80,7 +80,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table t1 (a int) engine=myisam' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create temporary table t1 (a int)'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -88,7 +88,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create temporary table t1 (a int)' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table if not exists t1 (a int)'; select * from t1; ERROR 42S02: Table 'test.t1' doesn't exist @@ -96,7 +96,7 @@ show warnings; Level Code Message Error 1939 Engine TEST_SQL_DISCOVERY failed to discover table `test`.`t1` with 'create table if not exists t1 (a int)' Error 1146 Table 'test.t1' doesn't exist -Error 1030 Got error 130 "Incorrect file format" from storage engine +Error 1030 Got error 130 "Incorrect file format" from storage engine TEST_SQL_DISCOVERY set @@test_sql_discovery_statement='t1:create table t1 (a int)'; select * from t1; a diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 88b07bbebe3..3a32cf95bc9 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -312,6 +312,7 @@ innobase_check_index_keys( } my_error(ER_WRONG_KEY_COLUMN, MYF(0), + field->table->file->table_type(), field->field_name); return(ER_WRONG_KEY_COLUMN); } @@ -326,6 +327,7 @@ innobase_check_index_keys( } my_error(ER_WRONG_KEY_COLUMN, MYF(0), + field->table->file->table_type(), key_part1.field->field_name); return(ER_WRONG_KEY_COLUMN); } From eda4c51241b647094b727643e1aad4153c45d647 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:14 +0200 Subject: [PATCH 308/324] cleanup --- sql/create_options.cc | 30 ++++++++++++++---------------- sql/create_options.h | 15 ++++++--------- sql/sql_plugin.cc | 11 ----------- 3 files changed, 20 insertions(+), 36 deletions(-) diff --git a/sql/create_options.cc b/sql/create_options.cc index 5cedfa03a63..47d3a2d06ea 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -74,7 +74,7 @@ void engine_option_value::link(engine_option_value **start, } static bool report_wrong_value(THD *thd, const char *name, const char *val, - my_bool suppress_warning) + bool suppress_warning) { if (suppress_warning) return 0; @@ -92,7 +92,7 @@ static bool report_wrong_value(THD *thd, const char *name, const char *val, } static bool report_unknown_option(THD *thd, engine_option_value *val, - my_bool suppress_warning) + bool suppress_warning) { DBUG_ENTER("report_unknown_option"); @@ -116,7 +116,7 @@ static bool report_unknown_option(THD *thd, engine_option_value *val, static bool set_one_value(ha_create_table_option *opt, THD *thd, LEX_STRING *value, void *base, - my_bool suppress_warning, + bool suppress_warning, MEM_ROOT *root) { DBUG_ENTER("set_one_value"); @@ -257,11 +257,10 @@ static const size_t ha_option_type_sizeof[]= @retval FALSE OK */ -my_bool parse_option_list(THD* thd, void *option_struct_arg, - engine_option_value *option_list, - ha_create_table_option *rules, - my_bool suppress_warning, - MEM_ROOT *root) +bool parse_option_list(THD* thd, void *option_struct_arg, + engine_option_value *option_list, + ha_create_table_option *rules, + bool suppress_warning, MEM_ROOT *root) { ha_create_table_option *opt; size_t option_struct_size= 0; @@ -269,13 +268,13 @@ my_bool parse_option_list(THD* thd, void *option_struct_arg, void **option_struct= (void**)option_struct_arg; DBUG_ENTER("parse_option_list"); DBUG_PRINT("enter", - ("struct: 0x%lx list: 0x%lx rules: 0x%lx suppres %u root 0x%lx", - (ulong) *option_struct, (ulong)option_list, (ulong)rules, - (uint) suppress_warning, (ulong) root)); + ("struct: %p list: %p rules: %p suppress_warning: %u root: %p", + *option_struct, option_list, rules, + (uint) suppress_warning, root)); if (rules) { - LEX_STRING default_val= {NULL, 0}; + LEX_STRING default_val= null_lex_str; for (opt= rules; opt->name; opt++) set_if_bigger(option_struct_size, opt->offset + ha_option_type_sizeof[opt->type]); @@ -323,8 +322,7 @@ my_bool parse_option_list(THD* thd, void *option_struct_arg, @retval FALSE OK */ -my_bool parse_engine_table_options(THD *thd, handlerton *ht, - TABLE_SHARE *share) +bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share) { MEM_ROOT *root= &share->mem_root; DBUG_ENTER("parse_engine_table_options"); @@ -543,8 +541,8 @@ uchar *engine_option_value::frm_read(const uchar *buff, engine_option_value **st @retval FALSE OK */ -my_bool engine_table_options_frm_read(const uchar *buff, uint length, - TABLE_SHARE *share) +bool engine_table_options_frm_read(const uchar *buff, uint length, + TABLE_SHARE *share) { const uchar *buff_end= buff + length; engine_option_value *UNINIT_VAR(end); diff --git a/sql/create_options.h b/sql/create_options.h index ae918f6cea1..5db826a3038 100644 --- a/sql/create_options.h +++ b/sql/create_options.h @@ -69,16 +69,13 @@ class engine_option_value: public Sql_alloc typedef struct st_key KEY; class Create_field; -my_bool parse_engine_table_options(THD *thd, handlerton *ht, +bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share); +bool parse_option_list(THD* thd, void *option_struct, + engine_option_value *option_list, + ha_create_table_option *rules, + bool suppress_warning, MEM_ROOT *root); +bool engine_table_options_frm_read(const uchar *buff, uint length, TABLE_SHARE *share); -my_bool parse_option_list(THD* thd, void *option_struct, - engine_option_value *option_list, - ha_create_table_option *rules, - my_bool suppress_warning, - MEM_ROOT *root); -my_bool engine_table_options_frm_read(const uchar *buff, - uint length, - TABLE_SHARE *share); engine_option_value *merge_engine_table_options(engine_option_value *source, engine_option_value *changes, MEM_ROOT *root); diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 2f9bcf92f6d..b19d6853164 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -3387,17 +3387,6 @@ static void plugin_opt_set_limits(struct my_option *options, options->arg_type= OPT_ARG; } -extern "C" my_bool get_one_plugin_option(int optid, const struct my_option *, - char *); - -my_bool get_one_plugin_option(int optid __attribute__((unused)), - const struct my_option *opt, - char *argument) -{ - return 0; -} - - /** Creates a set of my_option objects associated with a specified plugin- handle. From 7d3288129f6e5b52c7377ff68295f51606c7f002 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:19 +0200 Subject: [PATCH 309/324] create sys_var::val_str(), sys_var::val_int(), sys_var::val_real(). Change Item_func_get_system_var::val_xxx functions to use that. mysql-test/t/variables.test: @@GLOBAL.INIT_CONNECT is never NULL anymore. Nor it ever was. It was a bug that empty string system variables appeared as NULL in the *integer context* (but not in a string, real, or decimal context!) --- mysql-test/r/variables.result | 10 -- mysql-test/t/func_time.test | 2 + mysql-test/t/variables.test | 16 --- sql/item_func.cc | 180 +++------------------------------- sql/set_var.cc | 111 ++++++++++++++++++++- sql/set_var.h | 4 + 6 files changed, 127 insertions(+), 196 deletions(-) diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 6ec9d77230b..f280fce08d3 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1479,16 +1479,6 @@ SELECT @@GLOBAL.server_id; @@GLOBAL.server_id 0 SET GLOBAL server_id = @old_server_id; -SELECT @@GLOBAL.INIT_CONNECT, @@GLOBAL.INIT_CONNECT IS NULL; -@@GLOBAL.INIT_CONNECT @@GLOBAL.INIT_CONNECT IS NULL - 1 -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (); -SET @bug42778= @@sql_safe_updates; -SET @@sql_safe_updates= 0; -DELETE FROM t1 ORDER BY (@@GLOBAL.INIT_CONNECT) ASC LIMIT 10; -SET @@sql_safe_updates= @bug42778; -DROP TABLE t1; # # BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback # diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index f65681a6c5b..7a72c21d0ff 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -883,7 +883,9 @@ SELECT STR_TO_DATE(SPACE(2),'1'); --echo # SET GLOBAL SQL_MODE=''; +--disable_warnings DO STR_TO_DATE((''), FROM_DAYS(@@GLOBAL.SQL_MODE)); +--enable_warnings SET GLOBAL SQL_MODE=DEFAULT; --echo # diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 792859386e9..08e7e68c225 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1206,22 +1206,6 @@ SET GLOBAL server_id = -1; SELECT @@GLOBAL.server_id; SET GLOBAL server_id = @old_server_id; -# -# Bug #42778: delete order by null global variable causes -# assertion .\filesort.cc, line 797 -# - -SELECT @@GLOBAL.INIT_CONNECT, @@GLOBAL.INIT_CONNECT IS NULL; - -CREATE TABLE t1 (a INT); -INSERT INTO t1 VALUES (); -SET @bug42778= @@sql_safe_updates; -SET @@sql_safe_updates= 0; -DELETE FROM t1 ORDER BY (@@GLOBAL.INIT_CONNECT) ASC LIMIT 10; -SET @@sql_safe_updates= @bug42778; - -DROP TABLE t1; - --echo # --echo # BUG#10206 - InnoDB: Transaction requiring Max_BinLog_Cache_size > 4GB always rollsback --echo # diff --git a/sql/item_func.cc b/sql/item_func.cc index 2d27876df0b..5316f89e730 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -5668,24 +5668,6 @@ enum_field_types Item_func_get_system_var::field_type() const } -/* - Uses var, var_type, component, cache_present, used_query_id, thd, - cached_llval, null_value, cached_null_value -*/ -#define get_sys_var_safe(type) \ -do { \ - type value; \ - mysql_mutex_lock(&LOCK_global_system_variables); \ - value= *(type*) var->value_ptr(thd, var_type, &component); \ - mysql_mutex_unlock(&LOCK_global_system_variables); \ - cache_present |= GET_SYS_VAR_CACHE_LONG; \ - used_query_id= thd->query_id; \ - cached_llval= null_value ? 0 : (longlong) value; \ - cached_null_value= null_value; \ - return cached_llval; \ -} while (0) - - longlong Item_func_get_system_var::val_int() { THD *thd= current_thd; @@ -5719,51 +5701,11 @@ longlong Item_func_get_system_var::val_int() } } - switch (var->show_type()) - { - case SHOW_SINT: get_sys_var_safe (int); - case SHOW_SLONG: get_sys_var_safe (long); - case SHOW_SLONGLONG:get_sys_var_safe (longlong); - case SHOW_UINT: get_sys_var_safe (uint); - case SHOW_ULONG: get_sys_var_safe (ulong); - case SHOW_ULONGLONG:get_sys_var_safe (ulonglong); - case SHOW_HA_ROWS: get_sys_var_safe (ha_rows); - case SHOW_BOOL: get_sys_var_safe (bool); - case SHOW_MY_BOOL: get_sys_var_safe (my_bool); - case SHOW_DOUBLE: - { - double dval= val_real(); - - used_query_id= thd->query_id; - cached_llval= (longlong) dval; - cache_present|= GET_SYS_VAR_CACHE_LONG; - return cached_llval; - } - case SHOW_CHAR: - case SHOW_CHAR_PTR: - case SHOW_LEX_STRING: - { - String *str_val= val_str(NULL); - - if (str_val && str_val->length()) - cached_llval= longlong_from_string_with_check (system_charset_info, - str_val->c_ptr(), - str_val->c_ptr() + - str_val->length()); - else - { - null_value= TRUE; - cached_llval= 0; - } - - cache_present|= GET_SYS_VAR_CACHE_LONG; - return cached_llval; - } - - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - return 0; // keep the compiler happy - } + cached_llval= var->val_int(&null_value, thd, var_type, &component); + cache_present |= GET_SYS_VAR_CACHE_LONG; + used_query_id= thd->query_id; + cached_null_value= null_value; + return cached_llval; } @@ -5796,61 +5738,10 @@ String* Item_func_get_system_var::val_str(String* str) } } - str= &cached_strval; - switch (var->show_type()) - { - case SHOW_CHAR: - case SHOW_CHAR_PTR: - case SHOW_LEX_STRING: - { - mysql_mutex_lock(&LOCK_global_system_variables); - char *cptr= var->show_type() == SHOW_CHAR ? - (char*) var->value_ptr(thd, var_type, &component) : - *(char**) var->value_ptr(thd, var_type, &component); - if (cptr) - { - size_t len= var->show_type() == SHOW_LEX_STRING ? - ((LEX_STRING*)(var->value_ptr(thd, var_type, &component)))->length : - strlen(cptr); - if (str->copy(cptr, len, collation.collation)) - { - null_value= TRUE; - str= NULL; - } - } - else - { - null_value= TRUE; - str= NULL; - } - mysql_mutex_unlock(&LOCK_global_system_variables); - break; - } - - case SHOW_SINT: - case SHOW_SLONG: - case SHOW_SLONGLONG: - case SHOW_UINT: - case SHOW_ULONG: - case SHOW_ULONGLONG: - case SHOW_HA_ROWS: - case SHOW_BOOL: - case SHOW_MY_BOOL: - str->set (val_int(), collation.collation); - break; - case SHOW_DOUBLE: - str->set_real (val_real(), decimals, collation.collation); - break; - - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - str= NULL; - break; - } - + str= var->val_str(&cached_strval, thd, var_type, &component); cache_present|= GET_SYS_VAR_CACHE_STRING; used_query_id= thd->query_id; - cached_null_value= null_value; + cached_null_value= null_value= !str; return str; } @@ -5888,58 +5779,11 @@ double Item_func_get_system_var::val_real() } } - switch (var->show_type()) - { - case SHOW_DOUBLE: - mysql_mutex_lock(&LOCK_global_system_variables); - cached_dval= *(double*) var->value_ptr(thd, var_type, &component); - mysql_mutex_unlock(&LOCK_global_system_variables); - used_query_id= thd->query_id; - cached_null_value= null_value; - if (null_value) - cached_dval= 0; - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - return cached_dval; - case SHOW_CHAR: - case SHOW_LEX_STRING: - case SHOW_CHAR_PTR: - { - mysql_mutex_lock(&LOCK_global_system_variables); - char *cptr= var->show_type() == SHOW_CHAR ? - (char*) var->value_ptr(thd, var_type, &component) : - *(char**) var->value_ptr(thd, var_type, &component); - if (cptr) - cached_dval= double_from_string_with_check (system_charset_info, - cptr, cptr + strlen (cptr)); - else - { - null_value= TRUE; - cached_dval= 0; - } - mysql_mutex_unlock(&LOCK_global_system_variables); - used_query_id= thd->query_id; - cached_null_value= null_value; - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - return cached_dval; - } - case SHOW_SINT: - case SHOW_SLONG: - case SHOW_SLONGLONG: - case SHOW_UINT: - case SHOW_ULONG: - case SHOW_ULONGLONG: - case SHOW_HA_ROWS: - case SHOW_BOOL: - case SHOW_MY_BOOL: - cached_dval= (double) val_int(); - cache_present|= GET_SYS_VAR_CACHE_DOUBLE; - used_query_id= thd->query_id; - cached_null_value= null_value; - return cached_dval; - default: - my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name.str); - return 0; - } + cached_dval= var->val_real(&null_value, thd, var_type, &component); + cache_present |= GET_SYS_VAR_CACHE_DOUBLE; + used_query_id= thd->query_id; + cached_null_value= null_value; + return cached_dval; } diff --git a/sql/set_var.cc b/sql/set_var.cc index 2d3e0b7fec4..48f7cc7a054 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -257,8 +257,7 @@ uchar *sys_var::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base) bool sys_var::set_default(THD *thd, enum_var_type type) { - LEX_STRING empty={0,0}; - set_var var(type, this, &empty, 0); + set_var var(type, this, &null_lex_str, 0); if (type == OPT_GLOBAL || scope() == GLOBAL) global_save_default(thd, &var); @@ -268,6 +267,114 @@ bool sys_var::set_default(THD *thd, enum_var_type type) return check(thd, &var) || update(thd, &var); } + +#define do_num_val(T,CMD) \ +do { \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + T val= *(T*) value_ptr(thd, type, base); \ + mysql_mutex_unlock(&LOCK_global_system_variables); \ + CMD; \ +} while (0) + +#define case_for_integers(CMD) \ + case SHOW_SINT: do_num_val (int,CMD); \ + case SHOW_SLONG: do_num_val (long,CMD); \ + case SHOW_SLONGLONG:do_num_val (longlong,CMD); \ + case SHOW_UINT: do_num_val (uint,CMD); \ + case SHOW_ULONG: do_num_val (ulong,CMD); \ + case SHOW_ULONGLONG:do_num_val (ulonglong,CMD); \ + case SHOW_HA_ROWS: do_num_val (ha_rows,CMD); \ + case SHOW_BOOL: do_num_val (bool,CMD); \ + case SHOW_MY_BOOL: do_num_val (my_bool,CMD) + +#define case_for_double(CMD) \ + case SHOW_DOUBLE: do_num_val (double,CMD) + +#define case_get_string_as_lex_string \ + case SHOW_CHAR: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval.str= (char*) value_ptr(thd, type, base); \ + sval.length= sval.str ? strlen(sval.str) : 0; \ + break; \ + case SHOW_CHAR_PTR: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval.str= *(char**) value_ptr(thd, type, base); \ + sval.length= sval.str ? strlen(sval.str) : 0; \ + break; \ + case SHOW_LEX_STRING: \ + mysql_mutex_lock(&LOCK_global_system_variables); \ + sval= *(LEX_STRING *) value_ptr(thd, type, base); \ + break + +longlong sys_var::val_int(bool *is_null, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + *is_null= false; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return val); + case_for_double(return val); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + longlong ret= 0; + if (!(*is_null= !sval.str)) + ret= longlong_from_string_with_check(system_charset_info, + sval.str, sval.str + sval.length); + mysql_mutex_unlock(&LOCK_global_system_variables); + return ret; +} + + +String *sys_var::val_str(String *str, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return str->set((ulonglong)val, system_charset_info) ? 0 : str); + case_for_double(return str->set_real(val, 6, system_charset_info) ? 0 : str); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + if (!sval.str || str->copy(sval.str, sval.length, system_charset_info)) + str= NULL; + mysql_mutex_unlock(&LOCK_global_system_variables); + return str; +} + + +double sys_var::val_real(bool *is_null, + THD *thd, enum_var_type type, LEX_STRING *base) +{ + LEX_STRING sval; + *is_null= false; + switch (show_type()) + { + case_get_string_as_lex_string; + case_for_integers(return val); + case_for_double(return val); + default: + my_error(ER_VAR_CANT_BE_READ, MYF(0), name.str); + return 0; + } + + double ret= 0; + if (!(*is_null= !sval.str)) + ret= double_from_string_with_check(system_charset_info, + sval.str, sval.str + sval.length); + mysql_mutex_unlock(&LOCK_global_system_variables); + return ret; +} + + void sys_var::do_deprecated_warning(THD *thd) { if (deprecation_substitute != NULL) diff --git a/sql/set_var.h b/sql/set_var.h index f912c9fffad..6cb0cd33f87 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -108,6 +108,10 @@ public: bool set_default(THD *thd, enum_var_type type); bool update(THD *thd, set_var *var); + longlong val_int(bool *is_null, THD *thd, enum_var_type type, LEX_STRING *base); + String *val_str(String *str, THD *thd, enum_var_type type, LEX_STRING *base); + double val_real(bool *is_null, THD *thd, enum_var_type type, LEX_STRING *base); + SHOW_TYPE show_type() { return show_val_type; } int scope() const { return flags & SCOPE_MASK; } CHARSET_INFO *charset(THD *thd); From 5f293dd694f9b1b4a0bdf73bb6ae80cda70f21d4 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:24 +0200 Subject: [PATCH 310/324] MDEV-4022 table attributes with sysvar as a default value --- mysql-test/r/partition_example.result | 4 +- mysql-test/r/plugin.result | 36 ++++-- mysql-test/t/plugin.test | 11 ++ sql/create_options.cc | 175 +++++++++++++++++++++++--- sql/create_options.h | 6 +- sql/handler.cc | 6 +- sql/handler.h | 28 ++++- sql/sql_plugin.cc | 21 +++- sql/sql_plugin.h | 2 + sql/sql_table.cc | 12 +- storage/example/ha_example.cc | 10 ++ 11 files changed, 265 insertions(+), 46 deletions(-) diff --git a/mysql-test/r/partition_example.result b/mysql-test/r/partition_example.result index 2129eea0818..7b6e9aa5213 100644 --- a/mysql-test/r/partition_example.result +++ b/mysql-test/r/partition_example.result @@ -7,7 +7,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='5' /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1) ENGINE = EXAMPLE, PARTITION p1 VALUES IN (2) ENGINE = EXAMPLE) */ @@ -20,7 +20,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 `VAROPT`='5' /*!50100 PARTITION BY LIST (a) (PARTITION p0 VALUES IN (1) ENGINE = EXAMPLE, PARTITION p1 VALUES IN (2) ENGINE = EXAMPLE) */ diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index ac2ba843131..06e343a0886 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -49,6 +49,7 @@ show variables like 'example%'; Variable_name Value example_enum_var e1 example_ulong_var 500 +example_varopt_default 5 UNINSTALL SONAME 'ha_example'; Warnings: Warning 1620 Plugin is busy and will be uninstalled on shutdown @@ -119,7 +120,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,f,f,f' -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000 `STR`='dskj' `one_or_two`='one' `YESNO`=0 `VAROPT`='5' drop table t1; SET @OLD_SQL_MODE=@@SQL_MODE; SET SQL_MODE='IGNORE_BAD_TABLE_OPTIONS'; @@ -133,20 +134,20 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=10000000000000000000 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' #alter table alter table t1 ULL=10000000; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 alter table t1 change a a int complex='c,c,c'; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL `complex`='c,c,c' -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `ULL`=10000000 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `one_or_two`='ttt' `YESNO`=SSS `VAROPT`='5' `ULL`=10000000 drop table t1; #illegal value error SET SQL_MODE=''; @@ -161,17 +162,38 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=4660 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ULL`=4660 `VAROPT`='5' +SET example_varopt_default=33; select create_options from information_schema.tables where table_schema='test' and table_name='t1'; create_options -`ULL`=4660 +`ULL`=4660 `VAROPT`='5' ALTER TABLE t1 ULL=DEFAULT; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='5' DROP TABLE t1; +create table t1 (a int) engine=example; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='33' +drop table t1; +create table t1 (a int) engine=example varopt=15; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `varopt`=15 +alter table t1 varopt=default; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `VAROPT`='33' +drop table t1; SET @@SQL_MODE=@OLD_SQL_MODE; select 1; 1 diff --git a/mysql-test/t/plugin.test b/mysql-test/t/plugin.test index 71ca860e269..602b2e3c5c9 100644 --- a/mysql-test/t/plugin.test +++ b/mysql-test/t/plugin.test @@ -144,6 +144,7 @@ CREATE TABLE t1 (a int) ENGINE=example ULL=1e2; CREATE TABLE t1 (a int) ENGINE=example ULL=0x1234; SHOW CREATE TABLE t1; +SET example_varopt_default=33; # does not affect varopt of t1 select create_options from information_schema.tables where table_schema='test' and table_name='t1'; @@ -152,6 +153,16 @@ SHOW CREATE TABLE t1; DROP TABLE t1; +create table t1 (a int) engine=example; # varopt is 10 +show create table t1; +drop table t1; + +create table t1 (a int) engine=example varopt=15; +show create table t1; +alter table t1 varopt=default; +show create table t1; +drop table t1; + SET @@SQL_MODE=@OLD_SQL_MODE; # diff --git a/sql/create_options.cc b/sql/create_options.cc index 47d3a2d06ea..f12120bd0a1 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -21,6 +21,7 @@ #include "create_options.h" #include +#include "set_var.h" #define FRM_QUOTED_VALUE 0x8000 @@ -115,7 +116,7 @@ static bool report_unknown_option(THD *thd, engine_option_value *val, } static bool set_one_value(ha_create_table_option *opt, - THD *thd, LEX_STRING *value, void *base, + THD *thd, const LEX_STRING *value, void *base, bool suppress_warning, MEM_ROOT *root) { @@ -126,6 +127,8 @@ static bool set_one_value(ha_create_table_option *opt, (value->str ? value->str : ""))); switch (opt->type) { + case HA_OPTION_TYPE_SYSVAR: + DBUG_ASSERT(0); // HA_OPTION_TYPE_SYSVAR's are replaced in resolve_sysvars() case HA_OPTION_TYPE_ULL: { ulonglong *val= (ulonglong*)((char*)base + opt->offset); @@ -257,51 +260,92 @@ static const size_t ha_option_type_sizeof[]= @retval FALSE OK */ -bool parse_option_list(THD* thd, void *option_struct_arg, - engine_option_value *option_list, +bool parse_option_list(THD* thd, handlerton *hton, void *option_struct_arg, + engine_option_value **option_list, ha_create_table_option *rules, bool suppress_warning, MEM_ROOT *root) { ha_create_table_option *opt; size_t option_struct_size= 0; - engine_option_value *val= option_list; + engine_option_value *val, *last; void **option_struct= (void**)option_struct_arg; DBUG_ENTER("parse_option_list"); DBUG_PRINT("enter", ("struct: %p list: %p rules: %p suppress_warning: %u root: %p", - *option_struct, option_list, rules, + *option_struct, *option_list, rules, (uint) suppress_warning, root)); if (rules) { - LEX_STRING default_val= null_lex_str; for (opt= rules; opt->name; opt++) set_if_bigger(option_struct_size, opt->offset + ha_option_type_sizeof[opt->type]); *option_struct= alloc_root(root, option_struct_size); - - /* set all values to default */ - for (opt= rules; opt->name; opt++) - set_one_value(opt, thd, &default_val, *option_struct, - suppress_warning, root); } - for (; val; val= val->next) + for (opt= rules; opt && opt->name; opt++) { - for (opt= rules; opt && opt->name; opt++) + bool seen=false; + for (val= *option_list; val; val= val->next) { + last= val; if (my_strnncoll(system_charset_info, (uchar*)opt->name, opt->name_length, (uchar*)val->name.str, val->name.length)) continue; + seen=true; + + if (val->parsed && !val->value.str) + continue; + if (set_one_value(opt, thd, &val->value, *option_struct, suppress_warning || val->parsed, root)) DBUG_RETURN(TRUE); val->parsed= true; break; } + if (!seen) + { + LEX_STRING default_val= null_lex_str; + + /* + If it's CREATE/ALTER TABLE parsing mode (options are created in the + transient thd->mem_root, not in the long living TABLE_SHARE::mem_root), + and variable-backed option was not explicitly set. + + If it's not create, but opening of the existing frm (that was, + probably, created with the older version of the storage engine and + does not have this option stored), we take the *default* value of the + sysvar, not the *current* value. Because we don't want to have + different option values for the same table if it's opened many times. + */ + if (root == thd->mem_root && opt->var) + { + // take a value from the variable and add it to the list + sys_var *sysvar= find_hton_sysvar(hton, opt->var); + DBUG_ASSERT(sysvar); + + char buf[256]; + String sbuf(buf, sizeof(buf), system_charset_info), *str; + if ((str= sysvar->val_str(&sbuf, thd, OPT_SESSION, 0))) + { + LEX_STRING name= { const_cast(opt->name), opt->name_length }; + default_val.str= strmake_root(root, str->ptr(), str->length()); + default_val.length= str->length(); + val= new (root) engine_option_value(name, default_val, true, + option_list, &last); + val->parsed= true; + } + } + set_one_value(opt, thd, &default_val, *option_struct, + suppress_warning, root); + } + } + + for (val= *option_list; val; val= val->next) + { if (report_unknown_option(thd, val, suppress_warning)) DBUG_RETURN(TRUE); val->parsed= true; @@ -311,6 +355,102 @@ bool parse_option_list(THD* thd, void *option_struct_arg, } +/** + Resolves all HA_OPTION_TYPE_SYSVAR elements. + + This is done when an engine is loaded. +*/ +static bool resolve_sysvars(handlerton *hton, ha_create_table_option *rules) +{ + for (ha_create_table_option *opt= rules; opt && opt->name; opt++) + { + if (opt->type == HA_OPTION_TYPE_SYSVAR) + { + struct my_option optp; + plugin_opt_set_limits(&optp, opt->var); + switch(optp.var_type) { + case GET_ULL: + case GET_ULONG: + case GET_UINT: + opt->type= HA_OPTION_TYPE_ULL; + opt->def_value= (ulonglong)optp.def_value; + opt->min_value= (ulonglong)optp.min_value; + opt->max_value= (ulonglong)optp.max_value; + opt->block_size= (ulonglong)optp.block_size; + break; + case GET_STR: + case GET_STR_ALLOC: + opt->type= HA_OPTION_TYPE_STRING; + break; + case GET_BOOL: + opt->type= HA_OPTION_TYPE_BOOL; + opt->def_value= optp.def_value; + break; + case GET_ENUM: + { + opt->type= HA_OPTION_TYPE_ENUM; + opt->def_value= optp.def_value; + + char buf[256]; + String str(buf, sizeof(buf), system_charset_info); + for (const char **s= optp.typelib->type_names; *s; s++) + { + if (str.append(*s) || str.append(',')) + return 1; + } + DBUG_ASSERT(str.length()); + opt->values= my_strndup(str.ptr(), str.length()-1, MYF(MY_WME)); + if (!opt->values) + return 1; + break; + } + default: + DBUG_ASSERT(0); + } + } + } + return 0; +} + +bool resolve_sysvar_table_options(handlerton *hton) +{ + return resolve_sysvars(hton, hton->table_options) || + resolve_sysvars(hton, hton->field_options) || + resolve_sysvars(hton, hton->index_options); +} + +/* + Restore HA_OPTION_TYPE_SYSVAR options back as they were + before resolve_sysvars(). + + This is done when the engine is unloaded, so that we could + call resolve_sysvars() if the engine is installed again. +*/ +static void free_sysvars(handlerton *hton, ha_create_table_option *rules) +{ + for (ha_create_table_option *opt= rules; opt && opt->name; opt++) + { + if (opt->var) + { + my_free(const_cast(opt->values)); + opt->type= HA_OPTION_TYPE_SYSVAR; + opt->def_value= 0; + opt->min_value= 0; + opt->max_value= 0; + opt->block_size= 0; + opt->values= 0; + } + } +} + +void free_sysvar_table_options(handlerton *hton) +{ + free_sysvars(hton, hton->table_options); + free_sysvars(hton, hton->field_options); + free_sysvars(hton, hton->index_options); +} + + /** Parses all table/fields/keys options @@ -327,21 +467,22 @@ bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share) MEM_ROOT *root= &share->mem_root; DBUG_ENTER("parse_engine_table_options"); - if (parse_option_list(thd, &share->option_struct, share->option_list, + if (parse_option_list(thd, ht, &share->option_struct, & share->option_list, ht->table_options, TRUE, root)) DBUG_RETURN(TRUE); for (Field **field= share->field; *field; field++) { - if (parse_option_list(thd, &(*field)->option_struct, (*field)->option_list, + if (parse_option_list(thd, ht, &(*field)->option_struct, + & (*field)->option_list, ht->field_options, TRUE, root)) DBUG_RETURN(TRUE); } for (uint index= 0; index < share->keys; index ++) { - if (parse_option_list(thd, &share->key_info[index].option_struct, - share->key_info[index].option_list, + if (parse_option_list(thd, ht, &share->key_info[index].option_struct, + & share->key_info[index].option_list, ht->index_options, TRUE, root)) DBUG_RETURN(TRUE); } diff --git a/sql/create_options.h b/sql/create_options.h index 5db826a3038..ea05bf75fac 100644 --- a/sql/create_options.h +++ b/sql/create_options.h @@ -69,9 +69,11 @@ class engine_option_value: public Sql_alloc typedef struct st_key KEY; class Create_field; +bool resolve_sysvar_table_options(handlerton *hton); +void free_sysvar_table_options(handlerton *hton); bool parse_engine_table_options(THD *thd, handlerton *ht, TABLE_SHARE *share); -bool parse_option_list(THD* thd, void *option_struct, - engine_option_value *option_list, +bool parse_option_list(THD* thd, handlerton *hton, void *option_struct, + engine_option_value **option_list, ha_create_table_option *rules, bool suppress_warning, MEM_ROOT *root); bool engine_table_options_frm_read(const uchar *buff, uint length, diff --git a/sql/handler.cc b/sql/handler.cc index f094ff7bebb..2061b92c4e4 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -448,6 +448,9 @@ int ha_finalize_handlerton(st_plugin_int *plugin) } } + free_sysvar_table_options(hton); + update_discovery_counters(hton, -1); + /* In case a plugin is uninstalled and re-installed later, it should reuse an array slot. Otherwise the number of uninstall/install @@ -461,8 +464,6 @@ int ha_finalize_handlerton(st_plugin_int *plugin) hton2plugin[hton->slot]= NULL; } - update_discovery_counters(hton, -1); - my_free(hton); end: @@ -603,6 +604,7 @@ int ha_initialize_handlerton(st_plugin_int *plugin) break; }; + resolve_sysvar_table_options(hton); update_discovery_counters(hton, 1); DBUG_RETURN(0); diff --git a/sql/handler.h b/sql/handler.h index 2290b8f37fd..12f6b8808b3 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -714,22 +714,26 @@ struct ha_index_option_struct; enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ HA_OPTION_TYPE_STRING, /* char * */ HA_OPTION_TYPE_ENUM, /* uint */ - HA_OPTION_TYPE_BOOL}; /* bool */ + HA_OPTION_TYPE_BOOL, /* bool */ + HA_OPTION_TYPE_SYSVAR};/* type of the sysval */ #define HA_xOPTION_NUMBER(name, struc, field, def, min, max, blk_siz) \ { HA_OPTION_TYPE_ULL, name, sizeof(name)-1, \ - offsetof(struc, field), def, min, max, blk_siz, 0 } + offsetof(struc, field), def, min, max, blk_siz, 0, 0 } #define HA_xOPTION_STRING(name, struc, field) \ { HA_OPTION_TYPE_STRING, name, sizeof(name)-1, \ - offsetof(struc, field), 0, 0, 0, 0, 0 } + offsetof(struc, field), 0, 0, 0, 0, 0, 0} #define HA_xOPTION_ENUM(name, struc, field, values, def) \ { HA_OPTION_TYPE_ENUM, name, sizeof(name)-1, \ offsetof(struc, field), def, 0, \ - sizeof(values)-1, 0, values } + sizeof(values)-1, 0, values, 0 } #define HA_xOPTION_BOOL(name, struc, field, def) \ { HA_OPTION_TYPE_BOOL, name, sizeof(name)-1, \ - offsetof(struc, field), def, 0, 1, 0, 0 } -#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0 } + offsetof(struc, field), def, 0, 1, 0, 0, 0 } +#define HA_xOPTION_SYSVAR(name, struc, field, sysvar) \ + { HA_OPTION_TYPE_SYSVAR, name, sizeof(name)-1, \ + offsetof(struc, field), 0, 0, 0, 0, 0, MYSQL_SYSVAR(sysvar) } +#define HA_xOPTION_END { HA_OPTION_TYPE_ULL, 0, 0, 0, 0, 0, 0, 0, 0, 0 } #define HA_TOPTION_NUMBER(name, field, def, min, max, blk_siz) \ HA_xOPTION_NUMBER(name, ha_table_option_struct, field, def, min, max, blk_siz) @@ -739,6 +743,8 @@ enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ HA_xOPTION_ENUM(name, ha_table_option_struct, field, values, def) #define HA_TOPTION_BOOL(name, field, def) \ HA_xOPTION_BOOL(name, ha_table_option_struct, field, def) +#define HA_TOPTION_SYSVAR(name, field, sysvar) \ + HA_xOPTION_SYSVAR(name, ha_table_option_struct, field, sysvar) #define HA_TOPTION_END HA_xOPTION_END #define HA_FOPTION_NUMBER(name, field, def, min, max, blk_siz) \ @@ -749,6 +755,8 @@ enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ HA_xOPTION_ENUM(name, ha_field_option_struct, field, values, def) #define HA_FOPTION_BOOL(name, field, def) \ HA_xOPTION_BOOL(name, ha_field_option_struct, field, def) +#define HA_FOPTION_SYSVAR(name, field, sysvar) \ + HA_xOPTION_SYSVAR(name, ha_field_option_struct, field, sysvar) #define HA_FOPTION_END HA_xOPTION_END #define HA_IOPTION_NUMBER(name, field, def, min, max, blk_siz) \ @@ -759,6 +767,8 @@ enum ha_option_type { HA_OPTION_TYPE_ULL, /* unsigned long long */ HA_xOPTION_ENUM(name, ha_index_option_struct, field, values, def) #define HA_IOPTION_BOOL(name, field, values, def) \ HA_xOPTION_BOOL(name, ha_index_option_struct, field, values, def) +#define HA_IOPTION_SYSVAR(name, field, sysvar) \ + HA_xOPTION_SYSVAR(name, ha_index_option_struct, field, sysvar) #define HA_IOPTION_END HA_xOPTION_END typedef struct st_ha_create_table_option { @@ -769,6 +779,7 @@ typedef struct st_ha_create_table_option { ulonglong def_value; ulonglong min_value, max_value, block_size; const char *values; + struct st_mysql_sys_var *var; } ha_create_table_option; enum handler_iterator_type @@ -1197,6 +1208,11 @@ static inline LEX_STRING *hton_name(const handlerton *hton) return &(hton2plugin[hton->slot]->name); } +static inline sys_var *find_hton_sysvar(handlerton *hton, st_mysql_sys_var *var) +{ + return find_plugin_sysvar(hton2plugin[hton->slot], var); +} + /* Possible flags of a handlerton (there can be 32 of them) */ #define HTON_NO_FLAGS 0 diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index b19d6853164..6cf1050998b 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -308,8 +308,6 @@ static void unlock_variables(THD *thd, struct system_variables *vars); static void cleanup_variables(THD *thd, struct system_variables *vars); static void plugin_vars_free_values(sys_var *vars); static void restore_pluginvar_names(sys_var *first); -static void plugin_opt_set_limits(struct my_option *, - const struct st_mysql_sys_var *); static plugin_ref intern_plugin_lock(LEX *lex, plugin_ref plugin); static void intern_plugin_unlock(LEX *lex, plugin_ref plugin); static void reap_plugins(void); @@ -3286,8 +3284,8 @@ bool sys_var_pluginvar::global_update(THD *thd, set_var *var) options->block_size= (long) (opt)->blk_sz -static void plugin_opt_set_limits(struct my_option *options, - const struct st_mysql_sys_var *opt) +void plugin_opt_set_limits(struct my_option *options, + const struct st_mysql_sys_var *opt) { options->sub_size= 0; @@ -3866,3 +3864,18 @@ void add_plugin_options(DYNAMIC_ARRAY *options, MEM_ROOT *mem_root) } } + +/** + Returns a sys_var corresponding to a particular MYSQL_SYSVAR(...) +*/ +sys_var *find_plugin_sysvar(st_plugin_int *plugin, st_mysql_sys_var *plugin_var) +{ + for (sys_var *var= plugin->system_vars; var; var= var->next) + { + sys_var_pluginvar *pvar=var->cast_pluginvar(); + if (pvar->plugin_var == plugin_var) + return var; + } + return 0; +} + diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index d3c41a1e17b..bf4dbef6fc8 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -163,6 +163,8 @@ extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, extern bool plugin_register_builtin(struct st_mysql_plugin *plugin); extern void plugin_thdvar_init(THD *thd); extern void plugin_thdvar_cleanup(THD *thd); +sys_var *find_plugin_sysvar(st_plugin_int *plugin, st_mysql_sys_var *var); +void plugin_opt_set_limits(struct my_option *, const struct st_mysql_sys_var *); extern SHOW_COMP_OPTION plugin_status(const char *name, size_t len, int type); extern bool check_valid_path(const char *path, size_t length); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index dd00d921b6e..39c297fb5a2 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3224,8 +3224,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->offset= record_offset; if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER) auto_increment++; - if (parse_option_list(thd, &sql_field->option_struct, - sql_field->option_list, + if (parse_option_list(thd, create_info->db_type, &sql_field->option_struct, + &sql_field->option_list, create_info->db_type->field_options, FALSE, thd->mem_root)) DBUG_RETURN(TRUE); @@ -3427,8 +3427,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_info->usable_key_parts= key_number; key_info->algorithm= key->key_create_info.algorithm; key_info->option_list= key->option_list; - if (parse_option_list(thd, &key_info->option_struct, - key_info->option_list, + if (parse_option_list(thd, create_info->db_type, &key_info->option_struct, + &key_info->option_list, create_info->db_type->index_options, FALSE, thd->mem_root)) DBUG_RETURN(TRUE); @@ -3874,8 +3874,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, file->engine_name()->str, "TRANSACTIONAL=1"); - if (parse_option_list(thd, &create_info->option_struct, - create_info->option_list, + if (parse_option_list(thd, file->partition_ht(), &create_info->option_struct, + &create_info->option_list, file->partition_ht()->table_options, FALSE, thd->mem_root)) DBUG_RETURN(TRUE); diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index dac1ff81c10..bcf934b6b1c 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -118,6 +118,8 @@ static HASH example_open_tables; /* The mutex used to init the hash; variable for example share methods */ mysql_mutex_t example_mutex; +static MYSQL_THDVAR_ULONG(varopt_default, PLUGIN_VAR_RQCMDARG, + "default value of the VAROPT table option", NULL, NULL, 5, 0, 100, 0); /** Structure for CREATE TABLE options (table options). @@ -133,6 +135,7 @@ struct ha_table_option_struct ulonglong ullparam; uint enumparam; bool boolparam; + ulonglong varparam; }; @@ -179,6 +182,12 @@ ha_create_table_option example_table_option_list[]= The default is 1, that is true, yes, on. */ HA_TOPTION_BOOL("YESNO", boolparam, 1), + /* + one option defined by the system variable. The type, the range, or + a list of allowed values is the same as for the system variable. + */ + HA_TOPTION_SYSVAR("VAROPT", varparam, varopt_default), + HA_TOPTION_END }; @@ -1089,6 +1098,7 @@ static MYSQL_SYSVAR_ULONG( static struct st_mysql_sys_var* example_system_variables[]= { MYSQL_SYSVAR(enum_var), MYSQL_SYSVAR(ulong_var), + MYSQL_SYSVAR(varopt_default), NULL }; From c7eead7a965b33fbad5099c927d2bb0723725bf3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:29 +0200 Subject: [PATCH 311/324] MDEV-3807 show plugins soname 'xxx' and INFORMATION_SCHEMA.ALL_PLUGINS table with condition pushdown for I_S.ALL_PLUGINS and a new status variable to cound successful dlopen's --- mysql-test/r/information_schema-big.result | 2 + mysql-test/r/information_schema.result | 4 +- .../r/information_schema_all_engines.result | 10 +- .../suite/funcs_1/r/is_columns_is.result | 30 +++++- .../funcs_1/r/is_columns_is_embedded.result | 30 +++++- .../suite/funcs_1/r/is_tables_is.result | 46 +++++++++ .../funcs_1/r/is_tables_is_embedded.result | 46 +++++++++ .../suite/plugins/r/show_all_plugins.result | 35 +++++++ .../suite/plugins/t/show_all_plugins.test | 22 +++++ .../suite/rpl/r/rpl_table_options.result | 2 +- .../t/information_schema_all_engines.test | 2 +- sql/handler.h | 1 + sql/mysqld.cc | 11 ++- sql/sql_plugin.cc | 74 ++++++++++++++- sql/sql_plugin.h | 4 + sql/sql_show.cc | 93 +++++++++++++++++-- sql/sql_yacc.yy | 14 +++ 17 files changed, 402 insertions(+), 24 deletions(-) create mode 100644 mysql-test/suite/plugins/r/show_all_plugins.result create mode 100644 mysql-test/suite/plugins/t/show_all_plugins.test diff --git a/mysql-test/r/information_schema-big.result b/mysql-test/r/information_schema-big.result index 3d4fa27859d..c0016a8e5c3 100644 --- a/mysql-test/r/information_schema-big.result +++ b/mysql-test/r/information_schema-big.result @@ -36,6 +36,7 @@ KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARAMETERS SPECIFIC_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME +ALL_PLUGINS PLUGIN_NAME PROCESSLIST ID PROFILING QUERY_ID REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA @@ -88,6 +89,7 @@ KEY_COLUMN_USAGE CONSTRAINT_SCHEMA PARAMETERS SPECIFIC_SCHEMA PARTITIONS TABLE_SCHEMA PLUGINS PLUGIN_NAME +ALL_PLUGINS PLUGIN_NAME PROCESSLIST ID PROFILING QUERY_ID REFERENTIAL_CONSTRAINTS CONSTRAINT_SCHEMA diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index a30fe668490..a7051f275d7 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -46,6 +46,7 @@ table_name not like 'ndb_%' AND table_name not like 'innodb_%' AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%'; select * from v1; c +ALL_PLUGINS CHARACTER_SETS CLIENT_STATISTICS COLLATIONS @@ -802,6 +803,7 @@ information_schema PARTITIONS PARTITION_EXPRESSION information_schema PARTITIONS SUBPARTITION_EXPRESSION information_schema PARTITIONS PARTITION_DESCRIPTION information_schema PLUGINS PLUGIN_DESCRIPTION +information_schema ALL_PLUGINS PLUGIN_DESCRIPTION information_schema PROCESSLIST INFO information_schema ROUTINES DTD_IDENTIFIER information_schema ROUTINES ROUTINE_DEFINITION @@ -1180,7 +1182,7 @@ group by column_type order by num; column_type group_concat(table_schema, '.', table_name) num varchar(27) information_schema.COLUMNS 1 varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2 -varchar(20) information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PROFILING 6 +varchar(20) information_schema.FILES,information_schema.FILES,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.PLUGINS,information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.ALL_PLUGINS,information_schema.PROFILING 9 create table t1(f1 char(1) not null, f2 char(9) not null) default character set utf8; select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from diff --git a/mysql-test/r/information_schema_all_engines.result b/mysql-test/r/information_schema_all_engines.result index 455f2e36ffc..8b1aff8a209 100644 --- a/mysql-test/r/information_schema_all_engines.result +++ b/mysql-test/r/information_schema_all_engines.result @@ -1,6 +1,7 @@ use INFORMATION_SCHEMA; show tables; Tables_in_information_schema +ALL_PLUGINS CHARACTER_SETS CLIENT_STATISTICS COLLATIONS @@ -74,6 +75,7 @@ c2.table_name = t.table_name AND c2.column_name LIKE '%SCHEMA%' ) order by t.table_name; table_name column_name +ALL_PLUGINS PLUGIN_NAME CHARACTER_SETS CHARACTER_SET_NAME CLIENT_STATISTICS CLIENT COLLATIONS COLLATION_NAME @@ -147,6 +149,7 @@ c2.table_name = t.table_name AND c2.column_name LIKE '%SCHEMA%' ) order by t.table_name; table_name column_name +ALL_PLUGINS PLUGIN_NAME CHARACTER_SETS CHARACTER_SET_NAME CLIENT_STATISTICS CLIENT COLLATIONS COLLATION_NAME @@ -205,7 +208,7 @@ USER_PRIVILEGES GRANTEE USER_STATISTICS USER VIEWS TABLE_SCHEMA XTRADB_ADMIN_COMMAND result_message -select 1 as f1 from information_schema.tables where "CHARACTER_SETS"= +select 1 as f1 from information_schema.tables where "ALL_PLUGINS"= (select cast(table_name as char) from information_schema.tables order by table_name limit 1) limit 1; f1 @@ -226,6 +229,7 @@ c2.table_schema='information_schema' and group by c2.column_type order by num limit 1) group by t.table_name order by num1, t.table_name; table_name group_concat(t.table_schema, '.', t.table_name) num1 +ALL_PLUGINS information_schema.ALL_PLUGINS 1 CHARACTER_SETS information_schema.CHARACTER_SETS 1 CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1 COLLATIONS information_schema.COLLATIONS 1 @@ -288,6 +292,7 @@ VIEWS information_schema.VIEWS 1 +---------------------------------------+ Database: information_schema | Tables | +| ALL_PLUGINS | | CHARACTER_SETS | | CLIENT_STATISTICS | | COLLATIONS | @@ -351,6 +356,7 @@ Database: information_schema +---------------------------------------+ Database: INFORMATION_SCHEMA | Tables | +| ALL_PLUGINS | | CHARACTER_SETS | | CLIENT_STATISTICS | | COLLATIONS | @@ -417,5 +423,5 @@ Wildcard: inf_rmation_schema | information_schema | SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 58 +information_schema 59 mysql 26 diff --git a/mysql-test/suite/funcs_1/r/is_columns_is.result b/mysql-test/suite/funcs_1/r/is_columns_is.result index e161e8ed058..8bf290ba168 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is.result @@ -3,6 +3,19 @@ WHERE table_schema = 'information_schema' AND table_name <> 'profiling' AND table_name not like 'innodb_%' ORDER BY table_schema, table_name, column_name; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT +def information_schema ALL_PLUGINS LOAD_OPTION 11 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ALL_PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ALL_PLUGINS PLUGIN_AUTH_VERSION 13 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select +def information_schema ALL_PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext select +def information_schema ALL_PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ALL_PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select +def information_schema ALL_PLUGINS PLUGIN_LICENSE 10 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select +def information_schema ALL_PLUGINS PLUGIN_MATURITY 12 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select +def information_schema ALL_PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select +def information_schema ALL_PLUGINS PLUGIN_STATUS 3 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select +def information_schema ALL_PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select +def information_schema ALL_PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select +def information_schema ALL_PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) select def information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) select @@ -215,7 +228,7 @@ def information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 N def information_schema PLUGINS PLUGIN_LICENSE 10 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select def information_schema PLUGINS PLUGIN_MATURITY 12 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) select def information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) select -def information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) select +def information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) select def information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) select def information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select def information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) select @@ -473,6 +486,19 @@ WHERE table_schema = 'information_schema' AND table_name <> 'profiling' AND table_name not like 'innodb_%' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION; COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE +3.0000 information_schema ALL_PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_STATUS varchar 16 48 utf8 utf8_general_ci varchar(16) +3.0000 information_schema ALL_PLUGINS PLUGIN_TYPE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema ALL_PLUGINS PLUGIN_TYPE_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_LIBRARY varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_LIBRARY_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64) +1.0000 information_schema ALL_PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext +3.0000 information_schema ALL_PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema ALL_PLUGINS LOAD_OPTION varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_MATURITY varchar 12 36 utf8 utf8_general_ci varchar(12) +3.0000 information_schema ALL_PLUGINS PLUGIN_AUTH_VERSION varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema CHARACTER_SETS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60) @@ -678,7 +704,7 @@ NULL information_schema PARTITIONS CHECKSUM bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema PARTITIONS TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) -3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 10 30 utf8 utf8_general_ci varchar(10) +3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 16 48 utf8 utf8_general_ci varchar(16) 3.0000 information_schema PLUGINS PLUGIN_TYPE varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema PLUGINS PLUGIN_TYPE_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) 3.0000 information_schema PLUGINS PLUGIN_LIBRARY varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result index 003f506fee8..ba5166691c1 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_is_embedded.result @@ -4,6 +4,19 @@ AND table_name <> 'profiling' AND table_name not like 'innodb_%' AND table_name not like 'pbxt_%' ORDER BY table_schema, table_name, column_name; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT +def information_schema ALL_PLUGINS LOAD_OPTION 11 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) +def information_schema ALL_PLUGINS PLUGIN_AUTHOR 8 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) +def information_schema ALL_PLUGINS PLUGIN_AUTH_VERSION 13 NULL YES varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) +def information_schema ALL_PLUGINS PLUGIN_DESCRIPTION 9 NULL YES longtext 4294967295 4294967295 NULL NULL NULL utf8 utf8_general_ci longtext +def information_schema ALL_PLUGINS PLUGIN_LIBRARY 6 NULL YES varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) +def information_schema ALL_PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) +def information_schema ALL_PLUGINS PLUGIN_LICENSE 10 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) +def information_schema ALL_PLUGINS PLUGIN_MATURITY 12 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) +def information_schema ALL_PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) +def information_schema ALL_PLUGINS PLUGIN_STATUS 3 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) +def information_schema ALL_PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) +def information_schema ALL_PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) +def information_schema ALL_PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) def information_schema CHARACTER_SETS CHARACTER_SET_NAME 1 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) def information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME 2 NO varchar 32 96 NULL NULL NULL utf8 utf8_general_ci varchar(32) def information_schema CHARACTER_SETS DESCRIPTION 3 NO varchar 60 180 NULL NULL NULL utf8 utf8_general_ci varchar(60) @@ -216,7 +229,7 @@ def information_schema PLUGINS PLUGIN_LIBRARY_VERSION 7 NULL YES varchar 20 60 N def information_schema PLUGINS PLUGIN_LICENSE 10 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) def information_schema PLUGINS PLUGIN_MATURITY 12 NO varchar 12 36 NULL NULL NULL utf8 utf8_general_ci varchar(12) def information_schema PLUGINS PLUGIN_NAME 1 NO varchar 64 192 NULL NULL NULL utf8 utf8_general_ci varchar(64) -def information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 10 30 NULL NULL NULL utf8 utf8_general_ci varchar(10) +def information_schema PLUGINS PLUGIN_STATUS 3 NO varchar 16 48 NULL NULL NULL utf8 utf8_general_ci varchar(16) def information_schema PLUGINS PLUGIN_TYPE 4 NO varchar 80 240 NULL NULL NULL utf8 utf8_general_ci varchar(80) def information_schema PLUGINS PLUGIN_TYPE_VERSION 5 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) def information_schema PLUGINS PLUGIN_VERSION 2 NO varchar 20 60 NULL NULL NULL utf8 utf8_general_ci varchar(20) @@ -478,6 +491,19 @@ AND table_name <> 'profiling' AND table_name not like 'innodb_%' AND table_name not like 'pbxt_%' ORDER BY TABLE_SCHEMA, TABLE_NAME, ORDINAL_POSITION; COL_CML TABLE_SCHEMA TABLE_NAME COLUMN_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE +3.0000 information_schema ALL_PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_STATUS varchar 16 48 utf8 utf8_general_ci varchar(16) +3.0000 information_schema ALL_PLUGINS PLUGIN_TYPE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema ALL_PLUGINS PLUGIN_TYPE_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_LIBRARY varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_LIBRARY_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) +3.0000 information_schema ALL_PLUGINS PLUGIN_AUTHOR varchar 64 192 utf8 utf8_general_ci varchar(64) +1.0000 information_schema ALL_PLUGINS PLUGIN_DESCRIPTION longtext 4294967295 4294967295 utf8 utf8_general_ci longtext +3.0000 information_schema ALL_PLUGINS PLUGIN_LICENSE varchar 80 240 utf8 utf8_general_ci varchar(80) +3.0000 information_schema ALL_PLUGINS LOAD_OPTION varchar 64 192 utf8 utf8_general_ci varchar(64) +3.0000 information_schema ALL_PLUGINS PLUGIN_MATURITY varchar 12 36 utf8 utf8_general_ci varchar(12) +3.0000 information_schema ALL_PLUGINS PLUGIN_AUTH_VERSION varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema CHARACTER_SETS CHARACTER_SET_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DEFAULT_COLLATE_NAME varchar 32 96 utf8 utf8_general_ci varchar(32) 3.0000 information_schema CHARACTER_SETS DESCRIPTION varchar 60 180 utf8 utf8_general_ci varchar(60) @@ -683,7 +709,7 @@ NULL information_schema PARTITIONS CHECKSUM bigint NULL NULL NULL NULL bigint(21 3.0000 information_schema PARTITIONS TABLESPACE_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PLUGINS PLUGIN_NAME varchar 64 192 utf8 utf8_general_ci varchar(64) 3.0000 information_schema PLUGINS PLUGIN_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) -3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 10 30 utf8 utf8_general_ci varchar(10) +3.0000 information_schema PLUGINS PLUGIN_STATUS varchar 16 48 utf8 utf8_general_ci varchar(16) 3.0000 information_schema PLUGINS PLUGIN_TYPE varchar 80 240 utf8 utf8_general_ci varchar(80) 3.0000 information_schema PLUGINS PLUGIN_TYPE_VERSION varchar 20 60 utf8 utf8_general_ci varchar(20) 3.0000 information_schema PLUGINS PLUGIN_LIBRARY varchar 64 192 utf8 utf8_general_ci varchar(64) diff --git a/mysql-test/suite/funcs_1/r/is_tables_is.result b/mysql-test/suite/funcs_1/r/is_tables_is.result index 6aa2e3bb93d..6e92285dbaf 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is.result @@ -16,6 +16,29 @@ AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%' ORDER BY table_schema,table_name; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ALL_PLUGINS +TABLE_TYPE SYSTEM VIEW +ENGINE MYISAM_OR_MARIA +VERSION 10 +ROW_FORMAT DYNAMIC_OR_PAGE +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -816,6 +839,29 @@ AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%' ORDER BY table_schema,table_name; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ALL_PLUGINS +TABLE_TYPE SYSTEM VIEW +ENGINE MYISAM_OR_MARIA +VERSION 10 +ROW_FORMAT DYNAMIC_OR_PAGE +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY diff --git a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result index 6aa2e3bb93d..6e92285dbaf 100644 --- a/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_tables_is_embedded.result @@ -16,6 +16,29 @@ AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%' ORDER BY table_schema,table_name; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ALL_PLUGINS +TABLE_TYPE SYSTEM VIEW +ENGINE MYISAM_OR_MARIA +VERSION 10 +ROW_FORMAT DYNAMIC_OR_PAGE +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY @@ -816,6 +839,29 @@ AND table_name not like 'pbxt_%' AND table_name not like 'xtradb_%' ORDER BY table_schema,table_name; TABLE_CATALOG def TABLE_SCHEMA information_schema +TABLE_NAME ALL_PLUGINS +TABLE_TYPE SYSTEM VIEW +ENGINE MYISAM_OR_MARIA +VERSION 10 +ROW_FORMAT DYNAMIC_OR_PAGE +TABLE_ROWS #TBLR# +AVG_ROW_LENGTH #ARL# +DATA_LENGTH #DL# +MAX_DATA_LENGTH #MDL# +INDEX_LENGTH #IL# +DATA_FREE #DF# +AUTO_INCREMENT NULL +CREATE_TIME #CRT# +UPDATE_TIME #UT# +CHECK_TIME #CT# +TABLE_COLLATION utf8_general_ci +CHECKSUM NULL +CREATE_OPTIONS #CO# +TABLE_COMMENT #TC# +user_comment +Separator ----------------------------------------------------- +TABLE_CATALOG def +TABLE_SCHEMA information_schema TABLE_NAME CHARACTER_SETS TABLE_TYPE SYSTEM VIEW ENGINE MEMORY diff --git a/mysql-test/suite/plugins/r/show_all_plugins.result b/mysql-test/suite/plugins/r/show_all_plugins.result new file mode 100644 index 00000000000..8b9a41e0e1f --- /dev/null +++ b/mysql-test/suite/plugins/r/show_all_plugins.result @@ -0,0 +1,35 @@ +flush status; +show status like '%libraries%'; +Variable_name Value +Opened_plugin_libraries 0 +select * from information_schema.all_plugins where plugin_library='ha_example.so'; +PLUGIN_NAME PLUGIN_VERSION PLUGIN_STATUS PLUGIN_TYPE PLUGIN_TYPE_VERSION PLUGIN_LIBRARY PLUGIN_LIBRARY_VERSION PLUGIN_AUTHOR PLUGIN_DESCRIPTION PLUGIN_LICENSE LOAD_OPTION PLUGIN_MATURITY PLUGIN_AUTH_VERSION +EXAMPLE 0.1 NOT INSTALLED STORAGE ENGINE 100001.0 ha_example.so 1.4 Brian Aker, MySQL AB Example storage engine GPL OFF Experimental 0.1 +UNUSABLE 3.14 NOT INSTALLED DAEMON 100001.0 ha_example.so 1.4 Sergei Golubchik Unusable Daemon GPL OFF Experimental 3.14.15.926 +show status like '%libraries%'; +Variable_name Value +Opened_plugin_libraries 1 +show plugins soname 'ha_example.so'; +Name Status Type Library License +EXAMPLE NOT INSTALLED STORAGE ENGINE ha_example.so GPL +UNUSABLE NOT INSTALLED DAEMON ha_example.so GPL +show status like '%libraries%'; +Variable_name Value +Opened_plugin_libraries 2 +show plugins soname like '%example%'; +Name Status Type Library License +EXAMPLE NOT INSTALLED STORAGE ENGINE ha_example.so GPL +UNUSABLE NOT INSTALLED DAEMON ha_example.so GPL +daemon_example NOT INSTALLED DAEMON libdaemon_example.so GPL +three_attempts NOT INSTALLED AUTHENTICATION dialog_examples.so GPL +two_questions NOT INSTALLED AUTHENTICATION dialog_examples.so GPL +show status like '%libraries%'; +Variable_name Value +Opened_plugin_libraries 6 +show plugins soname where library = 'ha_example.so'; +Name Status Type Library License +EXAMPLE NOT INSTALLED STORAGE ENGINE ha_example.so GPL +UNUSABLE NOT INSTALLED DAEMON ha_example.so GPL +select variable_value > 10 from information_schema.global_status where variable_name like '%libraries%'; +variable_value > 10 +1 diff --git a/mysql-test/suite/plugins/t/show_all_plugins.test b/mysql-test/suite/plugins/t/show_all_plugins.test new file mode 100644 index 00000000000..dcc0fb09bd3 --- /dev/null +++ b/mysql-test/suite/plugins/t/show_all_plugins.test @@ -0,0 +1,22 @@ +if (!$DIALOG_EXAMPLES_SO) { skip requires dialog_examples.so; } +if (!$HA_EXAMPLE_SO) { skip requires ha_examples.so; } +if (!$LIBDAEMON_EXAMPLE_SO) { skip requires libdaemon_examples.so; } +if (!$UDF_EXAMPLE_SO) { skip requires udf_example.so; } + +flush status; +show status like '%libraries%'; +#--sorted_result +#select * from information_schema.all_plugins; +#show status like '%libraries%'; +select * from information_schema.all_plugins where plugin_library='ha_example.so'; +show status like '%libraries%'; +--sorted_result +show plugins soname 'ha_example.so'; +show status like '%libraries%'; +--sorted_result +show plugins soname like '%example%'; +show status like '%libraries%'; +--sorted_result +show plugins soname where library = 'ha_example.so'; +select variable_value > 10 from information_schema.global_status where variable_name like '%libraries%'; + diff --git a/mysql-test/suite/rpl/r/rpl_table_options.result b/mysql-test/suite/rpl/r/rpl_table_options.result index 423a2b65583..d69570a1709 100644 --- a/mysql-test/suite/rpl/r/rpl_table_options.result +++ b/mysql-test/suite/rpl/r/rpl_table_options.result @@ -7,7 +7,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL -) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 +) ENGINE=EXAMPLE DEFAULT CHARSET=latin1 `ull`=12340 `VAROPT`='5' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/t/information_schema_all_engines.test b/mysql-test/t/information_schema_all_engines.test index 553367d2b9a..73ed00376ab 100644 --- a/mysql-test/t/information_schema_all_engines.test +++ b/mysql-test/t/information_schema_all_engines.test @@ -49,7 +49,7 @@ SELECT t.table_name, c1.column_name # # Bug#24630 Subselect query crashes mysqld # -select 1 as f1 from information_schema.tables where "CHARACTER_SETS"= +select 1 as f1 from information_schema.tables where "ALL_PLUGINS"= (select cast(table_name as char) from information_schema.tables order by table_name limit 1) limit 1; diff --git a/sql/handler.h b/sql/handler.h index 12f6b8808b3..18639b6a8a4 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -610,6 +610,7 @@ enum enum_schema_tables SCH_PARAMETERS, SCH_PARTITIONS, SCH_PLUGINS, + SCH_ALL_PLUGINS, SCH_PROCESSLIST, SCH_PROFILES, SCH_REFERENTIAL_CONSTRAINTS, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d8e603d3009..64cc94fa8bd 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -7105,8 +7105,8 @@ SHOW_VAR status_vars[]= { {"Feature_locale", (char*) offsetof(STATUS_VAR, feature_locale), SHOW_LONG_STATUS}, {"Feature_subquery", (char*) offsetof(STATUS_VAR, feature_subquery), SHOW_LONG_STATUS}, {"Feature_timezone", (char*) offsetof(STATUS_VAR, feature_timezone), SHOW_LONG_STATUS}, - {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS}, - {"Feature_xml", (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS}, + {"Feature_trigger", (char*) offsetof(STATUS_VAR, feature_trigger), SHOW_LONG_STATUS}, + {"Feature_xml", (char*) offsetof(STATUS_VAR, feature_xml), SHOW_LONG_STATUS}, {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH}, {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS}, {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS}, @@ -7114,8 +7114,8 @@ SHOW_VAR status_vars[]= { {"Handler_icp_attempts", (char*) offsetof(STATUS_VAR, ha_icp_attempts), SHOW_LONG_STATUS}, {"Handler_icp_match", (char*) offsetof(STATUS_VAR, ha_icp_match), SHOW_LONG_STATUS}, {"Handler_mrr_init", (char*) offsetof(STATUS_VAR, ha_mrr_init_count), SHOW_LONG_STATUS}, - {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS}, - {"Handler_mrr_rowid_refills", (char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS}, + {"Handler_mrr_key_refills", (char*) offsetof(STATUS_VAR, ha_mrr_key_refills_count), SHOW_LONG_STATUS}, + {"Handler_mrr_rowid_refills",(char*) offsetof(STATUS_VAR, ha_mrr_rowid_refills_count), SHOW_LONG_STATUS}, {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS}, {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS}, {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS}, @@ -7142,9 +7142,10 @@ SHOW_VAR status_vars[]= { {"Open_table_definitions", (char*) &show_table_definitions, SHOW_SIMPLE_FUNC}, {"Open_tables", (char*) &show_open_tables, SHOW_SIMPLE_FUNC}, {"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH}, + {"Opened_plugin_libraries", (char*) &dlopen_count, SHOW_LONG}, {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS}, {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS}, - {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS}, + {"Opened_views", (char*) offsetof(STATUS_VAR, opened_views), SHOW_LONG_STATUS}, {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_SIMPLE_FUNC}, {"Rows_sent", (char*) offsetof(STATUS_VAR, rows_sent), SHOW_LONGLONG_STATUS}, {"Rows_read", (char*) offsetof(STATUS_VAR, rows_read), SHOW_LONGLONG_STATUS}, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 6cf1050998b..8d2379d7738 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -53,7 +53,6 @@ static TYPELIB global_plugin_typelib= { array_elements(global_plugin_typelib_names)-1, "", global_plugin_typelib_names, NULL }; - char *opt_plugin_load= NULL; char *opt_plugin_dir_ptr; char opt_plugin_dir[FN_REFLEN]; @@ -197,6 +196,8 @@ static bool reap_needed= false; static int plugin_array_version=0; static bool initialized= 0; +ulong dlopen_count; + /* write-lock on LOCK_system_variables_hash is required before modifying @@ -746,6 +747,7 @@ static st_plugin_dl *plugin_dl_add(const LEX_STRING *dl, int report) report_error(report, ER_CANT_OPEN_LIBRARY, dlpath, errno, errmsg); goto ret; } + dlopen_count++; /* Checks which plugin interface present and reads info */ if (!(sym= dlsym(plugin_dl.handle, maria_plugin_interface_version_sym))) @@ -1485,6 +1487,8 @@ int plugin_init(int *argc, char **argv, int flags) if (initialized) DBUG_RETURN(0); + dlopen_count =0; + #ifdef HAVE_PSI_INTERFACE init_plugin_psi_keys(); #endif @@ -2333,6 +2337,74 @@ err: } +static bool plugin_dl_foreach_internal(THD *thd, st_plugin_dl *plugin_dl, + st_maria_plugin *plug, + plugin_foreach_func *func, void *arg) +{ + for (; plug->name; plug++) + { + st_plugin_int tmp, *plugin; + + tmp.name.str= const_cast(plug->name); + tmp.name.length= strlen(plug->name); + tmp.plugin= plug; + tmp.plugin_dl= plugin_dl; + + mysql_mutex_lock(&LOCK_plugin); + if ((plugin= plugin_find_internal(&tmp.name, MYSQL_ANY_PLUGIN)) && + plugin->plugin == plug) + + { + tmp.state= plugin->state; + tmp.load_option= plugin->load_option; + } + else + { + tmp.state= PLUGIN_IS_FREED; + tmp.load_option= PLUGIN_OFF; + } + mysql_mutex_unlock(&LOCK_plugin); + + plugin= &tmp; + if (func(thd, plugin_int_to_ref(plugin), arg)) + return 1; + } + return 0; +} + +bool plugin_dl_foreach(THD *thd, const LEX_STRING *dl, + plugin_foreach_func *func, void *arg) +{ + bool err= 0; + + if (dl) + { + mysql_mutex_lock(&LOCK_plugin); + st_plugin_dl *plugin_dl= plugin_dl_add(dl, REPORT_TO_USER); + mysql_mutex_unlock(&LOCK_plugin); + + if (!plugin_dl) + return 1; + + err= plugin_dl_foreach_internal(thd, plugin_dl, plugin_dl->plugins, + func, arg); + + mysql_mutex_lock(&LOCK_plugin); + plugin_dl_del(plugin_dl); + mysql_mutex_unlock(&LOCK_plugin); + } + else + { + struct st_maria_plugin **builtins; + for (builtins= mysql_mandatory_plugins; !err && *builtins; builtins++) + err= plugin_dl_foreach_internal(thd, 0, *builtins, func, arg); + for (builtins= mysql_optional_plugins; !err && *builtins; builtins++) + err= plugin_dl_foreach_internal(thd, 0, *builtins, func, arg); + } + return err; +} + + /**************************************************************************** Internal type declarations for variables support ****************************************************************************/ diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index bf4dbef6fc8..11c91fe93eb 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -39,6 +39,8 @@ enum enum_plugin_load_option { PLUGIN_OFF, PLUGIN_ON, PLUGIN_FORCE, PLUGIN_FORCE_PLUS_PERMANENT }; extern const char *global_plugin_typelib_names[]; +extern ulong dlopen_count; + #include #ifdef DBUG_OFF @@ -174,4 +176,6 @@ typedef my_bool (plugin_foreach_func)(THD *thd, #define plugin_foreach(A,B,C,D) plugin_foreach_with_mask(A,B,C,PLUGIN_IS_READY,D) extern bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, int type, uint state_mask, void *arg); +extern bool plugin_dl_foreach(THD *thd, const LEX_STRING *dl, + plugin_foreach_func *func, void *arg); #endif diff --git a/sql/sql_show.cc b/sql/sql_show.cc index a0fa9807b29..eea1289015a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -119,6 +119,14 @@ append_algorithm(TABLE_LIST *table, String *buff); static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table); +typedef struct st_lookup_field_values +{ + LEX_STRING db_value, table_value; + bool wild_db_value, wild_table_value; +} LOOKUP_FIELD_VALUES; + +bool get_lookup_field_values(THD *, COND *, TABLE_LIST *, LOOKUP_FIELD_VALUES *); + /*************************************************************************** ** List all table types supported ***************************************************************************/ @@ -157,7 +165,6 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, cs); switch (plugin_state(plugin)) { - /* case PLUGIN_IS_FREED: does not happen */ case PLUGIN_IS_DELETED: table->field[2]->store(STRING_WITH_LEN("DELETED"), cs); break; @@ -170,6 +177,9 @@ static my_bool show_plugins(THD *thd, plugin_ref plugin, case PLUGIN_IS_DISABLED: table->field[2]->store(STRING_WITH_LEN("DISABLED"), cs); break; + case PLUGIN_IS_FREED: // filtered in fill_plugins, used in fill_all_plugins + table->field[2]->store(STRING_WITH_LEN("NOT INSTALLED"), cs); + break; default: DBUG_ASSERT(0); } @@ -267,6 +277,65 @@ int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond) } +int fill_all_plugins(THD *thd, TABLE_LIST *tables, COND *cond) +{ + DBUG_ENTER("fill_all_plugins"); + TABLE *table= tables->table; + LOOKUP_FIELD_VALUES lookup; + + if (get_lookup_field_values(thd, cond, tables, &lookup)) + DBUG_RETURN(0); + + if (lookup.db_value.str && !lookup.db_value.str[0]) + DBUG_RETURN(0); // empty string never matches a valid SONAME + + MY_DIR *dirp= my_dir(opt_plugin_dir, MY_THREAD_SPECIFIC); + if (!dirp) + { + my_error(ER_CANT_READ_DIR, MYF(0), opt_plugin_dir, my_errno); + DBUG_RETURN(1); + } + + if (!lookup.db_value.str) + plugin_dl_foreach(thd, 0, show_plugins, table); + + const char *wstr= lookup.db_value.str, *wend= wstr + lookup.db_value.length; + for (uint i=0; i < (uint) dirp->number_of_files; i++) + { + FILEINFO *file= dirp->dir_entry+i; + LEX_STRING dl= { file->name, strlen(file->name) }; + const char *dlend= dl.str + dl.length; + const size_t so_ext_len= sizeof(SO_EXT) - 1; + + if (strcasecmp(dlend - so_ext_len, SO_EXT)) + continue; + + if (lookup.db_value.str) + { + if (lookup.wild_db_value) + { + if (my_wildcmp(files_charset_info, dl.str, dlend, wstr, wend, + wild_prefix, wild_one, wild_many)) + continue; + } + else + { + if (my_strnncoll(files_charset_info, + (uchar*)dl.str, dl.length, + (uchar*)lookup.db_value.str, lookup.db_value.length)) + continue; + } + } + + plugin_dl_foreach(thd, &dl, show_plugins, table); + thd->clear_error(); + } + + my_dirend(dirp); + DBUG_RETURN(0); +} + + /*************************************************************************** ** List all Authors. ** If you can update it, you get to be in it :) @@ -3260,13 +3329,6 @@ void calc_sum_of_all_status(STATUS_VAR *to) /* This is only used internally, but we need it here as a forward reference */ extern ST_SCHEMA_TABLE schema_tables[]; -typedef struct st_lookup_field_values -{ - LEX_STRING db_value, table_value; - bool wild_db_value, wild_table_value; -} LOOKUP_FIELD_VALUES; - - /* Store record to I_S table, convert HEAP table to MyISAM if necessary @@ -3587,6 +3649,17 @@ bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables, lookup_field_values->wild_table_value= 1; } break; + case SQLCOM_SHOW_PLUGINS: + if (lex->ident.str) + thd->make_lex_string(&lookup_field_values->db_value, + lex->ident.str, lex->ident.length); + else if (lex->wild) + { + thd->make_lex_string(&lookup_field_values->db_value, + lex->wild->ptr(), lex->wild->length()); + lookup_field_values->wild_db_value= 1; + } + break; default: /* The "default" is for queries over I_S. @@ -8558,7 +8631,7 @@ ST_FIELD_INFO plugin_fields_info[]= {"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name", SKIP_OPEN_TABLE}, {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, - {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE}, + {"PLUGIN_STATUS", 16, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE}, {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE}, {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}, {"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library", @@ -8819,6 +8892,8 @@ ST_SCHEMA_TABLE schema_tables[]= OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"PLUGINS", plugin_fields_info, create_schema_table, fill_plugins, make_old_format, 0, -1, -1, 0, 0}, + {"ALL_PLUGINS", plugin_fields_info, create_schema_table, + fill_all_plugins, make_old_format, 0, 5, -1, 0, 0}, {"PROCESSLIST", processlist_fields_info, create_schema_table, fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0}, {"PROFILING", query_profile_statistics_info, create_schema_table, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 68319da9cf2..0c3a016fa28 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -11449,6 +11449,7 @@ show: { LEX *lex=Lex; lex->wild=0; + lex->ident=null_lex_str; mysql_init_select(lex); lex->current_select->parsing_place= SELECT_LIST; bzero((char*) &lex->create_info,sizeof(lex->create_info)); @@ -11512,6 +11513,19 @@ show_param: if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS)) MYSQL_YYABORT; } + | PLUGINS_SYM SONAME_SYM TEXT_STRING_sys + { + Lex->ident= $3; + Lex->sql_command= SQLCOM_SHOW_PLUGINS; + if (prepare_schema_table(YYTHD, Lex, 0, SCH_ALL_PLUGINS)) + MYSQL_YYABORT; + } + | PLUGINS_SYM SONAME_SYM wild_and_where + { + Lex->sql_command= SQLCOM_SHOW_PLUGINS; + if (prepare_schema_table(YYTHD, Lex, 0, SCH_ALL_PLUGINS)) + MYSQL_YYABORT; + } | ENGINE_SYM known_storage_engines show_engine_param { Lex->create_info.db_type= $2; } | ENGINE_SYM ALL show_engine_param From 775e82638b825747a2a8b7cf7d6d29c872693422 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:33 +0200 Subject: [PATCH 312/324] put status variables in the proper pluginname_ scope (but support the scopeless mysql style too). always output status/system variables in the correct lettercase --- mysql-test/r/plugin.result | 2 +- mysql-test/suite/plugins/r/audit_null.result | 4 +- plugin/audit_null/audit_null.c | 10 ++--- plugin/auth_socket/auth_socket.c | 17 -------- plugin/daemon_example/daemon_example.cc | 17 -------- plugin/fulltext/plugin_example.c | 18 -------- plugin/sql_errlog/sql_errlog.c | 18 -------- sql/sql_plugin.cc | 45 +++++++++----------- sql/sql_show.cc | 13 +++++- storage/cassandra/ha_cassandra.cc | 14 +++--- storage/example/ha_example.cc | 2 +- storage/maria/ha_maria.cc | 7 +-- 12 files changed, 49 insertions(+), 118 deletions(-) diff --git a/mysql-test/r/plugin.result b/mysql-test/r/plugin.result index 06e343a0886..0eb49584c4a 100644 --- a/mysql-test/r/plugin.result +++ b/mysql-test/r/plugin.result @@ -44,7 +44,7 @@ set global example_ulong_var=500; set global example_enum_var= e1; show status like 'example%'; Variable_name Value -example_func_example enum_var is 0, ulong_var is 500, really +Example_func_example enum_var is 0, ulong_var is 500, really show variables like 'example%'; Variable_name Value example_enum_var e1 diff --git a/mysql-test/suite/plugins/r/audit_null.result b/mysql-test/suite/plugins/r/audit_null.result index 4cf648510e6..2b1b64a9d85 100644 --- a/mysql-test/suite/plugins/r/audit_null.result +++ b/mysql-test/suite/plugins/r/audit_null.result @@ -9,8 +9,8 @@ ERROR 42S22: Unknown column 'foobar' in 'field list' show status like 'audit_null%'; Variable_name Value Audit_null_called 9 -Audit_null_general_error 1 Audit_null_general_log 3 +Audit_null_general_error 1 Audit_null_general_result 2 create procedure au1(x char(16)) select concat("test1", x); call au1("-12"); @@ -19,8 +19,8 @@ test1-12 show status like 'audit_null%'; Variable_name Value Audit_null_called 19 -Audit_null_general_error 1 Audit_null_general_log 7 +Audit_null_general_error 1 Audit_null_general_result 5 uninstall plugin audit_null; Warnings: diff --git a/plugin/audit_null/audit_null.c b/plugin/audit_null/audit_null.c index be0c70fbd35..0616f192f20 100644 --- a/plugin/audit_null/audit_null.c +++ b/plugin/audit_null/audit_null.c @@ -127,12 +127,10 @@ static struct st_mysql_audit audit_null_descriptor= static struct st_mysql_show_var simple_status[]= { - { "Audit_null_called", (char *) &number_of_calls, SHOW_INT }, - { "Audit_null_general_log", (char *) &number_of_calls_general_log, SHOW_INT }, - { "Audit_null_general_error", (char *) &number_of_calls_general_error, - SHOW_INT }, - { "Audit_null_general_result", (char *) &number_of_calls_general_result, - SHOW_INT }, + { "called", (char *) &number_of_calls, SHOW_INT }, + { "general_log", (char *) &number_of_calls_general_log, SHOW_INT }, + { "general_error", (char *) &number_of_calls_general_error, SHOW_INT }, + { "general_result", (char *) &number_of_calls_general_result, SHOW_INT }, { 0, 0, 0} }; diff --git a/plugin/auth_socket/auth_socket.c b/plugin/auth_socket/auth_socket.c index 41cb1039fd2..78d7e769f7b 100644 --- a/plugin/auth_socket/auth_socket.c +++ b/plugin/auth_socket/auth_socket.c @@ -85,23 +85,6 @@ static struct st_mysql_auth socket_auth_handler= socket_auth }; -mysql_declare_plugin(socket_auth) -{ - MYSQL_AUTHENTICATION_PLUGIN, - &socket_auth_handler, - "unix_socket", - "Sergei Golubchik", - "Unix Socket based authentication", - PLUGIN_LICENSE_GPL, - NULL, - NULL, - 0x0100, - NULL, - NULL, - NULL, - 0, -} -mysql_declare_plugin_end; maria_declare_plugin(socket_auth) { MYSQL_AUTHENTICATION_PLUGIN, diff --git a/plugin/daemon_example/daemon_example.cc b/plugin/daemon_example/daemon_example.cc index ec2979de3c3..7d047b2eaf7 100644 --- a/plugin/daemon_example/daemon_example.cc +++ b/plugin/daemon_example/daemon_example.cc @@ -188,23 +188,6 @@ struct st_mysql_daemon daemon_example_plugin= Plugin library descriptor */ -mysql_declare_plugin(daemon_example) -{ - MYSQL_DAEMON_PLUGIN, - &daemon_example_plugin, - "daemon_example", - "Brian Aker", - "Daemon example, creates a heartbeat beat file in mysql-heartbeat.log", - PLUGIN_LICENSE_GPL, - daemon_example_plugin_init, /* Plugin Init */ - daemon_example_plugin_deinit, /* Plugin Deinit */ - 0x0100 /* 1.0 */, - NULL, /* status variables */ - NULL, /* system variables */ - NULL, /* config options */ - 0, /* flags */ -} -mysql_declare_plugin_end; maria_declare_plugin(daemon_example) { MYSQL_DAEMON_PLUGIN, diff --git a/plugin/fulltext/plugin_example.c b/plugin/fulltext/plugin_example.c index 981335bddd6..2af3555393c 100644 --- a/plugin/fulltext/plugin_example.c +++ b/plugin/fulltext/plugin_example.c @@ -254,24 +254,6 @@ static struct st_mysql_sys_var* simple_system_variables[]= { Plugin library descriptor */ -mysql_declare_plugin(ftexample) -{ - MYSQL_FTPARSER_PLUGIN, /* type */ - &simple_parser_descriptor, /* descriptor */ - "simple_parser", /* name */ - "Sergei Golubchik", /* author */ - "Simple Full-Text Parser", /* description */ - PLUGIN_LICENSE_GPL, - simple_parser_plugin_init, /* init function (when loaded) */ - simple_parser_plugin_deinit,/* deinit function (when unloaded) */ - 0x0001, /* version */ - simple_status, /* status variables */ - simple_system_variables, /* system variables */ - NULL, - 0, -} -mysql_declare_plugin_end; - maria_declare_plugin(ftexample) { MYSQL_FTPARSER_PLUGIN, /* type */ diff --git a/plugin/sql_errlog/sql_errlog.c b/plugin/sql_errlog/sql_errlog.c index ce383916621..f84af963aca 100644 --- a/plugin/sql_errlog/sql_errlog.c +++ b/plugin/sql_errlog/sql_errlog.c @@ -144,24 +144,6 @@ static struct st_mysql_audit descriptor = { MYSQL_AUDIT_GENERAL_CLASSMASK } }; -mysql_declare_plugin(sql_errlog) -{ - MYSQL_AUDIT_PLUGIN, - &descriptor, - "SQL_ERROR_LOG", - "Alexey Botchkov", - "Log SQL level errors to a file with rotation", - PLUGIN_LICENSE_GPL, - sql_error_log_init, - sql_error_log_deinit, - 0x0100, - NULL, - vars, - NULL, - 0 -} -mysql_declare_plugin_end; - maria_declare_plugin(sql_errlog) { MYSQL_AUDIT_PLUGIN, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 8d2379d7738..e04a6f7c1eb 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1133,22 +1133,21 @@ static void plugin_deinitialize(struct st_plugin_int *plugin, bool ref_check) if (plugin->plugin->status_vars) { -#ifdef FIX_LATER - /** - @todo - unfortunately, status variables were introduced without a - pluginname_ namespace, that is pluginname_ was not added automatically - to status variable names. It should be fixed together with the next - incompatible API change. + /* + historical ndb behavior caused MySQL plugins to specify + status var names in full, with the plugin name prefix. + this was never fixed in MySQL. + MariaDB fixes that but support MySQL style too. */ - SHOW_VAR array[2]= { + SHOW_VAR *show_vars= plugin->plugin->status_vars; + SHOW_VAR tmp_array[2]= { {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY}, {0, 0, SHOW_UNDEF} }; - remove_status_vars(array); -#else - remove_status_vars(plugin->plugin->status_vars); -#endif /* FIX_LATER */ + if (strncasecmp(show_vars->name, plugin->name.str, plugin->name.length)) + show_vars= tmp_array; + + remove_status_vars(show_vars); } if (plugin_type_deinitialize[plugin->plugin->type]) @@ -1358,24 +1357,22 @@ static int plugin_initialize(struct st_plugin_int *plugin) if (plugin->plugin->status_vars) { -#ifdef FIX_LATER /* - We have a problem right now where we can not prepend without - breaking backwards compatibility. We will fix this shortly so - that engines have "use names" and we wil use those for - CREATE TABLE, and use the plugin name then for adding automatic - variable names. + historical ndb behavior caused MySQL plugins to specify + status var names in full, with the plugin name prefix. + this was never fixed in MySQL. + MariaDB fixes that, but supports MySQL style too. */ - SHOW_VAR array[2]= { + SHOW_VAR *show_vars= plugin->plugin->status_vars; + SHOW_VAR tmp_array[2]= { {plugin->plugin->name, (char*)plugin->plugin->status_vars, SHOW_ARRAY}, {0, 0, SHOW_UNDEF} }; - if (add_status_vars(array)) // add_status_vars makes a copy + if (strncasecmp(show_vars->name, plugin->name.str, plugin->name.length)) + show_vars= tmp_array; + + if (add_status_vars(show_vars)) goto err; -#else - if (add_status_vars(plugin->plugin->status_vars)) - goto err; -#endif /* FIX_LATER */ } /* diff --git a/sql/sql_show.cc b/sql/sql_show.cc index eea1289015a..ac71837def4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2626,7 +2626,7 @@ static bool status_vars_inited= 0; C_MODE_START static int show_var_cmp(const void *var1, const void *var2) { - return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name); + return strcasecmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name); } C_MODE_END @@ -2831,6 +2831,17 @@ static bool show_status_array(THD *thd, const char *wild, name_buffer[sizeof(name_buffer)-1]=0; /* Safety */ if (ucase_names) my_caseup_str(system_charset_info, name_buffer); + else + { + my_casedn_str(system_charset_info, name_buffer); + DBUG_ASSERT(name_buffer[0] >= 'a'); + DBUG_ASSERT(name_buffer[0] <= 'z'); + + /* traditionally status variables have a first letter uppercased */ + if (status_var) + name_buffer[0]-= 'a' - 'A'; + } + restore_record(table, s->default_values); table->field[0]->store(name_buffer, strlen(name_buffer), diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index 968d23c94b5..1ab64dcb697 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -2568,21 +2568,21 @@ struct st_mysql_storage_engine cassandra_storage_engine= { MYSQL_HANDLERTON_INTERFACE_VERSION }; static SHOW_VAR cassandra_status_variables[]= { - {"Cassandra_row_inserts", + {"row_inserts", (char*) &cassandra_counters.row_inserts, SHOW_LONG}, - {"Cassandra_row_insert_batches", + {"row_insert_batches", (char*) &cassandra_counters.row_insert_batches, SHOW_LONG}, - {"Cassandra_multiget_keys_scanned", + {"multiget_keys_scanned", (char*) &cassandra_counters.multiget_keys_scanned, SHOW_LONG}, - {"Cassandra_multiget_reads", + {"multiget_reads", (char*) &cassandra_counters.multiget_reads, SHOW_LONG}, - {"Cassandra_multiget_rows_read", + {"multiget_rows_read", (char*) &cassandra_counters.multiget_rows_read, SHOW_LONG}, - {"Cassandra_timeout_exceptions", + {"timeout_exceptions", (char*) &cassandra_counters.timeout_exceptions, SHOW_LONG}, - {"Cassandra_unavailable_exceptions", + {"unavailable_exceptions", (char*) &cassandra_counters.unavailable_exceptions, SHOW_LONG}, {NullS, NullS, SHOW_LONG} }; diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index bcf934b6b1c..0dc8e27fe61 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -1117,7 +1117,7 @@ static int show_func_example(MYSQL_THD thd, struct st_mysql_show_var *var, static struct st_mysql_show_var func_status[]= { - {"example_func_example", (char *)show_func_example, SHOW_SIMPLE_FUNC}, + {"func_example", (char *)show_func_example, SHOW_SIMPLE_FUNC}, {0,0,SHOW_UNDEF} }; diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 6ea1dccc40b..1a11bdd6050 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -3753,11 +3753,6 @@ SHOW_VAR status_variables[]= { {NullS, NullS, SHOW_LONG} }; -static struct st_mysql_show_var aria_status_variables[]= { - {"Aria", (char*) &status_variables, SHOW_ARRAY}, - {NullS, NullS, SHOW_LONG} -}; - /**************************************************************************** * Maria MRR implementation: use DS-MRR ***************************************************************************/ @@ -3832,7 +3827,7 @@ maria_declare_plugin(aria) ha_maria_init, /* Plugin Init */ NULL, /* Plugin Deinit */ 0x0105, /* 1.5 */ - aria_status_variables, /* status variables */ + status_variables, /* status variables */ system_variables, /* system variables */ "1.5", /* string version */ MariaDB_PLUGIN_MATURITY_GAMMA /* maturity */ From 68f6c229c563b5e92a2ef7ea2a429edbdb69c303 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:37 +0200 Subject: [PATCH 313/324] prefer static inline functions to macros. avoid unnecessary strlen()'s --- sql/mysqld.cc | 2 +- sql/sql_audit.h | 91 +++++++++++++++++++++++++++++----------------- sql/sql_connect.cc | 2 +- sql/sql_parse.cc | 2 +- 4 files changed, 60 insertions(+), 37 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 64cc94fa8bd..c8d8c09cbba 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2414,7 +2414,7 @@ void close_connection(THD *thd, uint sql_errno) { sleep(0); /* Workaround to avoid tailcall optimisation */ } - MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, sql_errno); + mysql_audit_notify_connection_disconnect(thd, sql_errno); DBUG_VOID_RETURN; } #endif /* EMBEDDED_LIBRARY */ diff --git a/sql/sql_audit.h b/sql/sql_audit.h index 46afe4b7596..a651ce61374 100644 --- a/sql/sql_audit.h +++ b/sql/sql_audit.h @@ -43,10 +43,16 @@ static inline bool mysql_audit_general_enabled() return mysql_global_audit_mask[0] & MYSQL_AUDIT_GENERAL_CLASSMASK; } +static inline bool mysql_audit_connection_enabled() +{ + return mysql_global_audit_mask[0] & MYSQL_AUDIT_CONNECTION_CLASSMASK; +} + #else static inline void mysql_audit_notify(THD *thd, uint event_class, uint event_subtype, ...) { } #define mysql_audit_general_enabled() 0 +#define mysql_audit_connection_enabled() 0 #endif extern void mysql_audit_release(THD *thd); @@ -137,41 +143,58 @@ void mysql_audit_general(THD *thd, uint event_subtype, } } -#define MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd) mysql_audit_notify(\ - (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CONNECT,\ - (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\ - (thd)->thread_id, (thd)->security_ctx->user,\ - (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\ - (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\ - (thd)->security_ctx->external_user,\ - (thd)->security_ctx->external_user ?\ - strlen((thd)->security_ctx->external_user) : 0,\ - (thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\ - (thd)->security_ctx->host,\ - (thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\ - (thd)->security_ctx->ip,\ - (thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\ - (thd)->db, (thd)->db ? strlen((thd)->db) : 0) +static inline +void mysql_audit_notify_connection_connect(THD *thd) +{ + if (mysql_audit_connection_enabled()) + { + const Security_context *sctx= thd->security_ctx; + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, + MYSQL_AUDIT_CONNECTION_CONNECT, + thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0, + thd->thread_id, + sctx->user, sctx->user ? strlen(sctx->user) : 0, + sctx->priv_user, strlen(sctx->priv_user), + sctx->external_user, + sctx->external_user ? strlen(sctx->external_user) : 0, + sctx->proxy_user, strlen(sctx->proxy_user), + sctx->host, sctx->host ? strlen(sctx->host) : 0, + sctx->ip, sctx->ip ? strlen(sctx->ip) : 0, + thd->db, thd->db ? strlen(thd->db) : 0); + } +} -#define MYSQL_AUDIT_NOTIFY_CONNECTION_DISCONNECT(thd, errcode)\ - mysql_audit_notify(\ - (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_DISCONNECT,\ - (errcode), (thd)->thread_id, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) +static inline +void mysql_audit_notify_connection_disconnect(THD *thd, int errcode) +{ + if (mysql_audit_connection_enabled()) + { + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, + MYSQL_AUDIT_CONNECTION_DISCONNECT, + errcode, thd->thread_id, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + } +} -#define MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd) mysql_audit_notify(\ - (thd), MYSQL_AUDIT_CONNECTION_CLASS, MYSQL_AUDIT_CONNECTION_CHANGE_USER,\ - (thd)->stmt_da->is_error() ? (thd)->stmt_da->sql_errno() : 0,\ - (thd)->thread_id, (thd)->security_ctx->user,\ - (thd)->security_ctx->user ? strlen((thd)->security_ctx->user) : 0,\ - (thd)->security_ctx->priv_user, strlen((thd)->security_ctx->priv_user),\ - (thd)->security_ctx->external_user,\ - (thd)->security_ctx->external_user ?\ - strlen((thd)->security_ctx->external_user) : 0,\ - (thd)->security_ctx->proxy_user, strlen((thd)->security_ctx->proxy_user),\ - (thd)->security_ctx->host,\ - (thd)->security_ctx->host ? strlen((thd)->security_ctx->host) : 0,\ - (thd)->security_ctx->ip,\ - (thd)->security_ctx->ip ? strlen((thd)->security_ctx->ip) : 0,\ - (thd)->db, (thd)->db ? strlen((thd)->db) : 0) +static inline +void mysql_audit_notify_connection_change_user(THD *thd) +{ + if (mysql_audit_connection_enabled()) + { + const Security_context *sctx= thd->security_ctx; + mysql_audit_notify(thd, MYSQL_AUDIT_CONNECTION_CLASS, + MYSQL_AUDIT_CONNECTION_CHANGE_USER, + thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0, + thd->thread_id, + sctx->user, sctx->user ? strlen(sctx->user) : 0, + sctx->priv_user, strlen(sctx->priv_user), + sctx->external_user, + sctx->external_user ? strlen(sctx->external_user) : 0, + sctx->proxy_user, strlen(sctx->proxy_user), + sctx->host, sctx->host ? strlen(sctx->host) : 0, + sctx->ip, sctx->ip ? strlen(sctx->ip) : 0, + thd->db, thd->db ? strlen(thd->db) : 0); + } +} #endif /* SQL_AUDIT_INCLUDED */ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 40bd59975f3..17e75f15adf 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -1187,7 +1187,7 @@ bool thd_prepare_connection(THD *thd) bool rc; lex_start(thd); rc= login_connection(thd); - MYSQL_AUDIT_NOTIFY_CONNECTION_CONNECT(thd); + mysql_audit_notify_connection_connect(thd); if (rc) return rc; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 62e5a99f941..c68e20f1b3a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1011,7 +1011,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, else rc= acl_authenticate(thd, 0, packet_length); - MYSQL_AUDIT_NOTIFY_CONNECTION_CHANGE_USER(thd); + mysql_audit_notify_connection_change_user(thd); if (rc) { /* Free user if allocated by acl_authenticate */ From da7eca021bbcd0d199a05543f58fae99e34646a1 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:41 +0200 Subject: [PATCH 314/324] remove old workaround for replicating from old MySQL 5.1 and 5.2 alpha trees. --- .../suite/binlog/r/binlog_old_versions.result | 15 --- .../binlog/std_data/ver_5_1-wl2325_r.001 | Bin 705 -> 0 bytes .../binlog/std_data/ver_5_1-wl2325_s.001 | Bin 149796 -> 0 bytes .../suite/binlog/t/binlog_old_versions.test | 19 ---- sql/log_event.cc | 103 ------------------ 5 files changed, 137 deletions(-) delete mode 100644 mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 delete mode 100644 mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 diff --git a/mysql-test/suite/binlog/r/binlog_old_versions.result b/mysql-test/suite/binlog/r/binlog_old_versions.result index a4850b835c8..169a23b2019 100644 --- a/mysql-test/suite/binlog/r/binlog_old_versions.result +++ b/mysql-test/suite/binlog/r/binlog_old_versions.result @@ -38,21 +38,6 @@ SELECT COUNT(*) FROM t3; COUNT(*) 17920 DROP TABLE t1, t3; -==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== -SELECT * FROM t1 ORDER BY a; -a b -0 last_insert_id -1 one -3 last stm in trx: next event should be xid -4 four -781729 random -SELECT * FROM t2 ORDER BY a; -a b -3 first stm in trx -SELECT COUNT(*) FROM t3; -COUNT(*) -17920 -DROP TABLE t1, t2, t3; ==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ==== SELECT * FROM t1 ORDER BY a; a b diff --git a/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 b/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_r.001 deleted file mode 100644 index 47071c011f91d63b666e3013f18acc019e884cbe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 705 zcmeyDl$rO*yv?1Tk%56B35e5xn1O+X!Bo#k&qy~hKBXwXz^uT~ST`j#sWe?TCqEsm z01E*!M%aRvfrCMafdvSJ7#RH7fPjHT3M9n@vY`lwZ-DhOLrq{|V2}bb9T*ru@?gNm zTwIdE!T~ghgP|m~xP-wu$kj2#RUyRD$;VZp#85#aQ6V$0L`NY>Avq(lNW;`XQ&Yj! z&)w6{Rl!!lx6(7%(HF%=FR;<%+h~N}M$f#wd>1FUji69mL!phv=r$Sw{Rpx_0A#Ql z5MP1^7cjQKp~O^T$iT$>52Q*EB&iF;|KX|_8JPb61d1>)=jWyV1PL>jl;@)usmcVB zhX4#Cg+N;Dfj9-O3X74*X8!~!#IU3bt{scJg+Z360P#AwDzGImllUy!+?hdYgn{@V GSPcNT7kLN( diff --git a/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 b/mysql-test/suite/binlog/std_data/ver_5_1-wl2325_s.001 deleted file mode 100644 index 4302bfed879d3b9dc692f11c13029f733771d724..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149796 zcmeI5&u-k-6~=EY#gGj+|Nj7P7X%VONe~;gjRZzF@fcQI0fr33O11*2p){<=WI|Gc zv}}Op8Tt%aWZ5_Az7NoiU!chO&LycD>SBg7tK>HZhnE};$)OML{l0U)bMAk$qCCF; z)8jW^3n65-9N7}WX87Xv-P?C>r3cfx`u@xB@7%jJ&9jr^Tl4DJ|KR_;=`io!zY(^= zJ7Lpa?}YI5s=dPIO?`AlXLw}G&;H#j-4QlJxM|G?A?R~|UEOHf>E@OlXe+dN(}ssT zk9YTmW6bT3w1lwCF?RQ!?R>MJ?C$M9P1?K3cataI?mSCAx%YXpeN@y6i zcjqm?ln``%Z)neFw*1>a(%V_M@|CT&Y_Z$wui=-ZwmI<|Hu|nz{E`P}x^2}-9k23+ zPX3WCQ$KdGeeJeR{>$NiwzVFv;RoCJ*SfCZo5|jzPd-gPOYZ#1Uv@=xT28AM@tR)O zHT}_+mwrNR`D?hCbKCsuhW4%DhCG=(+dqgVcCc%gWf!CW>4Tzd^4eD2f9LzUj1TRE zf7{SWwM^1_cG6t8RaIV}WNDUOx8?A;-j7&ETA7_<*zP;Oz*UGo*{IsyI>w~VTTi3V!YjJlZ}r87A5o_=yUO*y z;A?%`8bz7T)jB!U8MX2sq((eW*YZENot1u)_EmMiOUKtW+83=c_qQUIA>{MM4I;0n zxt-Z|)MeVvbS-&phOSep;itlgFd{PtjL3T_JzQx+Pvm_KJyF>YR~ks8ZTRrRaOR^} z?)QY@Y$=fC{fu`r5yOCq9MOP@mO<(mkv%~GYcqot=pIId5v}Yqz=$v+j0isw&PMAA zTbzwJ8)u!T8jm#|YbZWpkCDMRfHlAxU=6SaSOcty;%hVnSVskj#zmwcb{9-m)CXwM z6QL(kkUkPFwK^8AW^W`!@e!rDGS0dVbsxme{Bc3qxLC)rcB!O~U~wFCaW2CdQjn$T z9!4ZQjK-Sb%ryH5^{qQt5C=1yk?pZE4#tQuB8CsyX2qGqFY3}RNuWARwa z4$u?fv8H;gfu$~`1dp}#3V5tVqw!c%$9mE6(XA!g4A~wo32}iCg+G_^USdQVd&u^H zouMaMs_Zmj55gWRyLB)kj0htlc1G+>IGorSu`^<4#Lm_{3m+68ioY_*!iX>;jEL&7 zOP3RZ;zRLQ?l>?aj0hvbPlTTcKT%9s6dEUaF`_Z=7pMwC6yG`rG}dUWt#4dZLk6%0 zSOcs9)&OgOHNcv=J<_b3yn*CJgGMGtm}J&52v7m60oDNPW6JH7X-o1V$%~x>vZ_TM zNM00;CV7$M#YG)YZY|MfNM0m)F+K7QLlYk)Pt8ek2u23P~EZI0{|kM&>&0PAr=M2rYv4X_4S z1FQko0BeBt0I2X-7Vu zQ&E4M-d3Dll2m)gh%h3IsIT9s{}+s%Q{>8^kr3A!(np~9h|*RDSr`#Ugb~FGj3^uJS-?+(p9nvZhDFNlO^v&eyh!q* z=i*uVM^UD8!6h?`ZskL!w&g~SpE$*f%}SZ!7!i4AlYk)Pt+IqqkkF_P4F?}b~cbbey<05(@xf+^b&equSJTZ!)%R0~##W{XS86stf zS%#QpXbov%WyzcM4oh%h3Ih=L9jbP#`|jy2gH)Ul?HHFc~9mQEe(aTz`UYk)Pt z8ek2u23V6uP1s`qR8&f%Qrc-@X|EPB?x*ZjA%VWFA+w*Plj%DzcN_p~fHlAxU=6Sa zSOcstkB_cHi)u9L6H%XNoc9tVvL}f8L}mtuqzu8%%nmfrxQN$VT?x(0qYvy1b_P3x zox#ooq0kedCqhqzo(MhB5Yr&+F^-V~tO3>lYk)Pt8emP>@3afP8k21`&*HsClYu%5ZGv9!n!Omc3urt`% zAfP6VdR)8|c`Rwvq){VEBkV!ggEVT=s0Tnr8Z~Lur-kVR%;V5|shN%11_|{MQ9Oa3 zh-?qB2RznztnpY!H?`c7(N&Gd+HArHiYdVQHw3JY@Bj4p+G`<%4|hWN$6u~kOAAm* z9l(*sLx)KH8mL5Y-w{#?RB|$f^qSzle2tzL4OBW*w;+TBR4R}AL6hJoRR;DzqclBfvUFDFD_0Yk+l8rgQ5Ugs8g}z#3p3tC0;Tir_xM zeS-VXg(vY?$3oNqYpU>B-3O}h8E~QspW|q%@KJ?t-1z9`qtTTrd{p5Z3$idG5qKsa zqF6}h+3Z6g3L1Cq2-o@z&x*d-Pzrq}FEK`BeF+t3+!2Toq2H(C46(Dc>8L)UG>wqP z`l&dBD2>?JqWNvGGl2EVg(EN`j0hvDUF-@wvu9z^(TB1{Qup*+{(qXJ=wn23`$6%c z_)z>v?5kQHb11%s3@APne^HPHJ5#qo0G8Mp0ay<$FWPay&VGOFOl46%P+637Ti)L7 z%c9su*bL#O*GRc$8y{;=2oFNgAN%X-M$=9=w}Sqe7`Y8ko=zSmk0$$*WOwiD-6uQA nc2*o892N8Y_B3s`ZSVfmWPkF|K56g$XeZv#vEH@iV?Xh)HkN#? diff --git a/mysql-test/suite/binlog/t/binlog_old_versions.test b/mysql-test/suite/binlog/t/binlog_old_versions.test index b294adbc69d..77b3db31983 100644 --- a/mysql-test/suite/binlog/t/binlog_old_versions.test +++ b/mysql-test/suite/binlog/t/binlog_old_versions.test @@ -64,25 +64,6 @@ SELECT COUNT(*) FROM t3; DROP TABLE t1, t3; ---echo ==== Read binlog from alcatel tree (mysql-5.1-wl2325-5.0-drop6) ==== - -# In this version, it was not possible to switch between row-based and -# statement-based binlogging without restarting the server. So, we -# have two binlogs; one for row based and one for statement based -# replication. - -# Read rbr binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_r.001 | $MYSQL --local-infile=1 -# Read stm binlog. ---exec $MYSQL_BINLOG --local-load=$MYSQLTEST_VARDIR/tmp/ suite/binlog/std_data/ver_5_1-wl2325_s.001 | $MYSQL --local-infile=1 -# Show result. -SELECT * FROM t1 ORDER BY a; -SELECT * FROM t2 ORDER BY a; -SELECT COUNT(*) FROM t3; -# Reset. -DROP TABLE t1, t2, t3; - - --echo ==== Read binlog from ndb tree (mysql-5.1-telco-6.1) ==== # Read binlog. diff --git a/sql/log_event.cc b/sql/log_event.cc index 19bc79babb1..6c637be19fa 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -4568,109 +4568,6 @@ Format_description_log_event(const char* buf, checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF; } - /* - In some previous versions, the events were given other event type - id numbers than in the present version. When replicating from such - a version, we therefore set up an array that maps those id numbers - to the id numbers of the present server. - - If post_header_len is null, it means malloc failed, and is_valid - will fail, so there is no need to do anything. - - The trees in which events have wrong id's are: - - mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha - mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0 - mysql-5.1-wl2325-no-dd - - (this was found by grepping for two lines in sequence where the - first matches "FORMAT_DESCRIPTION_EVENT," and the second matches - "TABLE_MAP_EVENT," in log_event.h in all trees) - - In these trees, the following server_versions existed since - TABLE_MAP_EVENT was introduced: - - 5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha - 5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12 - 5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15 - 5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c - 5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5 - 5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8 - 5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b - 5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19 - 5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1 - 5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3 - 5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6 - 5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12 - 5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8 - 5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b - 5.2.2-a_drop6p13c - - (this was found by grepping for "mysql," in all historical - versions of configure.in in the trees listed above). - - There are 5.1.1-alpha versions that use the new event id's, so we - do not test that version string. So replication from 5.1.1-alpha - with the other event id's to a new version does not work. - Moreover, we can safely ignore the part after drop[56]. This - allows us to simplify the big list above to the following regexes: - - 5\.1\.[1-5]-a_drop5.* - 5\.1\.4-a_drop6.* - 5\.2\.[0-2]-a_drop6.* - - This is what we test for in the 'if' below. - */ - if (post_header_len && - server_version[0] == '5' && server_version[1] == '.' && - server_version[3] == '.' && - strncmp(server_version + 5, "-a_drop", 7) == 0 && - ((server_version[2] == '1' && - server_version[4] >= '1' && server_version[4] <= '5' && - server_version[12] == '5') || - (server_version[2] == '1' && - server_version[4] == '4' && - server_version[12] == '6') || - (server_version[2] == '2' && - server_version[4] >= '0' && server_version[4] <= '2' && - server_version[12] == '6'))) - { - if (number_of_event_types != 22) - { - DBUG_PRINT("info", (" number_of_event_types=%d", - number_of_event_types)); - /* this makes is_valid() return false. */ - my_free(post_header_len); - post_header_len= NULL; - DBUG_VOID_RETURN; - } - static const uint8 perm[23]= - { - UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT, - INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT, - APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT, - NEW_LOAD_EVENT, - RAND_EVENT, USER_VAR_EVENT, - FORMAT_DESCRIPTION_EVENT, - TABLE_MAP_EVENT, - PRE_GA_WRITE_ROWS_EVENT, - PRE_GA_UPDATE_ROWS_EVENT, - PRE_GA_DELETE_ROWS_EVENT, - XID_EVENT, - BEGIN_LOAD_QUERY_EVENT, - EXECUTE_LOAD_QUERY_EVENT, - }; - event_type_permutation= perm; - /* - Since we use (permuted) event id's to index the post_header_len - array, we need to permute the post_header_len array too. - */ - uint8 post_header_len_temp[23]; - for (int i= 1; i < 23; i++) - post_header_len_temp[perm[i] - 1]= post_header_len[i - 1]; - for (int i= 0; i < 22; i++) - post_header_len[i] = post_header_len_temp[i]; - } DBUG_VOID_RETURN; } From c50ee6c23dbeb090963580754bec2f0a96ac0557 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:27:52 +0200 Subject: [PATCH 315/324] MDEV-4088 Replication 10.0 -> 5.5 fails --- include/mysql_com.h | 7 +++++++ sql-common/client.c | 6 ++++++ sql/sql_acl.cc | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/include/mysql_com.h b/include/mysql_com.h index 9ba17b416c4..e9a24fd767d 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -34,6 +34,13 @@ #define MYSQL50_TABLE_NAME_PREFIX_LENGTH (sizeof(MYSQL50_TABLE_NAME_PREFIX)-1) #define SAFE_NAME_LEN (NAME_LEN + MYSQL50_TABLE_NAME_PREFIX_LENGTH) +#ifdef EMBEDDED_LIBRARY +#define RPL_VERSION_HACK "" +#else +/* this version must be the one that *does not* support pluggable auth */ +#define RPL_VERSION_HACK "5.5.5-" +#endif + #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 #define LIST_PROCESS_HOST_LEN 64 diff --git a/sql-common/client.c b/sql-common/client.c index 64010919fe3..e48cdac369e 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -3416,6 +3416,12 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, strmov(mysql->server_version,(char*) net->read_pos+1); mysql->port=port; + /* remove the rpl hack from the version string */ + if (mysql->server_capabilities & CLIENT_PLUGIN_AUTH && + strncmp(mysql->server_version, RPL_VERSION_HACK, + sizeof(RPL_VERSION_HACK) - 1) == 0) + mysql->server_version+= sizeof(RPL_VERSION_HACK) - 1; + if (pkt_end >= end + SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323 + 1) { /* diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 56dec73bac5..d9470094c63 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -7957,7 +7957,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, data_len= SCRAMBLE_LENGTH; } - end= strnmov(end, server_version, SERVER_VERSION_LENGTH) + 1; + end= strxnmov(end, SERVER_VERSION_LENGTH, RPL_VERSION_HACK, server_version, NullS) + 1; int4store((uchar*) end, mpvio->thd->thread_id); end+= 4; From 0d25ee4f13b2eb79e9af3b3778c23f63d9a57c12 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 9 Apr 2013 23:28:21 +0200 Subject: [PATCH 316/324] MDEV-4254 Semisync plugins to link statically into MariaDB fix semisync plugins and tests to work with both with static and dynamic linking --- cmake/plugin.cmake | 8 +- mysql-test/include/have_semisync.inc | 4 + mysql-test/include/have_semisync.opt | 4 + mysql-test/include/have_semisync_plugin.inc | 15 -- mysql-test/suite/rpl/r/rpl_mdev359.result | 2 - mysql-test/suite/rpl/r/rpl_semi_sync.result | 69 ++++++---- .../suite/rpl/r/rpl_semi_sync_event.result | 13 +- .../suite/rpl/r/semisync_memleak_4066.result | 2 - mysql-test/suite/rpl/t/rpl_mdev359.test | 7 +- mysql-test/suite/rpl/t/rpl_semi_sync.test | 128 +++++------------- .../suite/rpl/t/rpl_semi_sync_event.test | 37 +---- .../suite/rpl/t/semisync_memleak_4066.test | 6 +- .../rpl_semi_sync_master_enabled_basic.result | 2 - .../rpl_semi_sync_master_timeout_basic.result | 2 - ..._semi_sync_master_trace_level_basic.result | 2 - ...emi_sync_master_wait_no_slave_basic.result | 2 - .../rpl_semi_sync_slave_enabled_basic.result | 2 - ...l_semi_sync_slave_trace_level_basic.result | 2 - .../t/rpl_semi_sync_master_enabled_basic.test | 7 +- .../t/rpl_semi_sync_master_timeout_basic.test | 7 +- ...pl_semi_sync_master_trace_level_basic.test | 7 +- ..._semi_sync_master_wait_no_slave_basic.test | 6 +- .../t/rpl_semi_sync_slave_enabled_basic.test | 7 +- ...rpl_semi_sync_slave_trace_level_basic.test | 7 +- mysql-test/t/mysqld--help.test | 2 +- plugin/semisync/CMakeLists.txt | 7 +- plugin/semisync/semisync_master.cc | 3 +- plugin/semisync/semisync_master.h | 4 +- plugin/semisync/semisync_master_plugin.cc | 12 +- plugin/semisync/semisync_slave_plugin.cc | 11 +- sql/rpl_handler.cc | 20 +++ 31 files changed, 157 insertions(+), 250 deletions(-) create mode 100644 mysql-test/include/have_semisync.inc create mode 100644 mysql-test/include/have_semisync.opt delete mode 100644 mysql-test/include/have_semisync_plugin.inc diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index 2978fb1a13c..f016d8eab4f 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -171,12 +171,12 @@ MACRO(MYSQL_ADD_PLUGIN) IF(ARG_MANDATORY) SET (mysql_mandatory_plugins - "${mysql_mandatory_plugins} builtin_maria_${target}_plugin," - PARENT_SCOPE) + "${mysql_mandatory_plugins} builtin_maria_${target}_plugin,") + SET (mysql_mandatory_plugins ${mysql_mandatory_plugins} PARENT_SCOPE) ELSE() SET (mysql_optional_plugins - "${mysql_optional_plugins} builtin_maria_${target}_plugin," - PARENT_SCOPE) + "${mysql_optional_plugins} builtin_maria_${target}_plugin,") + SET (mysql_optional_plugins ${mysql_optional_plugins} PARENT_SCOPE) ENDIF() ELSEIF(NOT WITHOUT_${plugin} AND NOT ARG_STATIC_ONLY AND NOT WITHOUT_DYNAMIC_PLUGINS) diff --git a/mysql-test/include/have_semisync.inc b/mysql-test/include/have_semisync.inc new file mode 100644 index 00000000000..243fad83717 --- /dev/null +++ b/mysql-test/include/have_semisync.inc @@ -0,0 +1,4 @@ +if (`select count(*) < 2 from information_schema.plugins where plugin_name like 'rpl_semi_sync_%'`) +{ + --skip Test requires semisync plugins +} diff --git a/mysql-test/include/have_semisync.opt b/mysql-test/include/have_semisync.opt new file mode 100644 index 00000000000..2888844cdcd --- /dev/null +++ b/mysql-test/include/have_semisync.opt @@ -0,0 +1,4 @@ +--plugin-load=$SEMISYNC_MASTER_SO +--plugin-load=$SEMISYNC_SLAVE_SO +--loose-rpl-semi-sync-master +--loose-rpl-semi-sync-slave diff --git a/mysql-test/include/have_semisync_plugin.inc b/mysql-test/include/have_semisync_plugin.inc deleted file mode 100644 index 8a1679de636..00000000000 --- a/mysql-test/include/have_semisync_plugin.inc +++ /dev/null @@ -1,15 +0,0 @@ -# -# Check if server has support for loading plugins -# -if (`SELECT @@have_dynamic_loading != 'YES'`) { - --skip Requires dynamic loading -} - -# -# Check if the variable SEMISYNC_MASTER_SO is set -# -if (!$SEMISYNC_MASTER_SO) -{ - skip Need semisync plugins; -} - diff --git a/mysql-test/suite/rpl/r/rpl_mdev359.result b/mysql-test/suite/rpl/r/rpl_mdev359.result index f4382f672e4..c0c7bac1175 100644 --- a/mysql-test/suite/rpl/r/rpl_mdev359.result +++ b/mysql-test/suite/rpl/r/rpl_mdev359.result @@ -1,7 +1,6 @@ include/master-slave.inc [connection master] CREATE TABLE t1 (a INT) ENGINE=MyISAM; -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master'; SET GLOBAL rpl_semi_sync_master_enabled = ON; SET DEBUG_SYNC = "rpl_semisync_master_commit_trx_before_lock SIGNAL m1_ready WAIT_FOR m1_cont"; INSERT INTO t1 SELECT * FROM t1; @@ -9,5 +8,4 @@ SET DEBUG_SYNC= "now WAIT_FOR m1_ready"; SET GLOBAL rpl_semi_sync_master_enabled = OFF; SET DEBUG_SYNC= "now SIGNAL m1_cont"; DROP TABLE t1; -UNINSTALL PLUGIN rpl_semi_sync_master; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync.result b/mysql-test/suite/rpl/r/rpl_semi_sync.result index 51859b5b49b..06eb56a40c5 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync.result @@ -1,13 +1,26 @@ include/master-slave.inc [connection master] +call mtr.add_suppression("Timeout waiting for reply of binlog"); +call mtr.add_suppression("Read semi-sync reply"); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); +call mtr.add_suppression("Master server does not support semi-sync"); +call mtr.add_suppression("Semi-sync slave .* reply"); +call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); # # Uninstall semi-sync plugins on master and slave # include/stop_slave.inc +reset slave; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; +reset master; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; # # Main test of semi-sync replication start here # [ on master ] +set global rpl_semi_sync_master_timeout= 60000; [ default state of semi-sync on master should be OFF ] show variables like 'rpl_semi_sync_master_enabled'; Variable_name Value @@ -41,9 +54,7 @@ Rpl_semi_sync_master_status OFF show status like 'Rpl_semi_sync_master_yes_tx'; Variable_name Value Rpl_semi_sync_master_yes_tx 0 -# -# INSTALL PLUGIN semi-sync on slave -# +reset master; [ on slave ] [ default state of semi-sync on slave should be OFF ] show variables like 'rpl_semi_sync_slave_enabled'; @@ -84,6 +95,16 @@ select CONNECTIONS_NORMAL_SLAVE - CONNECTIONS_NORMAL_SLAVE as 'Should be 0'; Should be 0 0 [ insert records to table ] +insert t1 values (10); +insert t1 values (9); +insert t1 values (8); +insert t1 values (7); +insert t1 values (6); +insert t1 values (5); +insert t1 values (4); +insert t1 values (3); +insert t1 values (2); +insert t1 values (1); [ master status after inserts ] show status like 'Rpl_semi_sync_master_status'; Variable_name Value @@ -159,6 +180,16 @@ Rpl_semi_sync_master_no_tx 1 show status like 'Rpl_semi_sync_master_yes_tx'; Variable_name Value Rpl_semi_sync_master_yes_tx 14 +delete from t1 where a=10; +delete from t1 where a=9; +delete from t1 where a=8; +delete from t1 where a=7; +delete from t1 where a=6; +delete from t1 where a=5; +delete from t1 where a=4; +delete from t1 where a=3; +delete from t1 where a=2; +delete from t1 where a=1; insert into t1 values (100); [ master status should be OFF ] show status like 'Rpl_semi_sync_master_status'; @@ -278,6 +309,7 @@ Rpl_semi_sync_master_yes_tx 0 [ on slave ] include/stop_slave.inc reset slave; +kill query _tid; include/start_slave.inc [ on master ] create table t1 (a int) engine = ENGINE_TYPE; @@ -307,6 +339,7 @@ include/stop_slave.inc reset slave; [ on master ] reset master; +kill query _tid; set sql_log_bin=0; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl_password'; flush privileges; @@ -357,6 +390,7 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status OFF [ on master ] +kill query _tid; [ Semi-sync status on master should be ON ] show status like 'Rpl_semi_sync_master_clients'; Variable_name Value @@ -385,11 +419,7 @@ Variable_name Value Rpl_semi_sync_slave_status ON include/stop_slave.inc [ on master ] -set sql_log_bin=0; -UNINSTALL PLUGIN rpl_semi_sync_master; -set sql_log_bin=1; -SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'; -Variable_name Value +set global rpl_semi_sync_master_enabled= 0; [ on slave ] SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; Variable_name Value @@ -397,18 +427,10 @@ rpl_semi_sync_slave_enabled ON include/start_slave.inc [ on master ] insert into t1 values (10); -[ on slave ] -SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; -Variable_name Value -Rpl_semi_sync_slave_status OFF # # Test non-semi-sync slave connect to semi-sync master # -set sql_log_bin=0; -INSTALL PLUGIN rpl_semi_sync_master SONAME 'SEMISYNC_MASTER_SO'; set global rpl_semi_sync_master_timeout= 5000; -/* 5s */ -set sql_log_bin=1; set global rpl_semi_sync_master_enabled= 1; [ on slave ] include/stop_slave.inc @@ -416,16 +438,8 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; Variable_name Value Rpl_semi_sync_slave_status OFF [ uninstall semi-sync slave plugin ] -UNINSTALL PLUGIN rpl_semi_sync_slave; -SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; -Variable_name Value -include/start_slave.inc -SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; -Variable_name Value -include/stop_slave.inc -[ reinstall semi-sync slave plugin and disable semi-sync ] -INSTALL PLUGIN rpl_semi_sync_slave SONAME 'SEMISYNC_SLAVE_SO'; set global rpl_semi_sync_slave_enabled= 0; +[ reinstall semi-sync slave plugin and disable semi-sync ] SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; Variable_name Value rpl_semi_sync_slave_enabled OFF @@ -440,11 +454,12 @@ Rpl_semi_sync_slave_status OFF # Clean up # include/stop_slave.inc -UNINSTALL PLUGIN rpl_semi_sync_slave; -UNINSTALL PLUGIN rpl_semi_sync_master; +set global rpl_semi_sync_slave_enabled= 0; +set global rpl_semi_sync_master_enabled= 0; change master to master_user='root',master_password=''; include/start_slave.inc drop table t1; drop user rpl@127.0.0.1; flush privileges; +set global rpl_semi_sync_master_timeout= default; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_semi_sync_event.result b/mysql-test/suite/rpl/r/rpl_semi_sync_event.result index 1c6d73fe681..456c0c4475a 100644 --- a/mysql-test/suite/rpl/r/rpl_semi_sync_event.result +++ b/mysql-test/suite/rpl/r/rpl_semi_sync_event.result @@ -1,6 +1,15 @@ include/master-slave.inc [connection master] +call mtr.add_suppression("Timeout waiting for reply of binlog"); +call mtr.add_suppression("Semi-sync master .* waiting for slave reply"); +call mtr.add_suppression("Read semi-sync reply"); +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); +call mtr.add_suppression("Master server does not support semi-sync"); +call mtr.add_suppression("Semi-sync slave .* reply"); +call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); +set global rpl_semi_sync_master_enabled = 1; include/stop_slave.inc +set global rpl_semi_sync_slave_enabled = 1; include/start_slave.inc SET GLOBAL event_scheduler = ON; CREATE TABLE t1 (i INT NOT NULL AUTO_INCREMENT PRIMARY KEY, f varchar(8)) ENGINE=ENGINE_TYPE; @@ -34,8 +43,8 @@ UPDATE t1 SET f = CONCAT('up_',CONNECTION_ID()) WHERE i = 2; UPDATE t1 SET f = CONCAT('up_',CONNECTION_ID()) WHERE i = 1; SET GLOBAL event_scheduler = OFF; include/stop_slave.inc -UNINSTALL PLUGIN rpl_semi_sync_slave; -UNINSTALL PLUGIN rpl_semi_sync_master; +set global rpl_semi_sync_slave_enabled = 0; +set global rpl_semi_sync_master_enabled = 0; include/start_slave.inc DROP EVENT ev1; DROP EVENT ev2; diff --git a/mysql-test/suite/rpl/r/semisync_memleak_4066.result b/mysql-test/suite/rpl/r/semisync_memleak_4066.result index c0dd9f0c993..c599f1426d3 100644 --- a/mysql-test/suite/rpl/r/semisync_memleak_4066.result +++ b/mysql-test/suite/rpl/r/semisync_memleak_4066.result @@ -1,6 +1,4 @@ include/master-slave.inc [connection master] -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; CREATE TEMPORARY TABLE tmp (i INT); include/rpl_end.inc -uninstall plugin rpl_semi_sync_master; diff --git a/mysql-test/suite/rpl/t/rpl_mdev359.test b/mysql-test/suite/rpl/t/rpl_mdev359.test index ef4e41f5291..96c7ac859d9 100644 --- a/mysql-test/suite/rpl/t/rpl_mdev359.test +++ b/mysql-test/suite/rpl/t/rpl_mdev359.test @@ -1,4 +1,4 @@ ---source include/have_semisync_plugin.inc +--source include/have_semisync.inc --source include/not_embedded.inc --source include/have_debug_sync.inc --source include/have_binlog_format_mixed_or_statement.inc @@ -13,7 +13,6 @@ # the code, disable the semisync, and then continue the paused thread. CREATE TABLE t1 (a INT) ENGINE=MyISAM; -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master'; SET GLOBAL rpl_semi_sync_master_enabled = ON; --connection master1 SET DEBUG_SYNC = "rpl_semisync_master_commit_trx_before_lock SIGNAL m1_ready WAIT_FOR m1_cont"; @@ -29,8 +28,4 @@ SET DEBUG_SYNC= "now SIGNAL m1_cont"; connection master; DROP TABLE t1; -disable_warnings; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; - --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync.test b/mysql-test/suite/rpl/t/rpl_semi_sync.test index ac5511e28a3..aa36d70d4b7 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync.test @@ -1,4 +1,4 @@ -source include/have_semisync_plugin.inc; +source include/have_semisync.inc; source include/not_embedded.inc; source include/have_innodb.inc; source include/master-slave.inc; @@ -7,7 +7,6 @@ let $engine_type= InnoDB; #let $engine_type= MyISAM; # Suppress warnings that might be generated during the test -disable_query_log; connection master; call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Read semi-sync reply"); @@ -16,7 +15,6 @@ connection slave; call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); -enable_query_log; connection master; # wait for dying connections (if any) to disappear @@ -32,27 +30,15 @@ let $_connections_normal_slave= query_get_value(SHOW STATUS LIKE 'Threads_connec --echo # Uninstall semi-sync plugins on master and slave --echo # connection slave; -disable_query_log; source include/stop_slave.inc; reset slave; -disable_warnings; -error 0,1305; -UNINSTALL PLUGIN rpl_semi_sync_slave; -error 0,1305; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; connection master; reset master; -set sql_log_bin=0; -disable_warnings; -error 0,1305; -UNINSTALL PLUGIN rpl_semi_sync_slave; -error 0,1305; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; -set sql_log_bin=1; -enable_query_log; +set global rpl_semi_sync_master_enabled= 0; +set global rpl_semi_sync_slave_enabled= 0; --echo # --echo # Main test of semi-sync replication start here @@ -61,16 +47,7 @@ enable_query_log; connection master; echo [ on master ]; -disable_query_log; -let $value = query_get_value(show variables like 'rpl_semi_sync_master_enabled', Value, 1); -if ($value == No such row) -{ - set sql_log_bin=0; - eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; - set global rpl_semi_sync_master_timeout= 60000; /* 60s */ - set sql_log_bin=1; -} -enable_query_log; +set global rpl_semi_sync_master_timeout= 60000; # 60s echo [ default state of semi-sync on master should be OFF ]; show variables like 'rpl_semi_sync_master_enabled'; @@ -116,28 +93,12 @@ show status like 'Rpl_semi_sync_master_status'; --replace_result 305 304 show status like 'Rpl_semi_sync_master_yes_tx'; -disable_query_log; # reset master to make sure the following test will start with a clean environment reset master; -enable_query_log; - ---echo # ---echo # INSTALL PLUGIN semi-sync on slave ---echo # connection slave; echo [ on slave ]; -disable_query_log; -let $value= query_get_value(show variables like 'rpl_semi_sync_slave_enabled', Value, 1); -if ($value == No such row) -{ - set sql_log_bin=0; - eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; - set sql_log_bin=1; -} -enable_query_log; - echo [ default state of semi-sync on slave should be OFF ]; show variables like 'rpl_semi_sync_slave_enabled'; @@ -177,15 +138,17 @@ let $_connections_semisync_slave= query_get_value(SHOW STATUS LIKE 'Threads_conn replace_result $_connections_normal_slave CONNECTIONS_NORMAL_SLAVE $_connections_semisync_slave CONNECTIONS_SEMISYNC_SLAVE; eval select $_connections_semisync_slave - $_connections_normal_slave as 'Should be 0'; -let $i=10; echo [ insert records to table ]; -disable_query_log; -while ($i) -{ - eval insert into t1 values ($i); - dec $i; -} -enable_query_log; +insert t1 values (10); +insert t1 values (9); +insert t1 values (8); +insert t1 values (7); +insert t1 values (6); +insert t1 values (5); +insert t1 values (4); +insert t1 values (3); +insert t1 values (2); +insert t1 values (1); echo [ master status after inserts ]; show status like 'Rpl_semi_sync_master_status'; @@ -271,14 +234,16 @@ show status like 'Rpl_semi_sync_master_yes_tx'; # Semi-sync status on master is now OFF, so all these transactions # will be replicated asynchronously. -let $i=10; -disable_query_log; -while ($i) -{ - eval delete from t1 where a=$i; - dec $i; -} -enable_query_log; +delete from t1 where a=10; +delete from t1 where a=9; +delete from t1 where a=8; +delete from t1 where a=7; +delete from t1 where a=6; +delete from t1 where a=5; +delete from t1 where a=4; +delete from t1 where a=3; +delete from t1 where a=2; +delete from t1 where a=1; insert into t1 values (100); @@ -408,9 +373,8 @@ connection master; let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; if ($_tid) { - disable_query_log; + --replace_result $_tid _tid eval kill query $_tid; - enable_query_log; # After dump thread exit, Rpl_semi_sync_master_clients will be 0 let $status_var= Rpl_semi_sync_master_clients; @@ -463,9 +427,8 @@ reset master; let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; if ($_tid) { - disable_query_log; + --replace_result $_tid _tid eval kill query $_tid; - enable_query_log; # After dump thread exit, Rpl_semi_sync_master_clients will be 0 let $status_var= Rpl_semi_sync_master_clients; @@ -525,9 +488,8 @@ echo [ on master ]; let $_tid= `select id from information_schema.processlist where command = 'Binlog Dump' limit 1`; if ($_tid) { - disable_query_log; + --replace_result $_tid _tid eval kill query $_tid; - enable_query_log; # After dump thread exit, Rpl_semi_sync_master_clients will be 0 let $status_var= Rpl_semi_sync_master_clients; @@ -562,11 +524,7 @@ connection slave; source include/stop_slave.inc; connection master; echo [ on master ]; -set sql_log_bin=0; -UNINSTALL PLUGIN rpl_semi_sync_master; -set sql_log_bin=1; -enable_query_log; -SHOW VARIABLES LIKE 'rpl_semi_sync_master_enabled'; +set global rpl_semi_sync_master_enabled= 0; connection slave; echo [ on slave ]; @@ -577,19 +535,13 @@ connection master; echo [ on master ]; insert into t1 values (10); sync_slave_with_master; -echo [ on slave ]; -SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; --echo # --echo # Test non-semi-sync slave connect to semi-sync master --echo # connection master; -set sql_log_bin=0; -replace_result $SEMISYNC_MASTER_SO SEMISYNC_MASTER_SO; -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; -set global rpl_semi_sync_master_timeout= 5000; /* 5s */ -set sql_log_bin=1; +set global rpl_semi_sync_master_timeout= 5000; # 5s set global rpl_semi_sync_master_enabled= 1; connection slave; @@ -598,16 +550,9 @@ source include/stop_slave.inc; SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; echo [ uninstall semi-sync slave plugin ]; -UNINSTALL PLUGIN rpl_semi_sync_slave; -SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; -source include/start_slave.inc; -SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; -source include/stop_slave.inc; +set global rpl_semi_sync_slave_enabled= 0; echo [ reinstall semi-sync slave plugin and disable semi-sync ]; -replace_result $SEMISYNC_SLAVE_SO SEMISYNC_SLAVE_SO; -eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; -set global rpl_semi_sync_slave_enabled= 0; SHOW VARIABLES LIKE 'rpl_semi_sync_slave_enabled'; SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; source include/start_slave.inc; @@ -619,14 +564,10 @@ SHOW STATUS LIKE 'Rpl_semi_sync_slave_status'; connection slave; source include/stop_slave.inc; -UNINSTALL PLUGIN rpl_semi_sync_slave; +set global rpl_semi_sync_slave_enabled= 0; connection master; -# The dump thread may still be running on the master, and so the following -# UNINSTALL could generate a warning about the plugin is busy. -disable_warnings; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; +set global rpl_semi_sync_master_enabled= 0; connection slave; change master to master_user='root',master_password=''; @@ -639,4 +580,5 @@ sync_slave_with_master; connection master; drop user rpl@127.0.0.1; flush privileges; +set global rpl_semi_sync_master_timeout= default; --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test index b4a9a9e6e59..b8f3c8130be 100644 --- a/mysql-test/suite/rpl/t/rpl_semi_sync_event.test +++ b/mysql-test/suite/rpl/t/rpl_semi_sync_event.test @@ -1,12 +1,11 @@ -source include/have_semisync_plugin.inc; +source include/have_semisync.inc; source include/not_embedded.inc; -source include/master-slave.inc; source include/have_innodb.inc; +source include/master-slave.inc; let $engine_type= InnoDB; # Suppress warnings that might be generated during the test -disable_query_log; connection master; call mtr.add_suppression("Timeout waiting for reply of binlog"); call mtr.add_suppression("Semi-sync master .* waiting for slave reply"); @@ -16,33 +15,13 @@ connection slave; call mtr.add_suppression("Master server does not support semi-sync"); call mtr.add_suppression("Semi-sync slave .* reply"); call mtr.add_suppression("Slave SQL.*Request to stop slave SQL Thread received while applying a group that has non-transactional changes; waiting for completion of the group"); -enable_query_log; connection master; -disable_query_log; -let $value = query_get_value(show variables like 'rpl_semi_sync_master_enabled', Value, 1); -if ($value == No such row) -{ - set sql_log_bin=0; - eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; - SET GLOBAL rpl_semi_sync_master_enabled = 1; - set sql_log_bin=1; -} -enable_query_log; +set global rpl_semi_sync_master_enabled = 1; connection slave; source include/stop_slave.inc; - -disable_query_log; -let $value= query_get_value(show variables like 'rpl_semi_sync_slave_enabled', Value, 1); -if ($value == No such row) -{ - set sql_log_bin=0; - eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; - SET GLOBAL rpl_semi_sync_slave_enabled = 1; - set sql_log_bin=1; -} -enable_query_log; +set global rpl_semi_sync_slave_enabled = 1; source include/start_slave.inc; @@ -93,18 +72,16 @@ while ($run) # connection slave; source include/stop_slave.inc; - -disable_warnings; -UNINSTALL PLUGIN rpl_semi_sync_slave; +set global rpl_semi_sync_slave_enabled = 0; connection master; -UNINSTALL PLUGIN rpl_semi_sync_master; -enable_warnings; +set global rpl_semi_sync_master_enabled = 0; connection slave; source include/start_slave.inc; connection master; + DROP EVENT ev1; DROP EVENT ev2; DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/semisync_memleak_4066.test b/mysql-test/suite/rpl/t/semisync_memleak_4066.test index 687af883936..f888f764b43 100644 --- a/mysql-test/suite/rpl/t/semisync_memleak_4066.test +++ b/mysql-test/suite/rpl/t/semisync_memleak_4066.test @@ -1,19 +1,15 @@ # # MDEV-4066 semisync_master + temporary tables causes memory leaks # -source include/have_semisync_plugin.inc; +source include/have_semisync.inc; source include/have_binlog_format_row.inc; source include/master-slave.inc; connection master; ---replace_result .dll .so -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; - --connect (con1,localhost,root,,) CREATE TEMPORARY TABLE tmp (i INT); --disconnect con1 source include/rpl_end.inc; -uninstall plugin rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result index 3e444519441..7454f0b0089 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_enabled_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; select @@global.rpl_semi_sync_master_enabled; @@global.rpl_semi_sync_master_enabled 0 @@ -70,4 +69,3 @@ SET @@global.rpl_semi_sync_master_enabled = @start_global_value; select @@global.rpl_semi_sync_master_enabled; @@global.rpl_semi_sync_master_enabled 0 -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_timeout_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_timeout_basic.result index e77bcc1c12a..78fee2a91dc 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_timeout_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_timeout_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; select @@global.rpl_semi_sync_master_timeout; @@global.rpl_semi_sync_master_timeout 10000 @@ -51,4 +50,3 @@ SET @@global.rpl_semi_sync_master_timeout = @start_global_value; select @@global.rpl_semi_sync_master_timeout; @@global.rpl_semi_sync_master_timeout 10000 -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_trace_level_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_trace_level_basic.result index 55df5f57d9e..1096fa995e7 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_trace_level_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_trace_level_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; select @@global.rpl_semi_sync_master_trace_level; @@global.rpl_semi_sync_master_trace_level 32 @@ -69,4 +68,3 @@ SET @@global.rpl_semi_sync_master_trace_level = @start_global_value; select @@global.rpl_semi_sync_master_trace_level; @@global.rpl_semi_sync_master_trace_level 32 -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_wait_no_slave_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_wait_no_slave_basic.result index 3d951b499ed..535f777eff7 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_wait_no_slave_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_master_wait_no_slave_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; select @@global.rpl_semi_sync_master_wait_no_slave; @@global.rpl_semi_sync_master_wait_no_slave 1 @@ -70,4 +69,3 @@ SET @@global.rpl_semi_sync_master_wait_no_slave = @start_global_value; select @@global.rpl_semi_sync_master_wait_no_slave; @@global.rpl_semi_sync_master_wait_no_slave 1 -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_enabled_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_enabled_basic.result index a23b160e6f2..f52e8e80127 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_enabled_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_enabled_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; select @@global.rpl_semi_sync_slave_enabled; @@global.rpl_semi_sync_slave_enabled 0 @@ -70,4 +69,3 @@ SET @@global.rpl_semi_sync_slave_enabled = @start_global_value; select @@global.rpl_semi_sync_slave_enabled; @@global.rpl_semi_sync_slave_enabled 0 -UNINSTALL PLUGIN rpl_semi_sync_slave; diff --git a/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_trace_level_basic.result b/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_trace_level_basic.result index f7796309aea..9917ec6fce5 100644 --- a/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_trace_level_basic.result +++ b/mysql-test/suite/sys_vars/r/rpl_semi_sync_slave_trace_level_basic.result @@ -1,4 +1,3 @@ -INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; select @@global.rpl_semi_sync_slave_trace_level; @@global.rpl_semi_sync_slave_trace_level 32 @@ -69,4 +68,3 @@ SET @@global.rpl_semi_sync_slave_trace_level = @start_global_value; select @@global.rpl_semi_sync_slave_trace_level; @@global.rpl_semi_sync_slave_trace_level 32 -UNINSTALL PLUGIN rpl_semi_sync_slave; diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test index ded489f36ff..2ff03a53c42 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_enabled_basic.test @@ -6,10 +6,7 @@ # # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_master_enabled; SET @start_global_value = @@global.rpl_semi_sync_master_enabled; @@ -61,5 +58,3 @@ set global rpl_semi_sync_master_enabled="some text"; # SET @@global.rpl_semi_sync_master_enabled = @start_global_value; select @@global.rpl_semi_sync_master_enabled; -UNINSTALL PLUGIN rpl_semi_sync_master; - diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test index 5258894150d..74d3c41150b 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_timeout_basic.test @@ -5,10 +5,7 @@ # 2010-01-21 OBN - Added # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_master_timeout; SET @start_global_value = @@global.rpl_semi_sync_master_timeout; @@ -51,5 +48,3 @@ set global rpl_semi_sync_master_timeout="some text"; # SET @@global.rpl_semi_sync_master_timeout = @start_global_value; select @@global.rpl_semi_sync_master_timeout; -UNINSTALL PLUGIN rpl_semi_sync_master; - diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test index d9b1d860b35..c41b53fe5e6 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_trace_level_basic.test @@ -5,10 +5,7 @@ # 2010-01-21 OBN - Added # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_master_trace_level; SET @start_global_value = @@global.rpl_semi_sync_master_trace_level; @@ -59,5 +56,3 @@ set global rpl_semi_sync_master_trace_level="some text"; # SET @@global.rpl_semi_sync_master_trace_level = @start_global_value; select @@global.rpl_semi_sync_master_trace_level; -UNINSTALL PLUGIN rpl_semi_sync_master; - diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test index 896bd50d156..d4a46a08140 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_master_wait_no_slave_basic.test @@ -6,10 +6,7 @@ # # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_master SONAME '$SEMISYNC_MASTER_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_master_wait_no_slave; SET @start_global_value = @@global.rpl_semi_sync_master_wait_no_slave; @@ -61,5 +58,4 @@ set global rpl_semi_sync_master_wait_no_slave="some text"; # SET @@global.rpl_semi_sync_master_wait_no_slave = @start_global_value; select @@global.rpl_semi_sync_master_wait_no_slave; -UNINSTALL PLUGIN rpl_semi_sync_master; diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test index 030b0827a11..c7ce371970d 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_enabled_basic.test @@ -6,10 +6,7 @@ # # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_slave_enabled; SET @start_global_value = @@global.rpl_semi_sync_slave_enabled; @@ -62,5 +59,3 @@ set global rpl_semi_sync_slave_enabled="some text"; # SET @@global.rpl_semi_sync_slave_enabled = @start_global_value; select @@global.rpl_semi_sync_slave_enabled; -UNINSTALL PLUGIN rpl_semi_sync_slave; - diff --git a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test index 64c935ee957..d7e001b7322 100644 --- a/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test +++ b/mysql-test/suite/sys_vars/t/rpl_semi_sync_slave_trace_level_basic.test @@ -5,10 +5,7 @@ # 2010-01-21 OBN - Added # source include/not_embedded.inc; -source include/have_semisync_plugin.inc; -# The following is to prevent a mis-match on windows that has the name of of the lib ending with 'dll' ---replace_regex /\.dll/.so/ -eval INSTALL PLUGIN rpl_semi_sync_slave SONAME '$SEMISYNC_SLAVE_SO'; +source include/have_semisync.inc; select @@global.rpl_semi_sync_slave_trace_level; SET @start_global_value = @@global.rpl_semi_sync_slave_trace_level; @@ -59,5 +56,3 @@ set global rpl_semi_sync_slave_trace_level="some text"; # SET @@global.rpl_semi_sync_slave_trace_level = @start_global_value; select @@global.rpl_semi_sync_slave_trace_level; -UNINSTALL PLUGIN rpl_semi_sync_slave; - diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index 33bb50537ca..d1b68192250 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -27,7 +27,7 @@ perl; feedback debug temp-pool ssl des-key-file xtradb sequence thread-concurrency super-large-pages mutex-deadlock-detector null-audit aria pbxt oqgraph sphinx thread-handling - test-sql-discovery query-cache-info/; + test-sql-discovery rpl-semi-sync query-cache-info/; # And substitute the content some environment variables with their # names: diff --git a/plugin/semisync/CMakeLists.txt b/plugin/semisync/CMakeLists.txt index f1ada507f4f..33c0895e5e1 100644 --- a/plugin/semisync/CMakeLists.txt +++ b/plugin/semisync/CMakeLists.txt @@ -17,11 +17,10 @@ SET(SEMISYNC_MASTER_SOURCES semisync.cc semisync_master.cc semisync_master_plugin.cc semisync.h semisync_master.h) -MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES} - MODULE_ONLY MODULE_OUTPUT_NAME "semisync_master") +MYSQL_ADD_PLUGIN(semisync_master ${SEMISYNC_MASTER_SOURCES}) SET(SEMISYNC_SLAVE_SOURCES semisync.cc semisync_slave.cc semisync_slave_plugin.cc semisync.h semisync_slave.h ) -MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES} - MODULE_ONLY MODULE_OUTPUT_NAME "semisync_slave") + +MYSQL_ADD_PLUGIN(semisync_slave ${SEMISYNC_SLAVE_SOURCES}) diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc index f8eb962b857..88ae34e2a2d 100644 --- a/plugin/semisync/semisync_master.cc +++ b/plugin/semisync/semisync_master.cc @@ -429,12 +429,13 @@ int ReplSemiSyncMaster::disableMaster() return 0; } -ReplSemiSyncMaster::~ReplSemiSyncMaster() +void ReplSemiSyncMaster::cleanup() { if (init_done_) { mysql_mutex_destroy(&LOCK_binlog_); mysql_cond_destroy(&COND_binlog_send_); + init_done_= 0; } delete active_tranxs_; diff --git a/plugin/semisync/semisync_master.h b/plugin/semisync/semisync_master.h index 841c24197fc..9b266ca6565 100644 --- a/plugin/semisync/semisync_master.h +++ b/plugin/semisync/semisync_master.h @@ -453,7 +453,9 @@ class ReplSemiSyncMaster public: ReplSemiSyncMaster(); - ~ReplSemiSyncMaster(); + ~ReplSemiSyncMaster() {} + + void cleanup(); bool getMasterEnabled() { return master_enabled_; diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc index c811cb1cc9e..81ed9b55d99 100644 --- a/plugin/semisync/semisync_master_plugin.cc +++ b/plugin/semisync/semisync_master_plugin.cc @@ -19,7 +19,7 @@ #include "semisync_master.h" #include "sql_class.h" // THD -ReplSemiSyncMaster repl_semisync; +static ReplSemiSyncMaster repl_semisync; C_MODE_START @@ -405,6 +405,7 @@ static int semi_sync_master_plugin_deinit(void *p) sql_print_error("unregister_binlog_transmit_observer failed"); return 1; } + repl_semisync.cleanup(); sql_print_information("unregister_replicator OK"); return 0; } @@ -416,7 +417,7 @@ struct Mysql_replication semi_sync_master_plugin= { /* Plugin library descriptor */ -mysql_declare_plugin(semi_sync_master) +maria_declare_plugin(semisync_master) { MYSQL_REPLICATION_PLUGIN, &semi_sync_master_plugin, @@ -429,7 +430,8 @@ mysql_declare_plugin(semi_sync_master) 0x0100 /* 1.0 */, semi_sync_master_status_vars, /* status variables */ semi_sync_master_system_vars, /* system variables */ - NULL, /* config options */ - 0, /* flags */ + "1.0", + MariaDB_PLUGIN_MATURITY_UNKNOWN } -mysql_declare_plugin_end; +maria_declare_plugin_end; + diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc index 5d373fa0862..96e614b845e 100644 --- a/plugin/semisync/semisync_slave_plugin.cc +++ b/plugin/semisync/semisync_slave_plugin.cc @@ -18,7 +18,7 @@ #include "semisync_slave.h" #include -ReplSemiSyncSlave repl_semisync; +static ReplSemiSyncSlave repl_semisync; /* indicate whether or not the slave should send a reply to the master. @@ -212,7 +212,7 @@ struct Mysql_replication semi_sync_slave_plugin= { /* Plugin library descriptor */ -mysql_declare_plugin(semi_sync_slave) +maria_declare_plugin(semisync_slave) { MYSQL_REPLICATION_PLUGIN, &semi_sync_slave_plugin, @@ -225,7 +225,8 @@ mysql_declare_plugin(semi_sync_slave) 0x0100 /* 1.0 */, semi_sync_slave_status_vars, /* status variables */ semi_sync_slave_system_vars, /* system variables */ - NULL, /* config options */ - 0, /* flags */ + "1.0", + MariaDB_PLUGIN_MATURITY_UNKNOWN } -mysql_declare_plugin_end; +maria_declare_plugin_end; + diff --git a/sql/rpl_handler.cc b/sql/rpl_handler.cc index 258dae0edb2..1d21b3f9445 100644 --- a/sql/rpl_handler.cc +++ b/sql/rpl_handler.cc @@ -555,4 +555,24 @@ int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void { return binlog_relay_io_delegate->remove_observer(observer, (st_plugin_int *)p); } +#else +int register_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p) +{ + return 0; +} + +int unregister_binlog_transmit_observer(Binlog_transmit_observer *observer, void *p) +{ + return 0; +} + +int register_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p) +{ + return 0; +} + +int unregister_binlog_relay_io_observer(Binlog_relay_IO_observer *observer, void *p) +{ + return 0; +} #endif /* HAVE_REPLICATION */ From 3ed6b24d820edbee3bc333c726dd0aa66c015b56 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 10 Apr 2013 07:25:13 +0200 Subject: [PATCH 317/324] Linking problem on Windows --- storage/innobase/handler/handler0alter.cc | 6 ++---- storage/xtradb/handler/handler0alter.cc | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 3f61fbb3302..9019c7ba5df 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -310,8 +310,7 @@ innobase_check_index_keys( } } - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->table->file->table_type(), + my_error(ER_WRONG_KEY_COLUMN, MYF(0), "InnoDB", field->field_name); return(ER_WRONG_KEY_COLUMN); } @@ -325,8 +324,7 @@ innobase_check_index_keys( continue; } - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->table->file->table_type(), + my_error(ER_WRONG_KEY_COLUMN, MYF(0), "InnoDB", key_part1.field->field_name); return(ER_WRONG_KEY_COLUMN); } diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 3a32cf95bc9..9886e8f6bd9 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -311,8 +311,7 @@ innobase_check_index_keys( } } - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->table->file->table_type(), + my_error(ER_WRONG_KEY_COLUMN, MYF(0), "InnoDB", field->field_name); return(ER_WRONG_KEY_COLUMN); } @@ -326,8 +325,7 @@ innobase_check_index_keys( continue; } - my_error(ER_WRONG_KEY_COLUMN, MYF(0), - field->table->file->table_type(), + my_error(ER_WRONG_KEY_COLUMN, MYF(0), "InnoDB", key_part1.field->field_name); return(ER_WRONG_KEY_COLUMN); } From ff3407a111ec268e7bd5e726a75527089871c914 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 10 Apr 2013 15:43:57 +0200 Subject: [PATCH 318/324] portability fixes for mysql-test mysql-test/r/mysqld--help.result: that's default to number of CPUs mysql-test/suite/archive/discover.test: move_file uses rename(2), which may end up with "Invalid cross-device link" mysql-test/suite/archive/partition_archive.test: on Solaris the error message is different --- mysql-test/r/mysqld--help,win.rdiff | 61 +++++++++++++++---- mysql-test/r/mysqld--help.result | 1 - mysql-test/suite/archive/discover.test | 4 +- .../suite/archive/partition_archive.test | 2 +- .../suite/plugins/t/show_all_plugins.test | 10 ++- mysql-test/t/mysqld--help.test | 2 +- 6 files changed, 62 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/mysqld--help,win.rdiff b/mysql-test/r/mysqld--help,win.rdiff index cd39445f3e6..24719fce917 100644 --- a/mysql-test/r/mysqld--help,win.rdiff +++ b/mysql-test/r/mysqld--help,win.rdiff @@ -1,6 +1,6 @@ --- mysql-test/r/mysqld--help.result 2012-09-08 22:22:06 +0000 +++ mysql-test/r/mysqld--help.result 2012-10-01 14:03:59 +0000 -@@ -244,7 +244,6 @@ +@@ -248,7 +248,6 @@ The number of segments in a key cache -L, --language=name Client error messages in given language. May be given as a full path. Deprecated. Use --lc-messages-dir instead. @@ -8,7 +8,7 @@ --lc-messages=name Set the language used for the error messages. -L, --lc-messages-dir=name Directory where error messages are -@@ -440,6 +439,7 @@ +@@ -443,6 +442,7 @@ NULLS_UNEQUAL (default behavior for 4.1 and later), NULLS_EQUAL (emulate 4.0 behavior), and NULLS_IGNORED --myisam-use-mmap Use memory mapping for reading and writing MyISAM tables @@ -16,7 +16,7 @@ --net-buffer-length=# Buffer length for TCP/IP and socket communication --net-read-timeout=# -@@ -707,6 +707,9 @@ +@@ -710,6 +710,9 @@ files within specified directory --server-id=# Uniquely identifies the server instance in the community of replication partners @@ -26,7 +26,7 @@ --show-slave-auth-info Show user and password in SHOW SLAVE HOSTS on this master. -@@ -774,6 +777,10 @@ +@@ -777,6 +780,10 @@ Log slow queries to given log file. Defaults logging to 'hostname'-slow.log. Must be enabled to activate other slow log options @@ -37,7 +37,7 @@ --socket=name Socket file to use for connection --sort-buffer-size=# Each thread that needs to do a sort allocates a buffer of -@@ -782,6 +789,7 @@ +@@ -785,6 +792,7 @@ for the complete list of valid sql modes --stack-trace Print a symbolic stack trace on failure (Defaults to on; use --skip-stack-trace to disable.) @@ -45,7 +45,35 @@ --stored-program-cache=# The soft upper limit for number of cached stored routines for one connection. -@@ -822,8 +830,8 @@ +@@ -817,25 +825,11 @@ + values are COMMIT or ROLLBACK. + --thread-cache-size=# + How many threads we should keep in a cache for reuse +- --thread-pool-idle-timeout=# +- Timeout in seconds for an idle thread in the thread +- pool.Worker thread will be shut down after timeout + --thread-pool-max-threads=# + Maximum allowed number of worker threads in the thread + pool +- --thread-pool-oversubscribe=# +- How many additional active worker threads in a group are +- allowed. +- --thread-pool-size=# +- Number of thread groups in the pool. This parameter is +- roughly equivalent to maximum number of concurrently +- executing threads (threads in a waiting state do not +- count as executing). +- --thread-pool-stall-limit=# +- Maximum query execution time in milliseconds,before an +- executing non-yielding thread is considered stalled.If a +- worker thread is stalled, additional worker thread may be +- created to handle remaining clients. ++ --thread-pool-min-threads=# ++ Minimum number of threads in the thread pool. + --thread-stack=# The stack size for each thread + --time-format=name The TIME format (ignored) + --timed-mutexes Specify whether to time mutexes (only InnoDB mutexes are +@@ -844,8 +838,8 @@ size, MySQL will automatically convert it to an on-disk MyISAM or Aria table -t, --tmpdir=name Path for temporary files. Several paths may be specified, @@ -56,7 +84,7 @@ --transaction-alloc-block-size=# Allocation block size for transactions to be stored in binary log -@@ -923,7 +931,6 @@ key-cache-age-threshold 300 +@@ -949,7 +943,6 @@ key-cache-block-size 1024 key-cache-division-limit 100 key-cache-segments 0 @@ -64,7 +92,7 @@ lc-messages en_US lc-messages-dir MYSQL_SHAREDIR/ lc-time-names en_US -@@ -986,6 +993,7 @@ myisam-repair-threads 1 +@@ -1012,6 +1005,7 @@ myisam-sort-buffer-size 8388608 myisam-stats-method nulls_unequal myisam-use-mmap FALSE @@ -72,7 +100,7 @@ net-buffer-length 16384 net-read-timeout 30 net-retry-count 10 -@@ -1051,6 +1059,8 @@ safe-user-create FALSE +@@ -1077,6 +1071,8 @@ secure-auth FALSE secure-file-priv (No default value) server-id 0 @@ -81,7 +109,7 @@ show-slave-auth-info FALSE skip-grant-tables TRUE skip-name-resolve FALSE -@@ -1067,6 +1077,7 @@ slave-transaction-retries 10 +@@ -1093,6 +1089,7 @@ slave-type-conversions slow-launch-time 2 slow-query-log FALSE @@ -89,4 +117,15 @@ sort-buffer-size 2097152 sql-mode stack-trace TRUE - +@@ -1109,10 +1106,8 @@ + table-open-cache 400 + tc-heuristic-recover COMMIT + thread-cache-size 0 +-thread-pool-idle-timeout 60 + thread-pool-max-threads 500 +-thread-pool-oversubscribe 3 +-thread-pool-stall-limit 500 ++thread-pool-min-threads 1 + thread-stack 294912 + time-format %H:%i:%s + timed-mutexes FALSE diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index e5edb963ca9..2a551b1175e 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -1112,7 +1112,6 @@ thread-cache-size 0 thread-pool-idle-timeout 60 thread-pool-max-threads 500 thread-pool-oversubscribe 3 -thread-pool-size 4 thread-pool-stall-limit 500 thread-stack 294912 time-format %H:%i:%s diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index 75668baafbf..0b7e521185d 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -53,7 +53,9 @@ rename table t2 to t0; --echo # copy_file $mysqld_datadir/test/t1.ARZ $MYSQL_TMP_DIR/t1.ARZ; alter table t1 modify a int default 5; -move_file $MYSQL_TMP_DIR/t1.ARZ $mysqld_datadir/test/t1.ARZ; +remove_file $mysqld_datadir/test/t1.ARZ; +copy_file $MYSQL_TMP_DIR/t1.ARZ $mysqld_datadir/test/t1.ARZ; +remove_file $MYSQL_TMP_DIR/t1.ARZ; show create table t1; --echo # diff --git a/mysql-test/suite/archive/partition_archive.test b/mysql-test/suite/archive/partition_archive.test index e4cc39ff097..be2abeada73 100644 --- a/mysql-test/suite/archive/partition_archive.test +++ b/mysql-test/suite/archive/partition_archive.test @@ -47,7 +47,7 @@ engine=archive partition by list (a) (partition p0 values in (1), partition p1 values in (2)); insert into t1 values (1), (2); ---replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ +--replace_regex /#sql-[0-9a-f_]+/#sql-temporary/ /Not owner/Operation not permitted/ --error ER_CANT_CREATE_TABLE create index inx on t1 (a); alter table t1 add partition (partition p2 values in (3)); diff --git a/mysql-test/suite/plugins/t/show_all_plugins.test b/mysql-test/suite/plugins/t/show_all_plugins.test index dcc0fb09bd3..1beca12b52c 100644 --- a/mysql-test/suite/plugins/t/show_all_plugins.test +++ b/mysql-test/suite/plugins/t/show_all_plugins.test @@ -8,15 +8,19 @@ show status like '%libraries%'; #--sorted_result #select * from information_schema.all_plugins; #show status like '%libraries%'; -select * from information_schema.all_plugins where plugin_library='ha_example.so'; +--replace_result .dll .so +eval select * from information_schema.all_plugins where plugin_library='$HA_EXAMPLE_SO'; show status like '%libraries%'; --sorted_result -show plugins soname 'ha_example.so'; +--replace_result .dll .so +eval show plugins soname '$HA_EXAMPLE_SO'; show status like '%libraries%'; --sorted_result +--replace_result .dll .so show plugins soname like '%example%'; show status like '%libraries%'; --sorted_result -show plugins soname where library = 'ha_example.so'; +--replace_result .dll .so +eval show plugins soname where library = '$HA_EXAMPLE_SO'; select variable_value > 10 from information_schema.global_status where variable_name like '%libraries%'; diff --git a/mysql-test/t/mysqld--help.test b/mysql-test/t/mysqld--help.test index d1b68192250..0f3df10ea70 100644 --- a/mysql-test/t/mysqld--help.test +++ b/mysql-test/t/mysqld--help.test @@ -20,7 +20,7 @@ perl; # their paths may vary: @skipvars=qw/basedir open-files-limit general-log-file log plugin-dir log-slow-queries pid-file slow-query-log-file log-basename - datadir slave-load-tmpdir tmpdir socket/; + datadir slave-load-tmpdir tmpdir socket thread-pool-size/; # Plugins which may or may not be there: @plugins=qw/innodb ndb archive blackhole federated partition ndbcluster From 4494c804b8e5d33ae95223bcdd24c7c138901221 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 12 Apr 2013 01:05:29 +0200 Subject: [PATCH 319/324] complier warnings. hide the redundant condition under #ifdef (because only there it makes any sense) --- sql/table.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/table.cc b/sql/table.cc index c92a096be90..77e251729c7 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3537,9 +3537,9 @@ bool check_column_name(const char *name) } #else last_char_is_space= *name==' '; -#endif - if (*name == NAMES_SEP_CHAR) + if (*name == '\377') return 1; +#endif name++; name_length++; } From aa4c7deac71217d984d4fceca3b60d486eaaf7db Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 12 Apr 2013 13:19:00 +0300 Subject: [PATCH 320/324] Increase default value of max_binlog_cache_size and max_binlog_stmt_cache_size to ulonglong_max. This fixes that by default LOAD DATA INFILE will not generate the error: "Multi-statement transaction required more than 'max_binlog_cache_size' bytes of storage..." mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result: Updated test case mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result: Updated test case sql/sys_vars.cc: Increase default value of max_binlog_cache_size and max_binlog_stmt_cache_size to ulonglong_max. --- .../suite/sys_vars/r/max_binlog_cache_size_basic.result | 6 +++--- .../sys_vars/r/max_binlog_stmt_cache_size_basic.result | 6 +++--- sql/sys_vars.cc | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result b/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result index 9f630e8bb00..bb7492ee7ef 100644 --- a/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result +++ b/mysql-test/suite/sys_vars/r/max_binlog_cache_size_basic.result @@ -1,7 +1,7 @@ SET @start_value = @@global.max_binlog_cache_size; SELECT @start_value; @start_value -4294963200 +18446744073709547520 '#--------------------FN_DYNVARS_072_01------------------------#' SET @@global.max_binlog_cache_size = 5000; Warnings: @@ -9,7 +9,7 @@ Warning 1292 Truncated incorrect max_binlog_cache_size value: '5000' SET @@global.max_binlog_cache_size = DEFAULT; SELECT @@global.max_binlog_cache_size; @@global.max_binlog_cache_size -4294963200 +18446744073709547520 '#---------------------FN_DYNVARS_072_02-------------------------#' SET @@global.max_binlog_cache_size = @start_value; SELECT @@global.max_binlog_cache_size = 4294967295; @@ -149,4 +149,4 @@ ERROR 42S22: Unknown column 'max_binlog_cache_size' in 'field list' SET @@global.max_binlog_cache_size = @start_value; SELECT @@global.max_binlog_cache_size; @@global.max_binlog_cache_size -4294963200 +18446744073709547520 diff --git a/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result b/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result index 14407672aa3..0b2db8eef69 100644 --- a/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result +++ b/mysql-test/suite/sys_vars/r/max_binlog_stmt_cache_size_basic.result @@ -1,7 +1,7 @@ SET @start_value = @@global.max_binlog_stmt_cache_size; SELECT @start_value; @start_value -4294963200 +18446744073709547520 '#--------------------FN_DYNVARS_072_01------------------------#' SET @@global.max_binlog_stmt_cache_size = 5000; Warnings: @@ -9,7 +9,7 @@ Warning 1292 Truncated incorrect max_binlog_stmt_cache_size value: '5000' SET @@global.max_binlog_stmt_cache_size = DEFAULT; SELECT @@global.max_binlog_stmt_cache_size; @@global.max_binlog_stmt_cache_size -4294963200 +18446744073709547520 '#---------------------FN_DYNVARS_072_02-------------------------#' SET @@global.max_binlog_stmt_cache_size = @start_value; SELECT @@global.max_binlog_stmt_cache_size = 4294967295; @@ -149,4 +149,4 @@ ERROR 42S22: Unknown column 'max_binlog_stmt_cache_size' in 'field list' SET @@global.max_binlog_stmt_cache_size = @start_value; SELECT @@global.max_binlog_stmt_cache_size; @@global.max_binlog_stmt_cache_size -4294963200 +18446744073709547520 diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 76486dcca71..3df2605f834 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -1068,7 +1068,7 @@ static Sys_var_ulonglong Sys_max_binlog_cache_size( "Sets the total size of the transactional cache", GLOBAL_VAR(max_binlog_cache_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(IO_SIZE, ULONGLONG_MAX), - DEFAULT((UINT_MAX/IO_SIZE)*IO_SIZE), + DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE), BLOCK_SIZE(IO_SIZE)); static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size( @@ -1076,7 +1076,7 @@ static Sys_var_ulonglong Sys_max_binlog_stmt_cache_size( "Sets the total size of the statement cache", GLOBAL_VAR(max_binlog_stmt_cache_size), CMD_LINE(REQUIRED_ARG), VALID_RANGE(IO_SIZE, ULONGLONG_MAX), - DEFAULT((UINT_MAX/IO_SIZE)*IO_SIZE), + DEFAULT((ULONGLONG_MAX/IO_SIZE)*IO_SIZE), BLOCK_SIZE(IO_SIZE)); static bool fix_max_binlog_size(sys_var *self, THD *thd, enum_var_type type) From 1a600125ff77b57f6bcb57ba2fff45293ab7257d Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 12 Apr 2013 18:06:51 +0500 Subject: [PATCH 321/324] MDEV-3917 multiple use locks (GET_LOCK) in one connection. The patch contributed by Konstantin Osipov applied. Native comments: Implement multiple user-level locks per connection. GET_LOCK() function in MySQL allows a connection to hold at most one user level lock. Taking a new lock automatically releases the old lock, if any. The limit of one lock per session existed since early versions of MySQL didn't have a deadlock detector for SQL locks. MDL patches in MySQL 5.5 added a deadlock detector, so starting from 5.5 it became possible to take multiple locks in any order -- a deadlock, should it occur, would be detected and an error returned to the client which closed the wait chain. This is exactly what is done in this patch: ULLs are moved to use MDL subsystem. --- mysql-test/r/func_misc.result | 221 +++++++ .../suite/rpl/t/rpl_err_ignoredtable.test | 2 +- mysql-test/suite/rpl/t/rpl_stm_000001.test | 3 +- mysql-test/t/func_misc.test | 177 ++++++ sql/item.cc | 2 +- sql/item_func.cc | 596 +++++++++--------- sql/item_func.h | 13 +- sql/mdl.cc | 128 +++- sql/mdl.h | 43 +- sql/mysqld.cc | 2 +- sql/mysqld.h | 2 +- sql/sql_class.cc | 25 +- sql/sql_class.h | 7 +- sql/sql_reload.cc | 1 + 14 files changed, 869 insertions(+), 353 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 55b0f9d3c57..a033c91bc05 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -338,6 +338,227 @@ set optimizer_switch=@optimizer_switch_save; drop view v_merge, vm; drop table t1,tv; # +# GET_LOCK, RELEASE_LOCK, IS_USED_LOCK functions test +# +# IS_USED_LOCK, IS_FREE_LOCK: the lock is not acquired +# Note: IS_USED_LOCK returns NULL if the lock is unused +select is_used_lock('test'); +is_used_lock('test') +NULL +select is_free_lock('test'); +is_free_lock('test') +1 +# GET_LOCK returns 1 if it manages to acquire a lock +select get_lock('test', 0); +get_lock('test', 0) +1 +# IS_USED_LOCK, IS_FREE_LOCK: the lock is acquired +select is_free_lock('test'); +is_free_lock('test') +0 +select is_used_lock('test') = connection_id(); +is_used_lock('test') = connection_id() +1 +# -> Switching to connection 'con1' +# IS_USED_LOCK, IS_FREE_LOCK: the lock is acquired in another +# connection +select is_used_lock('test') = connection_id(); +is_used_lock('test') = connection_id() +0 +select is_free_lock('test'); +is_free_lock('test') +0 +# GET_LOCK returns 0 if it can't acquire a lock (wait timeout) +select get_lock('test', 0); +get_lock('test', 0) +0 +# RELEASE_LOCK returns 0 if the lock belongs to another connection +select release_lock('test'); +release_lock('test') +0 +# -> Switching to connection 'default' +# RELEASE_LOCK returns 1 if it successfully releases a lock +select release_lock('test'); +release_lock('test') +1 +# RELEASE_LOCK returns NULL if it doesn't release a lock and there is no such lock +select release_lock('test'); +release_lock('test') +NULL +# Test that get_lock() returns NULL if error. +select get_lock('test', 0); +get_lock('test', 0) +1 +# -> Switching to connection 'con1' +create table t1 select connection_id() as id; +select get_lock('test', 7200); +# -> Switching to connection 'default' +select (@id := id) - id from t1; +(@id := id) - id +0 +kill query @id; +# -> Switching to connection 'con1' +get_lock('test', 7200) +NULL +# -> Switching to connection 'default' +# GET_LOCK() works recursively +select get_lock('test', 0); +get_lock('test', 0) +1 +select get_lock('test', 0); +get_lock('test', 0) +1 +select get_lock('test', 0); +get_lock('test', 0) +1 +# RELEASE_LOCK() needs to be called recursively then, too +select release_lock('test'); +release_lock('test') +1 +select release_lock('test'); +release_lock('test') +1 +select release_lock('test'); +release_lock('test') +1 +# Once the last instance of the lock is released, +# the next call returns NULL +select release_lock('test'); +release_lock('test') +1 +# Multiple locks in the same session are OK +select get_lock('test1', 0); +get_lock('test1', 0) +1 +select get_lock('test2', 0); +get_lock('test2', 0) +1 +select get_lock('test3', 0); +get_lock('test3', 0) +1 +select release_lock('test1'); +release_lock('test1') +1 +select release_lock('test2'); +release_lock('test2') +1 +select release_lock('test3'); +release_lock('test3') +1 +# Deadlocks are detected e.g. in case of a mutual wait +select get_lock('test1', 0); +get_lock('test1', 0) +1 +# -> Switching to connection 'con1' +select get_lock('test2', 0); +get_lock('test2', 0) +1 +select get_lock('test1', 7200); +# -> Switching to connection 'default' +select get_lock('test2', 7200); +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +select release_lock('test1'); +release_lock('test1') +1 +# -> Switching to connection 'con1' +get_lock('test1', 7200) +1 +select release_lock('test2'); +release_lock('test2') +1 +select release_lock('test1'); +release_lock('test1') +1 +# -> Switching to connection 'default' +# LOCK/UNLOCK TABLES works fine with a user lock. +lock table t1 write; +select get_lock('test', 0); +get_lock('test', 0) +1 +unlock tables; +commit; +select release_lock('test'); +release_lock('test') +1 +# GLOBAL READ LOCK works with fine with user locks +select get_lock('test1', 0); +get_lock('test1', 0) +1 +flush tables with read lock; +select get_lock('test2', 0); +get_lock('test2', 0) +1 +unlock tables; +commit; +select release_lock('test1'); +release_lock('test1') +1 +select release_lock('test2'); +release_lock('test2') +1 +# BEGIN/COMMIT/ROLLBACK don't unlock user locks. +begin; +select get_lock('test1', 0); +get_lock('test1', 0) +1 +select get_lock('test2', 0); +get_lock('test2', 0) +1 +select count(*) from t1; +count(*) +1 +rollback; +select release_lock('test1'); +release_lock('test1') +1 +select release_lock('test2'); +release_lock('test2') +1 +# Deadlocks between user locks and LOCK TABLES locks +# are detected OK. +select get_lock('test', 0); +get_lock('test', 0) +1 +# -> Switching to connection 'con1' +lock table t1 write; +select get_lock('test', 7200); +# -> Switching to connection 'default' +lock table t1 read; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +select release_lock('test'); +release_lock('test') +1 +# -> Switching to connection 'con1' +get_lock('test', 7200) +1 +select release_lock('test'); +release_lock('test') +1 +unlock tables; +# cleanup +drop table t1; +# check too long identifier names +select get_lock(repeat('a', 192), 0); +get_lock(repeat('a', 192), 0) +1 +select is_used_lock(repeat('a', 192)) = connection_id(); +is_used_lock(repeat('a', 192)) = connection_id() +1 +select is_free_lock(repeat('a', 192)); +is_free_lock(repeat('a', 192)) +0 +select release_lock(repeat('a', 192)); +release_lock(repeat('a', 192)) +1 +select get_lock(repeat('a', 193), 0); +ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long +select is_used_lock(repeat('a', 193)); +ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long +select is_free_lock(repeat('a', 193)); +ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long +select release_lock(repeat('a', 193)); +ERROR 42000: Identifier name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' is too long +# # End of 5.5 tests # # diff --git a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test index 9ebed299956..49c5056c485 100644 --- a/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test +++ b/mysql-test/suite/rpl/t/rpl_err_ignoredtable.test @@ -43,7 +43,7 @@ insert into t3 values(connection_id()); send update t2 set a = a + 1 + get_lock('crash_lock%20C', 10); connection master1; -let $wait_condition= SELECT a > 1 FROM t2; +let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'update%' AND state='User lock'; source include/wait_condition.inc; select (@id := id) - id from t3; kill @id; diff --git a/mysql-test/suite/rpl/t/rpl_stm_000001.test b/mysql-test/suite/rpl/t/rpl_stm_000001.test index 16f89123d75..0805308aa73 100644 --- a/mysql-test/suite/rpl/t/rpl_stm_000001.test +++ b/mysql-test/suite/rpl/t/rpl_stm_000001.test @@ -88,7 +88,8 @@ insert into t3 select get_lock('crash_lock%20C', 1) from t2; connection master; send update t1 set n = n + get_lock('crash_lock%20C', 2); connection master1; -sleep 3; +let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'update%' AND state='User lock'; +source include/wait_condition.inc; select (@id := id) - id from t2; kill @id; # We don't drop t3 as this is a temporary table diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index 292db69a6e3..22ebb6248e2 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -368,6 +368,183 @@ drop view v_merge, vm; drop table t1,tv; +--echo # +--echo # GET_LOCK, RELEASE_LOCK, IS_USED_LOCK functions test +--echo # + +--echo # IS_USED_LOCK, IS_FREE_LOCK: the lock is not acquired +--echo # Note: IS_USED_LOCK returns NULL if the lock is unused +select is_used_lock('test'); +select is_free_lock('test'); + +--echo # GET_LOCK returns 1 if it manages to acquire a lock +select get_lock('test', 0); + +--echo # IS_USED_LOCK, IS_FREE_LOCK: the lock is acquired +select is_free_lock('test'); +select is_used_lock('test') = connection_id(); + +connect (con1,localhost,root,,); +--echo # -> Switching to connection 'con1' +connection con1; +--echo # IS_USED_LOCK, IS_FREE_LOCK: the lock is acquired in another +--echo # connection +select is_used_lock('test') = connection_id(); +select is_free_lock('test'); + +--echo # GET_LOCK returns 0 if it can't acquire a lock (wait timeout) +select get_lock('test', 0); + +--echo # RELEASE_LOCK returns 0 if the lock belongs to another connection +select release_lock('test'); + +--echo # -> Switching to connection 'default' +connection default; + +--echo # RELEASE_LOCK returns 1 if it successfully releases a lock +select release_lock('test'); +--echo # RELEASE_LOCK returns NULL if it doesn't release a lock and there is no such lock +select release_lock('test'); + +--echo # Test that get_lock() returns NULL if error. +select get_lock('test', 0); +--echo # -> Switching to connection 'con1' +connection con1; +create table t1 select connection_id() as id; +send select get_lock('test', 7200); + +--echo # -> Switching to connection 'default' +connection default; +let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'select%' AND state='User lock'; +source include/wait_condition.inc; +select (@id := id) - id from t1; +kill query @id; + +--echo # -> Switching to connection 'con1' +connection con1; +reap; + +--echo # -> Switching to connection 'default' +connection default; + +--echo # GET_LOCK() works recursively +select get_lock('test', 0); +select get_lock('test', 0); +select get_lock('test', 0); + +--echo # RELEASE_LOCK() needs to be called recursively then, too +select release_lock('test'); +select release_lock('test'); +select release_lock('test'); + +--echo # Once the last instance of the lock is released, +--echo # the next call returns NULL +select release_lock('test'); + + +--echo # Multiple locks in the same session are OK +select get_lock('test1', 0); +select get_lock('test2', 0); +select get_lock('test3', 0); + +select release_lock('test1'); +select release_lock('test2'); +select release_lock('test3'); + +--echo # Deadlocks are detected e.g. in case of a mutual wait +select get_lock('test1', 0); + +--echo # -> Switching to connection 'con1' +connection con1; +select get_lock('test2', 0); +send select get_lock('test1', 7200); + +--echo # -> Switching to connection 'default' +connection default; +let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'select%' AND state='User lock'; +source include/wait_condition.inc; +--error ER_LOCK_DEADLOCK +select get_lock('test2', 7200); + +select release_lock('test1'); + +--echo # -> Switching to connection 'con1' +connection con1; +reap; +select release_lock('test2'); +select release_lock('test1'); + +--echo # -> Switching to connection 'default' +connection default; + +--echo # LOCK/UNLOCK TABLES works fine with a user lock. +lock table t1 write; +select get_lock('test', 0); +unlock tables; +commit; +select release_lock('test'); + +--echo # GLOBAL READ LOCK works with fine with user locks +select get_lock('test1', 0); +flush tables with read lock; +select get_lock('test2', 0); +unlock tables; +commit; +select release_lock('test1'); +select release_lock('test2'); + +--echo # BEGIN/COMMIT/ROLLBACK don't unlock user locks. +begin; +select get_lock('test1', 0); +select get_lock('test2', 0); +select count(*) from t1; +rollback; +select release_lock('test1'); +select release_lock('test2'); + +--echo # Deadlocks between user locks and LOCK TABLES locks +--echo # are detected OK. +select get_lock('test', 0); + +--echo # -> Switching to connection 'con1' +connection con1; +lock table t1 write; +send select get_lock('test', 7200); + +--echo # -> Switching to connection 'default' +connection default; +let $wait_condition= SELECT count(*) > 0 FROM information_schema.processlist WHERE info LIKE 'select%' AND state = 'User lock'; +source include/wait_condition.inc; +--error ER_LOCK_DEADLOCK +lock table t1 read; + +select release_lock('test'); + +--echo # -> Switching to connection 'con1' +connection con1; +reap; +select release_lock('test'); +unlock tables; + +--echo # cleanup +disconnect con1; +connection default; +drop table t1; + +--echo # check too long identifier names +select get_lock(repeat('a', 192), 0); +select is_used_lock(repeat('a', 192)) = connection_id(); +select is_free_lock(repeat('a', 192)); +select release_lock(repeat('a', 192)); +--error ER_TOO_LONG_IDENT +select get_lock(repeat('a', 193), 0); +--error ER_TOO_LONG_IDENT +select is_used_lock(repeat('a', 193)); +--error ER_TOO_LONG_IDENT +select is_free_lock(repeat('a', 193)); +--error ER_TOO_LONG_IDENT +select release_lock(repeat('a', 193)); + --echo # --echo # End of 5.5 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index fd6a11c319b..90a652e92c7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -198,7 +198,7 @@ Hybrid_type_traits_integer::fix_length_and_dec(Item *item, Item *arg) const void item_init(void) { - item_user_lock_init(); + item_func_sleep_init(); uuid_short_init(); } diff --git a/sql/item_func.cc b/sql/item_func.cc index 5316f89e730..31bf11284b5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3750,120 +3750,6 @@ udf_handler::~udf_handler() bool udf_handler::get_arguments() { return 0; } #endif /* HAVE_DLOPEN */ -/* -** User level locks -*/ - -mysql_mutex_t LOCK_user_locks; -static HASH hash_user_locks; - -class User_level_lock -{ - uchar *key; - size_t key_length; - -public: - int count; - bool locked; - mysql_cond_t cond; - my_thread_id thread_id; - void set_thread(THD *thd) { thread_id= thd->thread_id; } - - User_level_lock(const uchar *key_arg,uint length, ulong id) - :key_length(length),count(1),locked(1), thread_id(id) - { - key= (uchar*) my_memdup(key_arg,length,MYF(0)); - mysql_cond_init(key_user_level_lock_cond, &cond, NULL); - if (key) - { - if (my_hash_insert(&hash_user_locks,(uchar*) this)) - { - my_free(key); - key=0; - } - } - } - ~User_level_lock() - { - if (key) - { - my_hash_delete(&hash_user_locks,(uchar*) this); - my_free(key); - } - mysql_cond_destroy(&cond); - } - inline bool initialized() { return key != 0; } - friend void item_user_lock_release(User_level_lock *ull); - friend uchar *ull_get_key(const User_level_lock *ull, size_t *length, - my_bool not_used); -}; - -uchar *ull_get_key(const User_level_lock *ull, size_t *length, - my_bool not_used __attribute__((unused))) -{ - *length= ull->key_length; - return ull->key; -} - -#ifdef HAVE_PSI_INTERFACE -static PSI_mutex_key key_LOCK_user_locks; - -static PSI_mutex_info all_user_mutexes[]= -{ - { &key_LOCK_user_locks, "LOCK_user_locks", PSI_FLAG_GLOBAL} -}; - -static void init_user_lock_psi_keys(void) -{ - const char* category= "sql"; - int count; - - if (PSI_server == NULL) - return; - - count= array_elements(all_user_mutexes); - PSI_server->register_mutex(category, all_user_mutexes, count); -} -#endif - -static bool item_user_lock_inited= 0; - -void item_user_lock_init(void) -{ -#ifdef HAVE_PSI_INTERFACE - init_user_lock_psi_keys(); -#endif - - mysql_mutex_init(key_LOCK_user_locks, &LOCK_user_locks, MY_MUTEX_INIT_SLOW); - my_hash_init(&hash_user_locks,system_charset_info, - 16,0,0,(my_hash_get_key) ull_get_key,NULL,0); - item_user_lock_inited= 1; -} - -void item_user_lock_free(void) -{ - if (item_user_lock_inited) - { - item_user_lock_inited= 0; - my_hash_free(&hash_user_locks); - mysql_mutex_destroy(&LOCK_user_locks); - } -} - -void item_user_lock_release(User_level_lock *ull) -{ - ull->locked=0; - ull->thread_id= 0; - if (--ull->count) - mysql_cond_signal(&ull->cond); - else - delete ull; -} - -/** - Wait until we are at or past the given position in the master binlog - on the slave. -*/ longlong Item_master_pos_wait::val_int() { @@ -4010,7 +3896,136 @@ int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex) /** - Get a user level lock. If the thread has an old lock this is first released. + For locks with EXPLICIT duration, MDL returns a new ticket + every time a lock is granted. This allows to implement recursive + locks without extra allocation or additional data structures, such + as below. However, if there are too many tickets in the same + MDL_context, MDL_context::find_ticket() is getting too slow, + since it's using a linear search. + This is why a separate structure is allocated for a user + level lock, and before requesting a new lock from MDL, + GET_LOCK() checks thd->ull_hash if such lock is already granted, + and if so, simply increments a reference counter. +*/ + +class User_level_lock +{ +public: + MDL_ticket *lock; + int refs; +}; + + +/** Extract a hash key from User_level_lock. */ + +uchar *ull_get_key(const uchar *ptr, size_t *length, + my_bool not_used __attribute__((unused))) +{ + User_level_lock *ull = (User_level_lock*) ptr; + MDL_key *key = ull->lock->get_key(); + *length= key->length(); + return (uchar*) key->ptr(); +} + + +/** + Release all user level locks for this THD. +*/ + +void mysql_ull_cleanup(THD *thd) +{ + User_level_lock *ull; + DBUG_ENTER("mysql_ull_cleanup"); + + for (uint i= 0; i < thd->ull_hash.records; i++) + { + ull = (User_level_lock*) my_hash_element(&thd->ull_hash, i); + thd->mdl_context.release_lock(ull->lock); + my_free(ull); + } + + my_hash_free(&thd->ull_hash); + + DBUG_VOID_RETURN; +} + + +/** + Set explicit duration for metadata locks corresponding to + user level locks to protect them from being released at the end + of transaction. +*/ + +void mysql_ull_set_explicit_lock_duration(THD *thd) +{ + User_level_lock *ull; + DBUG_ENTER("mysql_ull_set_explicit_lock_duration"); + + for (uint i= 0; i < thd->ull_hash.records; i++) + { + ull= (User_level_lock*) my_hash_element(&thd->ull_hash, i); + thd->mdl_context.set_lock_duration(ull->lock, MDL_EXPLICIT); + } + DBUG_VOID_RETURN; +} + + +/** + When MDL detects a lock wait timeout, it pushes + an error into the statement diagnostics area. + For GET_LOCK(), lock wait timeout is not an error, + but a special return value (0). NULL is returned in + case of error. + Capture and suppress lock wait timeout. +*/ + +class Lock_wait_timeout_handler: public Internal_error_handler +{ +public: + Lock_wait_timeout_handler() :m_lock_wait_timeout(false) {} + + bool m_lock_wait_timeout; + + bool handle_condition(THD * /* thd */, uint sql_errno, + const char * /* sqlstate */, + MYSQL_ERROR::enum_warning_level /* level */, + const char *message, + MYSQL_ERROR ** /* cond_hdl */); +}; + +bool +Lock_wait_timeout_handler:: +handle_condition(THD * /* thd */, uint sql_errno, + const char * /* sqlstate */, + MYSQL_ERROR::enum_warning_level /* level */, + const char *message, + MYSQL_ERROR ** /* cond_hdl */) +{ + if (sql_errno == ER_LOCK_WAIT_TIMEOUT) + { + m_lock_wait_timeout= true; + return true; /* condition handled */ + } + return false; +} + + +static int ull_name_ok(String *name) +{ + if (!name || !name->length()) + return 0; + + if (name->length() > NAME_LEN) + { + my_error(ER_TOO_LONG_IDENT, MYF(0), name->c_ptr_safe()); + return 0; + } + return 1; +} + + +/** + Get a user level lock. @retval 1 : Got lock @@ -4023,14 +4038,13 @@ int Interruptible_wait::wait(mysql_cond_t *cond, mysql_mutex_t *mutex) longlong Item_func_get_lock::val_int() { DBUG_ASSERT(fixed == 1); - String *res=args[0]->val_str(&value); + String *res= args[0]->val_str(&value); ulonglong timeout= args[1]->val_int(); - THD *thd=current_thd; + THD *thd= current_thd; User_level_lock *ull; - int error; - Interruptible_wait timed_cond(thd); DBUG_ENTER("Item_func_get_lock::val_int"); + null_value= 1; /* In slave thread no need to get locks, everything is serialized. Anyway there is no way to make GET_LOCK() work on slave like it did on master @@ -4039,104 +4053,70 @@ longlong Item_func_get_lock::val_int() it's not guaranteed to be same as on master. */ if (thd->slave_thread) - DBUG_RETURN(1); - - mysql_mutex_lock(&LOCK_user_locks); - - if (!res || !res->length()) { - mysql_mutex_unlock(&LOCK_user_locks); - null_value=1; - DBUG_RETURN(0); + null_value= 0; + DBUG_RETURN(1); } + + if (!ull_name_ok(res)) + DBUG_RETURN(0); + DBUG_PRINT("info", ("lock %.*s, thd=%ld", res->length(), res->ptr(), (long) thd->real_id)); - null_value=0; - - if (thd->ull) + /* HASH entries are of type User_level_lock. */ + if (! my_hash_inited(&thd->ull_hash) && + my_hash_init(&thd->ull_hash, &my_charset_bin, + 16 /* small hash */, 0, 0, ull_get_key, NULL, 0)) { - item_user_lock_release(thd->ull); - thd->ull=0; + DBUG_RETURN(0); } - if (!(ull= ((User_level_lock *) my_hash_search(&hash_user_locks, - (uchar*) res->ptr(), - (size_t) res->length())))) + MDL_request ull_request; + ull_request.init(MDL_key::USER_LOCK, res->c_ptr_safe(), "", + MDL_SHARED_NO_WRITE, MDL_EXPLICIT); + MDL_key *ull_key = &ull_request.key; + + + if ((ull= (User_level_lock*) + my_hash_search(&thd->ull_hash, ull_key->ptr(), ull_key->length()))) { - ull= new User_level_lock((uchar*) res->ptr(), (size_t) res->length(), - thd->thread_id); - if (!ull || !ull->initialized()) - { - delete ull; - mysql_mutex_unlock(&LOCK_user_locks); - null_value=1; // Probably out of memory - DBUG_RETURN(0); - } - ull->set_thread(thd); - thd->ull=ull; - mysql_mutex_unlock(&LOCK_user_locks); - DBUG_PRINT("info", ("made new lock")); - DBUG_RETURN(1); // Got new lock + /* Recursive lock */ + ull->refs++; + null_value = 0; + DBUG_RETURN(1); } - ull->count++; - DBUG_PRINT("info", ("ull->count=%d", ull->count)); - /* - Structure is now initialized. Try to get the lock. - Set up control struct to allow others to abort locks. - */ - thd_proc_info(thd, "User lock"); - thd->mysys_var->current_mutex= &LOCK_user_locks; - thd->mysys_var->current_cond= &ull->cond; - - timed_cond.set_timeout(timeout * 1000000000ULL); - - error= 0; - thd_wait_begin(thd, THD_WAIT_USER_LOCK); - while (ull->locked && !thd->killed) + Lock_wait_timeout_handler lock_wait_timeout_handler; + thd->push_internal_handler(&lock_wait_timeout_handler); + bool error= thd->mdl_context.acquire_lock(&ull_request, timeout); + (void) thd->pop_internal_handler(); + if (error) { - DBUG_PRINT("info", ("waiting on lock")); - error= timed_cond.wait(&ull->cond, &LOCK_user_locks); - if (error == ETIMEDOUT || error == ETIME) - { - DBUG_PRINT("info", ("lock wait timeout")); - break; - } - error= 0; + if (lock_wait_timeout_handler.m_lock_wait_timeout) + null_value= 0; + DBUG_RETURN(0); } - thd_wait_end(thd); - if (ull->locked) + ull= (User_level_lock*) my_malloc(sizeof(User_level_lock), + MYF(MY_WME|MY_THREAD_SPECIFIC)); + if (ull == NULL) { - if (!--ull->count) - { - DBUG_ASSERT(0); - delete ull; // Should never happen - } - if (!error) // Killed (thd->killed != 0) - { - error=1; - null_value=1; // Return NULL - } + thd->mdl_context.release_lock(ull_request.ticket); + DBUG_RETURN(0); } - else // We got the lock + + ull->lock= ull_request.ticket; + ull->refs= 1; + + if (my_hash_insert(&thd->ull_hash, (uchar*) ull)) { - ull->locked=1; - ull->set_thread(thd); - ull->thread_id= thd->thread_id; - thd->ull=ull; - error=0; - DBUG_PRINT("info", ("got the lock")); + thd->mdl_context.release_lock(ull->lock); + my_free(ull); + DBUG_RETURN(0); } - mysql_mutex_unlock(&LOCK_user_locks); + null_value= 0; - mysql_mutex_lock(&thd->mysys_var->mutex); - thd_proc_info(thd, 0); - thd->mysys_var->current_mutex= 0; - thd->mysys_var->current_cond= 0; - mysql_mutex_unlock(&thd->mysys_var->mutex); - - DBUG_RETURN(!error ? 1 : 0); + DBUG_RETURN(1); } @@ -4151,43 +4131,86 @@ longlong Item_func_get_lock::val_int() longlong Item_func_release_lock::val_int() { DBUG_ASSERT(fixed == 1); - String *res=args[0]->val_str(&value); - User_level_lock *ull; - longlong result; - THD *thd=current_thd; + String *res= args[0]->val_str(&value); + THD *thd= current_thd; DBUG_ENTER("Item_func_release_lock::val_int"); - if (!res || !res->length()) + null_value= 1; + + if (!ull_name_ok(res)) + DBUG_RETURN(0); + + DBUG_PRINT("info", ("lock %.*s", res->length(), res->ptr())); + + MDL_key ull_key; + ull_key.mdl_key_init(MDL_key::USER_LOCK, res->c_ptr_safe(), ""); + + User_level_lock *ull; + + if (!(ull= + (User_level_lock*) my_hash_search(&thd->ull_hash, + ull_key.ptr(), ull_key.length()))) { - null_value=1; + null_value= thd->mdl_context.get_lock_owner(&ull_key) == 0; DBUG_RETURN(0); } - DBUG_PRINT("info", ("lock %.*s", res->length(), res->ptr())); - null_value=0; + null_value= 0; + if (--ull->refs == 0) + { + my_hash_delete(&thd->ull_hash, (uchar*) ull); + thd->mdl_context.release_lock(ull->lock); + my_free(ull); + } + DBUG_RETURN(1); +} - result=0; - mysql_mutex_lock(&LOCK_user_locks); - if (!(ull= ((User_level_lock*) my_hash_search(&hash_user_locks, - (const uchar*) res->ptr(), - (size_t) res->length())))) - { - null_value=1; - } - else - { - DBUG_PRINT("info", ("ull->locked=%d ull->thread=%lu thd=%lu", - (int) ull->locked, - (long)ull->thread_id, - (long)thd->thread_id)); - if (ull->locked && current_thd->thread_id == ull->thread_id) - { - DBUG_PRINT("info", ("release lock")); - result=1; // Release is ok - item_user_lock_release(ull); - thd->ull=0; - } - } - mysql_mutex_unlock(&LOCK_user_locks); - DBUG_RETURN(result); + +/** + Check a user level lock. + + Sets null_value=TRUE on error. + + @retval + 1 Available + @retval + 0 Already taken, or error +*/ + +longlong Item_func_is_free_lock::val_int() +{ + DBUG_ASSERT(fixed == 1); + String *res= args[0]->val_str(&value); + THD *thd= current_thd; + null_value= 1; + + if (!ull_name_ok(res)) + return 0; + + MDL_key ull_key; + ull_key.mdl_key_init(MDL_key::USER_LOCK, res->c_ptr_safe(), ""); + + null_value= 0; + return thd->mdl_context.get_lock_owner(&ull_key) == 0; +} + + +longlong Item_func_is_used_lock::val_int() +{ + DBUG_ASSERT(fixed == 1); + String *res= args[0]->val_str(&value); + THD *thd= current_thd; + null_value= 1; + + if (!ull_name_ok(res)) + return 0; + + MDL_key ull_key; + ull_key.mdl_key_init(MDL_key::USER_LOCK, res->c_ptr_safe(), ""); + ulong thread_id = thd->mdl_context.get_lock_owner(&ull_key); + if (thread_id == 0) + return 0; + + null_value= 0; + return thread_id; } @@ -4288,6 +4311,54 @@ void Item_func_benchmark::print(String *str, enum_query_type query_type) } +mysql_mutex_t LOCK_item_func_sleep; + +#ifdef HAVE_PSI_INTERFACE +static PSI_mutex_key key_LOCK_item_func_sleep; + +static PSI_mutex_info item_func_sleep_mutexes[]= +{ + { &key_LOCK_item_func_sleep, "LOCK_user_locks", PSI_FLAG_GLOBAL} +}; + + +static void init_item_func_sleep_psi_keys(void) +{ + const char* category= "sql"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(item_func_sleep_mutexes); + PSI_server->register_mutex(category, item_func_sleep_mutexes, count); +} +#endif + +static bool item_func_sleep_inited= 0; + + +void item_func_sleep_init(void) +{ +#ifdef HAVE_PSI_INTERFACE + init_item_func_sleep_psi_keys(); +#endif + + mysql_mutex_init(key_LOCK_item_func_sleep, &LOCK_item_func_sleep, MY_MUTEX_INIT_SLOW); + item_func_sleep_inited= 1; +} + + +void item_func_sleep_free(void) +{ + if (item_func_sleep_inited) + { + item_func_sleep_inited= 0; + mysql_mutex_destroy(&LOCK_item_func_sleep); + } +} + + /** This function is just used to create tests with time gaps. */ longlong Item_func_sleep::val_int() @@ -4316,24 +4387,24 @@ longlong Item_func_sleep::val_int() timed_cond.set_timeout((ulonglong) (timeout * 1000000000.0)); mysql_cond_init(key_item_func_sleep_cond, &cond, NULL); - mysql_mutex_lock(&LOCK_user_locks); + mysql_mutex_lock(&LOCK_item_func_sleep); thd_proc_info(thd, "User sleep"); - thd->mysys_var->current_mutex= &LOCK_user_locks; + thd->mysys_var->current_mutex= &LOCK_item_func_sleep; thd->mysys_var->current_cond= &cond; error= 0; thd_wait_begin(thd, THD_WAIT_SLEEP); while (!thd->killed) { - error= timed_cond.wait(&cond, &LOCK_user_locks); + error= timed_cond.wait(&cond, &LOCK_item_func_sleep); if (error == ETIMEDOUT || error == ETIME) break; error= 0; } thd_wait_end(thd); thd_proc_info(thd, 0); - mysql_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_item_func_sleep); mysql_mutex_lock(&thd->mysys_var->mutex); thd->mysys_var->current_mutex= 0; thd->mysys_var->current_cond= 0; @@ -6208,61 +6279,6 @@ Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name, } -/** - Check a user level lock. - - Sets null_value=TRUE on error. - - @retval - 1 Available - @retval - 0 Already taken, or error -*/ - -longlong Item_func_is_free_lock::val_int() -{ - DBUG_ASSERT(fixed == 1); - String *res=args[0]->val_str(&value); - User_level_lock *ull; - - null_value=0; - if (!res || !res->length()) - { - null_value=1; - return 0; - } - - mysql_mutex_lock(&LOCK_user_locks); - ull= (User_level_lock *) my_hash_search(&hash_user_locks, (uchar*) res->ptr(), - (size_t) res->length()); - mysql_mutex_unlock(&LOCK_user_locks); - if (!ull || !ull->locked) - return 1; - return 0; -} - -longlong Item_func_is_used_lock::val_int() -{ - DBUG_ASSERT(fixed == 1); - String *res=args[0]->val_str(&value); - User_level_lock *ull; - - null_value=1; - if (!res || !res->length()) - return 0; - - mysql_mutex_lock(&LOCK_user_locks); - ull= (User_level_lock *) my_hash_search(&hash_user_locks, (uchar*) res->ptr(), - (size_t) res->length()); - mysql_mutex_unlock(&LOCK_user_locks); - if (!ull || !ull->locked) - return 0; - - null_value=0; - return ull->thread_id; -} - - longlong Item_func_row_count::val_int() { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_func.h b/sql/item_func.h index 653641c9f72..ab6ec706248 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1257,6 +1257,9 @@ public: }; +void item_func_sleep_init(void); +void item_func_sleep_free(void); + class Item_func_sleep :public Item_int_func { public: @@ -1506,14 +1509,8 @@ public: #endif /* HAVE_DLOPEN */ -/* -** User level locks -*/ - -class User_level_lock; -void item_user_lock_init(void); -void item_user_lock_release(User_level_lock *ull); -void item_user_lock_free(void); +void mysql_ull_cleanup(THD *thd); +void mysql_ull_set_explicit_lock_duration(THD *thd); class Item_func_get_lock :public Item_int_func { diff --git a/sql/mdl.cc b/sql/mdl.cc index 7fd522d053a..e739a9aff78 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -85,7 +85,8 @@ const char *MDL_key::m_namespace_to_wait_state_name[NAMESPACE_END]= "Waiting for stored procedure metadata lock", "Waiting for trigger metadata lock", "Waiting for event metadata lock", - "Waiting for commit lock" + "Waiting for commit lock", + "User lock" /* Be compatible with old status. */ }; static bool mdl_initialized= 0; @@ -107,6 +108,7 @@ public: void init(); void destroy(); MDL_lock *find_or_insert(const MDL_key *key); + unsigned long get_lock_owner(const MDL_key *key); void remove(MDL_lock *lock); private: bool move_from_hash_to_lock_mutex(MDL_lock *lock); @@ -382,6 +384,7 @@ public: bool ignore_lock_priority) const; inline static MDL_lock *create(const MDL_key *key); + inline unsigned long get_lock_owner() const; void reschedule_waiters(); @@ -856,6 +859,43 @@ bool MDL_map::move_from_hash_to_lock_mutex(MDL_lock *lock) } +/** + * Return thread id of the owner of the lock, if it is owned. + */ + +unsigned long +MDL_map::get_lock_owner(const MDL_key *mdl_key) +{ + MDL_lock *lock; + unsigned long res= 0; + + if (mdl_key->mdl_namespace() == MDL_key::GLOBAL || + mdl_key->mdl_namespace() == MDL_key::COMMIT) + { + lock= (mdl_key->mdl_namespace() == MDL_key::GLOBAL) ? m_global_lock : + m_commit_lock; + mysql_prlock_rdlock(&lock->m_rwlock); + res= lock->get_lock_owner(); + mysql_prlock_unlock(&lock->m_rwlock); + } + else + { + my_hash_value_type hash_value= my_calc_hash(&m_locks, + mdl_key->ptr(), + mdl_key->length()); + mysql_mutex_lock(&m_mutex); + lock= (MDL_lock*) my_hash_search_using_hash_value(&m_locks, + hash_value, + mdl_key->ptr(), + mdl_key->length()); + if (lock) + res= lock->get_lock_owner(); + mysql_mutex_unlock(&m_mutex); + } + return res; +} + + /** Destroy MDL_lock object or delegate this responsibility to whatever thread that holds the last outstanding reference to @@ -1621,6 +1661,23 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg, } +/** + Return thread id of the thread to which the first ticket was + granted. +*/ + +inline unsigned long +MDL_lock::get_lock_owner() const +{ + Ticket_iterator it(m_granted); + MDL_ticket *ticket; + + if ((ticket= it++)) + return thd_get_thread_id(ticket->get_ctx()->get_thd()); + return 0; +} + + /** Remove a ticket from waiting or pending queue and wakeup up waiters. */ void MDL_lock::remove_ticket(Ticket_list MDL_lock::*list, MDL_ticket *ticket) @@ -2094,31 +2151,37 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) find_deadlock(); - if (lock->needs_notification(ticket)) + struct timespec abs_shortwait; + set_timespec(abs_shortwait, 1); + wait_status= MDL_wait::EMPTY; + + while (cmp_timespec(abs_shortwait, abs_timeout) <= 0) { - struct timespec abs_shortwait; - set_timespec(abs_shortwait, 1); - wait_status= MDL_wait::EMPTY; + /* abs_timeout is far away. Wait a short while and notify locks. */ + wait_status= m_wait.timed_wait(m_thd, &abs_shortwait, FALSE, + mdl_request->key.get_wait_state_name()); - while (cmp_timespec(abs_shortwait, abs_timeout) <= 0) + if (wait_status != MDL_wait::EMPTY) + break; + /* Check if the client is gone while we were waiting. */ + if (! thd_is_connected(m_thd)) { - /* abs_timeout is far away. Wait a short while and notify locks. */ - wait_status= m_wait.timed_wait(m_thd, &abs_shortwait, FALSE, - mdl_request->key.get_wait_state_name()); - - if (wait_status != MDL_wait::EMPTY) - break; - - mysql_prlock_wrlock(&lock->m_rwlock); - lock->notify_conflicting_locks(this); - mysql_prlock_unlock(&lock->m_rwlock); - set_timespec(abs_shortwait, 1); + /* + * The client is disconnected. Don't wait forever: + * assume it's the same as a wait timeout, this + * ensures all error handling is correct. + */ + wait_status= MDL_wait::TIMEOUT; + break; } - if (wait_status == MDL_wait::EMPTY) - wait_status= m_wait.timed_wait(m_thd, &abs_timeout, TRUE, - mdl_request->key.get_wait_state_name()); + + mysql_prlock_wrlock(&lock->m_rwlock); + if (lock->needs_notification(ticket)) + lock->notify_conflicting_locks(this); + mysql_prlock_unlock(&lock->m_rwlock); + set_timespec(abs_shortwait, 1); } - else + if (wait_status == MDL_wait::EMPTY) wait_status= m_wait.timed_wait(m_thd, &abs_timeout, TRUE, mdl_request->key.get_wait_state_name()); @@ -2613,7 +2676,7 @@ void MDL_context::release_lock(MDL_ticket *ticket) the corresponding lists, i.e. stored in reverse temporal order. This allows to employ this function to: - back off in case of a lock conflict. - - release all locks in the end of a statment or transaction + - release all locks in the end of a statement or transaction - rollback to a savepoint. */ @@ -2724,6 +2787,22 @@ MDL_context::is_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace, } +/** + Return thread id of the owner of the lock or 0 if + there is no owner. + @note: Lock type is not considered at all, the function + simply checks that there is some lock for the given key. + + @return thread id of the owner of the lock or 0 +*/ + +unsigned long +MDL_context::get_lock_owner(MDL_key *key) +{ + return mdl_locks.get_lock_owner(key); +} + + /** Check if we have any pending locks which conflict with existing shared lock. @@ -2737,6 +2816,11 @@ bool MDL_ticket::has_pending_conflicting_lock() const return m_lock->has_pending_conflicting_lock(m_type); } +/** Return a key identifying this lock. */ +MDL_key *MDL_ticket::get_key() const +{ + return &m_lock->key; +} /** Releases metadata locks that were acquired after a specific savepoint. diff --git a/sql/mdl.h b/sql/mdl.h index 68f24a7a0e8..a86b45e180f 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -212,6 +212,7 @@ public: TRIGGER, EVENT, COMMIT, + USER_LOCK, /* user level locks. */ /* This should be the last ! */ NAMESPACE_END }; @@ -492,6 +493,7 @@ public: } enum_mdl_type get_type() const { return m_type; } MDL_lock *get_lock() const { return m_lock; } + MDL_key *get_key() const; void downgrade_exclusive_lock(enum_mdl_type type); bool has_stronger_or_equal_type(enum_mdl_type type) const; @@ -653,6 +655,7 @@ public: bool is_lock_owner(MDL_key::enum_mdl_namespace mdl_namespace, const char *db, const char *name, enum_mdl_type mdl_type); + unsigned long get_lock_owner(MDL_key *mdl_key); bool has_lock(const MDL_savepoint &mdl_savepoint, MDL_ticket *mdl_ticket); @@ -721,9 +724,9 @@ private: Lists of MDL tickets: --------------------- The entire set of locks acquired by a connection can be separated - in three subsets according to their: locks released at the end of - statement, at the end of transaction and locks are released - explicitly. + in three subsets according to their duration: locks released at + the end of statement, at the end of transaction and locks are + released explicitly. Statement and transactional locks are locks with automatic scope. They are accumulated in the course of a transaction, and released @@ -732,11 +735,12 @@ private: locks). They must not be (and never are) released manually, i.e. with release_lock() call. - Locks with explicit duration are taken for locks that span + Tickets with explicit duration are taken for locks that span multiple transactions or savepoints. These are: HANDLER SQL locks (HANDLER SQL is transaction-agnostic), LOCK TABLES locks (you can COMMIT/etc - under LOCK TABLES, and the locked tables stay locked), and + under LOCK TABLES, and the locked tables stay locked), user level + locks (GET_LOCK()/RELEASE_LOCK() functions) and locks implementing "global read lock". Statement/transactional locks are always prepended to the @@ -745,20 +749,19 @@ private: a savepoint, we start popping and releasing tickets from the front until we reach the last ticket acquired after the savepoint. - Locks with explicit duration stored are not stored in any + Locks with explicit duration are not stored in any particular order, and among each other can be split into - three sets: + four sets: - [LOCK TABLES locks] [HANDLER locks] [GLOBAL READ LOCK locks] + [LOCK TABLES locks] [USER locks] [HANDLER locks] [GLOBAL READ LOCK locks] The following is known about these sets: - * GLOBAL READ LOCK locks are always stored after LOCK TABLES - locks and after HANDLER locks. This is because one can't say - SET GLOBAL read_only=1 or FLUSH TABLES WITH READ LOCK - if one has locked tables. One can, however, LOCK TABLES - after having entered the read only mode. Note, that - subsequent LOCK TABLES statement will unlock the previous + * GLOBAL READ LOCK locks are always stored last. + This is because one can't say SET GLOBAL read_only=1 or + FLUSH TABLES WITH READ LOCK if one has locked tables. One can, + however, LOCK TABLES after having entered the read only mode. + Note, that subsequent LOCK TABLES statement will unlock the previous set of tables, but not the GRL! There are no HANDLER locks after GRL locks because SET GLOBAL read_only performs a FLUSH TABLES WITH @@ -853,6 +856,18 @@ extern bool mysql_notify_thread_having_shared_lock(THD *thd, THD *in_use, extern "C" const char* thd_enter_cond(MYSQL_THD thd, mysql_cond_t *cond, mysql_mutex_t *mutex, const char *msg); extern "C" void thd_exit_cond(MYSQL_THD thd, const char *old_msg); +extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd); + +/** + Check if a connection in question is no longer connected. + + @details + Replication apply thread is always connected. Otherwise, + does a poll on the associated socket to check if the client + is gone. +*/ +extern "C" int thd_is_connected(MYSQL_THD thd); + #ifndef DBUG_OFF extern mysql_mutex_t LOCK_open; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c8d8c09cbba..3f569e31d08 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1824,7 +1824,7 @@ void clean_up(bool print_message) #endif query_cache_destroy(); hostname_cache_free(); - item_user_lock_free(); + item_func_sleep_free(); lex_free(); /* Free some memory */ item_create_cleanup(); if (!opt_noacl) diff --git a/sql/mysqld.h b/sql/mysqld.h index 587673de37c..9f9f288b6d5 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -335,7 +335,7 @@ extern MYSQL_PLUGIN_IMPORT key_map key_map_full; /* Should be threaded Server mutex locks and condition variables. */ extern mysql_mutex_t - LOCK_user_locks, LOCK_status, + LOCK_item_func_sleep, LOCK_status, LOCK_error_log, LOCK_delayed_insert, LOCK_short_uuid_generator, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 95aa4a00122..caf56f9f84c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -827,6 +827,7 @@ THD::THD() col_access=0; is_slave_error= thread_specific_used= FALSE; my_hash_clear(&handler_tables_hash); + my_hash_clear(&ull_hash); tmp_table=0; cuted_fields= 0L; sent_row_count= 0L; @@ -866,7 +867,6 @@ THD::THD() net.vio=0; net.buff= 0; client_capabilities= 0; // minimalistic client - ull=0; system_thread= NON_SYSTEM_THREAD; cleanup_done= abort_on_warning= 0; peer_port= 0; // For SHOW PROCESSLIST @@ -1400,8 +1400,6 @@ void THD::cleanup(void) if (global_read_lock.is_acquired()) global_read_lock.unlock_global_read_lock(this); - /* All metadata locks must have been released by now. */ - DBUG_ASSERT(!mdl_context.has_locks()); if (user_connect) { decrease_user_connections(user_connect); @@ -1419,13 +1417,9 @@ void THD::cleanup(void) sp_cache_clear(&sp_proc_cache); sp_cache_clear(&sp_func_cache); - if (ull) - { - mysql_mutex_lock(&LOCK_user_locks); - item_user_lock_release(ull); - mysql_mutex_unlock(&LOCK_user_locks); - ull= NULL; - } + mysql_ull_cleanup(this); + /* All metadata locks must have been released by now. */ + DBUG_ASSERT(!mdl_context.has_locks()); apc_target.destroy(); cleanup_done=1; @@ -4001,6 +3995,15 @@ extern "C" unsigned long thd_get_thread_id(const MYSQL_THD thd) } +/** + Check if THD socket is still connected. + */ +extern "C" int thd_is_connected(MYSQL_THD thd) +{ + return thd->is_connected(); +} + + #ifdef INNODB_COMPATIBILITY_HOOKS extern "C" const struct charset_info_st *thd_charset(MYSQL_THD thd) { @@ -4321,6 +4324,8 @@ void THD::leave_locked_tables_mode() /* Also ensure that we don't release metadata locks for open HANDLERs. */ if (handler_tables_hash.records) mysql_ha_set_explicit_lock_duration(this); + if (ull_hash.records) + mysql_ull_set_explicit_lock_duration(this); } locked_tables_mode= LTM_NONE; } diff --git a/sql/sql_class.h b/sql/sql_class.h index 8ccb524f715..6b779484bbc 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -57,7 +57,6 @@ class Lex_input_stream; class Parser_state; class Rows_log_event; class Sroutine_hash_entry; -class User_level_lock; class user_var_entry; enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE }; @@ -1682,11 +1681,11 @@ public: HASH handler_tables_hash; /* - One thread can hold up to one named user-level lock. This variable - points to a lock object if the lock is present. See item_func.cc and + A thread can hold named user-level locks. This variable + contains granted tickets if a lock is present. See item_func.cc and chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK. */ - User_level_lock *ull; + HASH ull_hash; #ifndef DBUG_OFF uint dbug_sentry; // watch out for memory corruption #endif diff --git a/sql/sql_reload.cc b/sql/sql_reload.cc index 2720dc7cd74..e9c9dc86e41 100644 --- a/sql/sql_reload.cc +++ b/sql/sql_reload.cc @@ -205,6 +205,7 @@ bool reload_acl_and_cache(THD *thd, unsigned long options, DBUG_ASSERT(!thd || thd->locked_tables_mode || !thd->mdl_context.has_locks() || thd->handler_tables_hash.records || + thd->ull_hash.records || thd->global_read_lock.is_acquired()); /* From d8dccde6df47e814c208e8853b4118a569ccf142 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Sat, 13 Apr 2013 11:59:16 +0500 Subject: [PATCH 322/324] MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). Syntax modified to allow statements: ALTER TABLE ADD/DROP COLUMN ALTER TABLE ADD/DROP INDEX ALTER TABLE ADD/DROP FOREIGN KEY ALTER TABLE ADD/DROP PARTITION ALTER TABLE CHANGE COLUMN ALTER TABLE MODIFY COLUMN DROP INDEX to have IF (NOT) EXISTS options. Appropriate implementations added to mysql_alter_table(). per-file comments: mysql-test/r/alter_table.result MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). test result updated. mysql-test/r/fulltext.result MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/r/partition.result test result updated. MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/t/alter_table.test tests added. MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). mysql-test/t/fulltext.test MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). tests added. mysql-test/t/partition.test MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). tests added. sql/field.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists field added. sql/field.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists field added. sql/partition_info.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). has_unique_name made public. sql/sp_head.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). sql/sql_class.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists inited. sql/sql_class.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). create_if_not_exists inited. sql/sql_lex.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_lex.h MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_parse.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists inited. sql/sql_table.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). handle_if_exists_options() added. it's called in mysql_alter_table(). sql/sql_trigger.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists instead of drop_if_exists. sql/sql_view.cc MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). check_exists instead of drop_if_exists. sql/sql_yacc.yy MDEV-318 IF (NOT) EXIST clauses for ALTER TABLE (MWL #252). sintax modified. --- mysql-test/r/alter_table.result | 40 +++++ mysql-test/r/fulltext.result | 11 ++ mysql-test/r/partition.result | 22 +++ mysql-test/t/alter_table.test | 27 ++++ mysql-test/t/fulltext.test | 11 ++ mysql-test/t/partition.test | 28 ++++ sql/field.cc | 5 +- sql/field.h | 8 +- sql/partition_info.h | 1 + sql/sp_head.cc | 2 +- sql/sql_class.cc | 3 +- sql/sql_class.h | 22 ++- sql/sql_lex.cc | 1 + sql/sql_lex.h | 3 +- sql/sql_parse.cc | 20 +-- sql/sql_table.cc | 253 +++++++++++++++++++++++++++++++- sql/sql_trigger.cc | 2 +- sql/sql_view.cc | 2 +- sql/sql_yacc.yy | 150 +++++++++++-------- 19 files changed, 523 insertions(+), 88 deletions(-) diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result index 92b9d86365d..b6e99952c23 100644 --- a/mysql-test/r/alter_table.result +++ b/mysql-test/r/alter_table.result @@ -1340,3 +1340,43 @@ rename table t2 to t1; execute stmt1; deallocate prepare stmt1; drop table t2; +CREATE TABLE t1 ( +id INT(11) NOT NULL, +x_param INT(11) DEFAULT NULL, +PRIMARY KEY (id) +); +ALTER TABLE t1 ADD COLUMN IF NOT EXISTS id INT, +ADD COLUMN IF NOT EXISTS lol INT AFTER id; +Warnings: +Note 1060 Duplicate column name 'id' +ALTER TABLE t1 ADD COLUMN IF NOT EXISTS lol INT AFTER id; +Warnings: +Note 1060 Duplicate column name 'lol' +ALTER TABLE t1 DROP COLUMN IF EXISTS lol; +ALTER TABLE t1 DROP COLUMN IF EXISTS lol; +Warnings: +Note 1091 Can't DROP 'lol'; check that column/key exists +ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param); +ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param); +Warnings: +Note 1061 Duplicate key name 'x_param' +ALTER TABLE t1 MODIFY IF EXISTS lol INT; +Warnings: +Note 1054 Unknown column 'lol' in 't1' +DROP INDEX IF EXISTS x_param ON t1; +DROP INDEX IF EXISTS x_param ON t1; +Warnings: +Note 1091 Can't DROP 'x_param'; check that column/key exists +CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param); +CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param); +Warnings: +Note 1061 Duplicate key name 'x_param1' +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `x_param` int(11) DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `x_param1` (`x_param`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result index c067ff02574..e6abd44c267 100644 --- a/mysql-test/r/fulltext.result +++ b/mysql-test/r/fulltext.result @@ -699,3 +699,14 @@ EXECUTE stmt; DEALLOCATE PREPARE stmt; DROP TABLE t1; End of 5.1 tests +CREATE TABLE t1 ( +id int(11) auto_increment, +title varchar(100) default '', +PRIMARY KEY (id), +KEY ind5 (title) +) ENGINE=MyISAM; +CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title); +CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title); +Warnings: +Note 1061 Duplicate key name 'ft1' +DROP TABLE t1; diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index 86425825601..c6a806bec80 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -2493,3 +2493,25 @@ i 3 4 DROP TABLE t1; +CREATE TABLE t1 ( d DATE NOT NULL) +PARTITION BY RANGE( YEAR(d) ) ( +PARTITION p0 VALUES LESS THAN (1960), +PARTITION p1 VALUES LESS THAN (1970), +PARTITION p2 VALUES LESS THAN (1980), +PARTITION p3 VALUES LESS THAN (1990) +); +ALTER TABLE t1 ADD PARTITION IF NOT EXISTS( +PARTITION `p5` VALUES LESS THAN (2010) +COMMENT 'APSTART \' APEND' +); +ALTER TABLE t1 ADD PARTITION IF NOT EXISTS( +PARTITION `p5` VALUES LESS THAN (2010) +COMMENT 'APSTART \' APEND' +); +Warnings: +Note 1517 Duplicate partition name p5 +alter table t1 drop partition if exists p5; +alter table t1 drop partition if exists p5; +Warnings: +Note 1507 Error in list of partitions to DROP +DROP TABLE t1; diff --git a/mysql-test/t/alter_table.test b/mysql-test/t/alter_table.test index eade7ba721e..d48b1687fa0 100644 --- a/mysql-test/t/alter_table.test +++ b/mysql-test/t/alter_table.test @@ -1231,3 +1231,30 @@ execute stmt1; deallocate prepare stmt1; drop table t2; +# +# Test of ALTER TABLE IF [NOT] EXISTS +# + +CREATE TABLE t1 ( + id INT(11) NOT NULL, + x_param INT(11) DEFAULT NULL, + PRIMARY KEY (id) +); + +ALTER TABLE t1 ADD COLUMN IF NOT EXISTS id INT, + ADD COLUMN IF NOT EXISTS lol INT AFTER id; +ALTER TABLE t1 ADD COLUMN IF NOT EXISTS lol INT AFTER id; +ALTER TABLE t1 DROP COLUMN IF EXISTS lol; +ALTER TABLE t1 DROP COLUMN IF EXISTS lol; + +ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param); +ALTER TABLE t1 ADD KEY IF NOT EXISTS x_param(x_param); +ALTER TABLE t1 MODIFY IF EXISTS lol INT; + +DROP INDEX IF EXISTS x_param ON t1; +DROP INDEX IF EXISTS x_param ON t1; +CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param); +CREATE INDEX IF NOT EXISTS x_param1 ON t1(x_param); +SHOW CREATE TABLE t1; +DROP TABLE t1; + diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test index b4b09413896..6e44b4c1578 100644 --- a/mysql-test/t/fulltext.test +++ b/mysql-test/t/fulltext.test @@ -646,3 +646,14 @@ DEALLOCATE PREPARE stmt; DROP TABLE t1; --echo End of 5.1 tests + +CREATE TABLE t1 ( + id int(11) auto_increment, + title varchar(100) default '', + PRIMARY KEY (id), + KEY ind5 (title) +) ENGINE=MyISAM; + +CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title); +CREATE FULLTEXT INDEX IF NOT EXISTS ft1 ON t1(title); +DROP TABLE t1; diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 038907702d5..bad59ff09c3 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -2494,3 +2494,31 @@ INSERT INTO t1 VALUES (1),(2),(2),(3),(4); ALTER TABLE t1 ADD PARTITION PARTITIONS 2; SELECT * from t1 order by i; DROP TABLE t1; + +# +# Test ALTER TABLE ADD/DROP PARTITION IF EXISTS +# + +CREATE TABLE t1 ( d DATE NOT NULL) +PARTITION BY RANGE( YEAR(d) ) ( + PARTITION p0 VALUES LESS THAN (1960), + PARTITION p1 VALUES LESS THAN (1970), + PARTITION p2 VALUES LESS THAN (1980), + PARTITION p3 VALUES LESS THAN (1990) +); + +ALTER TABLE t1 ADD PARTITION IF NOT EXISTS( +PARTITION `p5` VALUES LESS THAN (2010) +COMMENT 'APSTART \' APEND' +); + +ALTER TABLE t1 ADD PARTITION IF NOT EXISTS( +PARTITION `p5` VALUES LESS THAN (2010) +COMMENT 'APSTART \' APEND' +); + +alter table t1 drop partition if exists p5; +alter table t1 drop partition if exists p5; + +DROP TABLE t1; + diff --git a/sql/field.cc b/sql/field.cc index 0a45c32d811..e2ec9d35707 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8886,6 +8886,7 @@ void Create_field::init_for_tmp_table(enum_field_types sql_type_arg, FLAGSTR(pack_flag, FIELDFLAG_DECIMAL), f_packtype(pack_flag))); vcol_info= 0; + create_if_not_exists= FALSE; stored_in_db= TRUE; DBUG_VOID_RETURN; @@ -8923,7 +8924,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, char *fld_change, List *fld_interval_list, CHARSET_INFO *fld_charset, uint fld_geom_type, Virtual_column_info *fld_vcol_info, - engine_option_value *create_opt) + engine_option_value *create_opt, bool check_exists) { uint sign_len, allowed_type_modifier= 0; ulong max_field_charlength= MAX_FIELD_CHARLENGTH; @@ -8977,6 +8978,7 @@ bool Create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, comment= *fld_comment; vcol_info= fld_vcol_info; + create_if_not_exists= check_exists; stored_in_db= TRUE; /* Initialize data for a computed field */ @@ -9585,6 +9587,7 @@ Create_field::Create_field(Field *old_field,Field *orig_field) comment= old_field->comment; decimals= old_field->decimals(); vcol_info= old_field->vcol_info; + create_if_not_exists= FALSE; stored_in_db= old_field->stored_in_db; option_list= old_field->option_list; option_struct= old_field->option_struct; diff --git a/sql/field.h b/sql/field.h index 6e880e78c6e..d03479bbd06 100644 --- a/sql/field.h +++ b/sql/field.h @@ -2385,8 +2385,9 @@ public: uint8 interval_id; // For rea_create_table uint offset,pack_flag; + bool create_if_not_exists; // Used in ALTER TABLE IF NOT EXISTS - /* + /* This is additinal data provided for any computed(virtual) field. In particular it includes a pointer to the item by which this field can be computed from other fields. @@ -2399,7 +2400,8 @@ public: */ bool stored_in_db; - Create_field() :after(0), option_list(NULL), option_struct(NULL) + Create_field() :after(0), option_list(NULL), option_struct(NULL), + create_if_not_exists(FALSE) {} Create_field(Field *field, Field *orig_field); /* Used to make a clone of this object for ALTER/CREATE TABLE */ @@ -2417,7 +2419,7 @@ public: Item *on_update_value, LEX_STRING *comment, char *change, List *interval_list, CHARSET_INFO *cs, uint uint_geom_type, Virtual_column_info *vcol_info, - engine_option_value *option_list); + engine_option_value *option_list, bool check_exists); bool field_flags_are_binary() { diff --git a/sql/partition_info.h b/sql/partition_info.h index e59d4ec8ba4..2fbdfff6636 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -306,6 +306,7 @@ private: char *create_default_partition_names(uint part_no, uint num_parts, uint start_no); char *create_subpartition_name(uint subpart_no, const char *part_name); +public: bool has_unique_name(partition_element *element); }; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index cb9c0325845..f0a87673857 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2434,7 +2434,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex, lex->charset ? lex->charset : thd->variables.collation_database, lex->uint_geom_type, - lex->vcol_info, NULL)) + lex->vcol_info, NULL, FALSE)) return TRUE; if (field_def->interval_list.elements) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index caf56f9f84c..d0f3f83d1d8 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -112,7 +112,8 @@ Key::Key(const Key &rhs, MEM_ROOT *mem_root) columns(rhs.columns, mem_root), name(rhs.name), option_list(rhs.option_list), - generated(rhs.generated) + generated(rhs.generated), + create_if_not_exists(rhs.create_if_not_exists) { list_copy_and_replace_each_value(columns, mem_root); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 6b779484bbc..9e550da4449 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -222,8 +222,9 @@ public: enum drop_type {KEY, COLUMN }; const char *name; enum drop_type type; - Alter_drop(enum drop_type par_type,const char *par_name) - :name(par_name), type(par_type) {} + bool drop_if_exists; + Alter_drop(enum drop_type par_type,const char *par_name, bool par_exists) + :name(par_name), type(par_type), drop_if_exists(par_exists) {} /** Used to make a clone of this object for ALTER/CREATE TABLE @sa comment for Key_part_spec::clone @@ -257,20 +258,23 @@ public: LEX_STRING name; engine_option_value *option_list; bool generated; + bool create_if_not_exists; Key(enum Keytype type_par, const LEX_STRING &name_arg, KEY_CREATE_INFO *key_info_arg, bool generated_arg, List &cols, - engine_option_value *create_opt) + engine_option_value *create_opt, bool if_not_exists_opt) :type(type_par), key_create_info(*key_info_arg), columns(cols), - name(name_arg), option_list(create_opt), generated(generated_arg) + name(name_arg), option_list(create_opt), generated(generated_arg), + create_if_not_exists(if_not_exists_opt) {} Key(enum Keytype type_par, const char *name_arg, size_t name_len_arg, KEY_CREATE_INFO *key_info_arg, bool generated_arg, List &cols, - engine_option_value *create_opt) + engine_option_value *create_opt, bool if_not_exists_opt) :type(type_par), key_create_info(*key_info_arg), columns(cols), - option_list(create_opt), generated(generated_arg) + option_list(create_opt), generated(generated_arg), + create_if_not_exists(if_not_exists_opt) { name.str= (char *)name_arg; name.length= name_len_arg; @@ -301,8 +305,10 @@ public: uint delete_opt, update_opt, match_opt; Foreign_key(const LEX_STRING &name_arg, List &cols, Table_ident *table, List &ref_cols, - uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg) - :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL), + uint delete_opt_arg, uint update_opt_arg, uint match_opt_arg, + bool if_not_exists_opt) + :Key(FOREIGN_KEY, name_arg, &default_key_create_info, 0, cols, NULL, + if_not_exists_opt), ref_table(table), ref_columns(ref_cols), delete_opt(delete_opt_arg), update_opt(update_opt_arg), match_opt(match_opt_arg) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index a56d9f4adc8..c1a138ec3ee 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -507,6 +507,7 @@ void lex_start(THD *thd) lex->expr_allows_subselect= TRUE; lex->use_only_table_context= FALSE; lex->parse_vcol_expr= FALSE; + lex->check_exists= FALSE; lex->verbose= 0; lex->name.str= 0; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ec229144b36..77ee3dfc461 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -2509,7 +2509,8 @@ struct LEX: public Query_tables_list uint16 create_view_algorithm; uint8 create_view_check; uint8 context_analysis_only; - bool drop_if_exists, drop_temporary, local_file, one_shot_set; + bool drop_temporary, local_file, one_shot_set; + bool check_exists; bool autocommit; bool verbose, no_write_to_binlog; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c68e20f1b3a..c6e46cbab80 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2084,7 +2084,7 @@ mysql_execute_command(THD *thd) if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) && !(lex->sql_command == SQLCOM_SET_OPTION) && !(lex->sql_command == SQLCOM_DROP_TABLE && - lex->drop_temporary && lex->drop_if_exists) && + lex->drop_temporary && lex->check_exists) && all_tables_not_ok(thd, all_tables)) { /* we warn the slave SQL thread */ @@ -3285,7 +3285,7 @@ end_with_restore_list: thd->variables.option_bits|= OPTION_KEEP_LOG; } /* DDL and binlog write order are protected by metadata locks. */ - res= mysql_rm_table(thd, first_table, lex->drop_if_exists, + res= mysql_rm_table(thd, first_table, lex->check_exists, lex->drop_temporary); } break; @@ -3499,7 +3499,7 @@ end_with_restore_list: #endif if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0)) break; - res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0); + res= mysql_rm_db(thd, lex->name.str, lex->check_exists, 0); break; } case SQLCOM_ALTER_DB_UPGRADE: @@ -3627,7 +3627,7 @@ end_with_restore_list: case SQLCOM_DROP_EVENT: if (!(res= Events::drop_event(thd, lex->spname->m_db, lex->spname->m_name, - lex->drop_if_exists))) + lex->check_exists))) my_ok(thd); break; #else @@ -4314,7 +4314,7 @@ create_sp_error: if (lex->spname->m_db.str == NULL) { - if (lex->drop_if_exists) + if (lex->check_exists) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), @@ -4383,7 +4383,7 @@ create_sp_error: my_ok(thd); break; case SP_KEY_NOT_FOUND: - if (lex->drop_if_exists) + if (lex->check_exists) { res= write_bin_log(thd, TRUE, thd->query(), thd->query_length()); push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, @@ -4596,7 +4596,7 @@ create_sp_error: if ((err_code= drop_server(thd, &lex->server_options))) { - if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST) + if (! lex->check_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST) { DBUG_PRINT("info", ("problem dropping server %s", lex->server_options.server_name)); @@ -6016,7 +6016,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, lex->col_list.push_back(new Key_part_spec(*field_name, 0)); key= new Key(Key::PRIMARY, null_lex_str, &default_key_create_info, - 0, lex->col_list, NULL); + 0, lex->col_list, NULL, lex->check_exists); lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } @@ -6026,7 +6026,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, lex->col_list.push_back(new Key_part_spec(*field_name, 0)); key= new Key(Key::UNIQUE, null_lex_str, &default_key_create_info, 0, - lex->col_list, NULL); + lex->col_list, NULL, lex->check_exists); lex->alter_info.key_list.push_back(key); lex->col_list.empty(); } @@ -6078,7 +6078,7 @@ bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type, new_field->init(thd, field_name->str, type, length, decimals, type_modifier, default_value, on_update_value, comment, change, interval_list, cs, uint_geom_type, vcol_info, - create_options)) + create_options, lex->check_exists)) DBUG_RETURN(1); lex->alter_info.create_list.push_back(new_field); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 39c297fb5a2..9079bca7c1d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4953,6 +4953,246 @@ is_index_maintenance_unique (TABLE *table, Alter_info *alter_info) } +/* + Preparation for table creation + + SYNOPSIS + handle_if_exists_option() + thd Thread object. + table The altered table. + alter_info List of columns and indexes to create + + DESCRIPTION + Looks for the IF [NOT] EXISTS options, checks the states and remove items + from the list if existing found. + + RETURN VALUES + NONE +*/ + +static void +handle_if_exists_options(THD *thd, TABLE *table, Alter_info *alter_info) +{ + Field **f_ptr; + DBUG_ENTER("handle_if_exists_option"); + + /* Handle ADD COLUMN IF NOT EXISTS. */ + { + List_iterator it(alter_info->create_list); + Create_field *sql_field; + + while ((sql_field=it++)) + { + if (!sql_field->create_if_not_exists || sql_field->change) + continue; + /* + If there is a field with the same name in the table already, + remove the sql_field from the list. + */ + for (f_ptr=table->field; *f_ptr; f_ptr++) + { + if (my_strcasecmp(system_charset_info, + sql_field->field_name, (*f_ptr)->field_name) == 0) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_DUP_FIELDNAME, ER(ER_DUP_FIELDNAME), + sql_field->field_name); + it.remove(); + if (alter_info->create_list.is_empty()) + { + alter_info->flags&= ~ALTER_ADD_COLUMN; + if (alter_info->key_list.is_empty()) + alter_info->flags&= ~ALTER_ADD_INDEX; + } + break; + } + } + } + } + + /* Handle MODIFY COLUMN IF EXISTS. */ + { + List_iterator it(alter_info->create_list); + Create_field *sql_field; + + while ((sql_field=it++)) + { + if (!sql_field->create_if_not_exists || !sql_field->change) + continue; + /* + If there is NO field with the same name in the table already, + remove the sql_field from the list. + */ + for (f_ptr=table->field; *f_ptr; f_ptr++) + { + if (my_strcasecmp(system_charset_info, + sql_field->field_name, (*f_ptr)->field_name) == 0) + { + break; + } + } + if (*f_ptr == NULL) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), + sql_field->change, table->s->table_name.str); + it.remove(); + if (alter_info->create_list.is_empty()) + { + alter_info->flags&= ~(ALTER_ADD_COLUMN | ALTER_CHANGE_COLUMN); + if (alter_info->key_list.is_empty()) + alter_info->flags&= ~ALTER_ADD_INDEX; + } + } + } + } + + /* Handle DROP COLUMN/KEY IF EXISTS. */ + { + List_iterator drop_it(alter_info->drop_list); + Alter_drop *drop; + bool remove_drop; + while ((drop= drop_it++)) + { + if (!drop->drop_if_exists) + continue; + remove_drop= TRUE; + if (drop->type == Alter_drop::COLUMN) + { + /* + If there is NO field with that name in the table, + remove the 'drop' from the list. + */ + for (f_ptr=table->field; *f_ptr; f_ptr++) + { + if (my_strcasecmp(system_charset_info, + drop->name, (*f_ptr)->field_name) == 0) + { + remove_drop= FALSE; + break; + } + } + } + else /* Alter_drop::KEY */ + { + uint n_key; + for (n_key=0; n_key < table->s->keys; n_key++) + { + if (my_strcasecmp(system_charset_info, + drop->name, table->key_info[n_key].name) == 0) + { + remove_drop= FALSE; + break; + } + } + } + if (remove_drop) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_CANT_DROP_FIELD_OR_KEY, ER(ER_CANT_DROP_FIELD_OR_KEY), + drop->name); + drop_it.remove(); + if (alter_info->drop_list.is_empty()) + alter_info->flags&= ~(ALTER_DROP_COLUMN | ALTER_DROP_INDEX); + } + } + } + + /* ALTER TABLE ADD KEY IF NOT EXISTS */ + /* ALTER TABLE ADD FOREIGN KEY IF NOT EXISTS */ + { + Key *key; + List_iterator key_it(alter_info->key_list); + uint n_key; + while ((key=key_it++)) + { + if (!key->create_if_not_exists) + continue; + for (n_key=0; n_key < table->s->keys; n_key++) + { + if (my_strcasecmp(system_charset_info, + key->name.str, table->key_info[n_key].name) == 0) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_DUP_KEYNAME, ER(ER_DUP_KEYNAME), key->name.str); + key_it.remove(); + if (key->type == Key::FOREIGN_KEY) + { + /* ADD FOREIGN KEY appends two items. */ + key_it.remove(); + } + if (alter_info->key_list.is_empty()) + alter_info->flags&= ~ALTER_ADD_INDEX; + break; + } + } + } + } + +#ifdef WITH_PARTITION_STORAGE_ENGINE + partition_info *tab_part_info= table->part_info; + if (tab_part_info && thd->lex->check_exists) + { + /* ALTER TABLE ADD PARTITION IF NOT EXISTS */ + if (alter_info->flags & ALTER_ADD_PARTITION) + { + partition_info *alt_part_info= thd->lex->part_info; + if (alt_part_info) + { + List_iterator new_part_it(alt_part_info->partitions); + partition_element *pe; + while ((pe= new_part_it++)) + { + if (!tab_part_info->has_unique_name(pe)) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_SAME_NAME_PARTITION, ER(ER_SAME_NAME_PARTITION), + pe->partition_name); + alter_info->flags&= ~ALTER_ADD_PARTITION; + thd->lex->part_info= NULL; + break; + } + } + } + } + /* ALTER TABLE DROP PARTITION IF EXISTS */ + if (alter_info->flags & ALTER_DROP_PARTITION) + { + List_iterator names_it(alter_info->partition_names); + char *name; + + while ((name= names_it++)) + { + List_iterator part_it(tab_part_info->partitions); + partition_element *part_elem; + while ((part_elem= part_it++)) + { + if (my_strcasecmp(system_charset_info, + part_elem->partition_name, name) == 0) + break; + } + if (!part_elem) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_DROP_PARTITION_NON_EXISTENT, + ER(ER_DROP_PARTITION_NON_EXISTENT), "DROP"); + names_it.remove(); + } + } + if (alter_info->partition_names.elements == 0) + alter_info->flags&= ~ALTER_DROP_PARTITION; + } + } +#endif /*WITH_PARTITION_STORAGE_ENGINE*/ + + /* Clear the ALTER_FOREIGN_KEY flag if nothing other than that set. */ + if (alter_info->flags == ALTER_FOREIGN_KEY) + alter_info->flags= 0; + + DBUG_VOID_RETURN; +} + + /* SYNOPSIS mysql_compare_tables() @@ -5873,7 +6113,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, key= new Key(key_type, key_name, strlen(key_name), &key_create_info, test(key_info->flags & HA_GENERATED_KEY), - key_parts, key_info->option_list); + key_parts, key_info->option_list, FALSE); new_key_list.push_back(key); } } @@ -6386,6 +6626,17 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, DBUG_RETURN(error); } + handle_if_exists_options(thd, table, alter_info); + + /* Look if we have to do anything at all. */ + /* Normally ALTER can become NOOP only after handling */ + /* the IF (NOT) EXISTS options. */ + if (alter_info->flags == 0) + { + copied= deleted= 0; + goto end_temporary; + } + /* We have to do full alter table. */ #ifdef WITH_PARTITION_STORAGE_ENGINE diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 882f7fcca8c..35a4464b9e2 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -443,7 +443,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) if (!create) { - bool if_exists= thd->lex->drop_if_exists; + bool if_exists= thd->lex->check_exists; /* Protect the query table list from the temporary and potentially diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 0a84dd996ce..37f6af13bb7 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1672,7 +1672,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) { char name[FN_REFLEN]; my_snprintf(name, sizeof(name), "%s.%s", view->db, view->table_name); - if (thd->lex->drop_if_exists) + if (thd->lex->check_exists) { push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0c3a016fa28..20a2d72ef26 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -722,7 +722,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type, { Key *key; key= new Key(type, name, info ? info : &lex->key_create_info, generated, - lex->col_list, lex->option_list); + lex->col_list, lex->option_list, lex->check_exists); if (key == NULL) return TRUE; @@ -1454,7 +1454,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); IDENT_sys TEXT_STRING_sys TEXT_STRING_literal NCHAR_STRING opt_component key_cache_name sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty - opt_constraint constraint opt_ident + opt_constraint constraint opt_ident opt_if_not_exists_ident %type opt_table_alias @@ -1471,7 +1471,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %type type type_with_opt_collate int_type real_type order_dir lock_option - udf_type if_exists opt_local opt_table_options table_options + udf_type opt_if_exists opt_local opt_table_options table_options table_option opt_if_not_exists opt_no_write_to_binlog opt_temporary all_or_any opt_distinct opt_ignore_leaves fulltext_options spatial_type union_option @@ -2131,36 +2131,36 @@ create: } create_table_set_open_action_and_adjust_tables(lex); } - | CREATE opt_unique INDEX_SYM ident key_alg ON table_ident + | CREATE opt_unique INDEX_SYM opt_if_not_exists ident key_alg ON table_ident { - if (add_create_index_prepare(Lex, $7)) + if (add_create_index_prepare(Lex, $8)) MYSQL_YYABORT; } '(' key_list ')' normal_key_options { - if (add_create_index(Lex, $2, $4)) + if (add_create_index(Lex, $2, $5)) MYSQL_YYABORT; } - | CREATE fulltext INDEX_SYM ident init_key_options ON + | CREATE fulltext INDEX_SYM opt_if_not_exists ident init_key_options ON table_ident { - if (add_create_index_prepare(Lex, $7)) + if (add_create_index_prepare(Lex, $8)) MYSQL_YYABORT; } '(' key_list ')' fulltext_key_options { - if (add_create_index(Lex, $2, $4)) + if (add_create_index(Lex, $2, $5)) MYSQL_YYABORT; } - | CREATE spatial INDEX_SYM ident init_key_options ON + | CREATE spatial INDEX_SYM opt_if_not_exists ident init_key_options ON table_ident { - if (add_create_index_prepare(Lex, $7)) + if (add_create_index_prepare(Lex, $8)) MYSQL_YYABORT; } '(' key_list ')' spatial_key_options { - if (add_create_index(Lex, $2, $4)) + if (add_create_index(Lex, $2, $5)) MYSQL_YYABORT; } | CREATE DATABASE opt_if_not_exists ident @@ -5079,9 +5079,17 @@ table_option: ; opt_if_not_exists: - /* empty */ { $$= 0; } - | IF not EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; } - ; + /* empty */ + { + Lex->check_exists= FALSE; + $$= 0; + } + | IF not EXISTS + { + Lex->check_exists= TRUE; + $$=HA_LEX_CREATE_IF_NOT_EXISTS; + } + ; opt_create_table_options: /* empty */ @@ -5399,14 +5407,14 @@ column_def: ; key_def: - normal_key_type opt_ident key_alg '(' key_list ')' + normal_key_type opt_if_not_exists_ident key_alg '(' key_list ')' { Lex->option_list= NULL; } normal_key_options { if (add_create_index (Lex, $1, $2)) MYSQL_YYABORT; } - | fulltext opt_key_or_index opt_ident init_key_options + | fulltext opt_key_or_index opt_if_not_exists_ident init_key_options '(' key_list ')' { Lex->option_list= NULL; } fulltext_key_options @@ -5414,7 +5422,7 @@ key_def: if (add_create_index (Lex, $1, $3)) MYSQL_YYABORT; } - | spatial opt_key_or_index opt_ident init_key_options + | spatial opt_key_or_index opt_if_not_exists_ident init_key_options '(' key_list ')' { Lex->option_list= NULL; } spatial_key_options @@ -5430,7 +5438,7 @@ key_def: if (add_create_index (Lex, $2, $3.str ? $3 : $1)) MYSQL_YYABORT; } - | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references + | opt_constraint FOREIGN KEY_SYM opt_if_not_exists_ident '(' key_list ')' references { LEX *lex=Lex; Key *key= new Foreign_key($4.str ? $4 : $1, lex->col_list, @@ -5438,7 +5446,8 @@ key_def: lex->ref_list, lex->fk_delete_opt, lex->fk_update_opt, - lex->fk_match_option); + lex->fk_match_option, + lex->check_exists); if (key == NULL) MYSQL_YYABORT; lex->alter_info.key_list.push_back(key); @@ -6407,6 +6416,18 @@ opt_ident: | field_ident { $$= $1; } ; +opt_if_not_exists_ident: + opt_if_not_exists opt_ident + { + LEX *lex= Lex; + if (lex->check_exists && lex->sql_command != SQLCOM_ALTER_TABLE) + { + my_parse_error(ER(ER_SYNTAX_ERROR)); + MYSQL_YYABORT; + } + $$= $2; + }; + opt_component: /* empty */ { $$= null_lex_str; } | '.' ident { $$= $2; } @@ -6663,7 +6684,7 @@ alter_commands: new table and so forth. */ | add_partition_rule - | DROP PARTITION_SYM alt_part_name_list + | DROP PARTITION_SYM opt_if_exists alt_part_name_list { Lex->alter_info.flags|= ALTER_DROP_PARTITION; } @@ -6764,7 +6785,7 @@ all_or_alt_part_name_list: ; add_partition_rule: - ADD PARTITION_SYM opt_no_write_to_binlog + ADD PARTITION_SYM opt_if_not_exists opt_no_write_to_binlog { LEX *lex= Lex; lex->part_info= new partition_info(); @@ -6774,7 +6795,7 @@ add_partition_rule: MYSQL_YYABORT; } lex->alter_info.flags|= ALTER_ADD_PARTITION; - lex->no_write_to_binlog= $3; + lex->no_write_to_binlog= $4; } add_part_extra {} @@ -6850,7 +6871,7 @@ alter_list: ; add_column: - ADD opt_column + ADD opt_column opt_if_not_exists { LEX *lex=Lex; lex->change=0; @@ -6872,10 +6893,10 @@ alter_list_item: { Lex->alter_info.flags|= ALTER_ADD_COLUMN | ALTER_ADD_INDEX; } - | CHANGE opt_column field_ident + | CHANGE opt_column opt_if_exists field_ident { LEX *lex=Lex; - lex->change= $3.str; + lex->change= $4.str; lex->alter_info.flags|= ALTER_CHANGE_COLUMN; lex->option_list= NULL; } @@ -6883,7 +6904,7 @@ alter_list_item: { Lex->create_last_non_select_table= Lex->last_table(); } - | MODIFY_SYM opt_column field_ident + | MODIFY_SYM opt_column opt_if_exists field_ident { LEX *lex=Lex; lex->length=lex->dec=0; lex->type=0; @@ -6897,12 +6918,12 @@ alter_list_item: field_def { LEX *lex=Lex; - if (add_field_to_list(lex->thd,&$3, - (enum enum_field_types) $5, + if (add_field_to_list(lex->thd,&$4, + (enum enum_field_types) $6, lex->length,lex->dec,lex->type, lex->default_value, lex->on_update_value, &lex->comment, - $3.str, &lex->interval_list, lex->charset, + $4.str, &lex->interval_list, lex->charset, lex->uint_geom_type, lex->vcol_info, lex->option_list)) MYSQL_YYABORT; @@ -6911,32 +6932,33 @@ alter_list_item: { Lex->create_last_non_select_table= Lex->last_table(); } - | DROP opt_column field_ident opt_restrict + | DROP opt_column opt_if_exists field_ident opt_restrict { LEX *lex=Lex; - Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $3.str); + Alter_drop *ad= new Alter_drop(Alter_drop::COLUMN, $4.str, $3); if (ad == NULL) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad); lex->alter_info.flags|= ALTER_DROP_COLUMN; } - | DROP FOREIGN KEY_SYM opt_ident + | DROP FOREIGN KEY_SYM opt_if_exists opt_ident { Lex->alter_info.flags|= ALTER_DROP_INDEX | ALTER_FOREIGN_KEY; } | DROP PRIMARY_SYM KEY_SYM { LEX *lex=Lex; - Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name); + Alter_drop *ad= new Alter_drop(Alter_drop::KEY, primary_key_name, + FALSE); if (ad == NULL) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad); lex->alter_info.flags|= ALTER_DROP_INDEX; } - | DROP key_or_index field_ident + | DROP key_or_index opt_if_exists field_ident { LEX *lex=Lex; - Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str); + Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $4.str, $3); if (ad == NULL) MYSQL_YYABORT; lex->alter_info.drop_list.push_back(ad); @@ -10815,41 +10837,41 @@ do: */ drop: - DROP opt_temporary table_or_tables if_exists + DROP opt_temporary table_or_tables opt_if_exists { LEX *lex=Lex; lex->sql_command = SQLCOM_DROP_TABLE; lex->drop_temporary= $2; - lex->drop_if_exists= $4; + lex->check_exists= $4; YYPS->m_lock_type= TL_UNLOCK; YYPS->m_mdl_type= MDL_EXCLUSIVE; } table_list opt_restrict {} - | DROP INDEX_SYM ident ON table_ident {} + | DROP INDEX_SYM opt_if_exists ident ON table_ident {} { LEX *lex=Lex; - Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $3.str); + Alter_drop *ad= new Alter_drop(Alter_drop::KEY, $4.str, $3); if (ad == NULL) MYSQL_YYABORT; lex->sql_command= SQLCOM_DROP_INDEX; lex->alter_info.reset(); lex->alter_info.flags= ALTER_DROP_INDEX; lex->alter_info.drop_list.push_back(ad); - if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL, + if (!lex->current_select->add_table_to_list(lex->thd, $6, NULL, TL_OPTION_UPDATING, TL_READ_NO_INSERT, MDL_SHARED_NO_WRITE)) MYSQL_YYABORT; } - | DROP DATABASE if_exists ident + | DROP DATABASE opt_if_exists ident { LEX *lex=Lex; lex->sql_command= SQLCOM_DROP_DB; - lex->drop_if_exists=$3; + lex->check_exists=$3; lex->name= $4; } - | DROP FUNCTION_SYM if_exists ident '.' ident + | DROP FUNCTION_SYM opt_if_exists ident '.' ident { THD *thd= YYTHD; LEX *lex= thd->lex; @@ -10865,14 +10887,14 @@ drop: MYSQL_YYABORT; } lex->sql_command = SQLCOM_DROP_FUNCTION; - lex->drop_if_exists= $3; + lex->check_exists= $3; spname= new sp_name($4, $6, true); if (spname == NULL) MYSQL_YYABORT; spname->init_qname(thd); lex->spname= spname; } - | DROP FUNCTION_SYM if_exists ident + | DROP FUNCTION_SYM opt_if_exists ident { THD *thd= YYTHD; LEX *lex= thd->lex; @@ -10886,14 +10908,14 @@ drop: if (thd->db && lex->copy_db_to(&db.str, &db.length)) MYSQL_YYABORT; lex->sql_command = SQLCOM_DROP_FUNCTION; - lex->drop_if_exists= $3; + lex->check_exists= $3; spname= new sp_name(db, $4, false); if (spname == NULL) MYSQL_YYABORT; spname->init_qname(thd); lex->spname= spname; } - | DROP PROCEDURE_SYM if_exists sp_name + | DROP PROCEDURE_SYM opt_if_exists sp_name { LEX *lex=Lex; if (lex->sphead) @@ -10902,34 +10924,34 @@ drop: MYSQL_YYABORT; } lex->sql_command = SQLCOM_DROP_PROCEDURE; - lex->drop_if_exists= $3; + lex->check_exists= $3; lex->spname= $4; } | DROP USER clear_privileges user_list { Lex->sql_command = SQLCOM_DROP_USER; } - | DROP VIEW_SYM if_exists + | DROP VIEW_SYM opt_if_exists { LEX *lex= Lex; lex->sql_command= SQLCOM_DROP_VIEW; - lex->drop_if_exists= $3; + lex->check_exists= $3; YYPS->m_lock_type= TL_UNLOCK; YYPS->m_mdl_type= MDL_EXCLUSIVE; } table_list opt_restrict {} - | DROP EVENT_SYM if_exists sp_name + | DROP EVENT_SYM opt_if_exists sp_name { - Lex->drop_if_exists= $3; + Lex->check_exists= $3; Lex->spname= $4; Lex->sql_command = SQLCOM_DROP_EVENT; } - | DROP TRIGGER_SYM if_exists sp_name + | DROP TRIGGER_SYM opt_if_exists sp_name { LEX *lex= Lex; lex->sql_command= SQLCOM_DROP_TRIGGER; - lex->drop_if_exists= $3; + lex->check_exists= $3; lex->spname= $4; } | DROP TABLESPACE tablespace_name opt_ts_engine opt_ts_wait @@ -10942,10 +10964,10 @@ drop: LEX *lex= Lex; lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP; } - | DROP SERVER_SYM if_exists ident_or_text + | DROP SERVER_SYM opt_if_exists ident_or_text { Lex->sql_command = SQLCOM_DROP_SERVER; - Lex->drop_if_exists= $3; + Lex->check_exists= $3; Lex->server_options.server_name= $4.str; Lex->server_options.server_name_length= $4.length; } @@ -10983,9 +11005,17 @@ table_alias_ref: } ; -if_exists: - /* empty */ { $$= 0; } - | IF EXISTS { $$= 1; } +opt_if_exists: + /* empty */ + { + Lex->check_exists= FALSE; + $$= 0; + } + | IF EXISTS + { + Lex->check_exists= TRUE; + $$= 1; + } ; opt_temporary: From 1095ef761d9d124a5aedded59e4b4b21fedbeee5 Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Sat, 13 Apr 2013 09:57:48 +0100 Subject: [PATCH 323/324] Temporarily disable show_explain.test --- mysql-test/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/disabled.def b/mysql-test/disabled.def index 3d33be79473..4133eb2a12c 100644 --- a/mysql-test/disabled.def +++ b/mysql-test/disabled.def @@ -16,3 +16,4 @@ read_many_rows_innodb : Bug#11748886 2010-11-15 mattiasj report already exist archive-big : Bug#11817185 2011-03-10 Anitha Disabled since this leads to timeout on Solaris Sparc log_tables-big : Bug#11756699 2010-11-15 mattiasj report already exists mysql_embedded : Bug#12561297 2011-05-14 Anitha Dependent on PB2 changes - eventum#41836 +show_explain : Psergey: random timeout in range-checked-for-each record query. From d364e64ae28c5588ea0ad013738a8dfe18412292 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 14 Apr 2013 10:00:42 +0200 Subject: [PATCH 324/324] add missing tests --- .../r/innodb_use_atomic_writes_basic.result | 21 ++++++++++++++++++ .../r/innodb_use_fallocate_basic.result | 21 ++++++++++++++++++ .../t/innodb_use_atomic_writes_basic.test | 22 +++++++++++++++++++ .../t/innodb_use_fallocate_basic.test | 22 +++++++++++++++++++ 4 files changed, 86 insertions(+) create mode 100644 mysql-test/suite/sys_vars/r/innodb_use_atomic_writes_basic.result create mode 100644 mysql-test/suite/sys_vars/r/innodb_use_fallocate_basic.result create mode 100644 mysql-test/suite/sys_vars/t/innodb_use_atomic_writes_basic.test create mode 100644 mysql-test/suite/sys_vars/t/innodb_use_fallocate_basic.test diff --git a/mysql-test/suite/sys_vars/r/innodb_use_atomic_writes_basic.result b/mysql-test/suite/sys_vars/r/innodb_use_atomic_writes_basic.result new file mode 100644 index 00000000000..fa6379fbe1c --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_use_atomic_writes_basic.result @@ -0,0 +1,21 @@ +select @@global.innodb_use_atomic_writes; +@@global.innodb_use_atomic_writes +0 +select @@session.innodb_use_atomic_writes; +ERROR HY000: Variable 'innodb_use_atomic_writes' is a GLOBAL variable +show global variables like 'innodb_use_atomic_writes'; +Variable_name Value +innodb_use_atomic_writes OFF +show session variables like 'innodb_use_atomic_writes'; +Variable_name Value +innodb_use_atomic_writes OFF +select * from information_schema.global_variables where variable_name='innodb_use_atomic_writes'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_USE_ATOMIC_WRITES OFF +select * from information_schema.session_variables where variable_name='innodb_use_atomic_writes'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_USE_ATOMIC_WRITES OFF +set global innodb_use_atomic_writes=1; +ERROR HY000: Variable 'innodb_use_atomic_writes' is a read only variable +set session innodb_use_atomic_writes=1; +ERROR HY000: Variable 'innodb_use_atomic_writes' is a read only variable diff --git a/mysql-test/suite/sys_vars/r/innodb_use_fallocate_basic.result b/mysql-test/suite/sys_vars/r/innodb_use_fallocate_basic.result new file mode 100644 index 00000000000..7ea55fba0a4 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/innodb_use_fallocate_basic.result @@ -0,0 +1,21 @@ +select @@global.innodb_use_fallocate; +@@global.innodb_use_fallocate +1 +select @@session.innodb_use_fallocate; +ERROR HY000: Variable 'innodb_use_fallocate' is a GLOBAL variable +show global variables like 'innodb_use_fallocate'; +Variable_name Value +innodb_use_fallocate ON +show session variables like 'innodb_use_fallocate'; +Variable_name Value +innodb_use_fallocate ON +select * from information_schema.global_variables where variable_name='innodb_use_fallocate'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_USE_FALLOCATE ON +select * from information_schema.session_variables where variable_name='innodb_use_fallocate'; +VARIABLE_NAME VARIABLE_VALUE +INNODB_USE_FALLOCATE ON +set global innodb_use_fallocate=1; +ERROR HY000: Variable 'innodb_use_fallocate' is a read only variable +set session innodb_use_fallocate=1; +ERROR HY000: Variable 'innodb_use_fallocate' is a read only variable diff --git a/mysql-test/suite/sys_vars/t/innodb_use_atomic_writes_basic.test b/mysql-test/suite/sys_vars/t/innodb_use_atomic_writes_basic.test new file mode 100644 index 00000000000..e14f618ee6b --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_use_atomic_writes_basic.test @@ -0,0 +1,22 @@ +--source include/have_innodb.inc +# bool readonly + +# +# show values; +# +select @@global.innodb_use_atomic_writes; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +select @@session.innodb_use_atomic_writes; +show global variables like 'innodb_use_atomic_writes'; +show session variables like 'innodb_use_atomic_writes'; +select * from information_schema.global_variables where variable_name='innodb_use_atomic_writes'; +select * from information_schema.session_variables where variable_name='innodb_use_atomic_writes'; + +# +# show that it's read-only +# +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +set global innodb_use_atomic_writes=1; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +set session innodb_use_atomic_writes=1; + diff --git a/mysql-test/suite/sys_vars/t/innodb_use_fallocate_basic.test b/mysql-test/suite/sys_vars/t/innodb_use_fallocate_basic.test new file mode 100644 index 00000000000..655893be98e --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_use_fallocate_basic.test @@ -0,0 +1,22 @@ +--source include/have_innodb.inc +# bool readonly + +# +# show values; +# +select @@global.innodb_use_fallocate; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +select @@session.innodb_use_fallocate; +show global variables like 'innodb_use_fallocate'; +show session variables like 'innodb_use_fallocate'; +select * from information_schema.global_variables where variable_name='innodb_use_fallocate'; +select * from information_schema.session_variables where variable_name='innodb_use_fallocate'; + +# +# show that it's read-only +# +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +set global innodb_use_fallocate=1; +--error ER_INCORRECT_GLOBAL_LOCAL_VAR +set session innodb_use_fallocate=1; +