diff options
Diffstat (limited to 'storage/innobase/row/row0log.cc')
| -rw-r--r-- | storage/innobase/row/row0log.cc | 95 |
1 files changed, 76 insertions, 19 deletions
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index e4f7be83940..051b99d928b 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -54,7 +54,9 @@ enum row_tab_op { /** Update a record in place */ ROW_T_UPDATE, /** Delete (purge) a record */ - ROW_T_DELETE + ROW_T_DELETE, + /** Empty the table */ + ROW_T_EMPTY }; /** Index record modification operations during online index creation */ @@ -62,7 +64,9 @@ enum row_op { /** Insert a record */ ROW_OP_INSERT = 0x61, /** Delete a record */ - ROW_OP_DELETE + ROW_OP_DELETE, + /** Empy the index */ + ROW_OP_EMPTY }; /** Size of the modification log entry header, in bytes */ @@ -339,8 +343,8 @@ row_log_online_op( ulint avail_size; row_log_t* log; - ut_ad(dtuple_validate(tuple)); - ut_ad(dtuple_get_n_fields(tuple) == dict_index_get_n_fields(index)); + ut_ad(!tuple || dtuple_validate(tuple)); + ut_ad(!tuple || dtuple_get_n_fields(tuple) == dict_index_get_n_fields(index)); ut_ad(index->lock.have_x() || index->lock.have_s()); if (index->is_corrupted()) { @@ -353,14 +357,19 @@ row_log_online_op( row_merge_buf_encode(), because here we do not encode extra_size+1 (and reserve 0 as the end-of-chunk marker). */ - size = rec_get_converted_size_temp( - index, tuple->fields, tuple->n_fields, &extra_size); - ut_ad(size >= extra_size); - ut_ad(size <= sizeof log->tail.buf); + if (!tuple) { + mrec_size = 4; + extra_size = 0; + } else { + size = rec_get_converted_size_temp( + index, tuple->fields, tuple->n_fields, &extra_size); + ut_ad(size >= extra_size); + ut_ad(size <= sizeof log->tail.buf); - mrec_size = ROW_LOG_HEADER_SIZE - + (extra_size >= 0x80) + size - + (trx_id ? DATA_TRX_ID_LEN : 0); + mrec_size = ROW_LOG_HEADER_SIZE + + (extra_size >= 0x80) + size + + (trx_id ? DATA_TRX_ID_LEN : 0); + } log = index->online_log; mysql_mutex_lock(&log->mutex); @@ -389,6 +398,8 @@ row_log_online_op( *b++ = ROW_OP_INSERT; trx_write_trx_id(b, trx_id); b += DATA_TRX_ID_LEN; + } else if (tuple == nullptr) { + *b++ = ROW_OP_EMPTY; } else { *b++ = ROW_OP_DELETE; } @@ -401,9 +412,15 @@ row_log_online_op( *b++ = (byte) extra_size; } - rec_convert_dtuple_to_temp( - b + extra_size, index, tuple->fields, tuple->n_fields); - b += size; + if (tuple) { + rec_convert_dtuple_to_temp( + b + extra_size, index, tuple->fields, + tuple->n_fields); + b += size; + } else { + *b++ = 0; + *b++ = 0; + } if (mrec_size >= avail_size) { const os_offset_t byte_offset @@ -2387,6 +2404,18 @@ func_exit_committed: goto func_exit; } +/** Applies the empty table to a table that was rebuilt. +@param index clustered index +@retrun success if index gets emptied */ +static +dberr_t +row_log_table_apply_empty(dict_index_t* index, que_thr_t *thr) +{ + dict_table_t* new_table= index->online_log->table; + new_table->empty_table(thr); + return DB_SUCCESS; +} + /******************************************************//** Applies an operation to a table that was rebuilt. @return NULL on failure (mrec corruption) or when out of data; @@ -2422,11 +2451,6 @@ row_log_table_apply_op( *error = DB_SUCCESS; - /* 3 = 1 (op type) + 1 (extra_size) + at least 1 byte payload */ - if (mrec + 3 >= mrec_end) { - return(NULL); - } - const bool is_instant = log->is_instant(dup->index); const mrec_t* const mrec_start = mrec; @@ -2657,6 +2681,11 @@ row_log_table_apply_op( thr, new_trx_id_col, mrec, offsets, offsets_heap, heap, dup, old_pk); break; + case ROW_T_EMPTY: + *error = row_log_table_apply_empty(dup->index, thr); + log->head.total += 1; + next_mrec = mrec; + break; } ut_ad(log->head.total <= log->tail.total); @@ -3438,6 +3467,9 @@ row_log_apply_op_low( } goto duplicate; + case ROW_OP_EMPTY: + ut_ad(0); + break; } } else { switch (op) { @@ -3508,6 +3540,9 @@ insert_the_rec: 0, NULL, &mtr); ut_ad(!big_rec); break; + case ROW_OP_EMPTY: + ut_ad(0); + break; } mem_heap_empty(offsets_heap); } @@ -3582,6 +3617,17 @@ row_log_apply_op( op = static_cast<enum row_op>(*mrec++); trx_id = 0; break; + case ROW_OP_EMPTY: + { + mem_heap_t* heap = mem_heap_create(512); + que_fork_t* fork = que_fork_create( + NULL, NULL, QUE_FORK_MYSQL_INTERFACE, heap); + que_thr_t* thr = que_thr_create(fork, heap, nullptr); + index->empty(thr); + *error = DB_SUCCESS; + mem_heap_free(heap); + return mrec + 4; + } default: corrupted: ut_ad(0); @@ -4024,3 +4070,14 @@ row_log_apply( DBUG_RETURN(error); } + +void row_log_table_empty(dict_index_t *index) +{ + row_log_t* log= index->online_log; + ulint avail_size; + if (byte* b = row_log_table_open(log, 1, &avail_size)) + { + *b++ = ROW_T_EMPTY; + row_log_table_close(index, b, 1, avail_size); + } +} |
