diff options
author | Monty <monty@mariadb.org> | 2016-05-28 01:15:39 +0300 |
---|---|---|
committer | Sergei Golubchik <serg@mariadb.org> | 2016-06-30 11:43:02 +0200 |
commit | 60916a8b9e81b9e9de14fa737848419f45ff899a (patch) | |
tree | 33aede23decf1bd128a06e51951606690f548430 /sql/sql_class.cc | |
parent | 6c173324ffa0c6d5a6997610ee4e6cc73bd9ae9e (diff) | |
download | mariadb-git-60916a8b9e81b9e9de14fa737848419f45ff899a.tar.gz |
Simplify THD::decide_logging_format()
Fixed some test for future when DELETE will not trigger row based replication
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 163 |
1 files changed, 47 insertions, 116 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0f9afb9c253..d016bfdae50 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5528,94 +5528,6 @@ int xid_cache_iterate(THD *thd, my_hash_walk_action action, void *arg) &argument); } -/* - Tells if two (or more) tables have auto_increment columns and we want to - lock those tables with a write lock. - - SYNOPSIS - has_two_write_locked_tables_with_auto_increment - tables Table list - - NOTES: - Call this function only when you have established the list of all tables - which you'll want to update (including stored functions, triggers, views - inside your statement). -*/ - -static bool -has_write_table_with_auto_increment(TABLE_LIST *tables) -{ - for (TABLE_LIST *table= tables; table; table= table->next_global) - { - /* we must do preliminary checks as table->table may be NULL */ - if (!table->placeholder() && - table->table->found_next_number_field && - (table->lock_type >= TL_WRITE_ALLOW_WRITE)) - return 1; - } - - return 0; -} - -/* - checks if we have select tables in the table list and write tables - with auto-increment column. - - SYNOPSIS - has_two_write_locked_tables_with_auto_increment_and_select - tables Table list - - RETURN VALUES - - -true if the table list has atleast one table with auto-increment column - - - and atleast one table to select from. - -false otherwise -*/ - -static bool -has_write_table_with_auto_increment_and_select(TABLE_LIST *tables) -{ - bool has_select= false; - bool has_auto_increment_tables = has_write_table_with_auto_increment(tables); - for(TABLE_LIST *table= tables; table; table= table->next_global) - { - if (!table->placeholder() && - (table->lock_type <= TL_READ_NO_INSERT)) - { - has_select= true; - break; - } - } - return(has_select && has_auto_increment_tables); -} - -/* - Tells if there is a table whose auto_increment column is a part - of a compound primary key while is not the first column in - the table definition. - - @param tables Table list - - @return true if the table exists, fais if does not. -*/ - -static bool -has_write_table_auto_increment_not_first_in_pk(TABLE_LIST *tables) -{ - for (TABLE_LIST *table= tables; table; table= table->next_global) - { - /* we must do preliminary checks as table->table may be NULL */ - if (!table->placeholder() && - table->table->found_next_number_field && - (table->lock_type >= TL_WRITE_ALLOW_WRITE) - && table->table->s->next_number_keypart != 0) - return 1; - } - - return 0; -} /** Decide on logging format to use for the statement and issue errors @@ -5746,17 +5658,24 @@ int THD::decide_logging_format(TABLE_LIST *tables) If different types of engines are about to be updated. For example: Innodb and Falcon; Innodb and MyIsam. */ - my_bool multi_write_engine= FALSE; + bool multi_write_engine= FALSE; /* If different types of engines are about to be accessed and any of them is about to be updated. For example: Innodb and Falcon; Innodb and MyIsam. */ - my_bool multi_access_engine= FALSE; + bool multi_access_engine= FALSE; /* Identifies if a table is changed. */ - my_bool is_write= FALSE; + bool is_write= FALSE; // If any write tables + bool has_read_tables= FALSE; // If any read only tables + bool has_auto_increment_write_tables= FALSE; // Write with auto-increment + /* If a write table that doesn't have auto increment part first */ + bool has_write_table_auto_increment_not_first_in_pk= FALSE; + bool has_auto_increment_write_tables_not_first= FALSE; + bool found_first_not_own_table= FALSE; + /* A pointer to a previous table that was changed. */ @@ -5800,31 +5719,6 @@ int THD::decide_logging_format(TABLE_LIST *tables) } #endif - if (wsrep_binlog_format() != BINLOG_FORMAT_ROW && tables) - { - /* - DML statements that modify a table with an auto_increment column based on - rows selected from a table are unsafe as the order in which the rows are - fetched fron the select tables cannot be determined and may differ on - master and slave. - */ - if (has_write_table_with_auto_increment_and_select(tables)) - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT); - - if (has_write_table_auto_increment_not_first_in_pk(tables)) - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST); - - /* - A query that modifies autoinc column in sub-statement can make the - master and slave inconsistent. - We can solve these problems in mixed mode by switching to binlogging - if at least one updated table is used by sub-statement - */ - if (lex->requires_prelocking() && - has_write_table_with_auto_increment(lex->first_not_own_table())) - lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS); - } - /* Get the capabilities vector for all involved storage engines and mask out the flags for the binary log. @@ -5863,9 +5757,22 @@ int THD::decide_logging_format(TABLE_LIST *tables) continue; } } + if (table == lex->first_not_own_table()) + found_first_not_own_table= true; replicated_tables_count++; + if (table->lock_type <= TL_READ_NO_INSERT) + has_read_tables= true; + else if (table->table->found_next_number_field && + (table->lock_type >= TL_WRITE_ALLOW_WRITE)) + { + has_auto_increment_write_tables= true; + has_auto_increment_write_tables_not_first= found_first_not_own_table; + if (table->table->s->next_number_keypart != 0) + has_write_table_auto_increment_not_first_in_pk= true; + } + if (table->lock_type >= TL_WRITE_ALLOW_WRITE) { if (prev_write_table && prev_write_table->file->ht != @@ -5910,6 +5817,30 @@ int THD::decide_logging_format(TABLE_LIST *tables) prev_access_table= table->table; } + if (wsrep_binlog_format() != BINLOG_FORMAT_ROW) + { + /* + DML statements that modify a table with an auto_increment + column based on rows selected from a table are unsafe as the + order in which the rows are fetched fron the select tables + cannot be determined and may differ on master and slave. + */ + if (has_auto_increment_write_tables && has_read_tables) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_WRITE_AUTOINC_SELECT); + + if (has_write_table_auto_increment_not_first_in_pk) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_NOT_FIRST); + /* + A query that modifies autoinc column in sub-statement can make the + master and slave inconsistent. + We can solve these problems in mixed mode by switching to binlogging + if at least one updated table is used by sub-statement + */ + if (lex->requires_prelocking() && + has_auto_increment_write_tables_not_first) + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS); + } + DBUG_PRINT("info", ("flags_write_all_set: 0x%llx", flags_write_all_set)); DBUG_PRINT("info", ("flags_write_some_set: 0x%llx", flags_write_some_set)); DBUG_PRINT("info", ("flags_access_some_set: 0x%llx", flags_access_some_set)); |