diff options
author | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2015-04-02 19:09:40 +0300 |
---|---|---|
committer | Vicențiu Ciorbaru <vicentiu@mariadb.org> | 2015-06-30 13:17:09 +0300 |
commit | e53ad95b733e5a3b67b31d231616b619b634c6da (patch) | |
tree | c1d7e89e28c5adc5a6283be791d1cd8b769f8e67 /sql/table.cc | |
parent | b9d1d348dd5f84e26732139ed8cfe0a4146ced4f (diff) | |
download | mariadb-git-e53ad95b733e5a3b67b31d231616b619b634c6da.tar.gz |
[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.
Diffstat (limited to 'sql/table.cc')
-rw-r--r-- | sql/table.cc | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/sql/table.cc b/sql/table.cc index 1f9247e28f2..8bc89c2e491 100644 --- a/sql/table.cc +++ b/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 |