From bc21e8cd6946e77ed0c594113d5b47949c89659b Mon Sep 17 00:00:00 2001 From: Venkatesh Duggirala Date: Sat, 19 Jan 2013 06:01:46 +0530 Subject: Bug#11752707-SLAVE CRASHES IF RBR HAS AS DESTINATION A VIEW RATHER THAN A TABLE Problem: In RBR, If a table is converted into a view at slave, (i.e., "drop table 'object1'" & "create view 'object1'"), then any DML operations on the table at master are causing crash at slave. Analysis: Slave prepares tables to be opened for DML list when it receives Table_map_log_event(s). And the same list will be sent to open_table function. Open_table logic assumes that if the list contains a view object, it also contains "select_lex" object of that view. In the above special case, the table object does not contain 'select_lex' as it is base table at master. Since it is a view at slave, open_table logic goes to 'mysql_make_view()' function which assumes that 'select_lex' exists for the object. Fix: While preparing 'tables to be opened' list, we should make sure that table required type is 'base table'. If it is not base table while opening the object, mysql_make_view will throw an error similar to 'object is not a base table' sql/log_event.cc: Restrict that all table_map_log_event's objects should be base tables @ slave also. --- sql/log_event.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql/log_event.cc') diff --git a/sql/log_event.cc b/sql/log_event.cc index 63770e340b0..542b5e2dc60 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8573,6 +8573,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) table_list->next_global= table_list->next_local= 0; table_list->table_id= DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id); table_list->updating= 1; + table_list->required_type= FRMTYPE_TABLE; strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len)); strmov(table_list->table_name, m_tblnam); DBUG_PRINT("debug", ("table: %s is mapped to %u", table_list->table_name, table_list->table_id)); -- cgit v1.2.1 From d1378565bba59726ae3f4d47d0709e68d77110ed Mon Sep 17 00:00:00 2001 From: Nuno Carvalho Date: Mon, 28 Jan 2013 19:05:09 +0000 Subject: BUG#16200555: EMPTY NAME FOR USER VARIABLE IS ALLOWED AND BREAKS STATEMENT BINARY LOGGING On a previous fix, user variables with zero length name were incorrectly considered as event corruption, despite that them are allowed by server. Fix this wrong assumption by allowing again user variables with zero length on binary log. --- sql/log_event.cc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'sql/log_event.cc') diff --git a/sql/log_event.cc b/sql/log_event.cc index 542b5e2dc60..8abd95bba0a 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,5 +1,5 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2000, 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 @@ -5729,10 +5729,9 @@ User_var_log_event(const char* buf, uint event_len, /* We don't know yet is_null value, so we must assume that name_len may have the bigger value possible, is_null= True and there is no - payload for val. + payload for val, or even that name_len is 0. */ - if (0 == name_len || - !valid_buffer_range(name_len, buf_start, name, + if (!valid_buffer_range(name_len, buf_start, name, event_len - UV_VAL_IS_NULL)) { error= true; -- cgit v1.2.1 From 7e8c887786dc76c0057acb5a73ff4355a4ea87b1 Mon Sep 17 00:00:00 2001 From: Pedro Gomes Date: Fri, 15 Feb 2013 21:57:35 +0000 Subject: BUG#13545447: RPL_ROTATE_LOGS FAILS DUE TO CONCURRENCY ISSUES IN REP. CODE In method mysql_binlog_send, right after detecting a EOF in the read event loop, and before deciding if we should change to a new binlog file there is a execution window where new events can be written to the binlog and a rotation can happen. When reaching the test, the function will then change to a new binlog file ignoring all the events written in this window. This will result in events not being replicated. Only when the binlog is detected as deactivated in the event loop of the dump thread, can we really know that no more events remain. For this reason, this test is now made under the log lock in the beginning of the event loop when reading the events. --- sql/log_event.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sql/log_event.cc') diff --git a/sql/log_event.cc b/sql/log_event.cc index 8abd95bba0a..7d2a80fdaf9 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1012,7 +1012,9 @@ bool Log_event::write_header(IO_CACHE* file, ulong event_data_length) */ int Log_event::read_log_event(IO_CACHE* file, String* packet, - pthread_mutex_t* log_lock) + pthread_mutex_t* log_lock, + const char *log_file_name_arg, + bool* is_binlog_active) { ulong data_len; int result=0; @@ -1021,6 +1023,10 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet, if (log_lock) pthread_mutex_lock(log_lock); + + if (log_file_name_arg) + *is_binlog_active= mysql_bin_log.is_active(log_file_name_arg); + if (my_b_read(file, (uchar*) buf, sizeof(buf))) { /* -- cgit v1.2.1 From c579bce3497bdf700b19bfe50a75e641330646d3 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Mon, 25 Mar 2013 16:45:24 +0200 Subject: Patch by Ian Good for MDEV-4319: mysqlbinlog output ambiguous escaping The output of mysqlbinlog (with "-v --base64-output=DECODE-ROWS" flags) can not always be read or parsed correctly when string columns contain single-quotes or backslash characters. The fix for this bug is to escape single-quote and backslash characters on output, so that the result is both more readable and more easily parse-able. Note that this is just for comments, so it doesn't affect the replication. sql/log_event.cc: Escape \ and ' properly for mysqlbin user comments. --- sql/log_event.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sql/log_event.cc') diff --git a/sql/log_event.cc b/sql/log_event.cc index 44ff00f9b25..331b86ca29f 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1804,6 +1804,7 @@ void Log_event::print_header(IO_CACHE* file, /** Prints a quoted string to io cache. Control characters are displayed as hex sequence, e.g. \x00 + Single-quote and backslash characters are escaped with a \ @param[in] file IO cache @param[in] prt Pointer to string @@ -1819,6 +1820,10 @@ my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length) { if (*s > 0x1F) my_b_write(file, s, 1); + else if (*s == '\'') + my_b_write(file, "\\'", 2); + else if (*s == '\\') + my_b_write(file, "\\\\", 2); else { uchar hex[10]; -- cgit v1.2.1 From 2901497b187ffcefbec73c4ac9b5270174e8682c Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 28 Mar 2013 20:04:14 +0100 Subject: MDEV-4243 Warnings/errors while compiling with clang --- sql/log_event.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql/log_event.cc') diff --git a/sql/log_event.cc b/sql/log_event.cc index 331b86ca29f..72e8b21066e 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1369,7 +1369,7 @@ failed my_b_read")); Log_event *res= 0; #ifndef max_allowed_packet THD *thd=current_thd; - uint max_allowed_packet= thd ? slave_max_allowed_packet:~(ulong)0; + uint max_allowed_packet= thd ? slave_max_allowed_packet:~(uint)0; #endif if (data_len > max_allowed_packet) -- cgit v1.2.1 From e013bf9f0e2ffd05de5bfe95c4102e61b08ac06a Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 8 May 2013 13:36:17 +0400 Subject: The bug MDEV-4489 "Replication of big5, cp932, gbk, sjis strings makes wrong values on slave" has been fixed. Problem: String constants of some Asian charsets (big5,cp932,gbk,sjis) can have backslash '\' (0x5C) in the second byte of multi-byte characters. Replicating of such constants using the standard '\'-escaping is dangerous. Therefore, constants of these charsets are replicated using hex notation: INSERT INTO t1 (a) VALUES (0x815C); However, 0xHHHH constants do not work well in some cases, because they can behave as strings and as numbers, depending on context (for example, depending on the data type of the column in an INSERT statement). This SQL script was not replicated correctly with statement-based replication: SET NAMES gbk; PREPARE STMT FROM 'INSERT INTO t1 (a) VALUES (?)'; SET @a = '1'; EXECUTE STMT USING @a; The INSERT statement was replicated as: INSERT INTO t1 (a) VALUES (0x31); '1' was correctly converted to the number 1 on master. But the 0x31 constant was treated as number 49 on slave. Fix: 1. Binary log now uses X'HHHH' instead of 0xHHHH constants. 2. The X'HHHH' constants now work always as strings, in all contexts. This is the SQL standard compliant behaviour. After the fix, the above statement is replicated as: INSERT INTO t1 (a) VALUES (X'31'); X'31' is treated as string '1' on slave, and is correctly converted to 1. modified: @ mysql-test/r/ctype_cp932_binlog_stm.result @ mysql-test/r/select.result @ mysql-test/r/select_jcl6.result @ mysql-test/r/select_pkeycache.result @ mysql-test/r/user_var-binlog.result @ mysql-test/r/varbinary.result @ mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result @ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result @ mysql-test/suite/rpl/r/rpl_charset_sjis.result @ mysql-test/suite/rpl/r/rpl_mdev382.result @ mysql-test/suite/rpl/t/rpl_charset_sjis.test @ mysql-test/t/ctype_cp932_binlog_stm.test @ mysql-test/t/select.test @ mysql-test/t/varbinary.test Adding and updating tests @ sql/item.cc @ sql/item.h @ sql/sql_yacc.yy @ sql/sql_lex.cc Splitting the implementations of X'HH' and 0xHH constants into two separate classes. Fixing the parser to distinguish the two syntaxes. @ sql/log_event.cc Using X'HH' instead of 0xHH for binary logging for string constants of the "dangerous" charsets. @ sql/sql_string.h Adding a helped method String::append_hex(). --- sql/log_event.cc | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'sql/log_event.cc') diff --git a/sql/log_event.cc b/sql/log_event.cc index f3cf3623d47..1c326863cc5 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -622,16 +622,18 @@ static inline int read_str(const char **buf, const char *buf_end, /** - Transforms a string into "" or its expression in 0x... form. + Transforms a string into "" or its expression in X'HHHH' form. */ char *str_to_hex(char *to, const char *from, uint len) { if (len) { - *to++= '0'; - *to++= 'x'; + *to++= 'X'; + *to++= '\''; to= octet2hex(to, from, len); + *to++= '\''; + *to= '\0'; } else to= strmov(to, "\"\""); @@ -652,7 +654,7 @@ append_query_string(THD *thd, CHARSET_INFO *csinfo, { char *beg, *ptr; uint32 const orig_len= to->length(); - if (to->reserve(orig_len + from->length()*2+3)) + if (to->reserve(orig_len + from->length() * 2 + 4)) return 1; beg= (char*) to->ptr() + to->length(); @@ -6295,7 +6297,7 @@ void User_var_log_event::pack_info(THD *thd, Protocol* protocol) buf.append(" ")) return; old_len= buf.length(); - if (buf.reserve(old_len + val_len*2 + 2 + sizeof(" COLLATE ") + + if (buf.reserve(old_len + val_len * 2 + 3 + sizeof(" COLLATE ") + MY_CS_NAME_SIZE)) return; beg= const_cast(buf.ptr()) + old_len; @@ -6563,7 +6565,8 @@ void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) char *hex_str; CHARSET_INFO *cs; - hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte + // 2 hex digits / byte + hex_str= (char *) my_malloc(2 * val_len + 1 + 3, MYF(MY_WME)); if (!hex_str) return; str_to_hex(hex_str, val, val_len); -- cgit v1.2.1