diff options
Diffstat (limited to 'sql/handler.cc')
-rw-r--r-- | sql/handler.cc | 71 |
1 files changed, 56 insertions, 15 deletions
diff --git a/sql/handler.cc b/sql/handler.cc index 68ca3855158..25cec431395 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3200,40 +3200,81 @@ template int binlog_log_row<Update_rows_log_event>(TABLE *, const byte *, const #endif /* HAVE_ROW_BASED_REPLICATION */ -int handler::ha_write_row(byte *buf) +int handler::ha_external_lock(THD *thd, int lock_type) { + DBUG_ENTER("handler::ha_external_lock"); int error; - if (likely(!(error= write_row(buf)))) + 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: + DBUG_RETURN(0); + } + + /* + 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); +} + +int handler::ha_write_row(byte *buf) +{ + int error; + if (unlikely(error= write_row(buf))) + return error; #ifdef HAVE_ROW_BASED_REPLICATION - error= binlog_log_row<Write_rows_log_event>(table, 0, buf); + if (unlikely(error= binlog_log_row<Write_rows_log_event>(table, 0, buf))) + return error; #endif - } - return error; + return 0; } int handler::ha_update_row(const byte *old_data, byte *new_data) { int error; - if (likely(!(error= update_row(old_data, new_data)))) - { + if (unlikely(error= update_row(old_data, new_data))) + return error; #ifdef HAVE_ROW_BASED_REPLICATION - error= binlog_log_row<Update_rows_log_event>(table, old_data, new_data); + if (unlikely(error= binlog_log_row<Update_rows_log_event>(table, old_data, new_data))) + return error; #endif - } - return error; + return 0; } int handler::ha_delete_row(const byte *buf) { int error; - if (likely(!(error= delete_row(buf)))) - { + if (unlikely(error= delete_row(buf))) + return error; #ifdef HAVE_ROW_BASED_REPLICATION - error= binlog_log_row<Delete_rows_log_event>(table, buf, 0); + if (unlikely(error= binlog_log_row<Delete_rows_log_event>(table, buf, 0))) + return error; #endif - } - return error; + return 0; } |