summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row/row0log.cc')
-rw-r--r--storage/innobase/row/row0log.cc95
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);
+ }
+}