summaryrefslogtreecommitdiff
path: root/innobase/dict/dict0crea.c
diff options
context:
space:
mode:
authorunknown <marko@hundin.mysql.fi>2005-03-01 19:42:59 +0200
committerunknown <marko@hundin.mysql.fi>2005-03-01 19:42:59 +0200
commit39cf45fd54247ca02554a2ecfedcbfbd996b9060 (patch)
tree87a9487085f2946b718777b52b8cfc500bea903b /innobase/dict/dict0crea.c
parent91fa4862c07354a7ac65055758ca21cf21296245 (diff)
downloadmariadb-git-39cf45fd54247ca02554a2ecfedcbfbd996b9060.tar.gz
After review fixes. Fix bugs in TRUNCATE.
innobase/dict/dict0crea.c: dict_truncate_index_tree(): Commit the mtr after deleting the index tree. Add diagnostics for error cases. Let the caller update SYS_INDEXES.PAGE_NO to the new root page number. Return the new root page number, or FIL_NULL on error. innobase/include/dict0crea.h: dict_truncate_index_tree(): Commit the mtr after deleting the index tree. Add diagnostics for error cases. Let the caller update SYS_INDEXES.PAGE_NO to the new root page number. Return the new root page number, or FIL_NULL on error. innobase/include/page0page.ic: page_mem_free(): Disable the memset() call, to make it possible to recover some data if someone accidentally deletes a large number of records from a table. innobase/log/log0recv.c: Do not disable InnoDB Hot Backup specific code in MySQL builds. innobase/row/row0mysql.c: row_truncate_table_for_mysql(): Remove an infinite loop in case a SYS_INDEXES record has been deleted. Avoid deadlocks by committing and restarting the mini-transaction. sql/ha_innodb.cc: ha_innobase::delete_all_rows(): set trx->active_trans = 1
Diffstat (limited to 'innobase/dict/dict0crea.c')
-rw-r--r--innobase/dict/dict0crea.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/innobase/dict/dict0crea.c b/innobase/dict/dict0crea.c
index 4926797721c..fda09feca6f 100644
--- a/innobase/dict/dict0crea.c
+++ b/innobase/dict/dict0crea.c
@@ -729,14 +729,17 @@ dict_drop_index_tree(
/***********************************************************************
Truncates the index tree associated with a row in SYS_INDEXES table. */
-void
+ulint
dict_truncate_index_tree(
/*=====================*/
+ /* out: new root page number, or
+ FIL_NULL on failure */
dict_table_t* table, /* in: the table the index belongs to */
rec_t* rec, /* in: record in the clustered index of
SYS_INDEXES table */
mtr_t* mtr) /* in: mtr having the latch
- on the record page */
+ on the record page. The mtr may be
+ committed and restarted in this call. */
{
ulint root_page_no;
ulint space;
@@ -761,7 +764,10 @@ dict_truncate_index_tree(
if (root_page_no == FIL_NULL) {
/* The tree has been freed. */
- return;
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Trying to TRUNCATE"
+ " a missing index of table %s!\n", table->name);
+ return(FIL_NULL);
}
ptr = rec_get_nth_field_old(rec,
@@ -775,7 +781,10 @@ dict_truncate_index_tree(
/* It is a single table tablespace and the .ibd file is
missing: do nothing */
- return;
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Trying to TRUNCATE"
+ " a missing .ibd file of table %s!\n", table->name);
+ return(FIL_NULL);
}
ptr = rec_get_nth_field_old(rec,
@@ -801,6 +810,20 @@ dict_truncate_index_tree(
space, root_page_no, RW_X_LATCH, mtr));
btr_free_root(space, root_page_no, mtr);
+ /* We will temporarily write FIL_NULL to the PAGE_NO field
+ in SYS_INDEXES, so that the database will not get into an
+ inconsistent state in case it crashes between the mtr_commit()
+ below and the following mtr_commit() call. */
+ page_rec_write_index_page_no(rec, DICT_SYS_INDEXES_PAGE_NO_FIELD,
+ FIL_NULL, mtr);
+
+ /* We will need to commit the mini-transaction in order to avoid
+ deadlocks in the btr_create() call, because otherwise we would
+ be freeing and allocating pages in the same mini-transaction. */
+ mtr_commit(mtr);
+ /* mtr_commit() will invalidate rec. */
+ rec = NULL;
+ mtr_start(mtr);
/* Find the index corresponding to this SYS_INDEXES record. */
for (index = UT_LIST_GET_FIRST(table->indexes);
@@ -814,11 +837,17 @@ dict_truncate_index_tree(
root_page_no = btr_create(type, space, index_id, comp, mtr);
if (index) {
index->tree->page = root_page_no;
+ } else {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Index %lu %lu of table %s is missing\n"
+ "InnoDB: from the data dictionary during TRUNCATE!\n",
+ ut_dulint_get_high(index_id),
+ ut_dulint_get_low(index_id),
+ table->name);
}
- page_rec_write_index_page_no(rec,
- DICT_SYS_INDEXES_PAGE_NO_FIELD,
- root_page_no, mtr);
+ return(root_page_no);
}
/*************************************************************************