summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2020-10-20 10:57:57 +0300
committerAleksey Midenkov <midenok@gmail.com>2020-10-20 10:57:57 +0300
commit7eda55619654b76add275695e0a6039e60876e81 (patch)
tree4f8e0451da12669fb51555b207a454b2fc3b7460 /storage
parenta6f956488c712bef3b13660584d1b905e0c676cc (diff)
downloadmariadb-git-7eda55619654b76add275695e0a6039e60876e81.tar.gz
MDEV-23672 Assertion `v.v_indexes.empty()' failed in dict_table_t::instant_column
dict_v_idx_t node was shared between two dict_v_col_t objects because of wrong object copy. Replace memory plain copy with copy constructor. Tha patch also removes n_v_indexes property and improves "page full" judgements for trx_undo_log_v_idx().
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/dict/dict0dict.cc1
-rw-r--r--storage/innobase/dict/dict0mem.cc1
-rw-r--r--storage/innobase/handler/handler0alter.cc10
-rw-r--r--storage/innobase/include/dict0mem.h9
-rw-r--r--storage/innobase/trx/trx0rec.cc26
5 files changed, 26 insertions, 21 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 411abdcd494..d33e1dd3c3a 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2146,7 +2146,6 @@ dict_index_add_col(
if (col->is_virtual()) {
dict_v_col_t* v_col = reinterpret_cast<dict_v_col_t*>(col);
/* Register the index with the virtual column index list */
- v_col->n_v_indexes++;
v_col->v_indexes.push_front(dict_v_idx_t(index, index->n_def));
col_name = dict_table_get_v_col_name_mysql(
table, dict_col_get_no(col));
diff --git a/storage/innobase/dict/dict0mem.cc b/storage/innobase/dict/dict0mem.cc
index b72451e0f34..d179806324f 100644
--- a/storage/innobase/dict/dict0mem.cc
+++ b/storage/innobase/dict/dict0mem.cc
@@ -425,7 +425,6 @@ dict_mem_table_add_v_col(
/* Initialize the index list for virtual columns */
ut_ad(v_col->v_indexes.empty());
- v_col->n_v_indexes = 0;
return(v_col);
}
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 1a355dbbeb1..b714dd63da6 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -589,8 +589,10 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
mem_heap_dup(heap, table.v_col_names,
ulint(end - table.v_col_names)));
v_cols = static_cast<dict_v_col_t*>(
- mem_heap_dup(heap, table.v_cols,
- table.n_v_cols * sizeof *v_cols));
+ mem_heap_alloc(heap, table.n_v_cols * sizeof(*v_cols)));
+ for (ulint i = table.n_v_cols; i--; ) {
+ new (&v_cols[i]) dict_v_col_t(table.v_cols[i]);
+ }
} else {
ut_ad(table.n_v_cols == 0);
v_col_names = NULL;
@@ -603,8 +605,6 @@ inline bool dict_table_t::instant_column(const dict_table_t& table,
for (unsigned i = 0; i < n_v_def; i++) {
dict_v_col_t& v = v_cols[i];
- DBUG_ASSERT(v.v_indexes.empty());
- v.n_v_indexes = 0;
v.base_col = static_cast<dict_col_t**>(
mem_heap_dup(heap, v.base_col,
v.num_base * sizeof *v.base_col));
@@ -714,7 +714,6 @@ dup_dropped:
<dict_v_col_t*>(f.col);
v_col->v_indexes.push_front(
dict_v_idx_t(index, i));
- v_col->n_v_indexes++;
}
}
}
@@ -5031,7 +5030,6 @@ prepare_inplace_add_virtual(
ctx->add_vcol[j].v_pos = ctx->old_table->n_v_cols
- ctx->num_to_drop_vcol + j;
- ctx->add_vcol[j].n_v_indexes = 0;
/* MDEV-17468: Do this on ctx->instant_table later */
innodb_base_col_setup(ctx->old_table, field, &ctx->add_vcol[j]);
j++;
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index e20812b862b..017b01e79ad 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -766,9 +766,6 @@ struct dict_v_col_t{
/** column pos in table */
unsigned v_pos:10;
- /** number of indexes */
- unsigned n_v_indexes:12;
-
/** Virtual index list, and column position in the index */
std::forward_list<dict_v_idx_t, ut_allocator<dict_v_idx_t> >
v_indexes;
@@ -777,21 +774,17 @@ struct dict_v_col_t{
@param index index to be detached from */
void detach(const dict_index_t &index)
{
- if (!n_v_indexes) return;
+ if (v_indexes.empty()) return;
auto i= v_indexes.before_begin();
- ut_d(unsigned n= 0);
do {
auto prev = i++;
if (i == v_indexes.end())
{
- ut_ad(n == n_v_indexes);
return;
}
- ut_ad(++n <= n_v_indexes);
if (i->index == &index)
{
v_indexes.erase_after(prev);
- n_v_indexes--;
return;
}
}
diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc
index b164daf0ecc..310d071d368 100644
--- a/storage/innobase/trx/trx0rec.cc
+++ b/storage/innobase/trx/trx0rec.cc
@@ -230,20 +230,35 @@ trx_undo_log_v_idx(
{
ut_ad(pos < table->n_v_def);
dict_v_col_t* vcol = dict_table_get_nth_v_col(table, pos);
- ulint n_idx = vcol->n_v_indexes;
byte* old_ptr;
- ut_ad(n_idx > 0);
+ ut_ad(!vcol->v_indexes.empty());
/* Size to reserve, max 5 bytes for each index id and position, plus
5 bytes for num of indexes, 2 bytes for write total length.
1 byte for undo log record format version marker */
- ulint size = n_idx * (5 + 5) + 5 + 2 + (first_v_col ? 1 : 0);
+ ulint size = 5 + 2 + (first_v_col ? 1 : 0);
+ const ulint avail = trx_undo_left(undo_block, ptr);
- if (trx_undo_left(undo_block, ptr) < size) {
+ if (avail < size) {
return(NULL);
}
+ size = 0;
+ ulint n_idx = 0;
+ for (const auto& v_index : vcol->v_indexes) {
+ n_idx++;
+ /* FIXME: index->id is 64 bits! */
+ size += mach_get_compressed_size(uint32_t(v_index.index->id));
+ size += mach_get_compressed_size(v_index.nth_field);
+ }
+ size += 2 + mach_get_compressed_size(n_idx);
+
+ if (avail < size) {
+ return(NULL);
+ }
+
+
if (first_v_col) {
/* write the version marker */
mach_write_to_1(ptr, VIRTUAL_COL_UNDO_FORMAT_1);
@@ -259,7 +274,8 @@ trx_undo_log_v_idx(
for (const auto& v_index : vcol->v_indexes) {
ptr += mach_write_compressed(
- ptr, static_cast<ulint>(v_index.index->id));
+ /* FIXME: index->id is 64 bits! */
+ ptr, uint32_t(v_index.index->id));
ptr += mach_write_compressed(ptr, v_index.nth_field);
}