Commit ea5c2a14 authored by unknown's avatar unknown
Browse files

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
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -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);

+3 −1
Original line number Diff line number Diff line
@@ -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);
+4 −1
Original line number Diff line number Diff line
@@ -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
+13 −0
Original line number Diff line number Diff line
@@ -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{
+15 −2
Original line number Diff line number Diff line
@@ -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); */

Loading