Below is the list of changes that have just been committed into a local
6.0 repository of mats. When mats does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-12-18 18:26:54+01:00, mats@stripped +10 -0
BUG#33055 (Replication fails for UPDATE when using falcon Storage engine):
The read- and write-sets were not respected when deciding what fields to
transfer to the slave, nor when writing the row to the handler on the sla-
ve side.
This patch adds code that only writes the columns actually needed to be
able to replicate row-based. This means that the columns in the write set
of the table is used for ha_write_row(), the columns in the read set for
ha_delete_row(), and for ha_update_row() the columns in the read set is
used for the before image, and the columns of the write set for the after
image.
In addition, for cursor-based delete and update, the necessary bits are
set to be able to get enough information to locate the affected row on
the slave side, which means that it behaves as if HA_PRIMARY_KEY_REQUIRED_
FOR_DELETE was set for the table when row-based logging is active.
mysql-test/suite/rpl/r/rpl_temporary_errors.result@stripped, 2007-12-18 18:26:43+01:00, mats@stripped +2 -2
Result change.
sql/handler.cc@stripped, 2007-12-18 18:26:44+01:00, mats@stripped +6 -23
The function binlog_row_logging_function() does not need column
information any more: that information is fetched directly from
the read- and write-sets of the table instead. Hence, an unused
initialization of a bitmap is removed, as well as error handling
code for that initialization.
sql/log_event.cc@stripped, 2007-12-18 18:26:44+01:00, mats@stripped +15 -25
Passing columns to new unpack_current_row() function: it now
takes a column bitmap with the columns to unpack. When preparing
the record before filling it in, the column vector now has to be
passed so that the function knows what columns to initialize.
The constructors for Write_rows, Delete_rows, and Update_rows
now use either the read- or write-set of the table when packing
rows for transfer, so the column vector parameter was removed.
As a consequence, an overloaded version of the Update_rows
constructor was removed.
sql/log_event.h@stripped, 2007-12-18 18:26:44+01:00, mats@stripped +8 -21
The function unpack_current_row() now takes an extra column
vector giving the columns to unpack and passes that to
::unpack_row() instead of m_cols previously (it can now be
either m_cols or m_cols_ai, depending on situation).
Removing redundant column vector parameter from constructors
for Write_rows, Delete_rows, and Update_rows and removing
a redundant constructor.
Removing column vector parameters to binlog_row_logging_
function() since they are no longer needed.
sql/log_event_old.h@stripped, 2007-12-18 18:26:45+01:00, mats@stripped +6 -6
Removing redundant column vector parameter from constructors
for Write_rows, Delete_rows, and Update_rows and removing
a redundant constructor.
sql/rpl_record.cc@stripped, 2007-12-18 18:26:45+01:00, mats@stripped +55 -21
Adding debug printouts to be able to debug packing and unpacking of rows.
Adding column vector to prepare_record(). The function prepare_record()
now initializes all fields of the record, not just the "extra" ones that
could be present on a slave with more columns. The function still prints
an error for extra fields that does not have a default value (in the same
manner as the old function), but does not print anything for columns that
are present on the master and the slave.
sql/rpl_record.h@stripped, 2007-12-18 18:26:45+01:00, mats@stripped +1 -1
Adding column vector parameter to prepare_record().
sql/sql_class.cc@stripped, 2007-12-18 18:26:45+01:00, mats@stripped +13 -24
Columns bitmap and number of columns no longer needed for binlog_*_row().
The correct columns are fetched from the read- and write-set of the table
instead. Consequence: binlog_prepare_pending_rows_event() does not need
this info either.
The function pack_row() is called with either the read- or the write-set
of the table.
sql/sql_class.h@stripped, 2007-12-18 18:26:46+01:00, mats@stripped +2 -7
Columns bitmap and number of columns no longer needed for binlog_*_row().
The correct columns are fetched from the read- and write-set of the table
instead. Consequence: binlog_prepare_pending_rows_event() does not need
this info either.
sql/table.cc@stripped, 2007-12-18 18:26:46+01:00, mats@stripped +12 -6
Columns marked for delete are marked in the same way as if
HA_PRIMARY_KEY_REQUIRED_FOR_DELETE when row-based replication
is active since the primary key (or entire row) has to be
transfered to the slave. There is no way that the slave can
know what row the master's cursor is positioned on when del-
eting a row. This is done for both DELETE and UPDATE.
diff -Nrup a/mysql-test/suite/rpl/r/rpl_temporary_errors.result b/mysql-test/suite/rpl/r/rpl_temporary_errors.result
--- a/mysql-test/suite/rpl/r/rpl_temporary_errors.result 2007-10-24 16:02:32 +02:00
+++ b/mysql-test/suite/rpl/r/rpl_temporary_errors.result 2007-12-18 18:26:43 +01:00
@@ -44,7 +44,7 @@ Master_User root
Master_Port MASTER_PORT
Connect_Retry 1
Master_Log_File master-bin.000001
-Read_Master_Log_Pos 408
+Read_Master_Log_Pos 404
Relay_Log_File #
Relay_Log_Pos #
Relay_Master_Log_File master-bin.000001
@@ -59,7 +59,7 @@ Replicate_Wild_Ignore_Table
Last_Errno 0
Last_Error
Skip_Counter 0
-Exec_Master_Log_Pos 408
+Exec_Master_Log_Pos 404
Relay_Log_Space #
Until_Condition None
Until_Log_File
diff -Nrup a/sql/handler.cc b/sql/handler.cc
--- a/sql/handler.cc 2007-12-05 20:44:35 +01:00
+++ b/sql/handler.cc 2007-12-18 18:26:44 +01:00
@@ -4516,35 +4516,18 @@ namespace
if (check_table_binlog_row_based(thd, table))
{
- MY_BITMAP cols;
- /* Potential buffer on the stack for the bitmap */
- uint32 bitbuf[BITMAP_STACKBUF_SIZE/sizeof(uint32)];
- uint n_fields= table->s->fields;
- my_bool use_bitbuf= n_fields <= sizeof(bitbuf)*8;
-
+ DBUG_DUMP("read_set 10", (uchar*) table->read_set->bitmap, (table->s->fields + 7) / 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))))
+ if (likely(!(error= write_locked_table_maps(thd))))
{
- bitmap_set_all(&cols);
- 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);
+ bool const has_trans= table->file->has_transactions();
+ error=
+ RowsEventT::binlog_row_logging_function(thd, table, has_trans,
+ before_record, after_record);
}
}
return error ? HA_ERR_RBR_LOGGING_FAILED : 0;
diff -Nrup a/sql/log_event.cc b/sql/log_event.cc
--- a/sql/log_event.cc 2007-11-15 14:41:44 +01:00
+++ b/sql/log_event.cc 2007-12-18 18:26:44 +01:00
@@ -6451,7 +6451,7 @@ int Rows_log_event::do_apply_event(Relay
(ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
if (!m_curr_row_end && !error)
- unpack_current_row(rli);
+ unpack_current_row(rli, &m_cols);
// at this moment m_curr_row_end should be set
DBUG_ASSERT(error || m_curr_row_end != NULL);
@@ -7265,9 +7265,8 @@ void Table_map_log_event::print(FILE *fi
#if !defined(MYSQL_CLIENT)
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
ulong tid_arg,
- MY_BITMAP const *cols,
bool is_transactional)
- : Rows_log_event(thd_arg, tbl_arg, tid_arg, cols, is_transactional)
+ : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
{
}
#endif
@@ -7344,6 +7343,7 @@ Write_rows_log_event::do_before_row_oper
analyze if explicit data is provided for slave's TIMESTAMP columns).
*/
m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
+
return error;
}
@@ -7455,12 +7455,12 @@ Rows_log_event::write_row(const Relay_lo
/* fill table->record[0] with default values */
- if ((error= prepare_record(rli, table, m_width,
+ if ((error= prepare_record(rli, table, &m_cols, m_width,
TRUE /* check if columns have def. values */)))
DBUG_RETURN(error);
/* unpack row into table->record[0] */
- error= unpack_current_row(rli); // TODO: how to handle errors?
+ error= unpack_current_row(rli, &m_cols);
#ifndef DBUG_OFF
DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
@@ -7569,7 +7569,7 @@ Rows_log_event::write_row(const Relay_lo
if (!get_flags(COMPLETE_ROWS_F))
{
restore_record(table,record[1]);
- error= unpack_current_row(rli);
+ error= unpack_current_row(rli, &m_cols);
}
#ifndef DBUG_OFF
@@ -7780,8 +7780,8 @@ int Rows_log_event::find_row(const Relay
/* unpack row - missing fields get default values */
// TODO: shall we check and report errors here?
- prepare_record(NULL,table,m_width,FALSE /* don't check errors */);
- error= unpack_current_row(rli);
+ prepare_record(NULL, table, &m_cols, m_width, FALSE /* don't check errors */);
+ error= unpack_current_row(rli, &m_cols);
#ifndef DBUG_OFF
DBUG_PRINT("info",("looking for the following record"));
@@ -8030,9 +8030,9 @@ int Rows_log_event::find_row(const Relay
#ifndef MYSQL_CLIENT
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
- ulong tid, MY_BITMAP const *cols,
+ ulong tid,
bool is_transactional)
- : Rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional)
+ : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
{
}
#endif /* #if !defined(MYSQL_CLIENT) */
@@ -8070,6 +8070,7 @@ Delete_rows_log_event::do_before_row_ope
if (!m_key)
return HA_ERR_OUT_OF_MEM;
}
+
return 0;
}
@@ -8121,21 +8122,10 @@ void Delete_rows_log_event::print(FILE *
#if !defined(MYSQL_CLIENT)
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
ulong tid,
- MY_BITMAP const *cols_bi,
- MY_BITMAP const *cols_ai,
- bool is_transactional)
-: Rows_log_event(thd_arg, tbl_arg, tid, cols_bi, is_transactional)
-{
- init(cols_ai);
-}
-
-Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
- ulong tid,
- MY_BITMAP const *cols,
bool is_transactional)
-: Rows_log_event(thd_arg, tbl_arg, tid, cols, is_transactional)
+: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
{
- init(cols);
+ init(tbl_arg->write_set);
}
void Update_rows_log_event::init(MY_BITMAP const *cols)
@@ -8221,7 +8211,7 @@ Update_rows_log_event::do_exec_row(const
able to skip to the next pair of updates
*/
m_curr_row= m_curr_row_end;
- unpack_current_row(rli);
+ unpack_current_row(rli, &m_cols_ai);
return error;
}
@@ -8239,7 +8229,7 @@ Update_rows_log_event::do_exec_row(const
store_record(m_table,record[1]);
m_curr_row= m_curr_row_end;
- error= unpack_current_row(rli); // this also updates m_curr_row_end
+ error= unpack_current_row(rli, &m_cols_ai); // this also updates m_curr_row_end
/*
Now we have the right row to update. The old row (the one we're
diff -Nrup a/sql/log_event.h b/sql/log_event.h
--- a/sql/log_event.h 2007-11-15 14:41:45 +01:00
+++ b/sql/log_event.h 2007-12-18 18:26:44 +01:00
@@ -3092,11 +3092,12 @@ protected:
int write_row(const Relay_log_info *const, const bool);
// Unpack the current row into m_table->record[0]
- int unpack_current_row(const Relay_log_info *const rli)
+ int unpack_current_row(const Relay_log_info *const rli,
+ MY_BITMAP const *cols)
{
DBUG_ASSERT(m_table);
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
- int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
+ int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, cols,
&m_curr_row_end, &m_master_reclength);
ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
return result;
@@ -3185,7 +3186,7 @@ public:
#if !defined(MYSQL_CLIENT)
Write_rows_log_event(THD*, TABLE*, ulong table_id,
- MY_BITMAP const *cols, bool is_transactional);
+ bool is_transactional);
#endif
#ifdef HAVE_REPLICATION
Write_rows_log_event(const char *buf, uint event_len,
@@ -3194,14 +3195,11 @@ public:
#if !defined(MYSQL_CLIENT)
static bool binlog_row_logging_function(THD *thd, TABLE *table,
bool is_transactional,
- MY_BITMAP *cols,
- uint fields,
const uchar *before_record
__attribute__((unused)),
const uchar *after_record)
{
- return thd->binlog_write_row(table, is_transactional,
- cols, fields, after_record);
+ return thd->binlog_write_row(table, is_transactional, after_record);
}
#endif
@@ -3243,12 +3241,6 @@ public:
#ifndef MYSQL_CLIENT
Update_rows_log_event(THD*, TABLE*, ulong table_id,
- MY_BITMAP const *cols_bi,
- MY_BITMAP const *cols_ai,
- bool is_transactional);
-
- Update_rows_log_event(THD*, TABLE*, ulong table_id,
- MY_BITMAP const *cols,
bool is_transactional);
void init(MY_BITMAP const *cols);
@@ -3264,13 +3256,11 @@ public:
#if !defined(MYSQL_CLIENT)
static bool binlog_row_logging_function(THD *thd, TABLE *table,
bool is_transactional,
- MY_BITMAP *cols,
- uint fields,
const uchar *before_record,
const uchar *after_record)
{
return thd->binlog_update_row(table, is_transactional,
- cols, fields, before_record, after_record);
+ before_record, after_record);
}
#endif
@@ -3324,7 +3314,7 @@ public:
#ifndef MYSQL_CLIENT
Delete_rows_log_event(THD*, TABLE*, ulong,
- MY_BITMAP const *cols, bool is_transactional);
+ bool is_transactional);
#endif
#ifdef HAVE_REPLICATION
Delete_rows_log_event(const char *buf, uint event_len,
@@ -3333,14 +3323,11 @@ public:
#if !defined(MYSQL_CLIENT)
static bool binlog_row_logging_function(THD *thd, TABLE *table,
bool is_transactional,
- MY_BITMAP *cols,
- uint fields,
const uchar *before_record,
const uchar *after_record
__attribute__((unused)))
{
- return thd->binlog_delete_row(table, is_transactional,
- cols, fields, before_record);
+ return thd->binlog_delete_row(table, is_transactional, before_record);
}
#endif
diff -Nrup a/sql/log_event_old.h b/sql/log_event_old.h
--- a/sql/log_event_old.h 2007-09-10 13:15:59 +02:00
+++ b/sql/log_event_old.h 2007-12-18 18:26:45 +01:00
@@ -113,8 +113,8 @@ public:
#if !defined(MYSQL_CLIENT)
Write_rows_log_event_old(THD *thd, TABLE *table, ulong table_id,
- MY_BITMAP const *cols, bool is_transactional)
- : Write_rows_log_event(thd, table, table_id, cols, is_transactional)
+ bool is_transactional)
+ : Write_rows_log_event(thd, table, table_id, is_transactional)
{
}
#endif
@@ -159,8 +159,8 @@ public:
#if !defined(MYSQL_CLIENT)
Update_rows_log_event_old(THD *thd, TABLE *table, ulong table_id,
- MY_BITMAP const *cols, bool is_transactional)
- : Update_rows_log_event(thd, table, table_id, cols, is_transactional),
+ bool is_transactional)
+ : Update_rows_log_event(thd, table, table_id, is_transactional),
m_after_image(NULL), m_memory(NULL)
{
}
@@ -206,8 +206,8 @@ public:
#if !defined(MYSQL_CLIENT)
Delete_rows_log_event_old(THD *thd, TABLE *table, ulong table_id,
- MY_BITMAP const *cols, bool is_transactional)
- : Delete_rows_log_event(thd, table, table_id, cols, is_transactional),
+ bool is_transactional)
+ : Delete_rows_log_event(thd, table, table_id, is_transactional),
m_after_image(NULL), m_memory(NULL)
{
}
diff -Nrup a/sql/rpl_record.cc b/sql/rpl_record.cc
--- a/sql/rpl_record.cc 2007-11-15 14:41:46 +01:00
+++ b/sql/rpl_record.cc 2007-12-18 18:26:45 +01:00
@@ -75,15 +75,20 @@ pack_row(TABLE *table, MY_BITMAP const*
unsigned int null_bits= (1U << 8) - 1;
// Mask to mask out the correct but among the null bits
unsigned int null_mask= 1U;
+ DBUG_PRINT("debug", ("null ptr: 0x%lx; row start: %p; null bytes: %d",
+ (ulong) null_ptr, row_data, null_byte_count));
+ DBUG_DUMP("cols", (uchar*) cols->bitmap, cols->last_word_ptr - cols->bitmap + 1);
for ( ; (field= *p_field) ; p_field++)
{
- DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d",
- null_mask, null_ptr, row_data, null_byte_count));
+ DBUG_PRINT("debug", ("field: %s; null mask: 0x%x",
+ field->field_name, null_mask));
if (bitmap_is_set(cols, p_field - table->field))
{
my_ptrdiff_t offset;
if (field->is_null(rec_offset))
{
+ DBUG_PRINT("debug", ("Is NULL; null_mask: 0x%x; null_bits: 0x%x",
+ null_mask, null_bits));
offset= def_offset;
null_bits |= null_mask;
}
@@ -104,9 +109,9 @@ pack_row(TABLE *table, MY_BITMAP const*
#endif
pack_ptr= field->pack(pack_ptr, field->ptr + offset,
field->max_data_length(), TRUE);
- DBUG_PRINT("debug", ("field: %s; pack_ptr: 0x%lx;"
+ DBUG_PRINT("debug", ("Packed into row; pack_ptr: 0x%lx;"
" pack_ptr':0x%lx; bytes: %d",
- field->field_name, (ulong) old_pack_ptr,
+ (ulong) old_pack_ptr,
(ulong) pack_ptr,
(int) (pack_ptr - old_pack_ptr)));
}
@@ -120,6 +125,12 @@ pack_row(TABLE *table, MY_BITMAP const*
null_bits= (1U << 8) - 1;
}
}
+#ifndef DBUG_OFF
+ else
+ {
+ DBUG_PRINT("debug", ("Skipped"));
+ }
+#endif
}
/*
@@ -206,6 +217,9 @@ unpack_row(Relay_log_info const *rli,
{
Field *const f= *field_ptr;
+ DBUG_PRINT("debug", ("field: %s; null mask: 0x%x; null bits: 0x%lx; row start: %p; null bytes: %d",
+ f->field_name, null_mask, (ulong) null_bits, pack_ptr, master_null_byte_count));
+
/*
No need to bother about columns that does not exist: they have
gotten default values when being emptied above.
@@ -225,7 +239,12 @@ unpack_row(Relay_log_info const *rli,
DBUG_ASSERT(pack_ptr != NULL);
if ((null_bits & null_mask) && f->maybe_null())
+ {
+ DBUG_PRINT("debug", ("Was NULL; null mask: 0x%x; null bits: 0x%x",
+ null_mask, null_bits));
+
f->set_null();
+ }
else
{
f->set_notnull();
@@ -240,15 +259,20 @@ unpack_row(Relay_log_info const *rli,
uchar const *const old_pack_ptr= pack_ptr;
#endif
pack_ptr= f->unpack(f->ptr, pack_ptr, metadata, TRUE);
- DBUG_PRINT("debug", ("field: %s; metadata: 0x%x;"
+ DBUG_PRINT("debug", ("Unpacked; metadata: 0x%x;"
" pack_ptr: 0x%lx; pack_ptr': 0x%lx; bytes: %d",
- f->field_name, metadata,
- (ulong) old_pack_ptr, (ulong) pack_ptr,
+ metadata, (ulong) old_pack_ptr, (ulong) pack_ptr,
(int) (pack_ptr - old_pack_ptr)));
}
null_mask <<= 1;
}
+#ifndef DBUG_OFF
+ else
+ {
+ DBUG_PRINT("debug", ("Non-existent: skipped"));
+ }
+#endif
i++;
}
@@ -318,35 +342,45 @@ unpack_row(Relay_log_info const *rli,
*/
int prepare_record(const Slave_reporting_capability *const log,
TABLE *const table,
- const uint skip, const bool check)
+ const MY_BITMAP *cols, uint width, const bool check)
{
DBUG_ENTER("prepare_record");
int error= 0;
empty_record(table);
- if (skip >= table->s->fields) // nothing to do
- DBUG_RETURN(0);
-
- /* Explicit initialization of fields */
+ /*
+ Explicit initialization of fields. For fields that are not in the
+ cols for the row, we set them to default. If the fields are in
+ addition to what exists on the master, we give an error if the
+ have no sensible default.
+ */
- for (Field **field_ptr= table->field+skip ; *field_ptr ; ++field_ptr)
+ for (Field **field_ptr= table->field ; *field_ptr ; ++field_ptr)
{
uint32 const mask= NOT_NULL_FLAG | NO_DEFAULT_VALUE_FLAG;
Field *const f= *field_ptr;
if (check && ((f->flags & mask) == mask))
{
- DBUG_ASSERT(log);
- log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
- "Field `%s` of table `%s`.`%s` "
- "has no default value and cannot be NULL",
- f->field_name, table->s->db.str,
- table->s->table_name.str);
- error = ER_NO_DEFAULT_FOR_FIELD;
+ DBUG_ASSERT(field_ptr >= table->field);
+ if ((uint) (field_ptr - table->field) >= width)
+ {
+ DBUG_ASSERT(log);
+ log->report(ERROR_LEVEL, ER_NO_DEFAULT_FOR_FIELD,
+ "Field `%s` of table `%s`.`%s` "
+ "has no default value and cannot be NULL",
+ f->field_name, table->s->db.str,
+ table->s->table_name.str);
+ error = ER_NO_DEFAULT_FOR_FIELD;
+ }
}
- else
+ else if (field_ptr - table->field >= cols->n_bits ||
+ !bitmap_is_set(cols, field_ptr - table->field))
+ {
+ DBUG_PRINT("debug", ("Set default; field: %s", f->field_name));
f->set_default();
+ }
}
DBUG_RETURN(error);
diff -Nrup a/sql/rpl_record.h b/sql/rpl_record.h
--- a/sql/rpl_record.h 2007-09-10 13:15:59 +02:00
+++ b/sql/rpl_record.h 2007-12-18 18:26:45 +01:00
@@ -31,7 +31,7 @@ int unpack_row(Relay_log_info const *rli
// Fill table's record[0] with default values.
int prepare_record(const Slave_reporting_capability *const, TABLE *const,
- const uint =0, const bool =FALSE);
+ const MY_BITMAP *cols, uint width, const bool);
#endif
#endif
diff -Nrup a/sql/sql_class.cc b/sql/sql_class.cc
--- a/sql/sql_class.cc 2007-11-28 15:34:34 +01:00
+++ b/sql/sql_class.cc 2007-12-18 18:26:45 +01:00
@@ -2950,8 +2950,6 @@ void xid_cache_delete(XID_STATE *xid_sta
template <class RowsEventT> Rows_log_event*
THD::binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
- MY_BITMAP const* cols,
- size_t colcnt,
size_t needed,
bool is_transactional,
RowsEventT *hint __attribute__((unused)))
@@ -2989,13 +2987,11 @@ THD::binlog_prepare_pending_rows_event(T
pending->server_id != serv_id ||
pending->get_table_id() != table->s->table_map_id ||
pending->get_type_code() != type_code ||
- pending->get_data_size() + needed > opt_binlog_rows_event_max_size ||
- pending->get_width() != colcnt ||
- !bitmap_cmp(pending->get_cols(), cols))
+ pending->get_data_size() + needed > opt_binlog_rows_event_max_size)
{
/* Create a new RowsEventT... */
Rows_log_event* const
- ev= new RowsEventT(this, table, table->s->table_map_id, cols,
+ ev= new RowsEventT(this, table, table->s->table_map_id,
is_transactional);
if (unlikely(!ev))
DBUG_RETURN(NULL);
@@ -3021,18 +3017,15 @@ THD::binlog_prepare_pending_rows_event(T
compiling option.
*/
template Rows_log_event*
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
- size_t, size_t, bool,
+THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
Write_rows_log_event*);
template Rows_log_event*
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
- size_t colcnt, size_t, bool,
+THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
Delete_rows_log_event *);
template Rows_log_event*
-THD::binlog_prepare_pending_rows_event(TABLE*, uint32, MY_BITMAP const*,
- size_t colcnt, size_t, bool,
+THD::binlog_prepare_pending_rows_event(TABLE*, uint32, size_t, bool,
Update_rows_log_event *);
#endif
@@ -3224,7 +3217,6 @@ namespace {
int THD::binlog_write_row(TABLE* table, bool is_trans,
- MY_BITMAP const* cols, size_t colcnt,
uchar const *record)
{
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
@@ -3239,11 +3231,10 @@ int THD::binlog_write_row(TABLE* table,
uchar *row_data= memory.slot(0);
- size_t const len= pack_row(table, cols, row_data, record);
+ size_t const len= pack_row(table, table->write_set, row_data, record);
Rows_log_event* const ev=
- binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
- len, is_trans,
+ binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
static_cast<Write_rows_log_event*>(0));
if (unlikely(ev == 0))
@@ -3253,7 +3244,6 @@ int THD::binlog_write_row(TABLE* table,
}
int THD::binlog_update_row(TABLE* table, bool is_trans,
- MY_BITMAP const* cols, size_t colcnt,
const uchar *before_record,
const uchar *after_record)
{
@@ -3269,9 +3259,9 @@ int THD::binlog_update_row(TABLE* table,
uchar *before_row= row_data.slot(0);
uchar *after_row= row_data.slot(1);
- size_t const before_size= pack_row(table, cols, before_row,
+ size_t const before_size= pack_row(table, table->read_set, before_row,
before_record);
- size_t const after_size= pack_row(table, cols, after_row,
+ size_t const after_size= pack_row(table, table->write_set, after_row,
after_record);
/*
@@ -3286,7 +3276,7 @@ int THD::binlog_update_row(TABLE* table,
#endif
Rows_log_event* const ev=
- binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
+ binlog_prepare_pending_rows_event(table, server_id,
before_size + after_size, is_trans,
static_cast<Update_rows_log_event*>(0));
@@ -3299,7 +3289,6 @@ int THD::binlog_update_row(TABLE* table,
}
int THD::binlog_delete_row(TABLE* table, bool is_trans,
- MY_BITMAP const* cols, size_t colcnt,
uchar const *record)
{
DBUG_ASSERT(current_stmt_binlog_row_based && mysql_bin_log.is_open());
@@ -3314,11 +3303,11 @@ int THD::binlog_delete_row(TABLE* table,
uchar *row_data= memory.slot(0);
- size_t const len= pack_row(table, cols, row_data, record);
+ DBUG_DUMP("table->read_set", (uchar*) table->read_set->bitmap, (table->s->fields + 7) / 8);
+ size_t const len= pack_row(table, table->read_set, row_data, record);
Rows_log_event* const ev=
- binlog_prepare_pending_rows_event(table, server_id, cols, colcnt,
- len, is_trans,
+ binlog_prepare_pending_rows_event(table, server_id, len, is_trans,
static_cast<Delete_rows_log_event*>(0));
if (unlikely(ev == 0))
diff -Nrup a/sql/sql_class.h b/sql/sql_class.h
--- a/sql/sql_class.h 2007-11-28 20:57:50 +01:00
+++ b/sql/sql_class.h 2007-12-18 18:26:46 +01:00
@@ -1145,13 +1145,10 @@ public:
void binlog_set_stmt_begin();
int binlog_write_table_map(TABLE *table, bool is_transactional);
int binlog_write_row(TABLE* table, bool is_transactional,
- MY_BITMAP const* cols, size_t colcnt,
- const uchar *buf);
+ const uchar *new_data);
int binlog_delete_row(TABLE* table, bool is_transactional,
- MY_BITMAP const* cols, size_t colcnt,
- const uchar *buf);
+ const uchar *old_data);
int binlog_update_row(TABLE* table, bool is_transactional,
- MY_BITMAP const* cols, size_t colcnt,
const uchar *old_data, const uchar *new_data);
void set_server_id(uint32 sid) { server_id = sid; }
@@ -1161,8 +1158,6 @@ public:
*/
template <class RowsEventT> Rows_log_event*
binlog_prepare_pending_rows_event(TABLE* table, uint32 serv_id,
- MY_BITMAP const* cols,
- size_t colcnt,
size_t needed,
bool is_transactional,
RowsEventT* hint);
diff -Nrup a/sql/table.cc b/sql/table.cc
--- a/sql/table.cc 2007-11-28 20:57:51 +01:00
+++ b/sql/table.cc 2007-12-18 18:26:46 +01:00
@@ -4467,12 +4467,15 @@ void st_table::mark_columns_needed_for_d
}
file->column_bitmaps_signal();
}
- if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
+ if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
+ mysql_bin_log.is_open() && in_use &&
+ in_use->current_stmt_binlog_row_based)
{
/*
- If the handler has no cursor capabilites, we have to read either
- the primary key, the hidden primary key or all columns to be
- able to do an delete
+ If the handler has no cursor capabilites, or we have row-based
+ replication active for the current statement, we have to read
+ either the primary key, the hidden primary key or all columns to
+ be able to do an delete
*/
if (s->primary_key == MAX_KEY)
file->use_hidden_primary_key();
@@ -4520,10 +4523,13 @@ void st_table::mark_columns_needed_for_u
}
file->column_bitmaps_signal();
}
- if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE)
+ if (file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_DELETE ||
+ mysql_bin_log.is_open() && in_use &&
+ in_use->current_stmt_binlog_row_based)
{
/*
- If the handler has no cursor capabilites, we have to read either
+ If the handler has no cursor capabilites, or we have row-based
+ logging active for the current statement, we have to read either
the primary key, the hidden primary key or all columns to be
able to do an update
*/