📄 row0purge.c
字号:
/******************************************************Purge obsolete records(c) 1997 Innobase OyCreated 3/14/1997 Heikki Tuuri*******************************************************/#include "row0purge.h"#ifdef UNIV_NONINL#include "row0purge.ic"#endif#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 "row0upd.h"#include "row0vers.h"#include "row0mysql.h"#include "log0log.h"/************************************************************************Creates a purge node to a query graph. */purge_node_t*row_purge_node_create(/*==================*/ /* out, own: purge node */ que_thr_t* parent, /* in: parent node, i.e., a thr node */ mem_heap_t* heap) /* in: memory heap where created */{ purge_node_t* node; ut_ad(parent && heap); node = mem_heap_alloc(heap, sizeof(purge_node_t)); node->common.type = QUE_NODE_PURGE; node->common.parent = parent; node->heap = mem_heap_create(256); return(node);}/***************************************************************Repositions the pcur in the purge node on the clustered index record,if found. */staticiboolrow_purge_reposition_pcur(/*======================*/ /* out: TRUE if the record was found */ ulint mode, /* in: latching mode */ purge_node_t* node, /* in: row purge node */ mtr_t* mtr) /* in: mtr */{ ibool found; if (node->found_clust) { found = btr_pcur_restore_position(mode, &(node->pcur), mtr); return(found); } found = row_search_on_row_ref(&(node->pcur), mode, node->table, node->ref, mtr); node->found_clust = found; if (found) { btr_pcur_store_position(&(node->pcur), mtr); } return(found);}/***************************************************************Removes a delete marked clustered index record if possible. */staticiboolrow_purge_remove_clust_if_poss_low(/*===============================*/ /* out: TRUE if success, or if not found, or if modified after the delete marking */ purge_node_t* node, /* in: row purge node */ ulint mode) /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */{ dict_index_t* index; btr_pcur_t* pcur; btr_cur_t* btr_cur; ibool success; ulint err; mtr_t mtr; rec_t* rec; mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; *offsets_ = (sizeof offsets_) / sizeof *offsets_; index = dict_table_get_first_index(node->table); pcur = &(node->pcur); btr_cur = btr_pcur_get_btr_cur(pcur); mtr_start(&mtr); success = row_purge_reposition_pcur(mode, node, &mtr); if (!success) { /* The record is already removed */ btr_pcur_commit_specify_mtr(pcur, &mtr); return(TRUE); } rec = btr_pcur_get_rec(pcur); if (0 != ut_dulint_cmp(node->roll_ptr, row_get_rec_roll_ptr(rec, index, rec_get_offsets( rec, index, offsets_, ULINT_UNDEFINED, &heap)))) { if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } /* Someone else has modified the record later: do not remove */ btr_pcur_commit_specify_mtr(pcur, &mtr); return(TRUE); } if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } if (mode == BTR_MODIFY_LEAF) { success = btr_cur_optimistic_delete(btr_cur, &mtr); } else { ut_ad(mode == BTR_MODIFY_TREE); btr_cur_pessimistic_delete(&err, FALSE, btr_cur, FALSE, &mtr); if (err == DB_SUCCESS) { success = TRUE; } else if (err == DB_OUT_OF_FILE_SPACE) { success = FALSE; } else { ut_error; } } btr_pcur_commit_specify_mtr(pcur, &mtr); return(success);} /***************************************************************Removes a clustered index record if it has not been modified after the deletemarking. */staticvoidrow_purge_remove_clust_if_poss(/*===========================*/ purge_node_t* node) /* in: row purge node */{ ibool success; ulint n_tries = 0; /* fputs("Purge: Removing clustered record\n", stderr); */ success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_LEAF); if (success) { return; }retry: success = row_purge_remove_clust_if_poss_low(node, BTR_MODIFY_TREE); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database and restart with more file space */ if (!success && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) { n_tries++; os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME); goto retry; } ut_a(success);} /***************************************************************Removes a secondary index entry if possible. */staticiboolrow_purge_remove_sec_if_poss_low(/*=============================*/ /* out: TRUE if success or if not found */ purge_node_t* node, /* in: row purge node */ dict_index_t* index, /* in: index */ dtuple_t* entry, /* in: index entry */ ulint mode) /* in: latch mode BTR_MODIFY_LEAF or BTR_MODIFY_TREE */ { btr_pcur_t pcur; btr_cur_t* btr_cur; ibool success; ibool old_has = 0; /* remove warning */ ibool found; ulint err; mtr_t mtr; mtr_t* mtr_vers; log_free_check(); mtr_start(&mtr); found = row_search_index_entry(index, entry, mode, &pcur, &mtr); if (!found) { /* Not found */ /* fputs("PURGE:........sec entry not found\n", stderr); */ /* dtuple_print(entry); */ btr_pcur_close(&pcur); mtr_commit(&mtr); return(TRUE); } btr_cur = btr_pcur_get_btr_cur(&pcur); /* We should remove the index record if no later version of the row, which cannot be purged yet, requires its existence. If some requires, we should do nothing. */ mtr_vers = mem_alloc(sizeof(mtr_t)); mtr_start(mtr_vers); success = row_purge_reposition_pcur(BTR_SEARCH_LEAF, node, mtr_vers); if (success) { old_has = row_vers_old_has_index_entry(TRUE, btr_pcur_get_rec(&(node->pcur)), mtr_vers, index, entry); } btr_pcur_commit_specify_mtr(&(node->pcur), mtr_vers); mem_free(mtr_vers); if (!success || !old_has) { /* Remove the index record */ if (mode == BTR_MODIFY_LEAF) { success = btr_cur_optimistic_delete(btr_cur, &mtr); } else { ut_ad(mode == BTR_MODIFY_TREE); btr_cur_pessimistic_delete(&err, FALSE, btr_cur, FALSE, &mtr); if (err == DB_SUCCESS) { success = TRUE; } else if (err == DB_OUT_OF_FILE_SPACE) { success = FALSE; } else { ut_error; } } } btr_pcur_close(&pcur); mtr_commit(&mtr); return(success);}/***************************************************************Removes a secondary index entry if possible. */UNIV_INLINEvoidrow_purge_remove_sec_if_poss(/*=========================*/ purge_node_t* node, /* in: row purge node */ dict_index_t* index, /* in: index */ dtuple_t* entry) /* in: index entry */{ ibool success; ulint n_tries = 0; /* fputs("Purge: Removing secondary record\n", stderr); */ success = row_purge_remove_sec_if_poss_low(node, index, entry, BTR_MODIFY_LEAF); if (success) { return; }retry: success = row_purge_remove_sec_if_poss_low(node, index, entry, BTR_MODIFY_TREE); /* The delete operation may fail if we have little file space left: TODO: easiest to crash the database and restart with more file space */ if (!success && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) { n_tries++; os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME); goto retry; } ut_a(success);}/***************************************************************Purges a delete marking of a record. */staticvoidrow_purge_del_mark(/*===============*/ purge_node_t* node) /* in: row purge node */{ mem_heap_t* heap; dtuple_t* entry; dict_index_t* index; ut_ad(node);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -