Commit e53ad95b authored by Vicențiu Ciorbaru's avatar Vicențiu Ciorbaru

[MDEV-6877] Added mark_columns_per_bitmap_row_image

Depending on which binlog_row_image we are using, we must
mark columns which to update differently both in the before image
as well as the after image.
parent b9d1d348
......@@ -5826,6 +5826,8 @@ void TABLE::mark_auto_increment_column()
void TABLE::mark_columns_needed_for_delete()
{
mark_columns_per_binlog_row_image();
if (triggers)
triggers->mark_fields_used(TRG_EVENT_DELETE);
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
......@@ -5877,6 +5879,9 @@ void TABLE::mark_columns_needed_for_delete()
void TABLE::mark_columns_needed_for_update()
{
DBUG_ENTER("mark_columns_needed_for_update");
mark_columns_per_binlog_row_image();
if (triggers)
triggers->mark_fields_used(TRG_EVENT_UPDATE);
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
......@@ -5921,6 +5926,8 @@ void TABLE::mark_columns_needed_for_update()
void TABLE::mark_columns_needed_for_insert()
{
mark_columns_per_binlog_row_image();
if (triggers)
{
/*
......@@ -5938,6 +5945,101 @@ void TABLE::mark_columns_needed_for_insert()
mark_virtual_columns_for_write(TRUE);
}
/*
Mark columns according the binlog row image option.
When logging in RBR, the user can select whether to
log partial or full rows, depending on the table
definition, and the value of binlog_row_image.
Semantics of the binlog_row_image are the following
(PKE - primary key equivalent, ie, PK fields if PK
exists, all fields otherwise):
binlog_row_image= MINIMAL
- This marks the PKE fields in the read_set
- This marks all fields where a value was specified
in the write_set
binlog_row_image= NOBLOB
- This marks PKE + all non-blob fields in the read_set
- This marks all fields where a value was specified
and all non-blob fields in the write_set
binlog_row_image= FULL
- all columns in the read_set
- all columns in the write_set
This marking is done without resetting the original
bitmaps. This means that we will strip extra fields in
the read_set at binlogging time (for those cases that
we only want to log a PK and we needed other fields for
execution).
*/
void TABLE::mark_columns_per_binlog_row_image()
{
DBUG_ENTER("mark_columns_per_binlog_row_image");
DBUG_ASSERT(read_set->bitmap);
DBUG_ASSERT(write_set->bitmap);
/**
If in RBR we may need to mark some extra columns,
depending on the binlog-row-image command line argument.
*/
if ((mysql_bin_log.is_open() && in_use &&
in_use->is_current_stmt_binlog_format_row() &&
!ha_check_storage_engine_flag(s->db_type(), HTON_NO_BINLOG_ROW_OPT)))
{
THD *thd= current_thd;
/* if there is no PK, then mark all columns for the BI. */
if (s->primary_key >= MAX_KEY)
bitmap_set_all(read_set);
switch (thd->variables.binlog_row_image)
{
case BINLOG_ROW_IMAGE_FULL:
if (s->primary_key < MAX_KEY)
bitmap_set_all(read_set);
bitmap_set_all(write_set);
break;
case BINLOG_ROW_IMAGE_NOBLOB:
/* for every field that is not set, mark it unless it is a blob */
for (Field **ptr=field ; *ptr ; ptr++)
{
Field *my_field= *ptr;
/*
bypass blob fields. These can be set or not set, we don't care.
Later, at binlogging time, if we don't need them in the before
image, we will discard them.
If set in the AI, then the blob is really needed, there is
nothing we can do about it.
*/
if ((s->primary_key < MAX_KEY) &&
((my_field->flags & PRI_KEY_FLAG) ||
(my_field->type() != MYSQL_TYPE_BLOB)))
bitmap_set_bit(read_set, my_field->field_index);
if (my_field->type() != MYSQL_TYPE_BLOB)
bitmap_set_bit(write_set, my_field->field_index);
}
break;
case BINLOG_ROW_IMAGE_MINIMAL:
/* mark the primary key if available in the read_set */
if (s->primary_key < MAX_KEY)
mark_columns_used_by_index_no_reset(s->primary_key, read_set);
break;
default:
DBUG_ASSERT(FALSE);
}
file->column_bitmaps_signal();
}
DBUG_VOID_RETURN;
}
/*
@brief Mark a column as virtual used by the query
......
......@@ -1275,6 +1275,7 @@ public:
void mark_columns_needed_for_update(void);
void mark_columns_needed_for_delete(void);
void mark_columns_needed_for_insert(void);
void mark_columns_per_binlog_row_image(void);
bool mark_virtual_col(Field *field);
void mark_virtual_columns_for_write(bool insert_fl);
void mark_default_fields_for_write();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment