1
/*****************************************************************************
3
Copyright (C) 1997, 2010, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
1
/******************************************************
23
6
Created 2/25/1997 Heikki Tuuri
24
7
*******************************************************/
46
29
#include "ibuf0ibuf.h"
47
30
#include "log0log.h"
49
/*************************************************************************
50
IMPORTANT NOTE: Any operation that generates redo MUST check that there
51
is enough space in the redo log before for that operation. This is
52
done by calling log_free_check(). The reason for checking the
53
availability of the redo log space before the start of the operation is
54
that we MUST not hold any synchonization objects when performing the
56
If you make a change in this module make sure that no codepath is
57
introduced where a call to log_free_check() is bypassed. */
59
/*************************************************************************
60
IMPORTANT NOTE: Any operation that generates redo MUST check that there
61
is enough space in the redo log before for that operation. This is
62
done by calling log_free_check(). The reason for checking the
63
availability of the redo log space before the start of the operation is
64
that we MUST not hold any synchonization objects when performing the
66
If you make a change in this module make sure that no codepath is
67
introduced where a call to log_free_check() is bypassed. */
69
/***************************************************************//**
32
/*******************************************************************
70
33
Removes a clustered index record. The pcur in node was positioned on the
71
record, now it is detached.
72
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
34
record, now it is detached. */
75
37
row_undo_ins_remove_clust_rec(
76
38
/*==========================*/
77
undo_node_t* node) /*!< in: undo node */
39
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
40
undo_node_t* node) /* in: undo node */
79
42
btr_cur_t* btr_cur;
91
if (node->table->id == DICT_INDEXES_ID) {
54
if (ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
92
55
ut_ad(node->trx->dict_operation_lock_mode == RW_X_LATCH);
94
57
/* Drop the index tree associated with the row in
155
/***************************************************************//**
156
Removes a secondary index entry if found.
157
@return DB_SUCCESS, DB_FAIL, or DB_OUT_OF_FILE_SPACE */
118
/*******************************************************************
119
Removes a secondary index entry if found. */
160
122
row_undo_ins_remove_sec_low(
161
123
/*========================*/
162
ulint mode, /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
124
/* out: DB_SUCCESS, DB_FAIL, or
125
DB_OUT_OF_FILE_SPACE */
126
ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
163
127
depending on whether we wish optimistic or
164
128
pessimistic descent down the index tree */
165
dict_index_t* index, /*!< in: index */
166
dtuple_t* entry) /*!< in: index entry to remove */
129
dict_index_t* index, /* in: index */
130
dtuple_t* entry) /* in: index entry to remove */
172
enum row_search_result search_result;
142
found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
176
144
btr_cur = btr_pcur_get_btr_cur(&pcur);
178
ut_ad(mode == BTR_MODIFY_TREE || mode == BTR_MODIFY_LEAF);
180
search_result = row_search_index_entry(index, entry, mode,
183
switch (search_result) {
190
case ROW_NOT_DELETED_REF:
191
/* These are invalid outcomes, because the mode passed
192
to row_search_index_entry() did not include any of the
193
flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */
149
btr_pcur_close(&pcur);
197
155
if (mode == BTR_MODIFY_LEAF) {
198
err = btr_cur_optimistic_delete(btr_cur, &mtr)
199
? DB_SUCCESS : DB_FAIL;
156
success = btr_cur_optimistic_delete(btr_cur, &mtr);
201
164
ut_ad(mode == BTR_MODIFY_TREE);
209
172
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
210
173
RB_NORMAL, &mtr);
213
176
btr_pcur_close(&pcur);
214
177
mtr_commit(&mtr);
219
/***************************************************************//**
182
/*******************************************************************
220
183
Removes a secondary index entry from the index if found. Tries first
221
optimistic, then pessimistic descent down the tree.
222
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
184
optimistic, then pessimistic descent down the tree. */
225
187
row_undo_ins_remove_sec(
226
188
/*====================*/
227
dict_index_t* index, /*!< in: index */
228
dtuple_t* entry) /*!< in: index entry to insert */
189
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
190
dict_index_t* index, /* in: index */
191
dtuple_t* entry) /* in: index entry to insert */
231
194
ulint n_tries = 0;
262
/***********************************************************//**
225
/***************************************************************
263
226
Parses the row reference and other info in a fresh insert undo record. */
266
229
row_undo_ins_parse_undo_rec(
267
230
/*========================*/
268
undo_node_t* node) /*!< in/out: row undo node */
231
undo_node_t* node) /* in/out: row undo node */
270
233
dict_index_t* clust_index;
276
239
ibool dummy_extern;
311
/***********************************************************//**
274
/***************************************************************
312
275
Undoes a fresh insert of a row to a table. A fresh insert means that
313
276
the same clustered index unique key did not have any record, even delete
314
marked, at the time of the insert. InnoDB is eager in a rollback:
315
if it figures out that an index record will be removed in the purge
316
anyway, it will remove it in the rollback.
317
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
277
marked, at the time of the insert. */
322
undo_node_t* node) /*!< in: row undo node */
282
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
283
undo_node_t* node) /* in: row undo node */
325
286
ut_ad(node->state == UNDO_NODE_INSERT);