#include "row0undo.h"#include "fsp0fsp.h"#include "mach0data.h"#include "trx0rseg.h"#include "trx0trx.h"#include "trx0roll.h"#include "trx0undo.h"#include "trx0purge.h"#include "trx0rec.h"#include "que0que.h"#include "row0row.h"#include "row0uins.h"#include "row0umod.h"#include "row0mysql.h"#include "srv0srv.h"Include dependency graph for row0undo.c:

Go to the source code of this file.
Functions | |
| undo_node_t * | row_undo_node_create (trx_t *trx, que_thr_t *parent, mem_heap_t *heap) |
| ibool | row_undo_search_clust_to_pcur (undo_node_t *node) |
| static ulint | row_undo (undo_node_t *node, que_thr_t *thr) |
| que_thr_t * | row_undo_step (que_thr_t *thr) |
| static ulint row_undo | ( | undo_node_t * | node, | |
| que_thr_t * | thr | |||
| ) | [static] |
Definition at line 205 of file row0undo.c.
References btr_pcur_close(), DB_SUCCESS, trx_struct::dict_operation_lock_mode, err, FALSE, undo_node_struct::heap, mem_heap_empty(), undo_node_struct::new_roll_ptr, undo_node_struct::pcur, que_node_get_parent(), trx_struct::roll_limit, undo_node_struct::roll_ptr, row_mysql_freeze_data_dictionary(), row_mysql_unfreeze_data_dictionary(), row_undo_ins(), row_undo_mod(), que_thr_struct::run_node, undo_node_struct::state, TRUE, undo_node_struct::trx, trx_roll_pop_top_rec_of_trx(), trx_undo_get_undo_rec_low(), trx_undo_rec_get_undo_no(), trx_undo_roll_ptr_is_insert(), undo_node_struct::undo_no, UNDO_NODE_FETCH_NEXT, UNDO_NODE_INSERT, UNDO_NODE_MODIFY, UNDO_NODE_PREV_VERS, undo_node_struct::undo_rec, and ut_ad.
Referenced by row_undo_step().
00207 : DB_SUCCESS if operation successfully 00208 completed, else error code */ 00209 undo_node_t* node, /* in: row undo node */ 00210 que_thr_t* thr) /* in: query thread */ 00211 { 00212 ulint err; 00213 trx_t* trx; 00214 dulint roll_ptr; 00215 ibool froze_data_dict = FALSE; 00216 00217 ut_ad(node && thr); 00218 00219 trx = node->trx; 00220 00221 if (node->state == UNDO_NODE_FETCH_NEXT) { 00222 00223 node->undo_rec = trx_roll_pop_top_rec_of_trx(trx, 00224 trx->roll_limit, 00225 &roll_ptr, 00226 node->heap); 00227 if (!node->undo_rec) { 00228 /* Rollback completed for this query thread */ 00229 00230 thr->run_node = que_node_get_parent(node); 00231 00232 return(DB_SUCCESS); 00233 } 00234 00235 node->roll_ptr = roll_ptr; 00236 node->undo_no = trx_undo_rec_get_undo_no(node->undo_rec); 00237 00238 if (trx_undo_roll_ptr_is_insert(roll_ptr)) { 00239 00240 node->state = UNDO_NODE_INSERT; 00241 } else { 00242 node->state = UNDO_NODE_MODIFY; 00243 } 00244 00245 } else if (node->state == UNDO_NODE_PREV_VERS) { 00246 00247 /* Undo should be done to the same clustered index record 00248 again in this same rollback, restoring the previous version */ 00249 00250 roll_ptr = node->new_roll_ptr; 00251 00252 node->undo_rec = trx_undo_get_undo_rec_low(roll_ptr, 00253 node->heap); 00254 node->roll_ptr = roll_ptr; 00255 node->undo_no = trx_undo_rec_get_undo_no(node->undo_rec); 00256 00257 if (trx_undo_roll_ptr_is_insert(roll_ptr)) { 00258 00259 node->state = UNDO_NODE_INSERT; 00260 } else { 00261 node->state = UNDO_NODE_MODIFY; 00262 } 00263 } 00264 00265 /* Prevent DROP TABLE etc. while we are rolling back this row. 00266 If we are doing a TABLE CREATE or some other dictionary operation, 00267 then we already have dict_operation_lock locked in x-mode. Do not 00268 try to lock again in s-mode, because that would cause a hang. */ 00269 00270 if (trx->dict_operation_lock_mode == 0) { 00271 00272 row_mysql_freeze_data_dictionary(trx); 00273 00274 froze_data_dict = TRUE; 00275 } 00276 00277 if (node->state == UNDO_NODE_INSERT) { 00278 00279 err = row_undo_ins(node); 00280 00281 node->state = UNDO_NODE_FETCH_NEXT; 00282 } else { 00283 ut_ad(node->state == UNDO_NODE_MODIFY); 00284 err = row_undo_mod(node, thr); 00285 } 00286 00287 if (froze_data_dict) { 00288 00289 row_mysql_unfreeze_data_dictionary(trx); 00290 } 00291 00292 /* Do some cleanup */ 00293 btr_pcur_close(&(node->pcur)); 00294 00295 mem_heap_empty(node->heap); 00296 00297 thr->run_node = node; 00298 00299 return(err); 00300 }
Here is the call graph for this function:

Here is the caller graph for this function:

| undo_node_t* row_undo_node_create | ( | trx_t * | trx, | |
| que_thr_t * | parent, | |||
| mem_heap_t * | heap | |||
| ) |
Definition at line 109 of file row0undo.c.
References btr_pcur_init(), undo_node_struct::common, undo_node_struct::heap, mem_heap_alloc(), mem_heap_create, que_common_struct::parent, undo_node_struct::pcur, QUE_NODE_UNDO, undo_node_struct::state, undo_node_struct::trx, que_common_struct::type, UNDO_NODE_FETCH_NEXT, and ut_ad.
Referenced by trx_roll_graph_build().
00111 : undo node */ 00112 trx_t* trx, /* in: transaction */ 00113 que_thr_t* parent, /* in: parent node, i.e., a thr node */ 00114 mem_heap_t* heap) /* in: memory heap where created */ 00115 { 00116 undo_node_t* undo; 00117 00118 ut_ad(trx && parent && heap); 00119 00120 undo = mem_heap_alloc(heap, sizeof(undo_node_t)); 00121 00122 undo->common.type = QUE_NODE_UNDO; 00123 undo->common.parent = parent; 00124 00125 undo->state = UNDO_NODE_FETCH_NEXT; 00126 undo->trx = trx; 00127 00128 btr_pcur_init(&(undo->pcur)); 00129 00130 undo->heap = mem_heap_create(256); 00131 00132 return(undo); 00133 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool row_undo_search_clust_to_pcur | ( | undo_node_t * | node | ) |
Definition at line 142 of file row0undo.c.
References BTR_MODIFY_LEAF, btr_pcur_commit_specify_mtr(), btr_pcur_get_rec(), btr_pcur_store_position(), dict_table_get_first_index(), FALSE, undo_node_struct::heap, mem_heap_free, mtr_start(), NULL, undo_node_struct::pcur, rec_get_offsets, REC_OFFS_NORMAL_SIZE, undo_node_struct::ref, undo_node_struct::roll_ptr, undo_node_struct::row, row_build(), ROW_COPY_DATA, row_get_rec_roll_ptr(), row_search_on_row_ref(), undo_node_struct::table, TRUE, and ut_dulint_cmp().
Referenced by row_undo_ins(), and row_undo_mod().
00144 : TRUE if found; NOTE the node->pcur 00145 must be closed by the caller, regardless of 00146 the return value */ 00147 undo_node_t* node) /* in: row undo node */ 00148 { 00149 dict_index_t* clust_index; 00150 ibool found; 00151 mtr_t mtr; 00152 ibool ret; 00153 rec_t* rec; 00154 mem_heap_t* heap = NULL; 00155 ulint offsets_[REC_OFFS_NORMAL_SIZE]; 00156 ulint* offsets = offsets_; 00157 *offsets_ = (sizeof offsets_) / sizeof *offsets_; 00158 00159 mtr_start(&mtr); 00160 00161 clust_index = dict_table_get_first_index(node->table); 00162 00163 found = row_search_on_row_ref(&(node->pcur), BTR_MODIFY_LEAF, 00164 node->table, node->ref, &mtr); 00165 00166 rec = btr_pcur_get_rec(&(node->pcur)); 00167 00168 offsets = rec_get_offsets(rec, clust_index, offsets, 00169 ULINT_UNDEFINED, &heap); 00170 00171 if (!found || 0 != ut_dulint_cmp(node->roll_ptr, 00172 row_get_rec_roll_ptr(rec, clust_index, offsets))) { 00173 00174 /* We must remove the reservation on the undo log record 00175 BEFORE releasing the latch on the clustered index page: this 00176 is to make sure that some thread will eventually undo the 00177 modification corresponding to node->roll_ptr. */ 00178 00179 /* fputs("--------------------undoing a previous version\n", 00180 stderr); */ 00181 00182 ret = FALSE; 00183 } else { 00184 node->row = row_build(ROW_COPY_DATA, clust_index, rec, 00185 offsets, node->heap); 00186 btr_pcur_store_position(&(node->pcur), &mtr); 00187 00188 ret = TRUE; 00189 } 00190 00191 btr_pcur_commit_specify_mtr(&(node->pcur), &mtr); 00192 00193 if (UNIV_LIKELY_NULL(heap)) { 00194 mem_heap_free(heap); 00195 } 00196 return(ret); 00197 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 307 of file row0undo.c.
References DB_OUT_OF_FILE_SPACE, DB_SUCCESS, err, trx_struct::error_state, exit, NULL, que_node_get_type(), QUE_NODE_UNDO, row_undo(), que_thr_struct::run_node, srv_activity_count, thr_get_trx(), ut_ad, and ut_error.
Referenced by que_thr_step().
00309 : query thread to run next or NULL */ 00310 que_thr_t* thr) /* in: query thread */ 00311 { 00312 ulint err; 00313 undo_node_t* node; 00314 trx_t* trx; 00315 00316 ut_ad(thr); 00317 00318 srv_activity_count++; 00319 00320 trx = thr_get_trx(thr); 00321 00322 node = thr->run_node; 00323 00324 ut_ad(que_node_get_type(node) == QUE_NODE_UNDO); 00325 00326 err = row_undo(node, thr); 00327 00328 trx->error_state = err; 00329 00330 if (err != DB_SUCCESS) { 00331 /* SQL error detected */ 00332 00333 fprintf(stderr, "InnoDB: Fatal error %lu in rollback.\n", 00334 (ulong) err); 00335 00336 if (err == DB_OUT_OF_FILE_SPACE) { 00337 fprintf(stderr, 00338 "InnoDB: Error 13 means out of tablespace.\n" 00339 "InnoDB: Consider increasing your tablespace.\n"); 00340 00341 exit(1); 00342 } 00343 00344 ut_error; 00345 00346 return(NULL); 00347 } 00348 00349 return(thr); 00350 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.4.7

