[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.
This commit is contained in:
parent
b9d1d348dd
commit
e53ad95b73
102
sql/table.cc
102
sql/table.cc
@ -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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user