diff options
author | unknown <mats@mysql.com> | 2006-05-31 19:21:52 +0200 |
---|---|---|
committer | unknown <mats@mysql.com> | 2006-05-31 19:21:52 +0200 |
commit | e9b5cafa8b2a95a0bf414922ac61335ea199c765 (patch) | |
tree | 470ce568d2974256afbf5d669352479e3b31fac1 /sql/handler.cc | |
parent | 39b6d186e8933a1e6e5544194e66138f78e14b11 (diff) | |
download | mariadb-git-e9b5cafa8b2a95a0bf414922ac61335ea199c765.tar.gz |
Bug#19995 (Extreneous table maps generated for statements that do not generate rows):
Switched to writing out table maps for tables that are locked when
the first row in a statement is seen.
mysql-test/include/master-slave.inc:
Moved code to reset master and slave into separate file.
mysql-test/r/binlog_row_blackhole.result:
Result change
mysql-test/r/binlog_row_mix_innodb_myisam.result:
Result change
mysql-test/r/ndb_binlog_ignore_db.result:
Result change
mysql-test/r/rpl_ndb_charset.result:
Result change
mysql-test/r/rpl_row_basic_11bugs.result:
Result change
mysql-test/r/rpl_row_charset.result:
Result change
mysql-test/r/rpl_row_create_table.result:
Result change
mysql-test/t/rpl_row_basic_11bugs.test:
Added test to check that no events are generated when no rows are changed.
mysql-test/t/rpl_row_create_table.test:
Master log position changed
sql/handler.cc:
Adding function write_locked_table_maps() that will write table maps for all
tables locked for write.
Using "table->in_use" instead of "current_thd" since tables are now locked
when the function is called.
Removing old code to write table map.
sql/log_event.cc:
Added assertion
sql/sql_class.cc:
Removing code to write "dummy termination event".
sql/sql_class.h:
Adding getter for binlog_table_maps.
sql/sql_insert.cc:
Setting thd->lock before calling write_record for the execution of
CREATE-SELECT and INSERT-SELECT since they keep multiple locks in the
air at the same time.
mysql-test/include/master-slave-reset.inc:
New BitKeeper file ``mysql-test/include/master-slave-reset.inc''
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 108 |
1 files changed, 67 insertions, 41 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index b9ef05a33c2..dfa3789f6a0 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3199,6 +3199,58 @@ namespace { } } +/** + Write table maps for all (manually or automatically) locked tables + to the binary log. + + This function will generate and write table maps for all tables + that are locked by the thread 'thd'. Either manually locked + (stored in THD::locked_tables) and automatically locked (stored in + THD::lock) are considered. + + See THD::lock and THD::locked_tables for more information. + */ +static int +write_locked_table_maps(THD *thd) +{ + DBUG_ENTER("write_locked_table_maps"); + DBUG_PRINT("enter", ("thd=%p, thd->lock=%p, thd->locked_tables=%p", + thd, thd->lock, thd->locked_tables)); + + if (thd->get_binlog_table_maps() == 0) + { + /* + Exactly one table has to be locked, otherwise this code is not + guaranteed to work. + */ + DBUG_ASSERT((thd->lock != NULL) + (thd->locked_tables != NULL) == 1); + + MYSQL_LOCK *lock= thd->lock ? thd->lock : thd->locked_tables; + DBUG_ASSERT(lock->table_count > 0); + TABLE **const end_ptr= lock->table + lock->table_count; + for (TABLE **table_ptr= lock->table ; + table_ptr != end_ptr ; + ++table_ptr) + { + TABLE *const table= *table_ptr; + DBUG_PRINT("info", ("Checking table %s", table->s->table_name)); + if (table->current_lock == F_WRLCK && + check_table_binlog_row_based(thd, table)) + { + int const has_trans= table->file->has_transactions(); + int const error= thd->binlog_write_table_map(table, has_trans); + /* + If an error occurs, it is the responsibility of the caller to + roll back the transaction. + */ + if (unlikely(error)) + DBUG_RETURN(1); + } + } + } + DBUG_RETURN(0); +} + template<class RowsEventT> int binlog_log_row(TABLE* table, const byte *before_record, const byte *after_record) @@ -3206,7 +3258,7 @@ template<class RowsEventT> int binlog_log_row(TABLE* table, if (table->file->is_injective()) return 0; bool error= 0; - THD *const thd= current_thd; + THD *const thd= table->in_use; if (check_table_binlog_row_based(thd, table)) { @@ -3215,17 +3267,26 @@ template<class RowsEventT> int binlog_log_row(TABLE* table, uint32 bitbuf[BITMAP_STACKBUF_SIZE/sizeof(uint32)]; uint n_fields= table->s->fields; my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8; + + /* + If there are no table maps written to the binary log, this is + the first row handled in this statement. In that case, we need + to write table maps for all locked tables to the binary log. + */ if (likely(!(error= bitmap_init(&cols, use_bitbuf ? bitbuf : NULL, (n_fields + 7) & ~7UL, false)))) { bitmap_set_all(&cols); - error= - RowsEventT::binlog_row_logging_function(thd, table, - table->file->has_transactions(), - &cols, table->s->fields, - before_record, after_record); + if (likely(!(error= write_locked_table_maps(thd)))) + { + error= + RowsEventT::binlog_row_logging_function(thd, table, + table->file->has_transactions(), + &cols, table->s->fields, + before_record, after_record); + } if (!use_bitbuf) bitmap_free(&cols); } @@ -3251,41 +3312,6 @@ int handler::ha_external_lock(THD *thd, int lock_type) int error; if (unlikely(error= external_lock(thd, lock_type))) DBUG_RETURN(error); -#ifdef HAVE_ROW_BASED_REPLICATION - if (table->file->is_injective()) - DBUG_RETURN(0); - - /* - There is a number of statements that are logged statement-based - but call external lock. For these, we do not need to generate a - table map. - - TODO: The need for this switch is an indication that the model for - locking combined with row-based replication needs to be looked - over. Ideally, no such special handling should be needed. - */ - switch (thd->lex->sql_command) { - case SQLCOM_TRUNCATE: - case SQLCOM_ALTER_TABLE: - case SQLCOM_OPTIMIZE: - case SQLCOM_REPAIR: - DBUG_RETURN(0); - default: - break; - } - - /* - If we are locking a table for writing, we generate a table map. - For all other kinds of locks, we don't do anything. - */ - if (lock_type == F_WRLCK && check_table_binlog_row_based(thd, table)) - { - int const has_trans= table->file->has_transactions(); - error= thd->binlog_write_table_map(table, has_trans); - if (unlikely(error)) - DBUG_RETURN(error); - } -#endif DBUG_RETURN(0); } |