summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2015-04-02 19:09:40 +0300
committerVicențiu Ciorbaru <vicentiu@mariadb.org>2015-06-30 13:17:09 +0300
commite53ad95b733e5a3b67b31d231616b619b634c6da (patch)
treec1d7e89e28c5adc5a6283be791d1cd8b769f8e67 /sql/table.cc
parentb9d1d348dd5f84e26732139ed8cfe0a4146ced4f (diff)
downloadmariadb-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.cc102
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