diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-07-22 22:24:02 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2021-07-22 22:29:44 +0300 |
commit | ec6406125bd6ab1083bfdcd0d491bae616580b55 (patch) | |
tree | 7cd0c3851f6a4bc4ea6218003cfc322303e7b5b8 | |
parent | 5f8651ac238d8d6cd3e4a7e3090b4b529f990331 (diff) | |
download | mariadb-git-ec6406125bd6ab1083bfdcd0d491bae616580b55.tar.gz |
fix index corruption during insertbb-10.2-nikita-MDEV-26205
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 2 | ||||
-rw-r--r-- | storage/innobase/include/row0ins.h | 1 | ||||
-rw-r--r-- | storage/innobase/include/row0mysql.h | 3 | ||||
-rw-r--r-- | storage/innobase/que/que0que.cc | 4 | ||||
-rw-r--r-- | storage/innobase/row/row0ins.cc | 26 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 10 |
6 files changed, 40 insertions, 6 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 81f1dae85b6..ffae5706176 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -21900,7 +21900,7 @@ innobase_get_field_from_update_vector( for purge thread. */ -bool innobase_allocate_row_for_vcol(THD *thd, dict_index_t *index, +bool innobase_allocate_row_for_vcol(THD *thd, const dict_index_t *index, mem_heap_t **heap, TABLE **table, VCOL_STORAGE *storage) { diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h index 27fe442f6ff..e5205aa0596 100644 --- a/storage/innobase/include/row0ins.h +++ b/storage/innobase/include/row0ins.h @@ -190,6 +190,7 @@ struct ins_node_t{ if this is NULL, entry list should be created and buffers for sys fields in row allocated */ ulint magic_n; + mem_heap_t *heap; }; #define INS_NODE_MAGIC_N 15849075 diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 8738f991368..6fb7be76799 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -829,6 +829,7 @@ struct VCOL_STORAGE bool innobase_allocate_row_for_vcol( THD * thd, + const dict_index_t* index, mem_heap_t** heap, TABLE** table, @@ -845,7 +846,7 @@ public: ib_vcol_row(mem_heap_t *heap) : heap(heap) {} - byte *record(THD *thd, dict_index_t *index, TABLE **table) + byte *record(THD *thd, const dict_index_t *index, TABLE **table) { if (!storage.innobase_record) { diff --git a/storage/innobase/que/que0que.cc b/storage/innobase/que/que0que.cc index 0b630bb1c8c..9085a59b071 100644 --- a/storage/innobase/que/que0que.cc +++ b/storage/innobase/que/que0que.cc @@ -465,6 +465,10 @@ que_graph_free_recursive( mem_heap_free(ins->entry_sys_heap); ins->entry_sys_heap = NULL; } + if (ins->heap != NULL) { + mem_heap_free(ins->heap); + ins->heap = NULL; + } break; case QUE_NODE_PURGE: diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 4dc9c66a536..3b3545e06c0 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -92,6 +92,8 @@ ins_node_create( node->magic_n = INS_NODE_MAGIC_N; + node->heap = mem_heap_create(128); + return(node); } @@ -3304,7 +3306,10 @@ dberr_t row_ins_index_entry_set_vals( const dict_index_t* index, dtuple_t* entry, - const dtuple_t* row) + dtuple_t* row, + mem_heap_t *heap, + THD* thd, + TABLE* mysql_table) { ulint n_fields; ulint i; @@ -3336,6 +3341,18 @@ row_ins_index_entry_set_vals( ut_ad(dtuple_get_n_fields(row) == dict_table_get_n_cols(index->table)); row_field = dtuple_get_nth_v_field(row, v_col->v_pos); + ib_vcol_row vc(NULL); + if (v_col->m_col.ord_part + && dfield_is_null(row_field)) { + uchar *record = vc.record(thd, index, + &mysql_table); + innobase_get_computed_value(row, v_col, index, + &vc.heap, heap, + NULL, + thd, mysql_table, + record, + NULL, NULL, NULL); + } } else { row_field = dtuple_get_nth_field( row, ind_field->col->ind); @@ -3394,13 +3411,18 @@ row_ins_index_entry_step( que_thr_t* thr) /*!< in: query thread */ { dberr_t err; + trx_t* trx = thr_get_trx(thr); DBUG_ENTER("row_ins_index_entry_step"); ut_ad(dtuple_check_typed(node->row)); err = row_ins_index_entry_set_vals(node->index, *node->entry, - node->row); + node->row, node->heap, + trx->mysql_thd, + thr->prebuilt + ? thr->prebuilt->m_mysql_table + : NULL); if (err != DB_SUCCESS) { DBUG_RETURN(err); diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 1a7652350a9..3a428c823cc 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -286,6 +286,7 @@ row_log_online_op( ulint mrec_size; ulint avail_size; row_log_t* log; + row_op op; ut_ad(dtuple_validate(tuple)); ut_ad(dtuple_get_n_fields(tuple) == dict_index_get_n_fields(index)); @@ -337,11 +338,11 @@ row_log_online_op( } if (trx_id != 0) { - *b++ = ROW_OP_INSERT; + *b++ = op = ROW_OP_INSERT; trx_write_trx_id(b, trx_id); b += DATA_TRX_ID_LEN; } else { - *b++ = ROW_OP_DELETE; + *b++ = op = ROW_OP_DELETE; } if (extra_size < 0x80) { @@ -352,6 +353,11 @@ row_log_online_op( *b++ = (byte) extra_size; } + DBUG_EXECUTE_IF("ib_log_online", + ib::info() << "LOG " << index->name() + << (op == ROW_OP_INSERT ? " INS " : " DEL ") + << *tuple;); + rec_convert_dtuple_to_temp( b + extra_size, index, tuple->fields, tuple->n_fields); b += size; |