Commit ea5c2a14 authored by unknown's avatar unknown

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().
parent dfa485b4
......@@ -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! */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment