diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2016-12-31 15:33:26 +0000 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2017-05-05 20:36:25 +0300 |
commit | 26a3ff0a22e931e44edf97b37c41db395eee6553 (patch) | |
tree | cd48d2a6c8a3f8ba2bbb2d8cf9f38a73e992ea2e /sql/partition_info.h | |
parent | e069de7d9da69dd0aed3147a493402cbdeca2c12 (diff) | |
download | mariadb-git-26a3ff0a22e931e44edf97b37c41db395eee6553.tar.gz |
SQL: (0.6) Pruning for VERSIONING partitions [closes #97]
* based on RANGE pruning by COLUMNS (sys_trx_end) condition
* removed DEFAULT; AS OF NOW is always last; current VERSIONING as last non-empty (or first empty)
* Min/Max stats in TABLE_SHARE
* ALTER TABLE ADD PARTITION adds before AS OF NOW partition
Diffstat (limited to 'sql/partition_info.h')
-rw-r--r-- | sql/partition_info.h | 89 |
1 files changed, 79 insertions, 10 deletions
diff --git a/sql/partition_info.h b/sql/partition_info.h index 844956594ff..5a671bfc50f 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -41,7 +41,7 @@ struct Vers_part_info : public Sql_alloc limit(0), now_part(NULL), hist_part(NULL), - hist_default(UINT32_MAX) + stat_serial(0) { } Vers_part_info(Vers_part_info &src) : @@ -49,7 +49,7 @@ struct Vers_part_info : public Sql_alloc limit(src.limit), now_part(NULL), hist_part(NULL), - hist_default(src.hist_default) + stat_serial(src.stat_serial) { } bool initialized(bool fully= true) @@ -71,7 +71,7 @@ struct Vers_part_info : public Sql_alloc ulonglong limit; partition_element *now_part; partition_element *hist_part; - uint32 hist_default; + ulonglong stat_serial; }; class partition_info : public Sql_alloc @@ -182,8 +182,9 @@ public: LIST_PART_ENTRY *list_array; part_column_list_val *range_col_array; part_column_list_val *list_col_array; - Vers_part_info *vers_info; }; + + Vers_part_info *vers_info; /******************************************** * INTERVAL ANALYSIS @@ -350,7 +351,7 @@ public: char *find_duplicate_field(); char *find_duplicate_name(); bool check_engine_mix(handlerton *engine_type, bool default_engine); - bool check_range_constants(THD *thd); + bool check_range_constants(THD *thd, bool init= true); bool check_list_constants(THD *thd); bool check_partition_info(THD *thd, handlerton **eng_type, handler *file, HA_CREATE_INFO *info, @@ -400,9 +401,10 @@ public: bool vers_set_interval(const INTERVAL &i); bool vers_set_limit(ulonglong limit); partition_element* vers_part_rotate(THD *thd); - bool vers_setup_1(THD *thd); + bool vers_setup_1(THD *thd, uint32 added= 0); bool vers_setup_2(THD *thd, bool is_create_table_ind); bool vers_scan_min_max(THD *thd, partition_element *part); + void vers_update_col_vals(THD *thd, partition_element *el0, partition_element *el1); partition_element *vers_hist_part() { @@ -427,6 +429,17 @@ public: DBUG_ASSERT(0); return NULL; } + partition_element *get_partition(uint part_id) + { + List_iterator<partition_element> it(partitions); + partition_element *el; + while ((el= it++)) + { + if (el->id == part_id) + return el; + } + return NULL; + } bool vers_limit_exceed(partition_element *part= NULL) { DBUG_ASSERT(vers_info); @@ -440,6 +453,18 @@ public: // TODO: cache thread-shared part_recs and increment on INSERT return table->file->part_recs_slow(part) >= vers_info->limit; } + Vers_field_stats& vers_stat_trx(stat_trx_field fld, uint32 part_element_id) + { + DBUG_ASSERT(table && table->s && table->s->stat_trx); + Vers_field_stats* res= table->s->stat_trx[part_element_id * num_columns + fld]; + DBUG_ASSERT(res); + return *res; + } + Vers_field_stats& vers_stat_trx(stat_trx_field fld, partition_element *part) + { + DBUG_ASSERT(part); + return vers_stat_trx(fld, part->id); + } bool vers_interval_exceed(my_time_t max_time, partition_element *part= NULL) { DBUG_ASSERT(vers_info); @@ -450,19 +475,63 @@ public: DBUG_ASSERT(vers_info->initialized()); part= vers_hist_part(); } - DBUG_ASSERT(part->stat_trx_end); - max_time-= part->stat_trx_end->min_time(); + max_time-= vers_stat_trx(STAT_TRX_END, part).min_time(); return max_time > vers_info->interval; } bool vers_interval_exceed(partition_element *part) { - DBUG_ASSERT(part->stat_trx_end); - return vers_interval_exceed(part->stat_trx_end->max_time(), part); + return vers_interval_exceed(vers_stat_trx(STAT_TRX_END, part).max_time(), part); } bool vers_interval_exceed() { return vers_interval_exceed(vers_hist_part()); } + void vers_update_stats(THD *thd, partition_element *el) + { + DBUG_ASSERT(vers_info && vers_info->initialized()); + DBUG_ASSERT(table && table->s); + DBUG_ASSERT(el && el->type == partition_element::VERSIONING); + mysql_rwlock_wrlock(&table->s->LOCK_stat_serial); + el->empty= false; + bool updated= + vers_stat_trx(STAT_TRX_END, el->id).update(table->vers_end_field()); + if (updated) + table->s->stat_serial++; + mysql_rwlock_unlock(&table->s->LOCK_stat_serial); + if (updated) + { + vers_update_col_vals(thd, + el->id > 0 ? get_partition(el->id - 1) : NULL, + el); + } + } + void vers_update_stats(THD *thd, uint part_id) + { + DBUG_ASSERT(vers_info && vers_info->initialized()); + if (part_id < vers_info->now_part->id) + vers_update_stats(thd, get_partition(part_id)); + } + void vers_update_range_constants(THD *thd) + { + DBUG_ASSERT(vers_info && vers_info->initialized()); + DBUG_ASSERT(table && table->s); + + mysql_rwlock_rdlock(&table->s->LOCK_stat_serial); + if (vers_info->stat_serial == table->s->stat_serial) + { + mysql_rwlock_unlock(&table->s->LOCK_stat_serial); + return; + } + + for (uint i= 0; i < num_columns; ++i) + { + Field *f= part_field_array[i]; + bitmap_set_bit(f->table->write_set, f->field_index); + } + check_range_constants(thd, false); + vers_info->stat_serial= table->s->stat_serial; + mysql_rwlock_unlock(&table->s->LOCK_stat_serial); + } }; uint32 get_next_partition_id_range(struct st_partition_iter* part_iter); |