summaryrefslogtreecommitdiff
path: root/sql/handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/handler.cc')
-rw-r--r--sql/handler.cc71
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;
}