mirror of
https://github.com/MariaDB/server.git
synced 2025-01-24 07:44:22 +01:00
025ddfea28
innobase/dict/dict0crea.c: Remove unneeded prototypes for static functions Remove unused parameters from some functions Replace some assertions with compile-time checks dict_create_add_foreigns_to_dictionary(): allocate space dynamically for the SQL, and quote quotes innobase/dict/dict0dict.c: Remove unnecessary prototypes for static functions dict_tables_have_same_db(): Remove length limitation dict_remove_db_name(): Use strchr() dict_get_db_name_len(): Use strchr() Replace mem_heap_alloc()+strlen()+memcpy() with mem_heap_strdup() Remove unnecessary strlen() calls Allocate space dynamically for generated strings dict_scan_id(): allow quotes within quoted strings innobase/dict/dict0load.c: Remove unnecessary strlen() calls Replace mem_heap_alloc()+strlen()+memcpy() with mem_heap_strdup() innobase/dict/dict0mem.c: Replace mem_heap_alloc()+strlen()+memcpy() with mem_heap_strdup() innobase/eval/eval0eval.c: Make TO_CHAR() work with any machine word width innobase/fil/fil0fil.c: Replace mem_alloc()+strlen()+strcpy() with mem_strdup() innobase/ibuf/ibuf0ibuf.c: Make some global variables static Add #ifdef UNIV_IBUF_DEBUG around debug statements innobase/include/data0data.h: Add #ifdef UNIV_DEBUG around dtuple_validate() innobase/include/data0data.ic: Replace = with == in ut_ad(tuple->magic_n == DATA_TUPLE_MAGIC_N) innobase/include/dict0dict.h: Add const qualifiers innobase/include/lock0lock.h: Add UL suffixes to unsigned long masks innobase/include/log0log.h: Remove unused parameter "type" of log_group_write_buf() innobase/include/mem0mem.h: Add mem_strdup(), mem_strdupl(), mem_strdupq(), mem_heap_strdup(), and mem_heap_strdupl() innobase/include/mem0mem.ic: Add mem_strdup(), mem_strdupl(), mem_strdupq(), mem_heap_strdup(), and mem_heap_strdupl() innobase/include/row0uins.h: Remove unused parameter "thr" of row_undo_ins() innobase/include/row0undo.h: Remvoe unused parameter "thr" of row_undo_search_clust_to_pcur() innobase/include/ut0byte.h: Add const qualifier to ut_cpy_in_lower_case() Remove parameter "len" of ut_cmp_in_lower_case() innobase/include/ut0mem.h: Add ut_strlenq(), ut_strcpyq() and ut_memcpyq() innobase/include/ut0mem.ic: Add ut_strlenq() innobase/include/ut0ut.h: Declare ut_sprintf() as a printf-style function innobase/lock/lock0lock.c: lock_clust_rec_modify_check_and_lock(): Remove unused variable "trx" innobase/log/log0log.c: Remove unused parameters innobase/log/log0recv.c: Remove parameter "type" from log_group_write_buf() innobase/mem/mem0mem.c: Simplify the initialization of block->init_block innobase/mtr/mtr0log.c: Add a debug assertion to mlog_parse_initial_log_record() innobase/page/page0cur.c: Add debug assertion to page_cur_insert_rec_write_log() Remove hard-coded buffer size in page_cur_parse_insert_rec() innobase/page/page0page.c: Remove unneeded variable rec innobase/pars/pars0opt.c: Correct a potential buffer overflow innobase/pars/pars0pars.c: Replace mem_heap_alloc()+strlen()+memcpy() with mem_heap_strdup() innobase/row/row0ins.c: Replace parameter "thr" with "trx" in row_ins_foreign_report_add_err() Remove unnecessary strlen() call Use strchr() innobase/row/row0mysql.c: Add row_mysql_is_recovered_tmp_table() Add row_mysql_is_system_table() Compare reserved table names with exact match Use strstr() and strchr() and mem_strdupl() Compute space needed for generated SQL, and allocate it dynamically innobase/row/row0purge.c: Remove unused parameters "thr" innobase/row/row0row.c: Simplify row_get_clust_rec() innobase/row/row0uins.c: Remove unused parameters "thr" innobase/row/row0umod.c: Remove unused variable "index" row_undo_mod_del_unmark_sec_and_undo_update(): Remove parameter "node" and variable "rec" Remove unused parameters "thr" innobase/row/row0undo.c: Remove unused parameters "thr" innobase/srv/srv0srv.c: Replace UT_NOT_USED() with __attribute__((unused)) innobase/srv/srv0start.c: Remove unnecessary strlen() calls Remove unused parameter "create_new_db" of open_or_create_log_file() innobase/trx/trx0roll.c: Replace mem_alloc()+strlen()+memcpy() with mem_strdup() innobase/trx/trx0sys.c: Remove unnecessary strlen() call innobase/ut/ut0byte.c: Add const qualifier to ut_cpy_in_lower_case() Remove parameter "len" of ut_cmp_in_lower_case() innobase/ut/ut0mem.c: Add ut_strlenq() and ut_memcpyq() sql/ha_innodb.cc: Remove parameter "len" of ut_cmp_in_lower_case()
301 lines
6.5 KiB
C
301 lines
6.5 KiB
C
/******************************************************
|
|
Fresh insert undo
|
|
|
|
(c) 1996 Innobase Oy
|
|
|
|
Created 2/25/1997 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#include "row0uins.h"
|
|
|
|
#ifdef UNIV_NONINL
|
|
#include "row0uins.ic"
|
|
#endif
|
|
|
|
#include "dict0dict.h"
|
|
#include "dict0boot.h"
|
|
#include "dict0crea.h"
|
|
#include "trx0undo.h"
|
|
#include "trx0roll.h"
|
|
#include "btr0btr.h"
|
|
#include "mach0data.h"
|
|
#include "row0undo.h"
|
|
#include "row0vers.h"
|
|
#include "trx0trx.h"
|
|
#include "trx0rec.h"
|
|
#include "row0row.h"
|
|
#include "row0upd.h"
|
|
#include "que0que.h"
|
|
#include "ibuf0ibuf.h"
|
|
#include "log0log.h"
|
|
|
|
/*******************************************************************
|
|
Removes a clustered index record. The pcur in node was positioned on the
|
|
record, now it is detached. */
|
|
static
|
|
ulint
|
|
row_undo_ins_remove_clust_rec(
|
|
/*==========================*/
|
|
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
|
undo_node_t* node) /* in: undo node */
|
|
{
|
|
btr_cur_t* btr_cur;
|
|
ibool success;
|
|
ulint err;
|
|
ulint n_tries = 0;
|
|
mtr_t mtr;
|
|
|
|
mtr_start(&mtr);
|
|
|
|
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, &(node->pcur),
|
|
&mtr);
|
|
ut_a(success);
|
|
|
|
if (ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
|
|
|
|
/* Drop the index tree associated with the row in
|
|
SYS_INDEXES table: */
|
|
|
|
dict_drop_index_tree(btr_pcur_get_rec(&(node->pcur)), &mtr);
|
|
|
|
mtr_commit(&mtr);
|
|
|
|
mtr_start(&mtr);
|
|
|
|
success = btr_pcur_restore_position(BTR_MODIFY_LEAF,
|
|
&(node->pcur), &mtr);
|
|
ut_a(success);
|
|
}
|
|
|
|
btr_cur = btr_pcur_get_btr_cur(&(node->pcur));
|
|
|
|
success = btr_cur_optimistic_delete(btr_cur, &mtr);
|
|
|
|
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
|
|
|
|
if (success) {
|
|
trx_undo_rec_release(node->trx, node->undo_no);
|
|
|
|
return(DB_SUCCESS);
|
|
}
|
|
retry:
|
|
/* If did not succeed, try pessimistic descent to tree */
|
|
mtr_start(&mtr);
|
|
|
|
success = btr_pcur_restore_position(BTR_MODIFY_TREE,
|
|
&(node->pcur), &mtr);
|
|
ut_a(success);
|
|
|
|
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
|
|
|
|
/* 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 (err == DB_OUT_OF_FILE_SPACE
|
|
&& n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
|
|
|
|
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
|
|
|
|
n_tries++;
|
|
|
|
os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
|
|
|
|
goto retry;
|
|
}
|
|
|
|
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
|
|
|
|
trx_undo_rec_release(node->trx, node->undo_no);
|
|
|
|
return(err);
|
|
}
|
|
|
|
/*******************************************************************
|
|
Removes a secondary index entry if found. */
|
|
static
|
|
ulint
|
|
row_undo_ins_remove_sec_low(
|
|
/*========================*/
|
|
/* out: DB_SUCCESS, DB_FAIL, or
|
|
DB_OUT_OF_FILE_SPACE */
|
|
ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
|
|
depending on whether we wish optimistic or
|
|
pessimistic descent down the index tree */
|
|
dict_index_t* index, /* in: index */
|
|
dtuple_t* entry) /* in: index entry to remove */
|
|
{
|
|
btr_pcur_t pcur;
|
|
btr_cur_t* btr_cur;
|
|
ibool found;
|
|
ibool success;
|
|
ulint err;
|
|
mtr_t mtr;
|
|
|
|
log_free_check();
|
|
mtr_start(&mtr);
|
|
|
|
found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
|
|
|
|
btr_cur = btr_pcur_get_btr_cur(&pcur);
|
|
|
|
if (!found) {
|
|
/* Not found */
|
|
|
|
btr_pcur_close(&pcur);
|
|
mtr_commit(&mtr);
|
|
|
|
return(DB_SUCCESS);
|
|
}
|
|
|
|
if (mode == BTR_MODIFY_LEAF) {
|
|
success = btr_cur_optimistic_delete(btr_cur, &mtr);
|
|
|
|
if (success) {
|
|
err = DB_SUCCESS;
|
|
} else {
|
|
err = DB_FAIL;
|
|
}
|
|
} else {
|
|
ut_ad(mode == BTR_MODIFY_TREE);
|
|
|
|
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
|
|
}
|
|
|
|
btr_pcur_close(&pcur);
|
|
mtr_commit(&mtr);
|
|
|
|
return(err);
|
|
}
|
|
|
|
/*******************************************************************
|
|
Removes a secondary index entry from the index if found. Tries first
|
|
optimistic, then pessimistic descent down the tree. */
|
|
static
|
|
ulint
|
|
row_undo_ins_remove_sec(
|
|
/*====================*/
|
|
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
|
dict_index_t* index, /* in: index */
|
|
dtuple_t* entry) /* in: index entry to insert */
|
|
{
|
|
ulint err;
|
|
ulint n_tries = 0;
|
|
|
|
/* Try first optimistic descent to the B-tree */
|
|
|
|
err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry);
|
|
|
|
if (err == DB_SUCCESS) {
|
|
|
|
return(err);
|
|
}
|
|
|
|
/* Try then pessimistic descent to the B-tree */
|
|
retry:
|
|
err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry);
|
|
|
|
/* 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 (err != DB_SUCCESS && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
|
|
|
|
n_tries++;
|
|
|
|
os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
|
|
|
|
goto retry;
|
|
}
|
|
|
|
return(err);
|
|
}
|
|
|
|
/***************************************************************
|
|
Parses the row reference and other info in a fresh insert undo record. */
|
|
static
|
|
void
|
|
row_undo_ins_parse_undo_rec(
|
|
/*========================*/
|
|
undo_node_t* node) /* in: row undo node */
|
|
{
|
|
dict_index_t* clust_index;
|
|
byte* ptr;
|
|
dulint undo_no;
|
|
dulint table_id;
|
|
ulint type;
|
|
ulint dummy;
|
|
ibool dummy_extern;
|
|
|
|
ut_ad(node);
|
|
|
|
ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &dummy,
|
|
&dummy_extern, &undo_no, &table_id);
|
|
ut_ad(type == TRX_UNDO_INSERT_REC);
|
|
node->rec_type = type;
|
|
|
|
node->table = dict_table_get_on_id(table_id, node->trx);
|
|
|
|
if (node->table == NULL) {
|
|
|
|
return;
|
|
}
|
|
|
|
clust_index = dict_table_get_first_index(node->table);
|
|
|
|
ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref),
|
|
node->heap);
|
|
}
|
|
|
|
/***************************************************************
|
|
Undoes a fresh insert of a row to a table. A fresh insert means that
|
|
the same clustered index unique key did not have any record, even delete
|
|
marked, at the time of the insert. */
|
|
|
|
ulint
|
|
row_undo_ins(
|
|
/*=========*/
|
|
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
|
undo_node_t* node) /* in: row undo node */
|
|
{
|
|
dtuple_t* entry;
|
|
ibool found;
|
|
ulint err;
|
|
|
|
ut_ad(node);
|
|
ut_ad(node->state == UNDO_NODE_INSERT);
|
|
|
|
row_undo_ins_parse_undo_rec(node);
|
|
|
|
if (node->table == NULL) {
|
|
found = FALSE;
|
|
} else {
|
|
found = row_undo_search_clust_to_pcur(node);
|
|
}
|
|
|
|
if (!found) {
|
|
trx_undo_rec_release(node->trx, node->undo_no);
|
|
|
|
return(DB_SUCCESS);
|
|
}
|
|
|
|
node->index = dict_table_get_next_index(
|
|
dict_table_get_first_index(node->table));
|
|
|
|
while (node->index != NULL) {
|
|
entry = row_build_index_entry(node->row, node->index,
|
|
node->heap);
|
|
err = row_undo_ins_remove_sec(node->index, entry);
|
|
|
|
if (err != DB_SUCCESS) {
|
|
|
|
return(err);
|
|
}
|
|
|
|
node->index = dict_table_get_next_index(node->index);
|
|
}
|
|
|
|
err = row_undo_ins_remove_clust_rec(node);
|
|
|
|
return(err);
|
|
}
|