From: Sven Sandberg Date: July 22 2009 4:29pm Subject: bzr commit into mysql-5.1-bugteam branch (sven.sandberg:3028) Bug#39934 List-Archive: http://lists.mysql.com/commits/79175 X-Bug: 39934 Message-Id: <0KN600M3MZ5EBZ30@fe-emea-09.sun.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="Boundary_(ID_eaEz1BKWUpQDJDuw443LxQ)" --Boundary_(ID_eaEz1BKWUpQDJDuw443LxQ) MIME-version: 1.0 Content-type: text/plain; CHARSET=US-ASCII Content-transfer-encoding: 7BIT Content-disposition: inline #At file:///home/sven/bzr/b39934-mats-slave_row_engine/5.1-bugteam/ based on revid:sven.sandberg@stripped 3028 Sven Sandberg 2009-07-22 Post-push fix for BUG#39934 Moved decide_logging_format to sql_class.cc @ sql/sql_base.cc Moved decide_logging_format to sql_class.cc The auxiliary macro FLAGSTR is not needed here any more. @ sql/sql_class.cc - Moved decide_logging_format from sql_base.cc to here. - To avoid copying the FLAGSTR macro, I changed some DBUG_PRINT to just print flags in hex. No need to pretty-print debug traces. - Changed the type of 'flags' to handler::Table_flags because that's the return type of handler::ha_table_flags. modified: sql/sql_base.cc sql/sql_class.cc === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2009-07-22 16:16:17 +0000 +++ b/sql/sql_base.cc 2009-07-22 16:29:26 +0000 @@ -28,7 +28,6 @@ #include #endif -#define FLAGSTR(S,F) ((S) & (F) ? #F " " : "") /** This internal handler is used to trap internally @@ -5052,303 +5051,6 @@ static void mark_real_tables_as_free_for } -/** - Decide on logging format to use for the statement and issue errors - or warnings as needed. The decision depends on the following - parameters: - - - The logging mode, i.e., the value of binlog_format. Can be - statement, mixed, or row. - - - The type of statement. There are three types of statements: - "normal" safe statements; unsafe statements; and row injections. - An unsafe statement is one that, if logged in statement format, - might produce different results when replayed on the slave (e.g., - INSERT DELAYED). A row injection is either a BINLOG statement, or - a row event executed by the slave's SQL thread. - - - The capabilities of tables modified by the statement. The - *capabilities vector* for a table is a set of flags associated - with the table. Currently, it only includes two flags: *row - capability flag* and *statement capability flag*. - - The row capability flag is set if and only if the engine can - handle row-based logging. The statement capability flag is set if - and only if the table can handle statement-based logging. - - Decision table for logging format - --------------------------------- - - The following table summarizes how the format and generated - warning/error depends on the tables' capabilities, the statement - type, and the current binlog_format. - - Row capable N NNNNNNNNN YYYYYYYYY YYYYYYYYY - Statement capable N YYYYYYYYY NNNNNNNNN YYYYYYYYY - - Statement type * SSSUUUIII SSSUUUIII SSSUUUIII - - binlog_format * SMRSMRSMR SMRSMRSMR SMRSMRSMR - - Logged format - SS-SS---- -RR-RR-RR SRRSRR-RR - Warning/Error 1 --2332444 5--5--6-- ---7--6-- - - Legend - ------ - - Row capable: N - Some table not row-capable, Y - All tables row-capable - Stmt capable: N - Some table not stmt-capable, Y - All tables stmt-capable - Statement type: (S)afe, (U)nsafe, or Row (I)njection - binlog_format: (S)TATEMENT, (M)IXED, or (R)OW - Logged format: (S)tatement or (R)ow - Warning/Error: Warnings and error messages are as follows: - - 1. Error: Cannot execute statement: binlogging impossible since both - row-incapable engines and statement-incapable engines are - involved. - - 2. Error: Cannot execute statement: binlogging impossible since - BINLOG_FORMAT = ROW and at least one table uses a storage engine - limited to statement-logging. - - 3. Warning: Unsafe statement binlogged as statement since storage - engine is limited to statement-logging. - - 4. Error: Cannot execute row injection: binlogging impossible since - at least one table uses a storage engine limited to - statement-logging. - - 5. Error: Cannot execute statement: binlogging impossible since - BINLOG_FORMAT = STATEMENT and at least one table uses a storage - engine limited to row-logging. - - 6. Error: Cannot execute row injection: binlogging impossible since - BINLOG_FORMAT = STATEMENT. - - 7. Warning: Unsafe statement binlogged in statement format since - BINLOG_FORMAT = STATEMENT. - - In addition, we can produce the following error (not depending on - the variables of the decision diagram): - - 8. Error: Cannot execute statement: binlogging impossible since more - than one engine is involved and at least one engine is - self-logging. - - For each error case above, the statement is prevented from being - logged, we report an error, and roll back the statement. For - warnings, we set the thd->binlog_flags variable: the warning will be - printed only if the statement is successfully logged. - - @see THD::binlog_query - - @param[in] thd Client thread - @param[in] tables Tables involved in the query - - @retval 0 No error; statement can be logged. - @retval -1 One of the error conditions above applies (1, 2, 4, 5, or 6). -*/ - -int THD::decide_logging_format(TABLE_LIST *tables) -{ - DBUG_ENTER("THD::decide_logging_format"); - DBUG_PRINT("info", ("query: %s", query)); - DBUG_PRINT("info", ("variables.binlog_format: %ld", - variables.binlog_format)); - DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x", - lex->get_stmt_unsafe_flags())); - if (mysql_bin_log.is_open() && (options & OPTION_BIN_LOG)) - { - /* - Compute one bit field with the union of all the engine - capabilities, and one with the intersection of all the engine - capabilities. - */ - handler::Table_flags flags_some_set= 0; - handler::Table_flags flags_all_set= - HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE; - - my_bool multi_engine= FALSE; - void* prev_ht= NULL; - -#ifndef DBUG_OFF - { - static const char *prelocked_mode_name[] = { - "NON_PRELOCKED", - "PRELOCKED", - "PRELOCKED_UNDER_LOCK_TABLES", - }; - DBUG_PRINT("debug", ("prelocked_mode: %s", - prelocked_mode_name[prelocked_mode])); - } -#endif - - /* - Get the capabilities vector for all involved storage engines and - mask out the flags for the binary log. - */ - for (TABLE_LIST *table= tables; table; table= table->next_global) - { - if (table->placeholder()) - continue; - if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE) - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE); - if (table->lock_type >= TL_WRITE_ALLOW_WRITE) - { - ulonglong const flags= table->table->file->ha_table_flags(); - DBUG_PRINT("info", ("table: %s; ha_table_flags: %s%s", - table->table_name, - FLAGSTR(flags, HA_BINLOG_STMT_CAPABLE), - FLAGSTR(flags, HA_BINLOG_ROW_CAPABLE))); - if (prev_ht && prev_ht != table->table->file->ht) - multi_engine= TRUE; - prev_ht= table->table->file->ht; - flags_all_set &= flags; - flags_some_set |= flags; - } - } - - DBUG_PRINT("info", ("flags_all_set: %s%s", - FLAGSTR(flags_all_set, HA_BINLOG_STMT_CAPABLE), - FLAGSTR(flags_all_set, HA_BINLOG_ROW_CAPABLE))); - DBUG_PRINT("info", ("flags_some_set: %s%s", - FLAGSTR(flags_some_set, HA_BINLOG_STMT_CAPABLE), - FLAGSTR(flags_some_set, HA_BINLOG_ROW_CAPABLE))); - DBUG_PRINT("info", ("multi_engine: %s", - multi_engine ? "TRUE" : "FALSE")); - - int error= 0; - int unsafe_flags; - - /* - If more than one engine is involved in the statement and at - least one is doing it's own logging (is *self-logging*), the - statement cannot be logged atomically, so we generate an error - rather than allowing the binlog to become corrupt. - */ - if (multi_engine && - (flags_some_set & HA_HAS_OWN_BINLOGGING)) - { - my_error((error= ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE), - MYF(0)); - } - - /* both statement-only and row-only engines involved */ - if ((flags_all_set & (HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE)) == 0) - { - /* - 1. Error: Binary logging impossible since both row-incapable - engines and statement-incapable engines are involved - */ - my_error((error= ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE), MYF(0)); - } - /* statement-only engines involved */ - else if ((flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0) - { - if (lex->is_stmt_row_injection()) - { - /* - 4. Error: Cannot execute row injection since table uses - storage engine limited to statement-logging - */ - my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE), MYF(0)); - } - else if (variables.binlog_format == BINLOG_FORMAT_ROW) - { - /* - 2. Error: Cannot modify table that uses a storage engine - limited to statement-logging when BINLOG_FORMAT = ROW - */ - my_error((error= ER_BINLOG_ROW_MODE_AND_STMT_ENGINE), MYF(0)); - } - else if ((unsafe_flags= lex->get_stmt_unsafe_flags()) != 0) - { - /* - 3. Warning: Unsafe statement binlogged as statement since - storage engine is limited to statement-logging. - */ - binlog_unsafe_warning_flags|= - (1 << BINLOG_STMT_WARNING_UNSAFE_AND_STMT_ENGINE) | - (unsafe_flags << BINLOG_STMT_WARNING_COUNT); - DBUG_PRINT("info", ("Scheduling warning to be issued by " - "binlog_query: %s", - ER(ER_BINLOG_UNSAFE_AND_STMT_ENGINE))); - DBUG_PRINT("info", ("binlog_unsafe_warning_flags: 0x%x", - binlog_unsafe_warning_flags)); - } - /* log in statement format! */ - } - /* no statement-only engines */ - else - { - /* binlog_format = STATEMENT */ - if (variables.binlog_format == BINLOG_FORMAT_STMT) - { - if (lex->is_stmt_row_injection()) - { - /* - 6. Error: Cannot execute row injection since - BINLOG_FORMAT = STATEMENT - */ - my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_MODE), MYF(0)); - } - else if ((flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0) - { - /* - 5. Error: Cannot modify table that uses a storage engine - limited to row-logging when binlog_format = STATEMENT - */ - my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), ""); - } - else if ((unsafe_flags= lex->get_stmt_unsafe_flags()) != 0) - { - /* - 7. Warning: Unsafe statement logged as statement due to - binlog_format = STATEMENT - */ - binlog_unsafe_warning_flags|= - (1 << BINLOG_STMT_WARNING_UNSAFE_AND_STMT_MODE) | - (unsafe_flags << BINLOG_STMT_WARNING_COUNT); - DBUG_PRINT("info", ("Scheduling warning to be issued by " - "binlog_query: '%s'", - ER(ER_BINLOG_UNSAFE_STATEMENT))); - DBUG_PRINT("info", ("binlog_stmt_flags: 0x%x", - binlog_unsafe_warning_flags)); - } - /* log in statement format! */ - } - /* No statement-only engines and binlog_format != STATEMENT. - I.e., nothing prevents us from row logging if needed. */ - else - { - if (lex->is_stmt_unsafe() || lex->is_stmt_row_injection() - || (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0) - { - /* log in row format! */ - set_current_stmt_binlog_row_based_if_mixed(); - } - } - } - - if (error) { - DBUG_PRINT("info", ("decision: no logging since an error was generated")); - DBUG_RETURN(-1); - } - DBUG_PRINT("info", ("decision: logging in %s format", - is_current_stmt_binlog_format_row() ? - "ROW" : "STATEMENT")); - } -#ifndef DBUG_OFF - else - DBUG_PRINT("info", ("decision: no logging since " - "mysql_bin_log.is_open() = %d " - "and (options & OPTION_BIN_LOG) = 0x%llx", - mysql_bin_log.is_open(), (options & OPTION_BIN_LOG))); -#endif - - DBUG_RETURN(0); -} - /* Lock all tables in list === modified file 'sql/sql_class.cc' --- a/sql/sql_class.cc 2009-07-22 16:16:17 +0000 +++ b/sql/sql_class.cc 2009-07-22 16:29:26 +0000 @@ -3158,6 +3158,298 @@ void xid_cache_delete(XID_STATE *xid_sta pthread_mutex_unlock(&LOCK_xid_cache); } + +/** + Decide on logging format to use for the statement and issue errors + or warnings as needed. The decision depends on the following + parameters: + + - The logging mode, i.e., the value of binlog_format. Can be + statement, mixed, or row. + + - The type of statement. There are three types of statements: + "normal" safe statements; unsafe statements; and row injections. + An unsafe statement is one that, if logged in statement format, + might produce different results when replayed on the slave (e.g., + INSERT DELAYED). A row injection is either a BINLOG statement, or + a row event executed by the slave's SQL thread. + + - The capabilities of tables modified by the statement. The + *capabilities vector* for a table is a set of flags associated + with the table. Currently, it only includes two flags: *row + capability flag* and *statement capability flag*. + + The row capability flag is set if and only if the engine can + handle row-based logging. The statement capability flag is set if + and only if the table can handle statement-based logging. + + Decision table for logging format + --------------------------------- + + The following table summarizes how the format and generated + warning/error depends on the tables' capabilities, the statement + type, and the current binlog_format. + + Row capable N NNNNNNNNN YYYYYYYYY YYYYYYYYY + Statement capable N YYYYYYYYY NNNNNNNNN YYYYYYYYY + + Statement type * SSSUUUIII SSSUUUIII SSSUUUIII + + binlog_format * SMRSMRSMR SMRSMRSMR SMRSMRSMR + + Logged format - SS-SS---- -RR-RR-RR SRRSRR-RR + Warning/Error 1 --2332444 5--5--6-- ---7--6-- + + Legend + ------ + + Row capable: N - Some table not row-capable, Y - All tables row-capable + Stmt capable: N - Some table not stmt-capable, Y - All tables stmt-capable + Statement type: (S)afe, (U)nsafe, or Row (I)njection + binlog_format: (S)TATEMENT, (M)IXED, or (R)OW + Logged format: (S)tatement or (R)ow + Warning/Error: Warnings and error messages are as follows: + + 1. Error: Cannot execute statement: binlogging impossible since both + row-incapable engines and statement-incapable engines are + involved. + + 2. Error: Cannot execute statement: binlogging impossible since + BINLOG_FORMAT = ROW and at least one table uses a storage engine + limited to statement-logging. + + 3. Warning: Unsafe statement binlogged as statement since storage + engine is limited to statement-logging. + + 4. Error: Cannot execute row injection: binlogging impossible since + at least one table uses a storage engine limited to + statement-logging. + + 5. Error: Cannot execute statement: binlogging impossible since + BINLOG_FORMAT = STATEMENT and at least one table uses a storage + engine limited to row-logging. + + 6. Error: Cannot execute row injection: binlogging impossible since + BINLOG_FORMAT = STATEMENT. + + 7. Warning: Unsafe statement binlogged in statement format since + BINLOG_FORMAT = STATEMENT. + + In addition, we can produce the following error (not depending on + the variables of the decision diagram): + + 8. Error: Cannot execute statement: binlogging impossible since more + than one engine is involved and at least one engine is + self-logging. + + For each error case above, the statement is prevented from being + logged, we report an error, and roll back the statement. For + warnings, we set the thd->binlog_flags variable: the warning will be + printed only if the statement is successfully logged. + + @see THD::binlog_query + + @param[in] thd Client thread + @param[in] tables Tables involved in the query + + @retval 0 No error; statement can be logged. + @retval -1 One of the error conditions above applies (1, 2, 4, 5, or 6). +*/ + +int THD::decide_logging_format(TABLE_LIST *tables) +{ + DBUG_ENTER("THD::decide_logging_format"); + DBUG_PRINT("info", ("query: %s", query)); + DBUG_PRINT("info", ("variables.binlog_format: %ld", + variables.binlog_format)); + DBUG_PRINT("info", ("lex->get_stmt_unsafe_flags(): 0x%x", + lex->get_stmt_unsafe_flags())); + if (mysql_bin_log.is_open() && (options & OPTION_BIN_LOG)) + { + /* + Compute one bit field with the union of all the engine + capabilities, and one with the intersection of all the engine + capabilities. + */ + handler::Table_flags flags_some_set= 0; + handler::Table_flags flags_all_set= + HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE; + + my_bool multi_engine= FALSE; + void* prev_ht= NULL; + +#ifndef DBUG_OFF + { + static const char *prelocked_mode_name[] = { + "NON_PRELOCKED", + "PRELOCKED", + "PRELOCKED_UNDER_LOCK_TABLES", + }; + DBUG_PRINT("debug", ("prelocked_mode: %s", + prelocked_mode_name[prelocked_mode])); + } +#endif + + /* + Get the capabilities vector for all involved storage engines and + mask out the flags for the binary log. + */ + for (TABLE_LIST *table= tables; table; table= table->next_global) + { + if (table->placeholder()) + continue; + if (table->table->s->table_category == TABLE_CATEGORY_PERFORMANCE) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_SYSTEM_TABLE); + if (table->lock_type >= TL_WRITE_ALLOW_WRITE) + { + handler::Table_flags const flags= table->table->file->ha_table_flags(); + DBUG_PRINT("info", ("table: %s; ha_table_flags: 0x%llx", + table->table_name, flags)); + if (prev_ht && prev_ht != table->table->file->ht) + multi_engine= TRUE; + prev_ht= table->table->file->ht; + flags_all_set &= flags; + flags_some_set |= flags; + } + } + + DBUG_PRINT("info", ("flags_all_set: 0x%llx", flags_all_set)); + DBUG_PRINT("info", ("flags_some_set: 0x%llx", flags_some_set)); + DBUG_PRINT("info", ("multi_engine: %d", multi_engine)); + + int error= 0; + int unsafe_flags; + + /* + If more than one engine is involved in the statement and at + least one is doing it's own logging (is *self-logging*), the + statement cannot be logged atomically, so we generate an error + rather than allowing the binlog to become corrupt. + */ + if (multi_engine && + (flags_some_set & HA_HAS_OWN_BINLOGGING)) + { + my_error((error= ER_BINLOG_MULTIPLE_ENGINES_AND_SELF_LOGGING_ENGINE), + MYF(0)); + } + + /* both statement-only and row-only engines involved */ + if ((flags_all_set & (HA_BINLOG_STMT_CAPABLE | HA_BINLOG_ROW_CAPABLE)) == 0) + { + /* + 1. Error: Binary logging impossible since both row-incapable + engines and statement-incapable engines are involved + */ + my_error((error= ER_BINLOG_ROW_ENGINE_AND_STMT_ENGINE), MYF(0)); + } + /* statement-only engines involved */ + else if ((flags_all_set & HA_BINLOG_ROW_CAPABLE) == 0) + { + if (lex->is_stmt_row_injection()) + { + /* + 4. Error: Cannot execute row injection since table uses + storage engine limited to statement-logging + */ + my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_ENGINE), MYF(0)); + } + else if (variables.binlog_format == BINLOG_FORMAT_ROW) + { + /* + 2. Error: Cannot modify table that uses a storage engine + limited to statement-logging when BINLOG_FORMAT = ROW + */ + my_error((error= ER_BINLOG_ROW_MODE_AND_STMT_ENGINE), MYF(0)); + } + else if ((unsafe_flags= lex->get_stmt_unsafe_flags()) != 0) + { + /* + 3. Warning: Unsafe statement binlogged as statement since + storage engine is limited to statement-logging. + */ + binlog_unsafe_warning_flags|= + (1 << BINLOG_STMT_WARNING_UNSAFE_AND_STMT_ENGINE) | + (unsafe_flags << BINLOG_STMT_WARNING_COUNT); + DBUG_PRINT("info", ("Scheduling warning to be issued by " + "binlog_query: %s", + ER(ER_BINLOG_UNSAFE_AND_STMT_ENGINE))); + DBUG_PRINT("info", ("binlog_unsafe_warning_flags: 0x%x", + binlog_unsafe_warning_flags)); + } + /* log in statement format! */ + } + /* no statement-only engines */ + else + { + /* binlog_format = STATEMENT */ + if (variables.binlog_format == BINLOG_FORMAT_STMT) + { + if (lex->is_stmt_row_injection()) + { + /* + 6. Error: Cannot execute row injection since + BINLOG_FORMAT = STATEMENT + */ + my_error((error= ER_BINLOG_ROW_INJECTION_AND_STMT_MODE), MYF(0)); + } + else if ((flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0) + { + /* + 5. Error: Cannot modify table that uses a storage engine + limited to row-logging when binlog_format = STATEMENT + */ + my_error((error= ER_BINLOG_STMT_MODE_AND_ROW_ENGINE), MYF(0), ""); + } + else if ((unsafe_flags= lex->get_stmt_unsafe_flags()) != 0) + { + /* + 7. Warning: Unsafe statement logged as statement due to + binlog_format = STATEMENT + */ + binlog_unsafe_warning_flags|= + (1 << BINLOG_STMT_WARNING_UNSAFE_AND_STMT_MODE) | + (unsafe_flags << BINLOG_STMT_WARNING_COUNT); + DBUG_PRINT("info", ("Scheduling warning to be issued by " + "binlog_query: '%s'", + ER(ER_BINLOG_UNSAFE_STATEMENT))); + DBUG_PRINT("info", ("binlog_stmt_flags: 0x%x", + binlog_unsafe_warning_flags)); + } + /* log in statement format! */ + } + /* No statement-only engines and binlog_format != STATEMENT. + I.e., nothing prevents us from row logging if needed. */ + else + { + if (lex->is_stmt_unsafe() || lex->is_stmt_row_injection() + || (flags_all_set & HA_BINLOG_STMT_CAPABLE) == 0) + { + /* log in row format! */ + set_current_stmt_binlog_row_based_if_mixed(); + } + } + } + + if (error) { + DBUG_PRINT("info", ("decision: no logging since an error was generated")); + DBUG_RETURN(-1); + } + DBUG_PRINT("info", ("decision: logging in %s format", + is_current_stmt_binlog_format_row() ? + "ROW" : "STATEMENT")); + } +#ifndef DBUG_OFF + else + DBUG_PRINT("info", ("decision: no logging since " + "mysql_bin_log.is_open() = %d " + "and (options & OPTION_BIN_LOG) = 0x%llx", + mysql_bin_log.is_open(), (options & OPTION_BIN_LOG))); +#endif + + DBUG_RETURN(0); +} + + /* Implementation of interface to write rows to the binary log through the thread. The thread is responsible for writing the rows it has --Boundary_(ID_eaEz1BKWUpQDJDuw443LxQ) MIME-version: 1.0 Content-type: text/bzr-bundle; CHARSET=US-ASCII; name="bzr/sven.sandberg@stripped" Content-transfer-encoding: 7BIT Content-disposition: inline; filename="bzr/sven.sandberg@stripped" # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: sven.sandberg@stripped # target_branch: file:///home/sven/bzr/b39934-mats-\ # slave_row_engine/5.1-bugteam/ # testament_sha1: be073c8af9f3c3073210accc836c7a5a8be5d98a # timestamp: 2009-07-22 18:29:36 +0200 # base_revision_id: sven.sandberg@stripped\ # j2zo0042mtd0raqm # # Begin bundle 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 --Boundary_(ID_eaEz1BKWUpQDJDuw443LxQ)--