summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
authorunknown <mats@mysql.com>2006-05-31 19:21:52 +0200
committerunknown <mats@mysql.com>2006-05-31 19:21:52 +0200
commite9b5cafa8b2a95a0bf414922ac61335ea199c765 (patch)
tree470ce568d2974256afbf5d669352479e3b31fac1 /sql/handler.cc
parent39b6d186e8933a1e6e5544194e66138f78e14b11 (diff)
downloadmariadb-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.cc108
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);
}