summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0umod.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row/row0umod.c')
-rw-r--r--storage/innobase/row/row0umod.c44
1 files changed, 38 insertions, 6 deletions
diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c
index 83288c570cb..37e857a4708 100644
--- a/storage/innobase/row/row0umod.c
+++ b/storage/innobase/row/row0umod.c
@@ -1,7 +1,7 @@
/******************************************************
Undo modify of a row
-(c) 1997 Innobase Oy
+Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
Created 2/27/1997 Heikki Tuuri
*******************************************************/
@@ -94,7 +94,10 @@ row_undo_mod_clust_low(
}
/***************************************************************
-Removes a clustered index record after undo if possible. */
+Purges a clustered index record after undo if possible.
+This is attempted when the record was inserted by updating a
+delete-marked record and there no longer exist transactions
+that would see the delete-marked record. */
static
ulint
row_undo_mod_remove_clust_low(
@@ -103,13 +106,16 @@ row_undo_mod_remove_clust_low(
we may run out of file space */
undo_node_t* node, /* in: row undo node */
que_thr_t* thr __attribute__((unused)), /* in: query thread */
- mtr_t* mtr, /* in: mtr */
+ mtr_t* mtr, /* in/out: mini-transaction */
ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
{
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
ulint err;
ibool success;
+ byte* db_trx_id;
+
+ ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
pcur = &(node->pcur);
btr_cur = btr_pcur_get_btr_cur(pcur);
@@ -123,11 +129,37 @@ row_undo_mod_remove_clust_low(
/* Find out if we can remove the whole clustered index record */
- if (node->rec_type == TRX_UNDO_UPD_DEL_REC
- && !row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) {
+ if (row_vers_must_preserve_del_marked(node->new_trx_id, mtr)) {
+ return(DB_SUCCESS);
+ }
+
+ if (!btr_cur_get_index(btr_cur)->trx_id_offset) {
+ mem_heap_t* heap = NULL;
+ ulint trx_id_col;
+ ulint* offsets;
+ ulint len;
- /* Ok, we can remove */
+ trx_id_col = dict_index_get_sys_col_pos(
+ btr_cur_get_index(btr_cur), DATA_TRX_ID);
+ ut_ad(trx_id_col > 0);
+ ut_ad(trx_id_col != ULINT_UNDEFINED);
+
+ offsets = rec_get_offsets(
+ btr_cur_get_rec(btr_cur), btr_cur_get_index(btr_cur),
+ NULL, trx_id_col + 1, &heap);
+
+ db_trx_id = rec_get_nth_field(btr_cur_get_rec(btr_cur),
+ offsets, trx_id_col, &len);
+ ut_ad(len == DATA_TRX_ID_LEN);
+ mem_heap_free(heap);
} else {
+ db_trx_id = btr_cur_get_rec(btr_cur)
+ + btr_cur_get_index(btr_cur)->trx_id_offset;
+ }
+
+ if (ut_dulint_cmp(trx_read_trx_id(db_trx_id), node->new_trx_id)) {
+ /* The record must have been purged and then replaced
+ with a different one. */
return(DB_SUCCESS);
}