mirror of
https://github.com/MariaDB/server.git
synced 2025-03-11 09:38:38 +01:00
Merge mkindahl@bk-internal.mysql.com:/home/bk/mysql-5.1-new-rpl
into kindahl-laptop.dnsalias.net:/home/bkroot/mysql-5.1-rpl
This commit is contained in:
commit
6d7d07ab78
13 changed files with 108 additions and 18 deletions
13
mysql-test/r/binlog_unsafe.result
Normal file
13
mysql-test/r/binlog_unsafe.result
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
SET BINLOG_FORMAT=STATEMENT;
|
||||||
|
CREATE TABLE t1 (a CHAR(40));
|
||||||
|
CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY);
|
||||||
|
CREATE TABLE t3 (b INT AUTO_INCREMENT PRIMARY KEY);
|
||||||
|
CREATE VIEW v1(a,b) AS SELECT a,b FROM t2,t3;
|
||||||
|
INSERT INTO t1 SELECT UUID();
|
||||||
|
Warnings:
|
||||||
|
Warning 1588 Statement is not safe to log in statement format.
|
||||||
|
SHOW WARNINGS;
|
||||||
|
Level Warning
|
||||||
|
Code 1588
|
||||||
|
Message Statement is not safe to log in statement format.
|
||||||
|
DROP TABLE t1;
|
16
mysql-test/t/binlog_unsafe.test
Normal file
16
mysql-test/t/binlog_unsafe.test
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
# Test to check that a warning is generated for unsafe statements
|
||||||
|
# executed under statement mode logging.
|
||||||
|
|
||||||
|
SET BINLOG_FORMAT=STATEMENT;
|
||||||
|
|
||||||
|
CREATE TABLE t1 (a CHAR(40));
|
||||||
|
CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY);
|
||||||
|
CREATE TABLE t3 (b INT AUTO_INCREMENT PRIMARY KEY);
|
||||||
|
CREATE VIEW v1(a,b) AS SELECT a,b FROM t2,t3;
|
||||||
|
|
||||||
|
INSERT INTO t1 SELECT UUID();
|
||||||
|
query_vertical SHOW WARNINGS;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
|
|
@ -2341,7 +2341,7 @@ Create_udf_func::create(THD *thd, udf_func *udf, List<Item> *item_list)
|
||||||
if (item_list != NULL)
|
if (item_list != NULL)
|
||||||
arg_count= item_list->elements;
|
arg_count= item_list->elements;
|
||||||
|
|
||||||
thd->lex->binlog_row_based_if_mixed= TRUE;
|
thd->lex->set_stmt_unsafe();
|
||||||
|
|
||||||
DBUG_ASSERT( (udf->type == UDFTYPE_FUNCTION)
|
DBUG_ASSERT( (udf->type == UDFTYPE_FUNCTION)
|
||||||
|| (udf->type == UDFTYPE_AGGREGATE));
|
|| (udf->type == UDFTYPE_AGGREGATE));
|
||||||
|
@ -4527,7 +4527,7 @@ Create_func_uuid Create_func_uuid::s_singleton;
|
||||||
Item*
|
Item*
|
||||||
Create_func_uuid::create(THD *thd)
|
Create_func_uuid::create(THD *thd)
|
||||||
{
|
{
|
||||||
thd->lex->binlog_row_based_if_mixed= TRUE;
|
thd->lex->set_stmt_unsafe();
|
||||||
return new (thd->mem_root) Item_func_uuid();
|
return new (thd->mem_root) Item_func_uuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6059,3 +6059,6 @@ ER_SLAVE_INCIDENT
|
||||||
eng "The incident %s occured on the master. Message: %-.64s"
|
eng "The incident %s occured on the master. Message: %-.64s"
|
||||||
ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT
|
ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT
|
||||||
eng "Table has no partition for some existing values"
|
eng "Table has no partition for some existing values"
|
||||||
|
ER_BINLOG_UNSAFE_STATEMENT
|
||||||
|
eng "Statement is not safe to log in statement format."
|
||||||
|
swe "Detta är inte säkert att logga i statement-format."
|
||||||
|
|
|
@ -1873,7 +1873,7 @@ sp_head::restore_lex(THD *thd)
|
||||||
cannot switch from statement-based to row-based only for this
|
cannot switch from statement-based to row-based only for this
|
||||||
substatement).
|
substatement).
|
||||||
*/
|
*/
|
||||||
if (sublex->binlog_row_based_if_mixed)
|
if (sublex->is_stmt_unsafe())
|
||||||
m_flags|= BINLOG_ROW_BASED_IF_MIXED;
|
m_flags|= BINLOG_ROW_BASED_IF_MIXED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -379,7 +379,7 @@ public:
|
||||||
the substatements not).
|
the substatements not).
|
||||||
*/
|
*/
|
||||||
if (m_flags & BINLOG_ROW_BASED_IF_MIXED)
|
if (m_flags & BINLOG_ROW_BASED_IF_MIXED)
|
||||||
lex->binlog_row_based_if_mixed= TRUE;
|
lex->set_stmt_unsafe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3591,7 +3591,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
||||||
/*
|
/*
|
||||||
CREATE ... SELECT UUID() locks no tables, we have to test here.
|
CREATE ... SELECT UUID() locks no tables, we have to test here.
|
||||||
*/
|
*/
|
||||||
if (thd->lex->binlog_row_based_if_mixed)
|
if (thd->lex->is_stmt_unsafe())
|
||||||
thd->set_current_stmt_binlog_row_based_if_mixed();
|
thd->set_current_stmt_binlog_row_based_if_mixed();
|
||||||
|
|
||||||
if (!tables && !thd->lex->requires_prelocking())
|
if (!tables && !thd->lex->requires_prelocking())
|
||||||
|
@ -3632,7 +3632,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
||||||
if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
|
if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
|
||||||
has_two_write_locked_tables_with_auto_increment(tables))
|
has_two_write_locked_tables_with_auto_increment(tables))
|
||||||
{
|
{
|
||||||
thd->lex->binlog_row_based_if_mixed= TRUE;
|
thd->lex->set_stmt_unsafe();
|
||||||
thd->set_current_stmt_binlog_row_based_if_mixed();
|
thd->set_current_stmt_binlog_row_based_if_mixed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ THD::THD()
|
||||||
Open_tables_state(refresh_version), rli_fake(0),
|
Open_tables_state(refresh_version), rli_fake(0),
|
||||||
lock_id(&main_lock_id),
|
lock_id(&main_lock_id),
|
||||||
user_time(0), in_sub_stmt(0),
|
user_time(0), in_sub_stmt(0),
|
||||||
binlog_table_maps(0),
|
binlog_table_maps(0), binlog_flags(0UL),
|
||||||
global_read_lock(0), is_fatal_error(0),
|
global_read_lock(0), is_fatal_error(0),
|
||||||
rand_used(0), time_zone_used(0),
|
rand_used(0), time_zone_used(0),
|
||||||
arg_of_last_insert_id_function(FALSE),
|
arg_of_last_insert_id_function(FALSE),
|
||||||
|
@ -2888,6 +2888,23 @@ int THD::binlog_query(THD::enum_binlog_query_type qtype,
|
||||||
to how you treat this.
|
to how you treat this.
|
||||||
*/
|
*/
|
||||||
case THD::STMT_QUERY_TYPE:
|
case THD::STMT_QUERY_TYPE:
|
||||||
|
if (lex->is_stmt_unsafe())
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(this->query != NULL);
|
||||||
|
push_warning(this, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
|
ER_BINLOG_UNSAFE_STATEMENT,
|
||||||
|
ER(ER_BINLOG_UNSAFE_STATEMENT));
|
||||||
|
if (!(binlog_flags & BINLOG_FLAG_UNSAFE_STMT_PRINTED))
|
||||||
|
{
|
||||||
|
|
||||||
|
char warn_buf[MYSQL_ERRMSG_SIZE];
|
||||||
|
my_snprintf(warn_buf, MYSQL_ERRMSG_SIZE, "%s Statement: %s",
|
||||||
|
ER(ER_BINLOG_UNSAFE_STATEMENT), this->query);
|
||||||
|
sql_print_warning(warn_buf);
|
||||||
|
binlog_flags|= BINLOG_FLAG_UNSAFE_STMT_PRINTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The MYSQL_LOG::write() function will set the STMT_END_F flag and
|
The MYSQL_LOG::write() function will set the STMT_END_F flag and
|
||||||
flush the pending rows event if necessary.
|
flush the pending rows event if necessary.
|
||||||
|
|
|
@ -1048,6 +1048,17 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint binlog_table_maps; // Number of table maps currently in the binlog
|
uint binlog_table_maps; // Number of table maps currently in the binlog
|
||||||
|
|
||||||
|
enum enum_binlog_flag {
|
||||||
|
BINLOG_FLAG_UNSAFE_STMT_PRINTED,
|
||||||
|
BINLOG_FLAG_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flags with per-thread information regarding the status of the
|
||||||
|
binary log.
|
||||||
|
*/
|
||||||
|
uint32 binlog_flags;
|
||||||
public:
|
public:
|
||||||
uint get_binlog_table_maps() const {
|
uint get_binlog_table_maps() const {
|
||||||
return binlog_table_maps;
|
return binlog_table_maps;
|
||||||
|
@ -1599,6 +1610,7 @@ public:
|
||||||
void restore_sub_statement_state(Sub_statement_state *backup);
|
void restore_sub_statement_state(Sub_statement_state *backup);
|
||||||
void set_n_backup_active_arena(Query_arena *set, Query_arena *backup);
|
void set_n_backup_active_arena(Query_arena *set, Query_arena *backup);
|
||||||
void restore_active_arena(Query_arena *set, Query_arena *backup);
|
void restore_active_arena(Query_arena *set, Query_arena *backup);
|
||||||
|
|
||||||
inline void set_current_stmt_binlog_row_based_if_mixed()
|
inline void set_current_stmt_binlog_row_based_if_mixed()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1533,6 +1533,7 @@ public:
|
||||||
Statement-based replication of INSERT DELAYED has problems with RAND()
|
Statement-based replication of INSERT DELAYED has problems with RAND()
|
||||||
and user vars, so in mixed mode we go to row-based.
|
and user vars, so in mixed mode we go to row-based.
|
||||||
*/
|
*/
|
||||||
|
thd.lex->set_stmt_unsafe();
|
||||||
thd.set_current_stmt_binlog_row_based_if_mixed();
|
thd.set_current_stmt_binlog_row_based_if_mixed();
|
||||||
|
|
||||||
bzero((char*) &thd.net, sizeof(thd.net)); // Safety
|
bzero((char*) &thd.net, sizeof(thd.net)); // Safety
|
||||||
|
|
|
@ -1719,7 +1719,7 @@ void Query_tables_list::reset_query_tables_list(bool init)
|
||||||
sroutines_list.empty();
|
sroutines_list.empty();
|
||||||
sroutines_list_own_last= sroutines_list.next;
|
sroutines_list_own_last= sroutines_list.next;
|
||||||
sroutines_list_own_elements= 0;
|
sroutines_list_own_elements= 0;
|
||||||
binlog_row_based_if_mixed= FALSE;
|
binlog_stmt_flags= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -909,14 +909,6 @@ public:
|
||||||
byte **sroutines_list_own_last;
|
byte **sroutines_list_own_last;
|
||||||
uint sroutines_list_own_elements;
|
uint sroutines_list_own_elements;
|
||||||
|
|
||||||
/*
|
|
||||||
Tells if the parsing stage detected that some items require row-based
|
|
||||||
binlogging to give a reliable binlog/replication, or if we will use
|
|
||||||
stored functions or triggers which themselves need require row-based
|
|
||||||
binlogging.
|
|
||||||
*/
|
|
||||||
bool binlog_row_based_if_mixed;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These constructor and destructor serve for creation/destruction
|
These constructor and destructor serve for creation/destruction
|
||||||
of Query_tables_list instances which are used as backup storage.
|
of Query_tables_list instances which are used as backup storage.
|
||||||
|
@ -964,6 +956,41 @@ public:
|
||||||
query_tables_own_last= 0;
|
query_tables_own_last= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Has the parser/scanner detected that this statement is unsafe?
|
||||||
|
*/
|
||||||
|
inline bool is_stmt_unsafe() const {
|
||||||
|
return binlog_stmt_flags & (1U << BINLOG_STMT_FLAG_UNSAFE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Flag the current (top-level) statement as unsafe.
|
||||||
|
|
||||||
|
The flag will be reset after the statement has finished.
|
||||||
|
|
||||||
|
*/
|
||||||
|
inline void set_stmt_unsafe() {
|
||||||
|
binlog_stmt_flags|= (1U << BINLOG_STMT_FLAG_UNSAFE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void clear_stmt_unsafe() {
|
||||||
|
binlog_stmt_flags&= ~(1U << BINLOG_STMT_FLAG_UNSAFE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum enum_binlog_stmt_flag {
|
||||||
|
BINLOG_STMT_FLAG_UNSAFE,
|
||||||
|
BINLOG_STMT_FLAG_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
Tells if the parsing stage detected properties of the statement,
|
||||||
|
for example: that some items require row-based binlogging to give
|
||||||
|
a reliable binlog/replication, or if we will use stored functions
|
||||||
|
or triggers which themselves need require row-based binlogging.
|
||||||
|
*/
|
||||||
|
uint32 binlog_stmt_flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1299,6 +1326,7 @@ typedef struct st_lex : public Query_tables_list
|
||||||
void restore_backup_query_tables_list(Query_tables_list *backup);
|
void restore_backup_query_tables_list(Query_tables_list *backup);
|
||||||
|
|
||||||
bool table_or_sp_used();
|
bool table_or_sp_used();
|
||||||
|
|
||||||
} LEX;
|
} LEX;
|
||||||
|
|
||||||
struct st_lex_local: public st_lex
|
struct st_lex_local: public st_lex
|
||||||
|
|
|
@ -1114,8 +1114,8 @@ bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table,
|
||||||
If the view's body needs row-based binlogging (e.g. the VIEW is created
|
If the view's body needs row-based binlogging (e.g. the VIEW is created
|
||||||
from SELECT UUID()), the top statement also needs it.
|
from SELECT UUID()), the top statement also needs it.
|
||||||
*/
|
*/
|
||||||
if (lex->binlog_row_based_if_mixed)
|
if (lex->is_stmt_unsafe())
|
||||||
old_lex->binlog_row_based_if_mixed= TRUE;
|
old_lex->set_stmt_unsafe();
|
||||||
view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
|
view_is_mergeable= (table->algorithm != VIEW_ALGORITHM_TMPTABLE &&
|
||||||
lex->can_be_merged());
|
lex->can_be_merged());
|
||||||
LINT_INIT(view_main_select_tables);
|
LINT_INIT(view_main_select_tables);
|
||||||
|
|
Loading…
Add table
Reference in a new issue