summaryrefslogtreecommitdiff
path: root/sql/table.cc
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2015-11-05 22:09:58 +0200
committerMonty <monty@mariadb.org>2015-11-10 13:46:56 +0200
commit93d1e5ce0b841bedbc071da85995f15611ed3d34 (patch)
tree7f6f567cbf7b0ef3e17345f271cefed81f098f63 /sql/table.cc
parentcb4737cb4e7df6c43de9d47483f17f8e2e7fa24b (diff)
downloadmariadb-git-93d1e5ce0b841bedbc071da85995f15611ed3d34.tar.gz
table->write_set was changed if binary logging was used, which caused the
changes in query execution plans. Fixed by introducing table->rpl_write_set which holds which columns should be stored in the binary log. Other things: - Removed some not needed references to read_set and write_set to make code really changing read_set and write_set easier to read (in opt_range.cc) - Added error handling of failed unpack_current_row() - Added missing call to mark_columns_needed_for_insert() for DELAYED INSERT - Removed not used functions in_read_set() and in_write_set() - In rpl_record.cc, removed not used variable error
Diffstat (limited to 'sql/table.cc')
-rw-r--r--sql/table.cc88
1 files changed, 58 insertions, 30 deletions
diff --git a/sql/table.cc b/sql/table.cc
index 573ae0105b6..4604a9a6958 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2885,20 +2885,28 @@ partititon_err:
/* Allocate bitmaps */
bitmap_size= share->column_bitmap_size;
- if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*6)))
+ if (!(bitmaps= (uchar*) alloc_root(&outparam->mem_root, bitmap_size*7)))
goto err;
my_bitmap_init(&outparam->def_read_set,
- (my_bitmap_map*) bitmaps, share->fields, FALSE);
+ (my_bitmap_map*) bitmaps, share->fields, FALSE);
my_bitmap_init(&outparam->def_write_set,
- (my_bitmap_map*) (bitmaps+bitmap_size), share->fields, FALSE);
+ (my_bitmap_map*) (bitmaps+bitmap_size), share->fields,
+ FALSE);
my_bitmap_init(&outparam->def_vcol_set,
- (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields, FALSE);
+ (my_bitmap_map*) (bitmaps+bitmap_size*2), share->fields,
+ FALSE);
my_bitmap_init(&outparam->tmp_set,
- (my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields, FALSE);
+ (my_bitmap_map*) (bitmaps+bitmap_size*3), share->fields,
+ FALSE);
my_bitmap_init(&outparam->eq_join_set,
- (my_bitmap_map*) (bitmaps+bitmap_size*4), share->fields, FALSE);
+ (my_bitmap_map*) (bitmaps+bitmap_size*4), share->fields,
+ FALSE);
my_bitmap_init(&outparam->cond_set,
- (my_bitmap_map*) (bitmaps+bitmap_size*5), share->fields, FALSE);
+ (my_bitmap_map*) (bitmaps+bitmap_size*5), share->fields,
+ FALSE);
+ my_bitmap_init(&outparam->def_rpl_write_set,
+ (my_bitmap_map*) (bitmaps+bitmap_size*6), share->fields,
+ FALSE);
outparam->default_column_bitmaps();
outparam->cond_selectivity= 1.0;
@@ -5679,6 +5687,7 @@ void TABLE::clear_column_bitmaps()
*/
bzero((char*) def_read_set.bitmap, s->column_bitmap_size*3);
column_bitmaps_set(&def_read_set, &def_write_set, &def_vcol_set);
+ rpl_write_set= 0; // Safety
}
@@ -5959,6 +5968,8 @@ void TABLE::mark_columns_needed_for_insert()
/*
Mark columns according the binlog row image option.
+ Columns to be written are stored in 'rpl_write_set'
+
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.
@@ -5970,16 +5981,16 @@ void TABLE::mark_columns_needed_for_insert()
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
+ in the rpl_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
+ and all non-blob fields in the rpl_write_set
binlog_row_image= FULL
- all columns in the read_set
- - all columns in the write_set
+ - all columns in the rpl_write_set
This marking is done without resetting the original
bitmaps. This means that we will strip extra fields in
@@ -5987,36 +5998,48 @@ void TABLE::mark_columns_needed_for_insert()
we only want to log a PK and we needed other fields for
execution).
*/
+
void TABLE::mark_columns_per_binlog_row_image()
{
+ THD *thd= in_use;
DBUG_ENTER("mark_columns_per_binlog_row_image");
DBUG_ASSERT(read_set->bitmap);
DBUG_ASSERT(write_set->bitmap);
- THD *thd= current_thd;
+ /* If not using row format */
+ rpl_write_set= write_set;
/**
If in RBR we may need to mark some extra columns,
depending on the binlog-row-image command line argument.
*/
if ((WSREP_EMULATE_BINLOG(thd) || mysql_bin_log.is_open()) &&
- in_use &&
- in_use->is_current_stmt_binlog_format_row() &&
+ thd->is_current_stmt_binlog_format_row() &&
!ha_check_storage_engine_flag(s->db_type(), HTON_NO_BINLOG_ROW_OPT))
{
/* 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)
+ rpl_write_set= read_set;
+ }
+ else
{
+ 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);
+ bitmap_set_all(read_set);
+ /* Set of columns that should be written (all) */
+ rpl_write_set= read_set;
break;
case BINLOG_ROW_IMAGE_NOBLOB:
- /* for every field that is not set, mark it unless it is a blob */
+ /* Only write changed columns + not blobs */
+ rpl_write_set= &def_rpl_write_set;
+ bitmap_copy(rpl_write_set, write_set);
+
+ /*
+ for every field that is not set, mark it unless it is a blob or
+ part of a primary key
+ */
for (Field **ptr=field ; *ptr ; ptr++)
{
Field *my_field= *ptr;
@@ -6027,24 +6050,30 @@ void TABLE::mark_columns_per_binlog_row_image()
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)))
+ */
+ if ((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);
+ bitmap_set_bit(rpl_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);
+ /*
+ mark the primary key in the read set so that we can find the row
+ that is updated / deleted.
+ We don't need to mark the primary key in the rpl_write_set as the
+ binary log will include all columns read anyway.
+ */
+ mark_columns_used_by_index_no_reset(s->primary_key, read_set);
+ /* Only write columns that have changed */
+ rpl_write_set= write_set;
break;
default:
DBUG_ASSERT(FALSE);
+ }
}
file->column_bitmaps_signal();
}
@@ -7389,4 +7418,3 @@ double KEY::actual_rec_per_key(uint i)
return (is_statistics_from_stat_tables ?
read_stats->get_avg_frequency(i) : (double) rec_per_key[i]);
}
-