InnoDB: Make CHECK TABLE killable. (Bug #9730)
innobase/btr/btr0btr.c: Enclose btr_print_size() and btr_print_tree() in #ifdef UNIV_BTR_PRINT Add trx_t* parameter to btr_validate_tree() and btr_validate_level(). btr_validate_level(): Call trx_is_interrupted() on each page. innobase/ibuf/ibuf0ibuf.c: Add trx_t* parameter to btr_validate_tree(). innobase/include/btr0btr.h: Enclose btr_print_size() and btr_print_tree() in #ifdef UNIV_BTR_PRINT Add trx_t* parameter to btr_validate_tree(). innobase/include/trx0trx.h: Declare trx_is_interrupted(). innobase/row/row0mysql.c: row_scan_and_check_index(): Check trx_is_interrupted() every 1,000 scanned rows. row_check_table_for_mysql(): Check trx_is_interrupted() for each index after btr_validate_tree(). sql/ha_innodb.cc: Define trx_is_interrupted().
This commit is contained in:
parent
dfa485b47d
commit
ea5c2a148a
@ -20,6 +20,7 @@ Created 6/2/1994 Heikki Tuuri
|
||||
#include "rem0cmp.h"
|
||||
#include "lock0lock.h"
|
||||
#include "ibuf0ibuf.h"
|
||||
#include "trx0trx.h"
|
||||
|
||||
/*
|
||||
Latching strategy of the InnoDB B-tree
|
||||
@ -2274,6 +2275,7 @@ btr_discard_page(
|
||||
ut_ad(btr_check_node_ptr(tree, merge_page, mtr));
|
||||
}
|
||||
|
||||
#ifdef UNIV_BTR_PRINT
|
||||
/*****************************************************************
|
||||
Prints size info of a B-tree. */
|
||||
|
||||
@ -2407,8 +2409,9 @@ btr_print_tree(
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
btr_validate_tree(tree);
|
||||
btr_validate_tree(tree, NULL);
|
||||
}
|
||||
#endif /* UNIV_BTR_PRINT */
|
||||
|
||||
/****************************************************************
|
||||
Checks that the node pointer to a page is appropriate. */
|
||||
@ -2649,6 +2652,7 @@ btr_validate_level(
|
||||
/*===============*/
|
||||
/* out: TRUE if ok */
|
||||
dict_tree_t* tree, /* in: index tree */
|
||||
trx_t* trx, /* in: transaction or NULL */
|
||||
ulint level) /* in: level number */
|
||||
{
|
||||
ulint space;
|
||||
@ -2696,6 +2700,11 @@ btr_validate_level(
|
||||
/* Now we are on the desired level. Loop through the pages on that
|
||||
level. */
|
||||
loop:
|
||||
if (trx_is_interrupted(trx)) {
|
||||
mtr_commit(&mtr);
|
||||
mem_heap_free(heap);
|
||||
return(ret);
|
||||
}
|
||||
mem_heap_empty(heap);
|
||||
offsets = offsets2 = NULL;
|
||||
mtr_x_lock(dict_tree_get_lock(tree), &mtr);
|
||||
@ -2941,7 +2950,8 @@ ibool
|
||||
btr_validate_tree(
|
||||
/*==============*/
|
||||
/* out: TRUE if ok */
|
||||
dict_tree_t* tree) /* in: tree */
|
||||
dict_tree_t* tree, /* in: tree */
|
||||
trx_t* trx) /* in: transaction or NULL */
|
||||
{
|
||||
mtr_t mtr;
|
||||
page_t* root;
|
||||
@ -2954,9 +2964,8 @@ btr_validate_tree(
|
||||
root = btr_root_get(tree, &mtr);
|
||||
n = btr_page_get_level(root, &mtr);
|
||||
|
||||
for (i = 0; i <= n; i++) {
|
||||
|
||||
if (!btr_validate_level(tree, n - i)) {
|
||||
for (i = 0; i <= n && !trx_is_interrupted(trx); i++) {
|
||||
if (!btr_validate_level(tree, trx, n - i)) {
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
|
@ -2969,7 +2969,9 @@ ibuf_delete_rec(
|
||||
btr_pcur_commit_specify_mtr(pcur, mtr);
|
||||
|
||||
fputs("InnoDB: Validating insert buffer tree:\n", stderr);
|
||||
ut_a(btr_validate_tree(ibuf_data->index->tree));
|
||||
if (!btr_validate_tree(ibuf_data->index->tree, NULL)) {
|
||||
ut_error;
|
||||
}
|
||||
|
||||
fprintf(stderr, "InnoDB: ibuf tree ok\n");
|
||||
fflush(stderr);
|
||||
|
@ -398,6 +398,7 @@ btr_page_free_low(
|
||||
page_t* page, /* in: page to be freed, x-latched */
|
||||
ulint level, /* in: page level */
|
||||
mtr_t* mtr); /* in: mtr */
|
||||
#ifdef UNIV_BTR_PRINT
|
||||
/*****************************************************************
|
||||
Prints size info of a B-tree. */
|
||||
|
||||
@ -414,6 +415,7 @@ btr_print_tree(
|
||||
dict_tree_t* tree, /* in: tree */
|
||||
ulint width); /* in: print this many entries from start
|
||||
and end */
|
||||
#endif /* UNIV_BTR_PRINT */
|
||||
/****************************************************************
|
||||
Checks the size and number of fields in a record based on the definition of
|
||||
the index. */
|
||||
@ -434,7 +436,8 @@ ibool
|
||||
btr_validate_tree(
|
||||
/*==============*/
|
||||
/* out: TRUE if ok */
|
||||
dict_tree_t* tree); /* in: tree */
|
||||
dict_tree_t* tree, /* in: tree */
|
||||
trx_t* trx); /* in: transaction or NULL */
|
||||
|
||||
#define BTR_N_LEAF_PAGES 1
|
||||
#define BTR_TOTAL_SIZE 2
|
||||
|
@ -312,6 +312,19 @@ trx_print(
|
||||
FILE* f, /* in: output stream */
|
||||
trx_t* trx); /* in: transaction */
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**************************************************************************
|
||||
Determines if the currently running transaction has been interrupted. */
|
||||
|
||||
ibool
|
||||
trx_is_interrupted(
|
||||
/*===============*/
|
||||
/* out: TRUE if interrupted */
|
||||
trx_t* trx); /* in: transaction */
|
||||
#else /* !UNIV_HOTBACKUP */
|
||||
#define trx_is_interrupted(trx) FALSE
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
|
||||
/* Signal to a transaction */
|
||||
struct trx_sig_struct{
|
||||
|
@ -3880,6 +3880,7 @@ row_scan_and_check_index(
|
||||
int cmp;
|
||||
ibool contains_null;
|
||||
ulint i;
|
||||
ulint cnt;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
@ -3902,11 +3903,19 @@ row_scan_and_check_index(
|
||||
dtuple_set_n_fields(prebuilt->search_tuple, 0);
|
||||
|
||||
prebuilt->select_lock_type = LOCK_NONE;
|
||||
cnt = 1000;
|
||||
|
||||
ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, 0);
|
||||
loop:
|
||||
/* Check thd->killed every 1,000 scanned rows */
|
||||
if (--cnt == 0) {
|
||||
if (trx_is_interrupted(prebuilt->trx)) {
|
||||
goto func_exit;
|
||||
}
|
||||
cnt = 1000;
|
||||
}
|
||||
if (ret != DB_SUCCESS) {
|
||||
|
||||
func_exit:
|
||||
mem_free(buf);
|
||||
mem_heap_free(heap);
|
||||
|
||||
@ -4033,7 +4042,7 @@ row_check_table_for_mysql(
|
||||
ut_print_name(stderr, index->name);
|
||||
putc('\n', stderr); */
|
||||
|
||||
if (!btr_validate_tree(index->tree)) {
|
||||
if (!btr_validate_tree(index->tree, prebuilt->trx)) {
|
||||
ret = DB_ERROR;
|
||||
} else {
|
||||
if (!row_scan_and_check_index(prebuilt,
|
||||
@ -4041,6 +4050,10 @@ row_check_table_for_mysql(
|
||||
ret = DB_ERROR;
|
||||
}
|
||||
|
||||
if (trx_is_interrupted(prebuilt->trx)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* fprintf(stderr, "%lu entries in index %s\n", n_rows,
|
||||
index->name); */
|
||||
|
||||
|
@ -996,6 +996,23 @@ mysql_get_identifier_quote_char(
|
||||
name, namelen));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Determines if the currently running transaction has been interrupted. */
|
||||
extern "C"
|
||||
ibool
|
||||
trx_is_interrupted(
|
||||
/*===============*/
|
||||
/* out: TRUE if interrupted */
|
||||
trx_t* trx) /* in: transaction */
|
||||
{
|
||||
fprintf(stderr,
|
||||
"trx_is_interrupted: %p %p %d\n",
|
||||
trx, trx ? trx->mysql_thd : 0,
|
||||
trx && trx->mysql_thd ? ((THD*) trx->mysql_thd)->killed : -1);
|
||||
|
||||
return(trx && trx->mysql_thd && ((THD*) trx->mysql_thd)->killed);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Obtain a pointer to the MySQL THD object, as in current_thd(). This
|
||||
definition must match the one in sql/ha_innodb.cc! */
|
||||
|
Loading…
x
Reference in New Issue
Block a user