diff options
author | unknown <marko@hundin.mysql.fi> | 2005-04-20 17:39:05 +0300 |
---|---|---|
committer | unknown <marko@hundin.mysql.fi> | 2005-04-20 17:39:05 +0300 |
commit | ea5c2a148a6b704265324a2adcd7ae779a0df0b0 (patch) | |
tree | 385dcdcccffb58642b6b6a5b9d7a9415e6622429 | |
parent | dfa485b47dd768304a5324f619af3da374c6165d (diff) | |
download | mariadb-git-ea5c2a148a6b704265324a2adcd7ae779a0df0b0.tar.gz |
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().
-rw-r--r-- | innobase/btr/btr0btr.c | 19 | ||||
-rw-r--r-- | innobase/ibuf/ibuf0ibuf.c | 4 | ||||
-rw-r--r-- | innobase/include/btr0btr.h | 5 | ||||
-rw-r--r-- | innobase/include/trx0trx.h | 13 | ||||
-rw-r--r-- | innobase/row/row0mysql.c | 17 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 17 |
6 files changed, 66 insertions, 9 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c index 1744fc36f4d..fe6220b860d 100644 --- a/innobase/btr/btr0btr.c +++ b/innobase/btr/btr0btr.c @@ -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); diff --git a/innobase/ibuf/ibuf0ibuf.c b/innobase/ibuf/ibuf0ibuf.c index caa2ac013d7..c72bb2b1b65 100644 --- a/innobase/ibuf/ibuf0ibuf.c +++ b/innobase/ibuf/ibuf0ibuf.c @@ -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); diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h index 0b19e64d4e0..23116d24288 100644 --- a/innobase/include/btr0btr.h +++ b/innobase/include/btr0btr.h @@ -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 diff --git a/innobase/include/trx0trx.h b/innobase/include/trx0trx.h index d46613c3a68..6ca9c778aeb 100644 --- a/innobase/include/trx0trx.h +++ b/innobase/include/trx0trx.h @@ -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{ diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 7f78a5b723b..a201368f3d5 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -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); */ diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index a26c706bb08..4834dd24fa8 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -997,6 +997,23 @@ mysql_get_identifier_quote_char( } /************************************************************************** +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! */ extern "C" |