mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
BUG#50479 DDL stmt on row-only/stmt-only tables generate spurious binlog_format
errors In the fix of BUG#39934 in 5.1-rep+3, errors are generated when binlog_format=row and a statement modifies a table restricted to statement-logging (ER_BINLOG_ROW_MODE_AND_STMT_ENGINE); or if binlog_format=statement and a statement modifies a table restricted to row-logging (ER_BINLOG_STMT_MODE_AND_ROW_ENGINE). However, some DDL statements that lock tables (e.g. ALTER TABLE, CREATE INDEX and CREATE TRIGGER) were causing spurious errors, although no row might be inserted into the binary log. To fix the problem, we tagged statements that may generate rows into the binary log and thence the warning messages are only printed out when the appropriate conditions hold and rows might be changed. sql/log_event.cc: Reorganized the Query_log_event's constructor based on the CF_CAN_GENERATE_ROW_EVENTS flag and as such any statement that has the associated flag should go through a cache before being written to the binary log. sql/share/errmsg-utf8.txt: Improved the error message ER_BINLOG_UNSAFE_MIXED_STATEMENT according to Paul's suggestion. sql/sql_class.cc: Created a hook to be used by innodb that checks if a statement may write rows to the binary log. In other words, if it has the CF_CAN_GENERATE_ROW_EVENTS flag associated. sql/sql_class.h: Defined the CF_CAN_GENERATE_ROW_EVENTS flag. sql/sql_parse.cc: Updated the sql_command_flags and added a function to check the CF_CAN_GENERATE_ROW_EVENTS. sql/sql_parse.h: Added a function to check the CF_CAN_GENERATE_ROW_EVENTS. storage/innobase/handler/ha_innodb.cc: Added a call to the hook thd_generates_rows(). storage/innobase/handler/ha_innodb.h: Defined an external reference to the hook thd_generates_rows().
This commit is contained in:
@ -247,8 +247,19 @@ void init_update_queries(void)
|
||||
/* Initialize the sql command flags array. */
|
||||
memset(sql_command_flags, 0, sizeof(sql_command_flags));
|
||||
|
||||
/*
|
||||
In general, DDL statements do not generate row events and do not go
|
||||
through a cache before being written to the binary log. However, the
|
||||
CREATE TABLE...SELECT is an exception because it may generate row
|
||||
events. For that reason, the SQLCOM_CREATE_TABLE which represents
|
||||
a CREATE TABLE, including the CREATE TABLE...SELECT, has the
|
||||
CF_CAN_GENERATE_ROW_EVENTS flag. The distinction between a regular
|
||||
CREATE TABLE and the CREATE TABLE...SELECT is made in other parts of
|
||||
the code, in particular in the Query_log_event's constructor.
|
||||
*/
|
||||
sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL;
|
||||
CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
|
||||
CF_AUTO_COMMIT_TRANS | CF_PROTECT_AGAINST_GRL;
|
||||
@ -256,7 +267,8 @@ void init_update_queries(void)
|
||||
CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_PROTECT_AGAINST_GRL;
|
||||
CF_PROTECT_AGAINST_GRL |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
|
||||
@ -275,22 +287,32 @@ void init_update_queries(void)
|
||||
sql_command_flags[SQLCOM_DROP_TRIGGER]= CF_AUTO_COMMIT_TRANS;
|
||||
|
||||
sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_PROTECT_AGAINST_GRL;
|
||||
CF_PROTECT_AGAINST_GRL |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_PROTECT_AGAINST_GRL;
|
||||
CF_PROTECT_AGAINST_GRL |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_PROTECT_AGAINST_GRL;
|
||||
CF_PROTECT_AGAINST_GRL |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_PROTECT_AGAINST_GRL;
|
||||
CF_PROTECT_AGAINST_GRL |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_PROTECT_AGAINST_GRL;
|
||||
CF_PROTECT_AGAINST_GRL |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_PROTECT_AGAINST_GRL;
|
||||
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
|
||||
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
|
||||
sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE;
|
||||
CF_PROTECT_AGAINST_GRL |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE | CF_AUTO_COMMIT_TRANS;
|
||||
sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE;
|
||||
sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
|
||||
sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
|
||||
sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
|
||||
@ -365,7 +387,9 @@ void init_update_queries(void)
|
||||
last called (or executed) statement is preserved.
|
||||
See mysql_execute_command() for how CF_ROW_COUNT is used.
|
||||
*/
|
||||
sql_command_flags[SQLCOM_CALL]= CF_REEXECUTION_FRAGILE;
|
||||
sql_command_flags[SQLCOM_CALL]= CF_REEXECUTION_FRAGILE |
|
||||
CF_CAN_GENERATE_ROW_EVENTS;
|
||||
sql_command_flags[SQLCOM_EXECUTE]= CF_CAN_GENERATE_ROW_EVENTS;
|
||||
|
||||
/*
|
||||
The following admin table operations are allowed
|
||||
@ -390,7 +414,12 @@ void init_update_queries(void)
|
||||
sql_command_flags[SQLCOM_CHECK]= CF_AUTO_COMMIT_TRANS;
|
||||
}
|
||||
|
||||
|
||||
bool sqlcom_can_generate_row_events(const THD *thd)
|
||||
{
|
||||
return (sql_command_flags[thd->lex->sql_command] &
|
||||
CF_CAN_GENERATE_ROW_EVENTS);
|
||||
}
|
||||
|
||||
bool is_update_query(enum enum_sql_command command)
|
||||
{
|
||||
DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
|
||||
|
Reference in New Issue
Block a user