[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()
|
void TABLE::mark_columns_needed_for_delete()
|
||||||
{
|
{
|
||||||
|
mark_columns_per_binlog_row_image();
|
||||||
|
|
||||||
if (triggers)
|
if (triggers)
|
||||||
triggers->mark_fields_used(TRG_EVENT_DELETE);
|
triggers->mark_fields_used(TRG_EVENT_DELETE);
|
||||||
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_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()
|
void TABLE::mark_columns_needed_for_update()
|
||||||
{
|
{
|
||||||
DBUG_ENTER("mark_columns_needed_for_update");
|
DBUG_ENTER("mark_columns_needed_for_update");
|
||||||
|
|
||||||
|
mark_columns_per_binlog_row_image();
|
||||||
|
|
||||||
if (triggers)
|
if (triggers)
|
||||||
triggers->mark_fields_used(TRG_EVENT_UPDATE);
|
triggers->mark_fields_used(TRG_EVENT_UPDATE);
|
||||||
if (file->ha_table_flags() & HA_REQUIRES_KEY_COLUMNS_FOR_DELETE)
|
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()
|
void TABLE::mark_columns_needed_for_insert()
|
||||||
{
|
{
|
||||||
|
mark_columns_per_binlog_row_image();
|
||||||
|
|
||||||
if (triggers)
|
if (triggers)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -5938,6 +5945,101 @@ void TABLE::mark_columns_needed_for_insert()
|
|||||||
mark_virtual_columns_for_write(TRUE);
|
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
|
@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_update(void);
|
||||||
void mark_columns_needed_for_delete(void);
|
void mark_columns_needed_for_delete(void);
|
||||||
void mark_columns_needed_for_insert(void);
|
void mark_columns_needed_for_insert(void);
|
||||||
|
void mark_columns_per_binlog_row_image(void);
|
||||||
bool mark_virtual_col(Field *field);
|
bool mark_virtual_col(Field *field);
|
||||||
void mark_virtual_columns_for_write(bool insert_fl);
|
void mark_virtual_columns_for_write(bool insert_fl);
|
||||||
void mark_default_fields_for_write();
|
void mark_default_fields_for_write();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user