← Back to team overview

maria-developers team mailing list archive

bzr commit into MariaDB 5.1, with Maria 1.5:maria branch (knielsen:2854)

 

#At lp:maria

 2854 knielsen@xxxxxxxxxxxxxxx	2010-04-28 [merge]
      Merge XtraDB 10 into MariaDB.
      modified:
        mysql-test/r/information_schema.result
        mysql-test/r/information_schema_all_engines.result
        storage/xtradb/btr/btr0btr.c
        storage/xtradb/btr/btr0cur.c
        storage/xtradb/btr/btr0pcur.c
        storage/xtradb/btr/btr0sea.c
        storage/xtradb/buf/buf0buddy.c
        storage/xtradb/buf/buf0buf.c
        storage/xtradb/buf/buf0flu.c
        storage/xtradb/buf/buf0rea.c
        storage/xtradb/build/debian/control
        storage/xtradb/build/debian/patches/60_percona_support.dpatch
        storage/xtradb/build/debian/rules
        storage/xtradb/build/percona-sql.spec
        storage/xtradb/dict/dict0dict.c
        storage/xtradb/dict/dict0mem.c
        storage/xtradb/fil/fil0fil.c
        storage/xtradb/fsp/fsp0fsp.c
        storage/xtradb/handler/ha_innodb.cc
        storage/xtradb/handler/ha_innodb.h
        storage/xtradb/handler/i_s.cc
        storage/xtradb/handler/i_s.h
        storage/xtradb/handler/innodb_patch_info.h
        storage/xtradb/include/btr0btr.ic
        storage/xtradb/include/buf0buddy.h
        storage/xtradb/include/buf0buf.h
        storage/xtradb/include/buf0buf.ic
        storage/xtradb/include/buf0types.h
        storage/xtradb/include/dict0dict.h
        storage/xtradb/include/dict0mem.h
        storage/xtradb/include/fil0fil.h
        storage/xtradb/include/fut0fut.ic
        storage/xtradb/include/page0cur.h
        storage/xtradb/include/page0types.h
        storage/xtradb/include/srv0srv.h
        storage/xtradb/include/trx0sys.h
        storage/xtradb/include/univ.i
        storage/xtradb/include/ut0rnd.h
        storage/xtradb/include/ut0rnd.ic
        storage/xtradb/lock/lock0lock.c
        storage/xtradb/log/log0log.c
        storage/xtradb/log/log0recv.c
        storage/xtradb/page/page0cur.c
        storage/xtradb/page/page0zip.c
        storage/xtradb/row/row0ins.c
        storage/xtradb/row/row0merge.c
        storage/xtradb/row/row0sel.c
        storage/xtradb/srv/srv0srv.c
        storage/xtradb/srv/srv0start.c

=== modified file 'mysql-test/r/information_schema.result'
--- a/mysql-test/r/information_schema.result	2010-03-10 09:12:23 +0000
+++ b/mysql-test/r/information_schema.result	2010-04-28 14:35:00 +0000
@@ -65,6 +65,8 @@ INNODB_INDEX_STATS
 INNODB_LOCKS
 INNODB_LOCK_WAITS
 INNODB_RSEG
+INNODB_SYS_INDEXES
+INNODB_SYS_TABLES
 INNODB_TABLE_STATS
 INNODB_TRX
 KEY_COLUMN_USAGE

=== modified file 'mysql-test/r/information_schema_all_engines.result'
--- a/mysql-test/r/information_schema_all_engines.result	2010-01-15 15:58:25 +0000
+++ b/mysql-test/r/information_schema_all_engines.result	2010-04-28 14:35:00 +0000
@@ -37,12 +37,14 @@ XTRADB_ENHANCEMENTS
 INNODB_BUFFER_POOL_PAGES_INDEX
 XTRADB_ADMIN_COMMAND
 INNODB_TRX
-INNODB_CMP_RESET
+INNODB_SYS_TABLES
 INNODB_LOCK_WAITS
 INNODB_CMPMEM_RESET
 INNODB_LOCKS
 INNODB_CMPMEM
 INNODB_TABLE_STATS
+INNODB_SYS_INDEXES
+INNODB_CMP_RESET
 INNODB_BUFFER_POOL_PAGES_BLOB
 INNODB_INDEX_STATS
 SELECT t.table_name, c1.column_name
@@ -96,14 +98,16 @@ XTRADB_ENHANCEMENTS	name
 INNODB_BUFFER_POOL_PAGES_INDEX	schema_name
 XTRADB_ADMIN_COMMAND	result_message
 INNODB_TRX	trx_id
-INNODB_CMP_RESET	page_size
+INNODB_SYS_TABLES	NAME
 INNODB_LOCK_WAITS	requesting_trx_id
 INNODB_CMPMEM_RESET	page_size
 INNODB_LOCKS	lock_id
 INNODB_CMPMEM	page_size
-INNODB_TABLE_STATS	table_name
+INNODB_TABLE_STATS	table_schema
+INNODB_SYS_INDEXES	TABLE_ID
+INNODB_CMP_RESET	page_size
 INNODB_BUFFER_POOL_PAGES_BLOB	space_id
-INNODB_INDEX_STATS	table_name
+INNODB_INDEX_STATS	table_schema
 SELECT t.table_name, c1.column_name
 FROM information_schema.tables t
 INNER JOIN
@@ -155,14 +159,16 @@ XTRADB_ENHANCEMENTS	name
 INNODB_BUFFER_POOL_PAGES_INDEX	schema_name
 XTRADB_ADMIN_COMMAND	result_message
 INNODB_TRX	trx_id
-INNODB_CMP_RESET	page_size
+INNODB_SYS_TABLES	NAME
 INNODB_LOCK_WAITS	requesting_trx_id
 INNODB_CMPMEM_RESET	page_size
 INNODB_LOCKS	lock_id
 INNODB_CMPMEM	page_size
-INNODB_TABLE_STATS	table_name
+INNODB_TABLE_STATS	table_schema
+INNODB_SYS_INDEXES	TABLE_ID
+INNODB_CMP_RESET	page_size
 INNODB_BUFFER_POOL_PAGES_BLOB	space_id
-INNODB_INDEX_STATS	table_name
+INNODB_INDEX_STATS	table_schema
 select 1 as f1 from information_schema.tables  where "CHARACTER_SETS"=
 (select cast(table_name as char)  from information_schema.tables
 order by table_name limit 1) limit 1;
@@ -205,6 +211,8 @@ INNODB_INDEX_STATS	information_schema.IN
 INNODB_LOCKS	information_schema.INNODB_LOCKS	1
 INNODB_LOCK_WAITS	information_schema.INNODB_LOCK_WAITS	1
 INNODB_RSEG	information_schema.INNODB_RSEG	1
+INNODB_SYS_INDEXES	information_schema.INNODB_SYS_INDEXES	1
+INNODB_SYS_TABLES	information_schema.INNODB_SYS_TABLES	1
 INNODB_TABLE_STATS	information_schema.INNODB_TABLE_STATS	1
 INNODB_TRX	information_schema.INNODB_TRX	1
 KEY_COLUMN_USAGE	information_schema.KEY_COLUMN_USAGE	1
@@ -267,12 +275,14 @@ Database: information_schema
 | INNODB_BUFFER_POOL_PAGES_INDEX        |
 | XTRADB_ADMIN_COMMAND                  |
 | INNODB_TRX                            |
-| INNODB_CMP_RESET                      |
+| INNODB_SYS_TABLES                     |
 | INNODB_LOCK_WAITS                     |
 | INNODB_CMPMEM_RESET                   |
 | INNODB_LOCKS                          |
 | INNODB_CMPMEM                         |
 | INNODB_TABLE_STATS                    |
+| INNODB_SYS_INDEXES                    |
+| INNODB_CMP_RESET                      |
 | INNODB_BUFFER_POOL_PAGES_BLOB         |
 | INNODB_INDEX_STATS                    |
 +---------------------------------------+
@@ -316,12 +326,14 @@ Database: INFORMATION_SCHEMA
 | INNODB_BUFFER_POOL_PAGES_INDEX        |
 | XTRADB_ADMIN_COMMAND                  |
 | INNODB_TRX                            |
-| INNODB_CMP_RESET                      |
+| INNODB_SYS_TABLES                     |
 | INNODB_LOCK_WAITS                     |
 | INNODB_CMPMEM_RESET                   |
 | INNODB_LOCKS                          |
 | INNODB_CMPMEM                         |
 | INNODB_TABLE_STATS                    |
+| INNODB_SYS_INDEXES                    |
+| INNODB_CMP_RESET                      |
 | INNODB_BUFFER_POOL_PAGES_BLOB         |
 | INNODB_INDEX_STATS                    |
 +---------------------------------------+
@@ -333,5 +345,5 @@ Wildcard: inf_rmation_schema
 +--------------------+
 SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') AND table_name<>'ndb_binlog_index' AND table_name<>'ndb_apply_status' GROUP BY TABLE_SCHEMA;
 table_schema	count(*)
-information_schema	44
+information_schema	46
 mysql	22

=== modified file 'storage/xtradb/btr/btr0btr.c'
--- a/storage/xtradb/btr/btr0btr.c	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/btr/btr0btr.c	2010-03-22 20:42:52 +0000
@@ -137,6 +137,12 @@ btr_root_block_get(
 	root_page_no = dict_index_get_page(index);
 
 	block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
+
+	if (srv_pass_corrupt_table && !block) {
+		return(0);
+	}
+	ut_a(block);
+
 	ut_a((ibool)!!page_is_comp(buf_block_get_frame(block))
 	     == dict_table_is_comp(index->table));
 #ifdef UNIV_BTR_DEBUG
@@ -422,6 +428,12 @@ btr_get_size(
 
 	root = btr_root_get(index, &mtr);
 
+	if (srv_pass_corrupt_table && !root) {
+		mtr_commit(&mtr);
+		return(0);
+	}
+	ut_a(root);
+
 	if (flag == BTR_N_LEAF_PAGES) {
 		seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
 
@@ -862,6 +874,13 @@ leaf_loop:
 	mtr_start(&mtr);
 
 	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
+
+	if (srv_pass_corrupt_table && !root) {
+		mtr_commit(&mtr);
+		return;
+	}
+	ut_a(root);
+	
 #ifdef UNIV_BTR_DEBUG
 	ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
 				    + root, space));
@@ -884,6 +903,12 @@ top_loop:
 	mtr_start(&mtr);
 
 	root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
+
+	if (srv_pass_corrupt_table && !root) {
+		mtr_commit(&mtr);
+		return;
+	}
+	ut_a(root);
 #ifdef UNIV_BTR_DEBUG
 	ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
 				    + root, space));
@@ -917,6 +942,11 @@ btr_free_root(
 
 	block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
 
+	if (srv_pass_corrupt_table && !block) {
+		return;
+	}
+	ut_a(block);
+
 	btr_search_drop_page_hash_index(block);
 
 	header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;

=== modified file 'storage/xtradb/btr/btr0cur.c'
--- a/storage/xtradb/btr/btr0cur.c	2010-03-10 10:32:14 +0000
+++ b/storage/xtradb/btr/btr0cur.c	2010-04-28 14:35:00 +0000
@@ -227,6 +227,11 @@ btr_cur_latch_leaves(
 	case BTR_MODIFY_LEAF:
 		mode = latch_mode == BTR_SEARCH_LEAF ? RW_S_LATCH : RW_X_LATCH;
 		get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
+
+		if (srv_pass_corrupt_table && !get_block) {
+			return;
+		}
+		ut_a(get_block);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
 #endif /* UNIV_BTR_DEBUG */
@@ -240,6 +245,11 @@ btr_cur_latch_leaves(
 			get_block = btr_block_get(space, zip_size,
 						  left_page_no,
 						  RW_X_LATCH, mtr);
+
+			if (srv_pass_corrupt_table && !get_block) {
+				return;
+			}
+			ut_a(get_block);
 #ifdef UNIV_BTR_DEBUG
 			ut_a(page_is_comp(get_block->frame)
 			     == page_is_comp(page));
@@ -251,6 +261,11 @@ btr_cur_latch_leaves(
 
 		get_block = btr_block_get(space, zip_size, page_no,
 					  RW_X_LATCH, mtr);
+
+		if (srv_pass_corrupt_table && !get_block) {
+			return;
+		}
+		ut_a(get_block);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
 #endif /* UNIV_BTR_DEBUG */
@@ -262,6 +277,11 @@ btr_cur_latch_leaves(
 			get_block = btr_block_get(space, zip_size,
 						  right_page_no,
 						  RW_X_LATCH, mtr);
+
+			if (srv_pass_corrupt_table && !get_block) {
+				return;
+			}
+			ut_a(get_block);
 #ifdef UNIV_BTR_DEBUG
 			ut_a(page_is_comp(get_block->frame)
 			     == page_is_comp(page));
@@ -283,6 +303,11 @@ btr_cur_latch_leaves(
 			get_block = btr_block_get(space, zip_size,
 						  left_page_no, mode, mtr);
 			cursor->left_block = get_block;
+
+			if (srv_pass_corrupt_table && !get_block) {
+				return;
+			}
+			ut_a(get_block);
 #ifdef UNIV_BTR_DEBUG
 			ut_a(page_is_comp(get_block->frame)
 			     == page_is_comp(page));
@@ -293,6 +318,11 @@ btr_cur_latch_leaves(
 		}
 
 		get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
+
+		if (srv_pass_corrupt_table && !get_block) {
+			return;
+		}
+		ut_a(get_block);
 #ifdef UNIV_BTR_DEBUG
 		ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
 #endif /* UNIV_BTR_DEBUG */
@@ -522,6 +552,16 @@ retry_page_get:
 					 rw_latch, guess, buf_mode,
 					 __FILE__, __LINE__, mtr);
 		if (block == NULL) {
+			if (srv_pass_corrupt_table && buf_mode != BUF_GET_IF_IN_POOL) {
+				page_cursor->block = 0;
+				page_cursor->rec = 0;
+				if (estimate) {
+					cursor->path_arr->nth_rec = ULINT_UNDEFINED;
+				}
+				break;
+			}
+			ut_a(buf_mode == BUF_GET_IF_IN_POOL);
+
 			/* This must be a search to perform an insert;
 			try insert to the insert buffer */
 
@@ -549,6 +589,16 @@ retry_page_get:
 
 		page = buf_block_get_frame(block);
 
+		if (srv_pass_corrupt_table && !page) {
+			page_cursor->block = 0;
+			page_cursor->rec = 0;
+			if (estimate) {
+				cursor->path_arr->nth_rec = ULINT_UNDEFINED;
+			}
+			break;
+		}
+		ut_a(page);
+
 		block->check_index_page_at_flush = TRUE;
 
 		if (rw_latch != RW_NO_LATCH) {
@@ -730,6 +780,17 @@ btr_cur_open_at_index_side(
 					 RW_NO_LATCH, NULL, BUF_GET,
 					 __FILE__, __LINE__, mtr);
 		page = buf_block_get_frame(block);
+
+		if (srv_pass_corrupt_table && !page) {
+			page_cursor->block = 0;
+			page_cursor->rec = 0;
+			if (estimate) {
+				cursor->path_arr->nth_rec = ULINT_UNDEFINED;
+			}
+			break;
+		}
+		ut_a(page);
+
 		ut_ad(0 == ut_dulint_cmp(index->id,
 					 btr_page_get_index_id(page)));
 
@@ -849,6 +910,14 @@ btr_cur_open_at_rnd_pos(
 					 RW_NO_LATCH, NULL, BUF_GET,
 					 __FILE__, __LINE__, mtr);
 		page = buf_block_get_frame(block);
+
+		if (srv_pass_corrupt_table && !page) {
+			page_cursor->block = 0;
+			page_cursor->rec = 0;
+			break;
+		}
+		ut_a(page);
+
 		ut_ad(0 == ut_dulint_cmp(index->id,
 					 btr_page_get_index_id(page)));
 
@@ -886,6 +955,108 @@ btr_cur_open_at_rnd_pos(
 	}
 }
 
+/**********************************************************************//**
+Positions a cursor at a randomly chosen position within a B-tree
+after the given path
+@return TRUE if the position is at the first page, and cursor must point
+        the first record for used by the caller.*/
+UNIV_INTERN
+ibool
+btr_cur_open_at_rnd_pos_after_path(
+/*====================*/
+	dict_index_t*	index,		/*!< in: index */
+	ulint		latch_mode,	/*!< in: BTR_SEARCH_LEAF, ... */
+	btr_path_t*	first_rec_path,
+	btr_cur_t*	cursor,		/*!< in/out: B-tree cursor */
+	mtr_t*		mtr)		/*!< in: mtr */
+{
+	page_cur_t*	page_cursor;
+	btr_path_t*	slot;
+	ibool		is_first_rec	= TRUE;
+	ulint		page_no;
+	ulint		space;
+	ulint		zip_size;
+	ulint		height;
+	rec_t*		node_ptr;
+	mem_heap_t*	heap		= NULL;
+	ulint		offsets_[REC_OFFS_NORMAL_SIZE];
+	ulint*		offsets		= offsets_;
+	rec_offs_init(offsets_);
+
+	if (latch_mode == BTR_MODIFY_TREE) {
+		mtr_x_lock(dict_index_get_lock(index), mtr);
+	} else {
+		mtr_s_lock(dict_index_get_lock(index), mtr);
+	}
+
+	page_cursor = btr_cur_get_page_cur(cursor);
+	cursor->index = index;
+
+	space = dict_index_get_space(index);
+	zip_size = dict_table_zip_size(index->table);
+	page_no = dict_index_get_page(index);
+
+	height = ULINT_UNDEFINED;
+	slot = first_rec_path;
+
+	for (;;) {
+		buf_block_t*	block;
+		page_t*		page;
+
+		block = buf_page_get_gen(space, zip_size, page_no,
+					 RW_NO_LATCH, NULL, BUF_GET,
+					 __FILE__, __LINE__, mtr);
+		page = buf_block_get_frame(block);
+		ut_ad(0 == ut_dulint_cmp(index->id,
+					 btr_page_get_index_id(page)));
+
+		if (height == ULINT_UNDEFINED) {
+			/* We are in the root node */
+
+			height = btr_page_get_level(page, mtr);
+		}
+
+		if (height == 0) {
+			btr_cur_latch_leaves(page, space, zip_size, page_no,
+					     latch_mode, cursor, mtr);
+		}
+
+		if (is_first_rec && slot->nth_rec != ULINT_UNDEFINED) {
+			if (height == 0) {
+				/* must open the first rec */
+				page_cur_open_on_nth_user_rec(block, page_cursor, slot->nth_rec);
+			} else {
+				is_first_rec = page_cur_open_on_rnd_user_rec_after_nth(block,
+								page_cursor, slot->nth_rec);
+			}
+		} else {
+			is_first_rec = FALSE;
+			page_cur_open_on_rnd_user_rec(block, page_cursor);
+		}
+
+		if (height == 0) {
+			break;
+		}
+
+		ut_ad(height > 0);
+
+		height--;
+		slot++;
+
+		node_ptr = page_cur_get_rec(page_cursor);
+		offsets = rec_get_offsets(node_ptr, cursor->index, offsets,
+					  ULINT_UNDEFINED, &heap);
+		/* Go to the child node */
+		page_no = btr_node_ptr_get_child_page_no(node_ptr, offsets);
+	}
+
+	if (UNIV_LIKELY_NULL(heap)) {
+		mem_heap_free(heap);
+	}
+
+	return (is_first_rec);
+}
+
 /*==================== B-TREE INSERT =========================*/
 
 /*************************************************************//**
@@ -1064,6 +1235,12 @@ btr_cur_optimistic_insert(
 	*big_rec = NULL;
 
 	block = btr_cur_get_block(cursor);
+
+	if (srv_pass_corrupt_table && !block) {
+		return(DB_CORRUPTION);
+	}
+	ut_a(block);
+
 	page = buf_block_get_frame(block);
 	index = cursor->index;
 	zip_size = buf_block_get_zip_size(block);
@@ -2810,6 +2987,11 @@ btr_cur_optimistic_delete(
 
 	block = btr_cur_get_block(cursor);
 
+	if (srv_pass_corrupt_table && !block) {
+		return(DB_CORRUPTION);
+	}
+	ut_a(block);
+
 	ut_ad(page_is_leaf(buf_block_get_frame(block)));
 
 	rec = btr_cur_get_rec(cursor);
@@ -3216,6 +3398,154 @@ btr_estimate_n_rows_in_range(
 }
 
 /*******************************************************************//**
+Estimates the number of pages which have not null value of the key of n_cols.
+@return	estimated number of pages */
+UNIV_INTERN
+ulint
+btr_estimate_n_pages_not_null(
+/*=========================*/
+	dict_index_t*	index,	/*!< in: index */
+	ulint		n_cols,	/*!< in: The cols should be not null */
+	btr_path_t*	path1)	/*!< in: path1[BTR_PATH_ARRAY_N_SLOTS] */
+{
+	dtuple_t*	tuple1;
+	btr_path_t	path2[BTR_PATH_ARRAY_N_SLOTS];
+	btr_cur_t	cursor;
+	btr_path_t*	slot1;
+	btr_path_t*	slot2;
+	ibool		diverged;
+	ibool		diverged_lot;
+	ulint		divergence_level;
+	ulint		n_pages;
+	ulint		i,j;
+	mtr_t		mtr;
+	mem_heap_t*	heap;
+
+	heap = mem_heap_create(n_cols * sizeof(dfield_t)
+				+ sizeof(dtuple_t));
+
+	/* make tuple1 (NULL,NULL,,,) from n_cols */
+	tuple1 = dtuple_create(heap, n_cols);
+	dict_index_copy_types(tuple1, index, n_cols);
+
+	for (i = 0; i < n_cols; i++) {
+		dfield_set_null(dtuple_get_nth_field(tuple1, i));
+	}
+
+	mtr_start(&mtr);
+
+	cursor.path_arr = path1;
+
+	btr_cur_search_to_nth_level(index, 0, tuple1, PAGE_CUR_G,
+				    BTR_SEARCH_LEAF | BTR_ESTIMATE,
+				    &cursor, 0, &mtr);
+
+	mtr_commit(&mtr);
+
+
+
+	mtr_start(&mtr);
+
+	cursor.path_arr = path2;
+
+	btr_cur_open_at_index_side(FALSE, index,
+				   BTR_SEARCH_LEAF | BTR_ESTIMATE,
+				   &cursor, &mtr);
+
+	mtr_commit(&mtr);
+
+	mem_heap_free(heap);
+
+	/* We have the path information for the range in path1 and path2 */
+
+	n_pages = 1;
+	diverged = FALSE;	    /* This becomes true when the path is not
+				    the same any more */
+	diverged_lot = FALSE;	    /* This becomes true when the paths are
+				    not the same or adjacent any more */
+	divergence_level = 1000000; /* This is the level where paths diverged
+				    a lot */
+	for (i = 0; ; i++) {
+		ut_ad(i < BTR_PATH_ARRAY_N_SLOTS);
+
+		slot1 = path1 + i;
+		slot2 = path2 + i;
+
+		if ((slot1 + 1)->nth_rec == ULINT_UNDEFINED
+		    || (slot2 + 1)->nth_rec == ULINT_UNDEFINED) {
+
+			if (i > divergence_level + 1) {
+				/* In trees whose height is > 1 our algorithm
+				tends to underestimate: multiply the estimate
+				by 2: */
+
+				n_pages = n_pages * 2;
+			}
+
+			/* Do not estimate the number of rows in the range
+			to over 1 / 2 of the estimated rows in the whole
+			table */
+
+			if (n_pages > index->stat_n_leaf_pages / 2) {
+				n_pages = index->stat_n_leaf_pages / 2;
+
+				/* If there are just 0 or 1 rows in the table,
+				then we estimate all rows are in the range */
+
+				if (n_pages == 0) {
+					n_pages = index->stat_n_leaf_pages;
+				}
+			}
+
+			return(n_pages);
+		}
+
+		if (!diverged && slot1->nth_rec != slot2->nth_rec) {
+
+			diverged = TRUE;
+
+			if (slot1->nth_rec < slot2->nth_rec) {
+				n_pages = slot2->nth_rec - slot1->nth_rec;
+
+				if (n_pages > 1) {
+					diverged_lot = TRUE;
+					divergence_level = i;
+				}
+			} else {
+				/* Maybe the tree has changed between
+				searches */
+
+				return(10);
+			}
+
+		} else if (diverged && !diverged_lot) {
+
+			if (slot1->nth_rec < slot1->n_recs
+			    || slot2->nth_rec > 1) {
+
+				diverged_lot = TRUE;
+				divergence_level = i;
+
+				n_pages = 0;
+
+				if (slot1->nth_rec < slot1->n_recs) {
+					n_pages += slot1->n_recs
+						- slot1->nth_rec;
+				}
+
+				if (slot2->nth_rec > 1) {
+					n_pages += slot2->nth_rec - 1;
+				}
+			}
+		} else if (diverged_lot) {
+
+			n_pages = (n_pages * (slot1->n_recs + slot2->n_recs))
+				/ 2;
+		}
+	}
+}
+
+/*******************************************************************//**
 Estimates the number of different key values in a given index, for
 each n-column prefix of the index where n <= dict_index_get_n_unique(index).
 The estimates are stored in the array index->stat_n_diff_key_vals. */
@@ -3231,9 +3561,7 @@ btr_estimate_number_of_different_key_val
 	ulint		n_cols;
 	ulint		matched_fields;
 	ulint		matched_bytes;
-	ib_int64_t	n_recs	= 0;
 	ib_int64_t*	n_diff;
-	ib_int64_t*	n_not_nulls= 0;
 	ullint		n_sample_pages; /* number of pages to sample */
 	ulint		not_empty_flag	= 0;
 	ulint		total_external_size = 0;
@@ -3247,22 +3575,37 @@ btr_estimate_number_of_different_key_val
 	ulint*		offsets_rec	= offsets_rec_;
 	ulint*		offsets_next_rec= offsets_next_rec_;
 	ulint		stats_method	= srv_stats_method;
+	btr_path_t	first_rec_path[BTR_PATH_ARRAY_N_SLOTS];
+	ulint		effective_pages; /* effective leaf pages */
 	rec_offs_init(offsets_rec_);
 	rec_offs_init(offsets_next_rec_);
 
 	n_cols = dict_index_get_n_unique(index);
 
-	n_diff = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
-
 	if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
-		n_not_nulls = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
+		/* estimate effective pages and path for the first effective record */
+		/* TODO: make it work also for n_cols > 1. */
+		effective_pages = btr_estimate_n_pages_not_null(index, 1 /*k*/, first_rec_path);
+
+		if (!effective_pages) {
+			for (j = 0; j <= n_cols; j++) {
+				index->stat_n_diff_key_vals[j] = (ib_int64_t)index->stat_n_leaf_pages;
+			}
+			return;
+		} else if (effective_pages > index->stat_n_leaf_pages) {
+			effective_pages = index->stat_n_leaf_pages;
+		}
+	} else {
+		effective_pages = index->stat_n_leaf_pages;
 	}
 
+	n_diff = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
+
 	/* It makes no sense to test more pages than are contained
 	in the index, thus we lower the number if it is too high */
-	if (srv_stats_sample_pages > index->stat_index_size) {
-		if (index->stat_index_size > 0) {
-			n_sample_pages = index->stat_index_size;
+	if (srv_stats_sample_pages > effective_pages) {
+		if (effective_pages > 0) {
+			n_sample_pages = effective_pages;
 		} else {
 			n_sample_pages = 1;
 		}
@@ -3274,9 +3617,15 @@ btr_estimate_number_of_different_key_val
 
 	for (i = 0; i < n_sample_pages; i++) {
 		rec_t*	supremum;
+		ibool	is_first_page = TRUE;
 		mtr_start(&mtr);
 
+		if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
+			is_first_page = btr_cur_open_at_rnd_pos_after_path(index, BTR_SEARCH_LEAF,
+									first_rec_path, &cursor, &mtr);
+		} else {
 		btr_cur_open_at_rnd_pos(index, BTR_SEARCH_LEAF, &cursor, &mtr);
+		}
 
 		/* Count the number of different key values for each prefix of
 		the key on this index page. If the prefix does not determine
@@ -3286,8 +3635,19 @@ btr_estimate_number_of_different_key_val
 
 		page = btr_cur_get_page(&cursor);
 
+		if (srv_pass_corrupt_table && !page) {
+			break;
+		}
+		ut_a(page);
+
 		supremum = page_get_supremum_rec(page);
+		if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS && is_first_page) {
+			/* the cursor should be the first record of the page. */
+			/* Counting should be started from here. */
+			rec = btr_cur_get_rec(&cursor);
+		} else {
 		rec = page_rec_get_next(page_get_infimum_rec(page));
+		}
 
 		if (rec != supremum) {
 			not_empty_flag = 1;
@@ -3297,19 +3657,6 @@ btr_estimate_number_of_different_key_val
 
 		while (rec != supremum) {
 			rec_t*  next_rec;
-			/* count recs */
-			if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
-				n_recs++;
-				for (j = 0; j <= n_cols; j++) {
-					ulint	f_len;
-					rec_get_nth_field(rec, offsets_rec,
-							  j, &f_len);
-					if (f_len == UNIV_SQL_NULL)
-						break;
-
-					n_not_nulls[j]++;
-				}
-			}
 			next_rec = page_rec_get_next(rec);
 			if (next_rec == supremum) {
 				break;
@@ -3324,7 +3671,10 @@ btr_estimate_number_of_different_key_val
 			cmp_rec_rec_with_match(rec, next_rec,
 					       offsets_rec, offsets_next_rec,
 					       index, &matched_fields,
-					       &matched_bytes, srv_stats_method);
+					       &matched_bytes,
+				(stats_method==SRV_STATS_METHOD_NULLS_NOT_EQUAL) ?
+				SRV_STATS_METHOD_NULLS_NOT_EQUAL :
+				SRV_STATS_METHOD_NULLS_EQUAL);
 
 			for (j = matched_fields + 1; j <= n_cols; j++) {
 				/* We add one if this index record has
@@ -3385,7 +3735,7 @@ btr_estimate_number_of_different_key_val
 	for (j = 0; j <= n_cols; j++) {
 		index->stat_n_diff_key_vals[j]
 			= ((n_diff[j]
-			    * (ib_int64_t)index->stat_n_leaf_pages
+			    * (ib_int64_t)effective_pages
 			    + n_sample_pages - 1
 			    + total_external_size
 			    + not_empty_flag)
@@ -3400,7 +3750,7 @@ btr_estimate_number_of_different_key_val
 		different key values, or even more. Let us try to approximate
 		that: */
 
-		add_on = index->stat_n_leaf_pages
+		add_on = effective_pages
 			/ (10 * (n_sample_pages
 				 + total_external_size));
 
@@ -3410,20 +3760,18 @@ btr_estimate_number_of_different_key_val
 
 		index->stat_n_diff_key_vals[j] += add_on;
 
-		/* revision for 'nulls_ignored' */
 		if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
-			if (!n_not_nulls[j])
-				n_not_nulls[j] = 1;
+			/* index->stat_n_diff_key_vals[k] is used for calc rec_per_key,
+			as "stats.records / index->stat_n_diff_key_vals[x]".
+			So it should be adjusted to the value which is based on whole of the index. */
 			index->stat_n_diff_key_vals[j] =
-				index->stat_n_diff_key_vals[j] * n_recs
-					/ n_not_nulls[j];
+				index->stat_n_diff_key_vals[j] * (ib_int64_t)index->stat_n_leaf_pages
+					/ (ib_int64_t)effective_pages;
 		}
 	}
 
 	mem_free(n_diff);
-	if (stats_method == SRV_STATS_METHOD_IGNORE_NULLS) {
-		mem_free(n_not_nulls);
-	}
+
 	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}

=== modified file 'storage/xtradb/btr/btr0pcur.c'
--- a/storage/xtradb/btr/btr0pcur.c	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/btr/btr0pcur.c	2010-03-22 20:42:52 +0000
@@ -32,7 +32,7 @@ Created 2/23/1996 Heikki Tuuri
 #include "ut0byte.h"
 #include "rem0cmp.h"
 #include "trx0trx.h"
-
+#include "srv0srv.h"
 /**************************************************************//**
 Allocates memory for a persistent cursor object and initializes the cursor.
 @return	own: persistent cursor */
@@ -102,6 +102,12 @@ btr_pcur_store_position(
 	ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
 
 	block = btr_pcur_get_block(cursor);
+
+	if (srv_pass_corrupt_table && !block) {
+		return;
+	}
+	ut_a(block);
+
 	index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
 
 	page_cursor = btr_pcur_get_page_cur(cursor);
@@ -413,6 +419,15 @@ btr_pcur_move_to_next_page(
 	next_block = btr_block_get(space, zip_size, next_page_no,
 				   cursor->latch_mode, mtr);
 	next_page = buf_block_get_frame(next_block);
+
+	if (srv_pass_corrupt_table && !next_page) {
+		btr_leaf_page_release(btr_pcur_get_block(cursor),
+				      cursor->latch_mode, mtr);
+		btr_pcur_get_page_cur(cursor)->block = 0;
+		btr_pcur_get_page_cur(cursor)->rec = 0;
+		return;
+	}
+	ut_a(next_page);
 #ifdef UNIV_BTR_DEBUG
 	ut_a(page_is_comp(next_page) == page_is_comp(page));
 	ut_a(btr_page_get_prev(next_page, mtr)

=== modified file 'storage/xtradb/btr/btr0sea.c'
--- a/storage/xtradb/btr/btr0sea.c	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/btr/btr0sea.c	2010-03-22 20:42:52 +0000
@@ -42,7 +42,7 @@ Created 2/17/1996 Heikki Tuuri
 #include "btr0pcur.h"
 #include "btr0btr.h"
 #include "ha0ha.h"
-
+#include "srv0srv.h"
 /** Flag: has the search system been enabled?
 Protected by btr_search_latch and btr_search_enabled_mutex. */
 UNIV_INTERN char		btr_search_enabled	= TRUE;
@@ -585,6 +585,11 @@ btr_search_info_update_slow(
 
 	block = btr_cur_get_block(cursor);
 
+	if (srv_pass_corrupt_table && !block) {
+		return;
+	}
+	ut_a(block);
+
 	/* NOTE that the following two function calls do NOT protect
 	info or block->n_fields etc. with any semaphore, to save CPU time!
 	We cannot assume the fields are consistent when we return from

=== modified file 'storage/xtradb/buf/buf0buddy.c'
--- a/storage/xtradb/buf/buf0buddy.c	2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/buf/buf0buddy.c	2010-04-28 14:35:00 +0000
@@ -43,7 +43,7 @@ static ulint buf_buddy_n_frames;
 #endif /* UNIV_DEBUG */
 /** Statistics of the buddy system, indexed by block size.
 Protected by buf_pool_mutex. */
-UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
+UNIV_INTERN buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES_MAX + 1];
 
 /**********************************************************************//**
 Get the offset of the buddy of a compressed page frame.

=== modified file 'storage/xtradb/buf/buf0buf.c'
--- a/storage/xtradb/buf/buf0buf.c	2010-01-28 11:35:10 +0000
+++ b/storage/xtradb/buf/buf0buf.c	2010-04-28 14:35:00 +0000
@@ -52,6 +52,7 @@ Created 11/5/1995 Heikki Tuuri
 #include "log0recv.h"
 #include "page0zip.h"
 #include "trx0trx.h"
+#include "srv0start.h"
 
 /* prototypes for new functions added to ha_innodb.cc */
 trx_t* innobase_get_trx();
@@ -348,6 +349,27 @@ buf_calc_page_new_checksum(
 	return(checksum);
 }
 
+UNIV_INTERN
+ulint
+buf_calc_page_new_checksum_32(
+/*==========================*/
+	const byte*	page)	/*!< in: buffer page */
+{
+	ulint checksum;
+
+	checksum = ut_fold_binary(page + FIL_PAGE_OFFSET,
+				  FIL_PAGE_FILE_FLUSH_LSN - FIL_PAGE_OFFSET)
+		+ ut_fold_binary(page + FIL_PAGE_DATA,
+				 FIL_PAGE_DATA_ALIGN_32 - FIL_PAGE_DATA)
+		+ ut_fold_binary_32(page + FIL_PAGE_DATA_ALIGN_32,
+				    UNIV_PAGE_SIZE - FIL_PAGE_DATA_ALIGN_32
+				    - FIL_PAGE_END_LSN_OLD_CHKSUM);
+
+	checksum = checksum & 0xFFFFFFFFUL;
+
+	return(checksum);
+}
+
 /********************************************************************//**
 In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
 looked at the first few bytes of the page. This calculates that old
@@ -462,13 +484,25 @@ buf_page_is_corrupted(
 		/* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
 		(always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
 
-		if (checksum_field != 0
+		if (!srv_fast_checksum
+		    && checksum_field != 0
 		    && checksum_field != BUF_NO_CHECKSUM_MAGIC
 		    && checksum_field
 		    != buf_calc_page_new_checksum(read_buf)) {
 
 			return(TRUE);
 		}
+
+		if (srv_fast_checksum
+		    && checksum_field != 0
+		    && checksum_field != BUF_NO_CHECKSUM_MAGIC
+		    && checksum_field
+		    != buf_calc_page_new_checksum_32(read_buf)
+		    && checksum_field
+		    != buf_calc_page_new_checksum(read_buf)) {
+
+			return(TRUE);
+		}
 	}
 
 	return(FALSE);
@@ -488,6 +522,7 @@ buf_page_print(
 	dict_index_t*	index;
 #endif /* !UNIV_HOTBACKUP */
 	ulint		checksum;
+	ulint		checksum_32;
 	ulint		old_checksum;
 	ulint		size	= zip_size;
 
@@ -574,12 +609,14 @@ buf_page_print(
 
 	checksum = srv_use_checksums
 		? buf_calc_page_new_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
+	checksum_32 = srv_use_checksums
+		? buf_calc_page_new_checksum_32(read_buf) : BUF_NO_CHECKSUM_MAGIC;
 	old_checksum = srv_use_checksums
 		? buf_calc_page_old_checksum(read_buf) : BUF_NO_CHECKSUM_MAGIC;
 
 	ut_print_timestamp(stderr);
 	fprintf(stderr,
-		"  InnoDB: Page checksum %lu, prior-to-4.0.14-form"
+		"  InnoDB: Page checksum %lu (32bit_calc: %lu), prior-to-4.0.14-form"
 		" checksum %lu\n"
 		"InnoDB: stored checksum %lu, prior-to-4.0.14-form"
 		" stored checksum %lu\n"
@@ -588,7 +625,7 @@ buf_page_print(
 		"InnoDB: Page number (if stored to page already) %lu,\n"
 		"InnoDB: space id (if created with >= MySQL-4.1.1"
 		" and stored already) %lu\n",
-		(ulong) checksum, (ulong) old_checksum,
+		(ulong) checksum, (ulong) checksum_32, (ulong) old_checksum,
 		(ulong) mach_read_from_4(read_buf + FIL_PAGE_SPACE_OR_CHKSUM),
 		(ulong) mach_read_from_4(read_buf + UNIV_PAGE_SIZE
 					 - FIL_PAGE_END_LSN_OLD_CHKSUM),
@@ -1809,6 +1846,14 @@ err_exit:
 		return(NULL);
 	}
 
+	if (srv_pass_corrupt_table) {
+		if (bpage->is_corrupt) {
+			rw_lock_s_unlock(&page_hash_latch);
+			return(NULL);
+		}
+	}
+	ut_a(!(bpage->is_corrupt));
+
 	block_mutex = buf_page_get_mutex_enter(bpage);
 
 	rw_lock_s_unlock(&page_hash_latch);
@@ -2246,6 +2291,14 @@ loop2:
 		return(NULL);
 	}
 
+	if (srv_pass_corrupt_table) {
+		if (block->page.is_corrupt) {
+			mutex_exit(block_mutex);
+			return(NULL);
+		}
+	}
+	ut_a(!(block->page.is_corrupt));
+
 	switch (buf_block_get_state(block)) {
 		buf_page_t*	bpage;
 		ibool		success;
@@ -2874,6 +2927,7 @@ buf_page_init_low(
 	bpage->newest_modification = 0;
 	bpage->oldest_modification = 0;
 	HASH_INVALIDATE(bpage, hash);
+	bpage->is_corrupt = FALSE;
 #ifdef UNIV_DEBUG_FILE_ACCESSES
 	bpage->file_page_was_freed = FALSE;
 #endif /* UNIV_DEBUG_FILE_ACCESSES */
@@ -3329,7 +3383,8 @@ UNIV_INTERN
 void
 buf_page_io_complete(
 /*=================*/
-	buf_page_t*	bpage)	/*!< in: pointer to the block in question */
+	buf_page_t*	bpage,	/*!< in: pointer to the block in question */
+	trx_t*		trx)
 {
 	enum buf_io_fix	io_type;
 	const ibool	uncompressed = (buf_page_get_state(bpage)
@@ -3406,6 +3461,7 @@ buf_page_io_complete(
 				(ulong) bpage->offset);
 		}
 
+		if (!srv_pass_corrupt_table || !bpage->is_corrupt) {
 		/* From version 3.23.38 up we store the page checksum
 		to the 4 first bytes of the page end lsn field */
 
@@ -3447,6 +3503,19 @@ corrupt:
 			      REFMAN "forcing-recovery.html\n"
 			      "InnoDB: about forcing recovery.\n", stderr);
 
+			if (srv_pass_corrupt_table && bpage->space > 0
+			    && bpage->space < SRV_LOG_SPACE_FIRST_ID) {
+				fprintf(stderr,
+					"InnoDB: space %lu will be treated as corrupt.\n",
+					bpage->space);
+				fil_space_set_corrupt(bpage->space);
+				if (trx && trx->dict_operation_lock_mode == 0) {
+					dict_table_set_corrupt_by_space(bpage->space, TRUE);
+				} else {
+					dict_table_set_corrupt_by_space(bpage->space, FALSE);
+				}
+				bpage->is_corrupt = TRUE;
+			} else
 			if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
 				fputs("InnoDB: Ending processing because of"
 				      " a corrupt database page.\n",
@@ -3454,6 +3523,7 @@ corrupt:
 				exit(1);
 			}
 		}
+		} /**/
 
 		if (recv_recovery_is_on()) {
 			/* Pages must be uncompressed for crash recovery. */
@@ -3463,8 +3533,11 @@ corrupt:
 
 		if (uncompressed && !recv_no_ibuf_operations) {
 			ibuf_merge_or_delete_for_page(
+				/* Delete possible entries, if bpage is_corrupt */
+				(srv_pass_corrupt_table && bpage->is_corrupt) ? NULL :
 				(buf_block_t*) bpage, bpage->space,
 				bpage->offset, buf_page_get_zip_size(bpage),
+				(srv_pass_corrupt_table && bpage->is_corrupt) ? FALSE :
 				TRUE);
 		}
 	}

=== modified file 'storage/xtradb/buf/buf0flu.c'
--- a/storage/xtradb/buf/buf0flu.c	2010-04-28 13:53:04 +0000
+++ b/storage/xtradb/buf/buf0flu.c	2010-04-28 14:35:00 +0000
@@ -711,7 +711,9 @@ buf_flush_init_for_writing(
 
 	mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
 			srv_use_checksums
-			? buf_calc_page_new_checksum(page)
+			? (!srv_fast_checksum
+			   ? buf_calc_page_new_checksum(page)
+			   : buf_calc_page_new_checksum_32(page))
 			: BUF_NO_CHECKSUM_MAGIC);
 
 	/* We overwrite the first 4 bytes of the end lsn field to store

=== modified file 'storage/xtradb/buf/buf0rea.c'
--- a/storage/xtradb/buf/buf0rea.c	2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/buf/buf0rea.c	2010-04-28 14:35:00 +0000
@@ -187,12 +187,19 @@ not_to_recover:
 			      sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
 			      ((buf_block_t*) bpage)->frame, bpage, trx);
 	}
+
+	if (srv_pass_corrupt_table) {
+		if (*err != DB_SUCCESS) {
+			bpage->is_corrupt = TRUE;
+		}
+	} else {
 	ut_a(*err == DB_SUCCESS);
+	}
 
 	if (sync) {
 		/* The i/o is already completed when we arrive from
 		fil_read */
-		buf_page_io_complete(bpage);
+		buf_page_io_complete(bpage, trx);
 	}
 
 	return(1);

=== modified file 'storage/xtradb/build/debian/control'
--- a/storage/xtradb/build/debian/control	2010-02-22 19:53:53 +0000
+++ b/storage/xtradb/build/debian/control	2010-04-06 08:23:16 +0000
@@ -47,9 +47,9 @@ Package: percona-xtradb-common
 Section: database
 Architecture: all
 Depends: ${shlibs:Depends}, ${misc:Depends}
-Conflicts: mysql-common-4.1, mysql-common-5.0, mysql-common-5.1
-Provides: mysql-common-4.1, percona-xtradb-common
-Replaces: mysql-common-4.1, mysql-common-5.0, mysql-common-5.1
+Conflicts: mysql-common-4.1, mysql-common-5.0, mysql-common-5.1, mysql-common
+Provides: mysql-common
+Replaces: mysql-common-4.1, mysql-common-5.0, mysql-common-5.1, mysql-common
 Description: Percona SQL database common files (e.g. /etc/mysql/my.cnf)
  Percona SQL is a fast, stable and true multi-user, multi-threaded SQL database
  server. SQL (Structured Query Language) is the most popular database query

=== modified file 'storage/xtradb/build/debian/patches/60_percona_support.dpatch'
--- a/storage/xtradb/build/debian/patches/60_percona_support.dpatch	2010-01-26 18:02:46 +0000
+++ b/storage/xtradb/build/debian/patches/60_percona_support.dpatch	2010-03-25 12:25:33 +0000
@@ -4,12 +4,13 @@
 
 --- a/scripts/mysql_install_db.sh	2009-08-08 09:20:07.000000000 +0000
 +++ b/scripts/mysql_install_db.sh	2009-08-08 09:29:23.000000000 +0000
-@@ -471,7 +471,7 @@
+@@ -469,6 +469,9 @@
+   echo
    echo "Please report any problems with the $scriptdir/mysqlbug script!"
    echo
-   echo "The latest information about MySQL is available at http://www.mysql.com/";
--  echo "Support MySQL by buying support/licenses from http://shop.mysql.com/";
 +  echo "For commercial support please contact Percona at http://www.percona.com/contacts.html";
-   echo
++  echo
++
  fi
- 
+
+ exit 0

=== modified file 'storage/xtradb/build/debian/rules'
--- a/storage/xtradb/build/debian/rules	2010-02-18 23:51:40 +0000
+++ b/storage/xtradb/build/debian/rules	2010-03-29 15:30:32 +0000
@@ -20,7 +20,7 @@ DEB_NOEPOCH_VERSION ?= $(shell echo $(DE
 DEB_UPSTREAM_VERSION ?= $(shell echo $(DEB_NOEPOCH_VERSION) | sed 's/-[^-]*$$//')
 DEB_UPSTREAM_VERSION_MAJOR_MINOR := $(shell echo $(DEB_UPSTREAM_VERSION) | sed -r -n 's/^([0-9]+\.[0-9]+).*/\1/p')
 
-DISTRIBUTION = $(shell echo "Percona SQL Server (GPL), XtraDB $(BB_PERCONA_VERSION), Revision $(BB_PERCONA_REVISION)")
+DISTRIBUTION = $(shell echo "Percona SQL Server (GPL), XtraDB 10")
 
 MAKE_J = -j$(shell if [ -f /proc/cpuinfo ] ; then grep -c processor.* /proc/cpuinfo ; else echo 1 ; fi)
 ifeq (${MAKE_J}, -j0)

=== modified file 'storage/xtradb/build/percona-sql.spec'
--- a/storage/xtradb/build/percona-sql.spec	2010-02-18 18:47:04 +0000
+++ b/storage/xtradb/build/percona-sql.spec	2010-04-09 05:18:19 +0000
@@ -13,10 +13,13 @@
 # pluginversion	- Version of InnoDB plugin taken as the basis, e.g. 1.0.3
 # redhatversion	- 5 or 4
 # xtradbversion	- The XtraDB release, eg. 6
-# gotrevision		- bzr revision of the sources the package is built of
 
 %define mysql_vendor  Percona, Inc
-%{!?redhatversion:%define redhatversion 5}
+%define redhatversion %(cat /etc/redhat-release | awk '{ print $3}' | awk -F. '{ print $1}')
+%define community 1
+%define mysqlversion 5.1.45
+%define pluginversion 1.0.6
+%define xtradbversion 10
 %define distribution  rhel%{redhatversion}
 %define release       %{xtradbversion}.%{distribution}
 
@@ -106,8 +109,8 @@
 
 %define server_suffix  -51
 %define package_suffix -51
-%define ndbug_comment Percona SQL Server (GPL), XtraDB %{xtradbversion}, Revision %{gotrevision}
-%define debug_comment Percona SQL Server - Debug (GPL), XtraDB %{xtradbversion}, Revision %{gotrevision}
+%define ndbug_comment Percona SQL Server (GPL), XtraDB %{xtradbversion}
+%define debug_comment Percona SQL Server - Debug (GPL), XtraDB %{xtradbversion}
 %define commercial 0
 %define YASSL_BUILD 1
 %define EMBEDDED_BUILD 0
@@ -143,6 +146,7 @@ Patch04: microsec_process.patch
 Patch05: userstat.patch
 Patch06: optimizer_fix.patch
 Patch07: mysql-test_for_xtradb.diff
+Patch08: show_temp_51.patch
 
 
 %define perconaxtradbplugin percona-xtradb-%{pluginversion}-%{xtradbversion}.tar.gz
@@ -162,8 +166,8 @@ Source:		%{src_dir}.tar.gz
 URL:		http://www.percona.com/
 Packager:	%{mysql_vendor} MySQL Development Team <mysql-dev@xxxxxxxxxxx>
 Vendor:		%{mysql_vendor}
-Provides:	msqlormysql MySQL-server mysql Percona-XtraDB-server
-BuildRequires:  gperf perl readline-devel gcc-c++ ncurses-devel zlib-devel libtool automake autoconf time ccache
+Provides:	msqlormysql MySQL-server Percona-XtraDB-server
+BuildRequires:  gperf perl readline-devel gcc-c++ ncurses-devel zlib-devel libtool automake autoconf time ccache bison
 
 # Think about what you use here since the first step is to
 # run a rm -rf
@@ -187,7 +191,7 @@ For more information visist our web site
 Summary:	%{ndbug_comment} for Red Hat Enterprise Linux %{redhatversion}
 Group:		Applications/Databases
 Requires:	 chkconfig coreutils shadow-utils grep procps
-Provides:	msqlormysql mysql-server mysql MySQL MySQL-server Percona-XtraDB-server
+Provides:	msqlormysql mysql-server MySQL-server Percona-XtraDB-server
 Obsoletes:	MySQL mysql mysql-server MySQL-server MySQL-server-community MySQL-server-percona
 
 %description -n Percona-XtraDB-server%{package_suffix}
@@ -214,7 +218,7 @@ package "Percona-XtraDB-client%{package_
 Summary: Percona-XtraDB - Client
 Group: Applications/Databases
 Obsoletes: mysql-client MySQL-client MySQL-client-community MySQL-client-percona
-Provides: mysql-client MySQL-client Percona-XtraDB-client
+Provides: mysql-client MySQL-client Percona-XtraDB-client mysql MySQL
 
 %description -n Percona-XtraDB-client%{package_suffix}
 This package contains the standard Percona-XtraDB clients and administration tools. 
@@ -308,6 +312,7 @@ judgment as a high-performance consultin
 %patch05 -p1
 %patch06 -p1
 %patch07 -p1
+%patch08 -p1
 
 if [ "%{redhatversion}" = "5" ] ; then 
 tar xfz $RPM_SOURCE_DIR/%{perconaxtradbplugin} -C storage/innobase --strip-components=1
@@ -1018,6 +1023,10 @@ fi
 # merging BK trees)
 ##############################################################################
 %changelog
+* Mon Mar 22 2010 Aleksandr Kuzminsky <aleksandr.kuzminsky@xxxxxxxxxxx>
+
+XtraDB Release 10
+
 * Thu Feb 11 2010 Aleksandr Kuzminsky <aleksandr.kuzminsky@xxxxxxxxxxx>
 
 Package name changed to Percona-XtraDB

=== modified file 'storage/xtradb/dict/dict0dict.c'
--- a/storage/xtradb/dict/dict0dict.c	2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/dict/dict0dict.c	2010-04-28 14:35:00 +0000
@@ -54,6 +54,7 @@ UNIV_INTERN dict_index_t*	dict_ind_compa
 #include "row0merge.h"
 #include "m_ctype.h" /* my_isspace() */
 #include "ha_prototypes.h" /* innobase_strcasecmp() */
+#include "srv0start.h" /* SRV_LOG_SPACE_FIRST_ID */
 
 #include <ctype.h>
 
@@ -658,7 +659,7 @@ dict_table_get(
 	mutex_exit(&(dict_sys->mutex));
 
 	if (table != NULL) {
-		if (!table->stat_initialized) {
+		if (!table->stat_initialized && !table->is_corrupt) {
 			/* If table->ibd_file_missing == TRUE, this will
 			print an error message and return without doing
 			anything. */
@@ -1181,7 +1182,7 @@ retry:
 		    + dict_sys->size) > srv_dict_size_limit ) {
 		prev_table = UT_LIST_GET_PREV(table_LRU, table);
 
-		if (table == self || table->n_mysql_handles_opened)
+		if (table == self || table->n_mysql_handles_opened || table->is_corrupt)
 			goto next_loop;
 
 		cached_foreign_tables = 0;
@@ -4219,6 +4220,11 @@ dict_update_statistics_low(
 	}
 
 	while (index) {
+		if (table->is_corrupt) {
+			ut_a(srv_pass_corrupt_table);
+			return;
+		}
+
 		size = btr_get_size(index, BTR_TOTAL_SIZE);
 
 		index->stat_index_size = size;
@@ -4920,4 +4926,42 @@ dict_close(void)
 	mem_free(dict_sys);
 	dict_sys = NULL;
 }
+
+/*************************************************************************
+set is_corrupt flag by space_id*/
+
+void
+dict_table_set_corrupt_by_space(
+/*============================*/
+	ulint	space_id,
+	ibool	need_mutex)
+{
+	dict_table_t*	table;
+	ibool		found = FALSE;
+
+	ut_a(space_id != 0 && space_id < SRV_LOG_SPACE_FIRST_ID);
+
+	if (need_mutex)
+		mutex_enter(&(dict_sys->mutex));
+
+	table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
+
+	while (table) {
+		if (table->space == space_id) {
+			table->is_corrupt = TRUE;
+			found = TRUE;
+		}
+
+		table = UT_LIST_GET_NEXT(table_LRU, table);
+	}
+
+	if (need_mutex)
+		mutex_exit(&(dict_sys->mutex));
+
+	if (!found) {
+		fprintf(stderr, "InnoDB: space to be marked as "
+			"crashed was not found for id %lu.\n",
+			(ulong) space_id);
+	}
+}
 #endif /* !UNIV_HOTBACKUP */

=== modified file 'storage/xtradb/dict/dict0mem.c'
--- a/storage/xtradb/dict/dict0mem.c	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/dict/dict0mem.c	2010-03-22 20:42:52 +0000
@@ -85,6 +85,8 @@ dict_mem_table_create(
 	/* The number of transactions that are either waiting on the
 	AUTOINC lock or have been granted the lock. */
 	table->n_waiting_or_granted_auto_inc_locks = 0;
+
+	table->is_corrupt = FALSE;
 #endif /* !UNIV_HOTBACKUP */
 
 	ut_d(table->magic_n = DICT_TABLE_MAGIC_N);

=== modified file 'storage/xtradb/fil/fil0fil.c'
--- a/storage/xtradb/fil/fil0fil.c	2010-03-28 18:10:00 +0000
+++ b/storage/xtradb/fil/fil0fil.c	2010-04-28 14:35:00 +0000
@@ -222,6 +222,7 @@ struct fil_space_struct {
 				file we have written to */
 	ibool		is_in_unflushed_spaces; /*!< TRUE if this space is
 				currently in unflushed_spaces */
+	ibool		is_corrupt;
 	UT_LIST_NODE_T(fil_space_t) space_list;
 				/*!< list of all spaces */
 	ulint		magic_n;/*!< FIL_SPACE_MAGIC_N */
@@ -1222,6 +1223,8 @@ try_again:
 		    ut_fold_string(name), space);
 	space->is_in_unflushed_spaces = FALSE;
 
+	space->is_corrupt = FALSE;
+
 	UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
 
 	mutex_exit(&fil_system->mutex);
@@ -3044,7 +3047,9 @@ fil_open_single_table_tablespace(
 			mach_write_ull(page + FIL_PAGE_FILE_FLUSH_LSN, current_lsn);
 		mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
 				srv_use_checksums
-				? buf_calc_page_new_checksum(page)
+				? (!srv_fast_checksum
+				   ? buf_calc_page_new_checksum(page)
+				   : buf_calc_page_new_checksum_32(page))
 						: BUF_NO_CHECKSUM_MAGIC);
 		mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
 				srv_use_checksums
@@ -3156,7 +3161,8 @@ skip_info:
 					goto skip_write;
 				}
 
-				if (checksum_field != 0
+				if (!srv_fast_checksum
+				    && checksum_field != 0
 				    && checksum_field != BUF_NO_CHECKSUM_MAGIC
 				    && checksum_field
 				    != buf_calc_page_new_checksum(page)) {
@@ -3164,6 +3170,17 @@ skip_info:
 					goto skip_write;
 				}
 
+				if (srv_fast_checksum
+				    && checksum_field != 0
+				    && checksum_field != BUF_NO_CHECKSUM_MAGIC
+				    && checksum_field
+				    != buf_calc_page_new_checksum_32(page)
+				    && checksum_field
+				    != buf_calc_page_new_checksum(page)) {
+
+					goto skip_write;
+				}
+
 				if (mach_read_from_4(page + FIL_PAGE_OFFSET) || !offset) {
 					mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, id);
 
@@ -3238,7 +3255,9 @@ skip_info:
 
 					mach_write_to_4(page + FIL_PAGE_SPACE_OR_CHKSUM,
 							srv_use_checksums
-							? buf_calc_page_new_checksum(page)
+							? (!srv_fast_checksum
+							   ? buf_calc_page_new_checksum(page)
+							   : buf_calc_page_new_checksum_32(page))
 									: BUF_NO_CHECKSUM_MAGIC);
 					mach_write_to_4(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM,
 							srv_use_checksums
@@ -4577,9 +4596,9 @@ _fil_io(
 	ut_ad(ut_is_2pow(zip_size));
 	ut_ad(buf);
 	ut_ad(len > 0);
-#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
-# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
-#endif
+//#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
+//# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
+//#endif
 	ut_ad(fil_validate());
 #ifndef UNIV_HOTBACKUP
 # ifndef UNIV_LOG_DEBUG
@@ -4713,6 +4732,22 @@ _fil_io(
 	ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
 	ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
 
+	if (srv_pass_corrupt_table && space->is_corrupt) {
+		/* should ignore i/o for the crashed space */
+		mutex_enter(&fil_system->mutex);
+		fil_node_complete_io(node, fil_system, type);
+		mutex_exit(&fil_system->mutex);
+		if (mode == OS_AIO_NORMAL) {
+			ut_a(space->purpose == FIL_TABLESPACE);
+			buf_page_io_complete(message, trx);
+		}
+		if (type == OS_FILE_READ) {
+			return(DB_TABLESPACE_DELETED);
+		} else {
+			return(DB_SUCCESS);
+		}
+	} else {
+		ut_a(!space->is_corrupt);
 #ifdef UNIV_HOTBACKUP
 	/* In ibbackup do normal i/o, not aio */
 	if (type == OS_FILE_READ) {
@@ -4727,6 +4762,8 @@ _fil_io(
 	ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
 		     offset_low, offset_high, len, node, message, trx);
 #endif
+	} /**/
+
 	ut_a(ret);
 
 	if (mode == OS_AIO_SYNC) {
@@ -4873,7 +4910,7 @@ fil_aio_wait(
 
 	if (fil_node->space->purpose == FIL_TABLESPACE) {
 		srv_set_io_thread_op_info(segment, "complete io for buf page");
-		buf_page_io_complete(message);
+		buf_page_io_complete(message, NULL);
 	} else {
 		srv_set_io_thread_op_info(segment, "complete io for log");
 		log_io_complete(message);
@@ -5225,3 +5262,46 @@ fil_system_hash_nodes(void)
                return 0;
        }
 }
+
+/*************************************************************************
+functions to access is_corrupt flag of fil_space_t*/
+
+ibool
+fil_space_is_corrupt(
+/*=================*/
+	ulint	space_id)
+{
+	fil_space_t*	space;
+	ibool		ret = FALSE;
+
+	mutex_enter(&fil_system->mutex);
+
+	space = fil_space_get_by_id(space_id);
+
+	if (space && space->is_corrupt) {
+		ret = TRUE;
+	}
+
+	mutex_exit(&fil_system->mutex);
+
+	return(ret);
+}
+
+void
+fil_space_set_corrupt(
+/*==================*/
+	ulint	space_id)
+{
+	fil_space_t*	space;
+
+	mutex_enter(&fil_system->mutex);
+
+	space = fil_space_get_by_id(space_id);
+
+	if (space) {
+		space->is_corrupt = TRUE;
+	}
+
+	mutex_exit(&fil_system->mutex);
+}
+

=== modified file 'storage/xtradb/fsp/fsp0fsp.c'
--- a/storage/xtradb/fsp/fsp0fsp.c	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/fsp/fsp0fsp.c	2010-03-22 20:42:52 +0000
@@ -370,6 +370,12 @@ fsp_get_space_header(
 	ut_ad(id || !zip_size);
 
 	block = buf_page_get(id, zip_size, 0, RW_X_LATCH, mtr);
+
+	if (srv_pass_corrupt_table && !block) {
+		return(0);
+	}
+	ut_a(block);
+
 	header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
 	buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
 
@@ -652,15 +658,16 @@ xdes_calc_descriptor_page(
 	ulint	offset)		/*!< in: page offset */
 {
 #ifndef DOXYGEN /* Doxygen gets confused of these */
-# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
-		+ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
-#  error
-# endif
+//# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET \
+//		+ (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
+//#  error
+//# endif
 # if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \
 		+ (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE
 #  error
 # endif
 #endif /* !DOXYGEN */
+	ut_a(UNIV_PAGE_SIZE > XDES_ARR_OFFSET + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE);
 	ut_ad(ut_is_2pow(zip_size));
 
 	if (!zip_size) {
@@ -788,6 +795,12 @@ xdes_get_descriptor(
 	fsp_header_t*	sp_header;
 
 	block = buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
+
+	if (srv_pass_corrupt_table && !block) {
+		return(0);
+	}
+	ut_a(block);
+
 	buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
 
 	sp_header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
@@ -1457,12 +1470,12 @@ fsp_fill_free_list(
 							   mtr);
 		xdes_init(descr, mtr);
 
-#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
-# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
-#endif
-#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
-# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
-#endif
+//#if UNIV_PAGE_SIZE % FSP_EXTENT_SIZE
+//# error "UNIV_PAGE_SIZE % FSP_EXTENT_SIZE != 0"
+//#endif
+//#if PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE
+//# error "PAGE_ZIP_MIN_SIZE % FSP_EXTENT_SIZE != 0"
+//#endif
 
 		if (UNIV_UNLIKELY(init_xdes)) {
 
@@ -1871,6 +1884,11 @@ fsp_seg_inode_page_find_free(
 {
 	fseg_inode_t*	inode;
 
+	if (srv_pass_corrupt_table && !page) {
+		return(ULINT_UNDEFINED);
+	}
+	ut_a(page);
+
 	for (; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
 
 		inode = fsp_seg_inode_page_get_nth_inode(
@@ -1984,6 +2002,11 @@ fsp_alloc_seg_inode(
 
 	page = buf_block_get_frame(block);
 
+	if (srv_pass_corrupt_table && !page) {
+		return(0);
+	}
+	ut_a(page);
+
 	n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr);
 
 	ut_a(n != ULINT_UNDEFINED);
@@ -2077,6 +2100,11 @@ fseg_inode_try_get(
 
 	inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
 
+	if (srv_pass_corrupt_table && !inode) {
+		return(0);
+	}
+	ut_a(inode);
+
 	if (UNIV_UNLIKELY
 	    (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) {
 
@@ -2104,7 +2132,7 @@ fseg_inode_get(
 {
 	fseg_inode_t*	inode
 		= fseg_inode_try_get(header, space, zip_size, mtr);
-	ut_a(inode);
+	ut_a(srv_pass_corrupt_table || inode);
 	return(inode);
 }
 
@@ -3263,6 +3291,11 @@ fseg_free_page_low(
 
 	descr = xdes_get_descriptor(space, zip_size, page, mtr);
 
+	if (srv_pass_corrupt_table && !descr) {
+		/* The page may be corrupt. pass it. */
+		return;
+	}
+
 	ut_a(descr);
 	if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) {
 		fputs("InnoDB: Dump of the tablespace extent descriptor: ",
@@ -3515,6 +3548,11 @@ fseg_free_step(
 
 	descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
 
+	if (srv_pass_corrupt_table && !descr) {
+		/* The page may be corrupt. pass it. */
+		return(TRUE);
+	}
+
 	/* Check that the header resides on a page which has not been
 	freed yet */
 
@@ -3599,6 +3637,12 @@ fseg_free_step_not_header(
 
 	inode = fseg_inode_get(header, space, zip_size, mtr);
 
+	if (srv_pass_corrupt_table && !inode) {
+		/* ignore the corruption */
+		return(TRUE);
+	}
+	ut_a(inode);
+
 	descr = fseg_get_first_extent(inode, space, zip_size, mtr);
 
 	if (descr != NULL) {

=== modified file 'storage/xtradb/handler/ha_innodb.cc'
--- a/storage/xtradb/handler/ha_innodb.cc	2010-04-28 13:53:04 +0000
+++ b/storage/xtradb/handler/ha_innodb.cc	2010-04-28 14:35:00 +0000
@@ -167,6 +167,8 @@ static ulong innobase_commit_concurrency
 static ulong innobase_read_io_threads;
 static ulong innobase_write_io_threads;
 
+static ulong innobase_page_size;
+
 static my_bool innobase_thread_concurrency_timer_based;
 static long long innobase_buffer_pool_size, innobase_log_file_size;
 
@@ -200,6 +202,7 @@ static char*	innobase_log_arch_dir			= N
 #endif /* UNIV_LOG_ARCHIVE */
 static my_bool	innobase_use_doublewrite		= TRUE;
 static my_bool	innobase_use_checksums			= TRUE;
+static my_bool	innobase_fast_checksum			= FALSE;
 static my_bool	innobase_extra_undoslots		= FALSE;
 static my_bool	innobase_fast_recovery			= FALSE;
 static my_bool	innobase_recovery_stats			= TRUE;
@@ -2030,6 +2033,36 @@ innobase_init(
 	}
 #endif /* UNIV_DEBUG */
 
+	srv_page_size = 0;
+	srv_page_size_shift = 0;
+
+	if (innobase_page_size != (1 << 14)) {
+		int n_shift;
+
+		fprintf(stderr,
+			"InnoDB: Warning: innodb_page_size has been changed from default value 16384. (###EXPERIMENTAL### operation)\n");
+		for (n_shift = 12; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
+			if (innobase_page_size == (1 << n_shift)) {
+				srv_page_size_shift = n_shift;
+				srv_page_size = (1 << srv_page_size_shift);
+				fprintf(stderr,
+					"InnoDB: The universal page size of the database is set to %lu.\n",
+					srv_page_size);
+				break;
+			}
+		}
+	} else {
+		srv_page_size_shift = 14;
+		srv_page_size = (1 << srv_page_size_shift);
+	}
+
+	if (!srv_page_size_shift) {
+		fprintf(stderr,
+			"InnoDB: Error: %lu is not valid value for innodb_page_size.\n",
+			innobase_page_size);
+		goto error;
+	}
+
 #ifndef MYSQL_SERVER
 	innodb_overwrite_relay_log_info = FALSE;
 #endif
@@ -2338,6 +2371,7 @@ innobase_change_buffering_inited_ok:
 
 	srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
 	srv_use_checksums = (ibool) innobase_use_checksums;
+	srv_fast_checksum = (ibool) innobase_fast_checksum;
 
 #ifdef HAVE_LARGE_PAGES
         if ((os_use_large_pages = (ibool) my_use_large_pages))
@@ -3348,6 +3382,12 @@ ha_innobase::open(
 		DBUG_RETURN(1);
 	}
 
+	if (share->ib_table && share->ib_table->is_corrupt) {
+		free_share(share);
+
+		DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
+	}
+
 	/* Create buffers for packing the fields of a record. Why
 	table->reclength did not work here? Obviously, because char
 	fields when packed actually became 1 byte longer, when we also
@@ -3375,6 +3415,19 @@ retry:
 	/* Get pointer to a table object in InnoDB dictionary cache */
 	ib_table = dict_table_get(norm_name, TRUE);
 	
+	if (ib_table && ib_table->is_corrupt) {
+		free_share(share);
+		my_free(upd_buff, MYF(0));
+
+		DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
+	}
+
+	if (share->ib_table) {
+		ut_a(share->ib_table == ib_table);
+	} else {
+		share->ib_table = ib_table;
+	}
+
 	if (NULL == ib_table) {
 		if (is_part && retries < 10) {
 			++retries;
@@ -4541,6 +4594,10 @@ ha_innobase::write_row(
 
 	ha_statistic_increment(&SSV::ha_write_count);
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
 		table->timestamp_field->set_time();
 
@@ -4653,6 +4710,10 @@ no_commit:
 
 	error = row_insert_for_mysql((byte*) record, prebuilt);
 
+#ifdef EXTENDED_FOR_USERSTAT
+	if (error == DB_SUCCESS) rows_changed++;
+#endif
+
 	/* Handle duplicate key errors */
 	if (auto_inc_used) {
 		ulint		err;
@@ -4748,6 +4809,10 @@ report_error:
 func_exit:
 	innobase_active_small();
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	DBUG_RETURN(error_result);
 }
 
@@ -4924,6 +4989,10 @@ ha_innobase::update_row(
 
 	ha_statistic_increment(&SSV::ha_update_count);
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
 		table->timestamp_field->set_time();
 
@@ -4989,6 +5058,10 @@ ha_innobase::update_row(
 		}
 	}
 
+#ifdef EXTENDED_FOR_USERSTAT
+	if (error == DB_SUCCESS) rows_changed++;
+#endif
+
 	innodb_srv_conc_exit_innodb(trx);
 
 	error = convert_error_code_to_mysql(error,
@@ -5009,6 +5082,10 @@ ha_innobase::update_row(
 
 	innobase_active_small();
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	DBUG_RETURN(error);
 }
 
@@ -5030,6 +5107,10 @@ ha_innobase::delete_row(
 
 	ha_statistic_increment(&SSV::ha_delete_count);
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	if (!prebuilt->upd_node) {
 		row_get_prebuilt_update_vector(prebuilt);
 	}
@@ -5042,6 +5123,10 @@ ha_innobase::delete_row(
 
 	error = row_update_for_mysql((byte*) record, prebuilt);
 
+#ifdef EXTENDED_FOR_USERSTAT
+	if (error == DB_SUCCESS) rows_changed++;
+#endif
+
 	innodb_srv_conc_exit_innodb(trx);
 
 	error = convert_error_code_to_mysql(
@@ -5052,6 +5137,10 @@ ha_innobase::delete_row(
 
 	innobase_active_small();
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	DBUG_RETURN(error);
 }
 
@@ -5291,6 +5380,10 @@ ha_innobase::index_read(
 
 	ha_statistic_increment(&SSV::ha_read_key_count);
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	index = prebuilt->index;
 
 	if (UNIV_UNLIKELY(index == NULL)) {
@@ -5353,6 +5446,10 @@ ha_innobase::index_read(
 		ret = DB_UNSUPPORTED;
 	}
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	switch (ret) {
 	case DB_SUCCESS:
 		error = 0;
@@ -5447,6 +5544,10 @@ ha_innobase::change_active_index(
 {
 	DBUG_ENTER("change_active_index");
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	ut_ad(user_thd == ha_thd());
 	ut_a(prebuilt->trx == thd_to_trx(user_thd));
 
@@ -5538,6 +5639,10 @@ ha_innobase::general_fetch(
 
 	DBUG_ENTER("general_fetch");
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	ut_a(prebuilt->trx == thd_to_trx(user_thd));
 
 	innodb_srv_conc_enter_innodb(prebuilt->trx);
@@ -5547,10 +5652,19 @@ ha_innobase::general_fetch(
 
 	innodb_srv_conc_exit_innodb(prebuilt->trx);
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	switch (ret) {
 	case DB_SUCCESS:
 		error = 0;
 		table->status = 0;
+#ifdef EXTENDED_FOR_USERSTAT
+		rows_read++;
+		if (active_index >= 0 && active_index < MAX_KEY)
+			index_rows_read[active_index]++;
+#endif
 		break;
 	case DB_RECORD_NOT_FOUND:
 		error = HA_ERR_END_OF_FILE;
@@ -6506,9 +6620,9 @@ ha_innobase::create(
 					| DICT_TF_COMPACT
 					| DICT_TF_FORMAT_ZIP
 					<< DICT_TF_FORMAT_SHIFT;
-#if DICT_TF_ZSSIZE_MAX < 1
-# error "DICT_TF_ZSSIZE_MAX < 1"
-#endif
+//#if DICT_TF_ZSSIZE_MAX < 1
+//# error "DICT_TF_ZSSIZE_MAX < 1"
+//#endif
 			}
 		}
 
@@ -6768,6 +6882,10 @@ ha_innobase::delete_all_rows(void)
 		DBUG_RETURN(my_errno=HA_ERR_WRONG_COMMAND);
 	}
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	/* Truncate the table in InnoDB */
 
 	error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
@@ -6776,6 +6894,10 @@ ha_innobase::delete_all_rows(void)
 		goto fallback;
 	}
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	error = convert_error_code_to_mysql(error, prebuilt->table->flags,
 					    NULL);
 
@@ -7279,6 +7401,16 @@ ha_innobase::read_time(
 	return(ranges + (double) rows / (double) total_rows * time_for_scan);
 }
 
+UNIV_INTERN
+bool
+ha_innobase::is_corrupt() const
+{
+	if (share->ib_table)
+		return ((bool)share->ib_table->is_corrupt);
+	else
+		return (FALSE);
+}
+
 /*********************************************************************//**
 Returns statistics information of the table to the MySQL interpreter,
 in various fields of the handle object. */
@@ -7329,9 +7461,9 @@ ha_innobase::info(
 	ib_table = prebuilt->table;
 
 	if (flag & HA_STATUS_TIME) {
-		if (innobase_stats_on_metadata
-		    && (thd_sql_command(user_thd) == SQLCOM_ANALYZE
-			|| srv_stats_auto_update)) {
+		if ((innobase_stats_on_metadata
+		     || thd_sql_command(user_thd) == SQLCOM_ANALYZE)
+		    && !share->ib_table->is_corrupt) {
 			/* In sql_show we call with this flag: update
 			then statistics so that they are up-to-date */
 
@@ -7558,6 +7690,10 @@ ha_innobase::analyze(
 	THD*		thd,		/*!< in: connection thread handle */
 	HA_CHECK_OPT*	check_opt)	/*!< in: currently ignored */
 {
+	if (share->ib_table->is_corrupt) {
+		return(HA_ADMIN_CORRUPT);
+	}
+
 	/* Serialize ANALYZE TABLE inside InnoDB, see
 	Bug#38996 Race condition in ANALYZE TABLE */
 	pthread_mutex_lock(&analyze_mutex);
@@ -7567,6 +7703,10 @@ ha_innobase::analyze(
 
 	pthread_mutex_unlock(&analyze_mutex);
 
+	if (share->ib_table->is_corrupt) {
+		return(HA_ADMIN_CORRUPT);
+	}
+
 	return(0);
 }
 
@@ -7612,6 +7752,10 @@ ha_innobase::check(
 
 	ret = row_check_table_for_mysql(prebuilt);
 
+	if (ret != DB_INTERRUPTED && share->ib_table->is_corrupt) {
+		return(HA_ADMIN_CORRUPT);
+	}
+
 	switch (ret) {
 	case DB_SUCCESS:
 		return(HA_ADMIN_OK);
@@ -8345,6 +8489,10 @@ ha_innobase::transactional_table_lock(
 
 	update_thd(thd);
 
+	if (share->ib_table->is_corrupt) {
+		DBUG_RETURN(HA_ERR_CRASHED);
+	}
+
 	if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
 		ut_print_timestamp(stderr);
 		fprintf(stderr,
@@ -10209,6 +10357,20 @@ static MYSQL_SYSVAR_BOOL(checksums, inno
   "Disable with --skip-innodb-checksums.",
   NULL, NULL, TRUE);
 
+static MYSQL_SYSVAR_BOOL(fast_checksum, innobase_fast_checksum,
+  PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+  "Change the algorithm of checksum for the whole of datapage to 4-bytes word based. "
+  "The original checksum is checked after the new one. It may be slow for reading page"
+  " which has orginal checksum. Overwrite the page or recreate the InnoDB database, "
+  "if you want the entire benefit for performance at once. "
+  "#### Attention: The checksum is not compatible for normal or disabled version! ####",
+  NULL, NULL, FALSE);
+
+static MYSQL_SYSVAR_ULONG(page_size, innobase_page_size,
+  PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+  "###EXPERIMENTAL###: The universal page size of the database. Changing for created database is not supported. Use on your own risk!",
+  NULL, NULL, (1 << 14), (1 << 12), (1 << UNIV_PAGE_SIZE_SHIFT_MAX), 0);
+
 static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
   PLUGIN_VAR_READONLY,
   "The common part for InnoDB table spaces.",
@@ -10665,11 +10827,21 @@ static MYSQL_SYSVAR_ULONG(relax_table_cr
   "Relax limitation of column size at table creation as builtin InnoDB.",
   NULL, NULL, 0, 0, 1, 0);
 
+static	MYSQL_SYSVAR_ULONG(pass_corrupt_table, srv_pass_corrupt_table,
+  PLUGIN_VAR_RQCMDARG,
+  "Pass corruptions of user tables as 'corrupt table' instead of not crashing itself, "
+  "when used with file_per_table. "
+  "All file io for the datafile after detected as corrupt are disabled, "
+  "except for the deletion.",
+  NULL, NULL, 0, 0, 1, 0);
+
 static struct st_mysql_sys_var* innobase_system_variables[]= {
+  MYSQL_SYSVAR(page_size),
   MYSQL_SYSVAR(additional_mem_pool_size),
   MYSQL_SYSVAR(autoextend_increment),
   MYSQL_SYSVAR(buffer_pool_size),
   MYSQL_SYSVAR(checksums),
+  MYSQL_SYSVAR(fast_checksum),
   MYSQL_SYSVAR(commit_concurrency),
   MYSQL_SYSVAR(concurrency_tickets),
   MYSQL_SYSVAR(data_file_path),
@@ -10744,6 +10916,7 @@ static struct st_mysql_sys_var* innobase
   MYSQL_SYSVAR(io_capacity),
   MYSQL_SYSVAR(use_purge_thread),
   MYSQL_SYSVAR(relax_table_creation),
+  MYSQL_SYSVAR(pass_corrupt_table),
   NULL
 };
 
@@ -10776,6 +10949,8 @@ i_s_innodb_cmpmem_reset,
 i_s_innodb_table_stats,
 i_s_innodb_index_stats,
 i_s_innodb_admin_command,
+i_s_innodb_sys_tables,
+i_s_innodb_sys_indexes,
 i_s_innodb_patches
 mysql_declare_plugin_end;
 

=== modified file 'storage/xtradb/handler/ha_innodb.h'
--- a/storage/xtradb/handler/ha_innodb.h	2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/handler/ha_innodb.h	2010-04-28 14:35:00 +0000
@@ -36,6 +36,7 @@ typedef struct st_innobase_share {
 					incremented in get_share()
 					and decremented in free_share() */
 	void*		table_name_hash;/*!< hash table chain node */
+	dict_table_t*	ib_table;
 } INNOBASE_SHARE;
 
 
@@ -119,6 +120,7 @@ class ha_innobase: public handler
 	int close(void);
 	double scan_time();
 	double read_time(uint index, uint ranges, ha_rows rows);
+	bool is_corrupt() const;
 
 	int write_row(uchar * buf);
 	int update_row(const uchar * old_data, uchar * new_data);

=== modified file 'storage/xtradb/handler/i_s.cc'
--- a/storage/xtradb/handler/i_s.cc	2010-03-31 20:50:54 +0000
+++ b/storage/xtradb/handler/i_s.cc	2010-04-28 14:35:00 +0000
@@ -47,6 +47,7 @@ extern "C" {
 #include "trx0rseg.h" /* for trx_rseg_struct */
 #include "trx0sys.h" /* for trx_sys */
 #include "dict0dict.h" /* for dict_sys */
+#include "btr0pcur.h"
 #include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */
 /* from buf0buf.c */
 struct buf_chunk_struct{
@@ -807,7 +808,7 @@ i_s_innodb_buffer_pool_pages_index_fill(
             p++;            
           } else {
             field_store_string(table->field[0], NULL);
-            p = (char *)index->table_name;
+            p = index->table_name;
           }
           strcpy(table_name_raw, (const char*)p);
           filename_to_tablename(table_name_raw, table_name, sizeof(table_name));
@@ -2664,6 +2665,14 @@ UNIV_INTERN struct st_mysql_plugin	i_s_i
 */
 static ST_FIELD_INFO	i_s_innodb_table_stats_info[] =
 {
+	{STRUCT_FLD(field_name,		"table_schema"),
+	 STRUCT_FLD(field_length,	NAME_LEN),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	0),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
 	{STRUCT_FLD(field_name,		"table_name"),
 	 STRUCT_FLD(field_length,	NAME_LEN),
 	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
@@ -2709,6 +2718,14 @@ static ST_FIELD_INFO	i_s_innodb_table_st
 
 static ST_FIELD_INFO	i_s_innodb_index_stats_info[] =
 {
+	{STRUCT_FLD(field_name,		"table_schema"),
+	 STRUCT_FLD(field_length,	NAME_LEN),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	0),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
 	{STRUCT_FLD(field_name,		"table_name"),
 	 STRUCT_FLD(field_length,	NAME_LEN),
 	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
@@ -2784,16 +2801,30 @@ i_s_innodb_table_stats_fill(
 	table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
 
 	while (table) {
+		char	buf[NAME_LEN * 2 + 2];
+		char*	ptr;
+
 		if (table->stat_clustered_index_size == 0) {
 			table = UT_LIST_GET_NEXT(table_LRU, table);
 			continue;
 		}
 
-		field_store_string(i_s_table->field[0], table->name);
-		i_s_table->field[1]->store(table->stat_n_rows);
-		i_s_table->field[2]->store(table->stat_clustered_index_size);
-		i_s_table->field[3]->store(table->stat_sum_of_other_index_sizes);
-		i_s_table->field[4]->store(table->stat_modified_counter);
+		buf[NAME_LEN * 2 + 1] = 0;
+		strncpy(buf, table->name, NAME_LEN * 2 + 1);
+		ptr = strchr(buf, '/');
+		if (ptr) {
+			*ptr = '\0';
+			++ptr;
+		} else {
+			ptr = buf;
+		}
+
+		field_store_string(i_s_table->field[0], buf);
+		field_store_string(i_s_table->field[1], ptr);
+		i_s_table->field[2]->store(table->stat_n_rows);
+		i_s_table->field[3]->store(table->stat_clustered_index_size);
+		i_s_table->field[4]->store(table->stat_sum_of_other_index_sizes);
+		i_s_table->field[5]->store(table->stat_modified_counter);
 
 		if (schema_table_store_record(thd, i_s_table)) {
 			status = 1;
@@ -2849,11 +2880,24 @@ i_s_innodb_index_stats_fill(
 		while (index) {
 			char	buff[256+1];
 			char	row_per_keys[256+1];
+			char	buf[NAME_LEN * 2 + 2];
+			char*	ptr;
 			ulint	i;
 
-			field_store_string(i_s_table->field[0], table->name);
-			field_store_string(i_s_table->field[1], index->name);
-			i_s_table->field[2]->store(index->n_uniq);
+			buf[NAME_LEN * 2 + 1] = 0;
+			strncpy(buf, table->name, NAME_LEN * 2 + 1);
+			ptr = strchr(buf, '/');
+			if (ptr) {
+				*ptr = '\0';
+				++ptr;
+			} else {
+				ptr = buf;
+			}
+
+			field_store_string(i_s_table->field[0], buf);
+			field_store_string(i_s_table->field[1], ptr);
+			field_store_string(i_s_table->field[2], index->name);
+			i_s_table->field[3]->store(index->n_uniq);
 
 			row_per_keys[0] = '\0';
 			if (index->stat_n_diff_key_vals) {
@@ -2869,10 +2913,10 @@ i_s_innodb_index_stats_fill(
 					strncat(row_per_keys, buff, 256 - strlen(row_per_keys));
 				}
 			}
-			field_store_string(i_s_table->field[3], row_per_keys);
+			field_store_string(i_s_table->field[4], row_per_keys);
 
-			i_s_table->field[4]->store(index->stat_index_size);
-			i_s_table->field[5]->store(index->stat_n_leaf_pages);
+			i_s_table->field[5]->store(index->stat_index_size);
+			i_s_table->field[6]->store(index->stat_n_leaf_pages);
 
 			if (schema_table_store_record(thd, i_s_table)) {
 				status = 1;
@@ -3121,3 +3165,505 @@ UNIV_INTERN struct st_mysql_plugin	i_s_i
 	STRUCT_FLD(system_vars, NULL),
 	STRUCT_FLD(__reserved1, NULL)
 };
+
+static ST_FIELD_INFO	i_s_innodb_sys_tables_info[] =
+{
+	{STRUCT_FLD(field_name,		"NAME"),
+	 STRUCT_FLD(field_length,	NAME_LEN),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	0),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"ID"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"N_COLS"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"TYPE"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"MIX_ID"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"MIX_LEN"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"CLUSTER_NAME"),
+	 STRUCT_FLD(field_length,	NAME_LEN),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	0),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"SPACE"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	 END_OF_ST_FIELD_INFO
+};
+
+static ST_FIELD_INFO	i_s_innodb_sys_indexes_info[] =
+{
+	{STRUCT_FLD(field_name,		"TABLE_ID"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"ID"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"NAME"),
+	 STRUCT_FLD(field_length,	NAME_LEN),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_STRING),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	0),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"N_FIELDS"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"TYPE"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"SPACE"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	{STRUCT_FLD(field_name,		"PAGE_NO"),
+	 STRUCT_FLD(field_length,	MY_INT64_NUM_DECIMAL_DIGITS),
+	 STRUCT_FLD(field_type,		MYSQL_TYPE_LONGLONG),
+	 STRUCT_FLD(value,		0),
+	 STRUCT_FLD(field_flags,	MY_I_S_UNSIGNED),
+	 STRUCT_FLD(old_name,		""),
+	 STRUCT_FLD(open_method,	SKIP_OPEN_TABLE)},
+
+	 END_OF_ST_FIELD_INFO
+};
+
+static
+int
+copy_string_field(
+/*==============*/
+	TABLE*			table,
+	int			table_field,
+	const rec_t*		rec,
+	int			rec_field)
+{
+	int		status;
+	const byte*	data;
+	ulint		len;
+
+	/*fprintf(stderr, "copy_string_field %d %d\n", table_field, rec_field);*/
+
+	data = rec_get_nth_field_old(rec, rec_field, &len);
+	if (len == UNIV_SQL_NULL) {
+		table->field[table_field]->set_null();
+		status = 0; /* success */
+	} else {
+		table->field[table_field]->set_notnull();
+		status = table->field[table_field]->store(
+			(char *) data, len, system_charset_info);
+	}
+
+	return status;
+}
+
+static
+int
+copy_int_field(
+/*===========*/
+	TABLE*			table,
+	int			table_field,
+	const rec_t*		rec,
+	int			rec_field)
+{
+	int		status;
+	const byte*	data;
+	ulint		len;
+
+	/*fprintf(stderr, "copy_int_field %d %d\n", table_field, rec_field);*/
+
+	data = rec_get_nth_field_old(rec, rec_field, &len);
+	if (len == UNIV_SQL_NULL) {
+		table->field[table_field]->set_null();
+		status = 0; /* success */
+	} else {
+		table->field[table_field]->set_notnull();
+		status = table->field[table_field]->store(
+			mach_read_from_4(data), true);
+	}
+
+	return status;
+}
+
+static
+int
+copy_id_field(
+/*==========*/
+	TABLE*			table,
+	int			table_field,
+	const rec_t*		rec,
+	int			rec_field)
+{
+	int		status;
+	const byte*	data;
+	ulint		len;
+
+	/*fprintf(stderr, "copy_id_field %d %d\n", table_field, rec_field);*/
+
+	data = rec_get_nth_field_old(rec, rec_field, &len);
+	if (len == UNIV_SQL_NULL) {
+		table->field[table_field]->set_null();
+		status = 0; /* success */
+	} else {
+		table->field[table_field]->set_notnull();
+		status = table->field[table_field]->store(
+			ut_conv_dulint_to_longlong(mach_read_from_8(data)), true);
+	}
+
+	return status;
+}
+
+static
+int
+copy_sys_tables_rec(
+/*================*/
+	TABLE*			table,
+	const dict_index_t*	index,
+	const rec_t*		rec
+)
+{
+	int	status;
+	int	field;
+
+	/* NAME */
+	field = dict_index_get_nth_col_pos(index, 0);
+	status = copy_string_field(table, 0, rec, field);
+	if (status) {
+		return status;
+	}
+	/* ID */
+	field = dict_index_get_nth_col_pos(index, 1);
+	status = copy_id_field(table, 1, rec, field);
+	if (status) {
+		return status;
+	}
+	/* N_COLS */
+	field = dict_index_get_nth_col_pos(index, 2);
+	status = copy_int_field(table, 2, rec, field);
+	if (status) {
+		return status;
+	}
+	/* TYPE */
+	field = dict_index_get_nth_col_pos(index, 3);
+	status = copy_int_field(table, 3, rec, field);
+	if (status) {
+		return status;
+	}
+	/* MIX_ID */
+	field = dict_index_get_nth_col_pos(index, 4);
+	status = copy_id_field(table, 4, rec, field);
+	if (status) {
+		return status;
+	}
+	/* MIX_LEN */
+	field = dict_index_get_nth_col_pos(index, 5);
+	status = copy_int_field(table, 5, rec, field);
+	if (status) {
+		return status;
+	}
+	/* CLUSTER_NAME */
+	field = dict_index_get_nth_col_pos(index, 6);
+	status = copy_string_field(table, 6, rec, field);
+	if (status) {
+		return status;
+	}
+	/* SPACE */
+	field = dict_index_get_nth_col_pos(index, 7);
+	status = copy_int_field(table, 7, rec, field);
+	if (status) {
+		return status;
+	}
+
+	return 0;
+}
+
+static
+int
+copy_sys_indexes_rec(
+/*=================*/
+	TABLE*			table,
+	const dict_index_t*	index,
+	const rec_t*		rec
+)
+{
+	int	status;
+	int	field;
+
+	/* TABLE_ID */
+	field = dict_index_get_nth_col_pos(index, 0);
+	status = copy_id_field(table, 0, rec, field);
+	if (status) {
+		return status;
+	}
+	/* ID */
+	field = dict_index_get_nth_col_pos(index, 1);
+	status = copy_id_field(table, 1, rec, field);
+	if (status) {
+		return status;
+	}
+	/* NAME */
+	field = dict_index_get_nth_col_pos(index, 2);
+	status = copy_string_field(table, 2, rec, field);
+	if (status) {
+		return status;
+	}
+	/* N_FIELDS */
+	field = dict_index_get_nth_col_pos(index, 3);
+	status = copy_int_field(table, 3, rec, field);
+	if (status) {
+		return status;
+	}
+	/* TYPE */
+	field = dict_index_get_nth_col_pos(index, 4);
+	status = copy_int_field(table, 4, rec, field);
+	if (status) {
+		return status;
+	}
+	/* SPACE */
+	field = dict_index_get_nth_col_pos(index, 5);
+	status = copy_int_field(table, 5, rec, field);
+	if (status) {
+		return status;
+	}
+	/* PAGE_NO */
+	field = dict_index_get_nth_col_pos(index, 6);
+	status = copy_int_field(table, 6, rec, field);
+	if (status) {
+		return status;
+	}
+
+	return 0;
+}
+
+static
+int
+i_s_innodb_schema_table_fill(
+/*=========================*/
+	THD*		thd,
+	TABLE_LIST*	tables,
+	COND*		cond)
+{
+	int		status	= 0;
+	TABLE*		table	= (TABLE *) tables->table;
+	const char*	table_name = tables->schema_table_name;
+	dict_table_t*	innodb_table;
+	dict_index_t*	index;
+	btr_pcur_t	pcur;
+	const rec_t*	rec;
+	mtr_t		mtr;
+	int		id;
+
+	DBUG_ENTER("i_s_innodb_schema_table_fill");
+
+	/* deny access to non-superusers */
+	if (check_global_access(thd, PROCESS_ACL)) {
+		DBUG_RETURN(0);
+	}
+
+	if (innobase_strcasecmp(table_name, "innodb_sys_tables") == 0) {
+		id = 0;
+	} else if (innobase_strcasecmp(table_name, "innodb_sys_indexes") == 0) {
+		id = 1;
+	} else {
+		DBUG_RETURN(1);
+	}
+
+
+	RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
+
+	mutex_enter(&(dict_sys->mutex));
+
+	mtr_start(&mtr);
+
+	if (id == 0) {
+		innodb_table = dict_table_get_low("SYS_TABLES");
+	} else {
+		innodb_table = dict_table_get_low("SYS_INDEXES");
+	}
+	index = UT_LIST_GET_FIRST(innodb_table->indexes);
+
+	btr_pcur_open_at_index_side(TRUE, index, BTR_SEARCH_LEAF, &pcur,
+				    TRUE, &mtr);
+	for (;;) {
+		btr_pcur_move_to_next_user_rec(&pcur, &mtr);
+
+		rec = btr_pcur_get_rec(&pcur);
+		if (!btr_pcur_is_on_user_rec(&pcur)) {
+			/* end of index */
+			btr_pcur_close(&pcur);
+			mtr_commit(&mtr);
+			break;
+		}
+		if (rec_get_deleted_flag(rec, 0)) {
+			/* record marked as deleted */
+			btr_pcur_close(&pcur);
+			mtr_commit(&mtr);
+			continue;
+		}
+
+		if (id == 0) {
+			status = copy_sys_tables_rec(table, index, rec);
+		} else {
+			status = copy_sys_indexes_rec(table, index, rec);
+		}
+		if (status) {
+			btr_pcur_close(&pcur);
+			mtr_commit(&mtr);
+			break;
+		}
+
+#if 0
+		btr_pcur_store_position(&pcur, &mtr);
+		mtr_commit(&mtr);
+
+		status = schema_table_store_record(thd, table);
+		if (status) {
+			btr_pcur_close(&pcur);
+			break;
+		}
+
+		mtr_start(&mtr);
+		btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr);
+#else
+		status = schema_table_store_record(thd, table);
+		if (status) {
+			btr_pcur_close(&pcur);
+			mtr_commit(&mtr);
+			break;
+		}
+#endif
+	}
+
+	mutex_exit(&(dict_sys->mutex));
+
+	DBUG_RETURN(status);
+}
+
+static
+int
+i_s_innodb_sys_tables_init(
+/*=======================*/
+	void*   p)
+{
+	DBUG_ENTER("i_s_innodb_sys_tables_init");
+	ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
+
+	schema->fields_info = i_s_innodb_sys_tables_info;
+	schema->fill_table = i_s_innodb_schema_table_fill;
+
+	DBUG_RETURN(0);
+}
+
+static
+int
+i_s_innodb_sys_indexes_init(
+/*========================*/
+	void*   p)
+{
+	DBUG_ENTER("i_s_innodb_sys_indexes_init");
+	ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p;
+
+	schema->fields_info = i_s_innodb_sys_indexes_info;
+	schema->fill_table = i_s_innodb_schema_table_fill;
+
+	DBUG_RETURN(0);
+}
+
+UNIV_INTERN struct st_mysql_plugin   i_s_innodb_sys_tables =
+{
+	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+	STRUCT_FLD(info, &i_s_info),
+	STRUCT_FLD(name, "INNODB_SYS_TABLES"),
+	STRUCT_FLD(author, plugin_author),
+	STRUCT_FLD(descr, "InnoDB SYS_TABLES table"),
+	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+	STRUCT_FLD(init, i_s_innodb_sys_tables_init),
+	STRUCT_FLD(deinit, i_s_common_deinit),
+	STRUCT_FLD(version, 0x0100 /* 1.0 */),
+	STRUCT_FLD(status_vars, NULL),
+	STRUCT_FLD(system_vars, NULL),
+	STRUCT_FLD(__reserved1, NULL)
+};
+
+UNIV_INTERN struct st_mysql_plugin   i_s_innodb_sys_indexes =
+{
+	STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN),
+	STRUCT_FLD(info, &i_s_info),
+	STRUCT_FLD(name, "INNODB_SYS_INDEXES"),
+	STRUCT_FLD(author, plugin_author),
+	STRUCT_FLD(descr, "InnoDB SYS_INDEXES table"),
+	STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+	STRUCT_FLD(init, i_s_innodb_sys_indexes_init),
+	STRUCT_FLD(deinit, i_s_common_deinit),
+	STRUCT_FLD(version, 0x0100 /* 1.0 */),
+	STRUCT_FLD(status_vars, NULL),
+	STRUCT_FLD(system_vars, NULL),
+	STRUCT_FLD(__reserved1, NULL)
+};

=== modified file 'storage/xtradb/handler/i_s.h'
--- a/storage/xtradb/handler/i_s.h	2009-11-04 20:11:12 +0000
+++ b/storage/xtradb/handler/i_s.h	2010-03-22 20:42:52 +0000
@@ -41,5 +41,7 @@ extern struct st_mysql_plugin	i_s_innodb
 extern struct st_mysql_plugin	i_s_innodb_table_stats;
 extern struct st_mysql_plugin	i_s_innodb_index_stats;
 extern struct st_mysql_plugin	i_s_innodb_admin_command;
+extern struct st_mysql_plugin   i_s_innodb_sys_tables;
+extern struct st_mysql_plugin   i_s_innodb_sys_indexes;
 
 #endif /* i_s_h */

=== modified file 'storage/xtradb/handler/innodb_patch_info.h'
--- a/storage/xtradb/handler/innodb_patch_info.h	2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/handler/innodb_patch_info.h	2010-04-28 14:35:00 +0000
@@ -43,5 +43,9 @@ struct innodb_enhancement {
 {"innodb_extend_slow","Extended statistics in slow.log","It is InnoDB-part only. It needs to patch also to mysqld.","http://www.percona.com/docs/wiki/percona-xtradb"},
 {"innodb_relax_table_creation","Relax limitation of column size at table creation as builtin InnoDB.","","http://www.percona.com/docs/wiki/percona-xtradb"},
 {"innodb_lru_dump_restore","Dump and restore command for content of buffer pool","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_pass_corrupt_table","Treat tables as corrupt instead of crash, when meet corrupt blocks","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_sys_tables_sys_indexes","Expose InnoDB SYS_TABLES and SYS_INDEXES schema tables","","http://www.percona.com/docs/wiki/percona-xtradb"},
 {NULL, NULL, NULL, NULL}
 };

=== modified file 'storage/xtradb/include/btr0btr.ic'
--- a/storage/xtradb/include/btr0btr.ic	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/btr0btr.ic	2010-03-22 20:42:52 +0000
@@ -28,7 +28,7 @@ Created 6/2/1994 Heikki Tuuri
 #include "mtr0mtr.h"
 #include "mtr0log.h"
 #include "page0zip.h"
-
+#include "srv0srv.h"
 #define BTR_MAX_NODE_LEVEL	50	/*!< Maximum B-tree page level
 					(not really a hard limit).
 					Used in debug assertions
@@ -52,7 +52,9 @@ btr_block_get(
 
 	block = buf_page_get(space, zip_size, page_no, mode, mtr);
 
-	if (mode != RW_NO_LATCH) {
+	ut_a(srv_pass_corrupt_table || block);
+
+	if (block && mode != RW_NO_LATCH) {
 
 		buf_block_dbg_add_level(block, SYNC_TREE_NODE);
 	}

=== modified file 'storage/xtradb/include/buf0buddy.h'
--- a/storage/xtradb/include/buf0buddy.h	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/buf0buddy.h	2010-03-22 20:42:52 +0000
@@ -83,7 +83,7 @@ typedef struct buf_buddy_stat_struct buf
 
 /** Statistics of the buddy system, indexed by block size.
 Protected by buf_pool_mutex. */
-extern buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES + 1];
+extern buf_buddy_stat_t buf_buddy_stat[BUF_BUDDY_SIZES_MAX + 1];
 
 #ifndef UNIV_NONINL
 # include "buf0buddy.ic"

=== modified file 'storage/xtradb/include/buf0buf.h'
--- a/storage/xtradb/include/buf0buf.h	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/buf0buf.h	2010-03-22 20:42:52 +0000
@@ -482,6 +482,11 @@ ulint
 buf_calc_page_new_checksum(
 /*=======================*/
 	const byte*	page);	/*!< in: buffer page */
+UNIV_INTERN
+ulint
+buf_calc_page_new_checksum_32(
+/*==========================*/
+	const byte*	page);	/*!< in: buffer page */
 /********************************************************************//**
 In versions < 4.0.14 and < 4.1.1 there was a bug that the checksum only
 looked at the first few bytes of the page. This calculates that old
@@ -855,7 +860,7 @@ buf_block_get_frame(
 	const buf_block_t*	block)	/*!< in: pointer to the control block */
 	__attribute__((pure));
 #else /* UNIV_DEBUG */
-# define buf_block_get_frame(block) (block)->frame
+# define buf_block_get_frame(block) (block ? (block)->frame : 0)
 #endif /* UNIV_DEBUG */
 /*********************************************************************//**
 Gets the space id of a block.
@@ -987,7 +992,8 @@ UNIV_INTERN
 void
 buf_page_io_complete(
 /*=================*/
-	buf_page_t*	bpage);	/*!< in: pointer to the block in question */
+	buf_page_t*	bpage,	/*!< in: pointer to the block in question */
+	trx_t*		trx);
 /********************************************************************//**
 Calculates a folded value of a file page address to use in the page hash
 table.
@@ -1155,6 +1161,7 @@ struct buf_page_struct{
 					0 if the block was never accessed
 					in the buffer pool */
 	/* @} */
+	ibool		is_corrupt;
 # ifdef UNIV_DEBUG_FILE_ACCESSES
 	ibool		file_page_was_freed;
 					/*!< this is set to TRUE when fsp
@@ -1422,11 +1429,11 @@ struct buf_pool_struct{
 	/* @{ */
 	UT_LIST_BASE_NODE_T(buf_page_t)	zip_clean;
 					/*!< unmodified compressed pages */
-	UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES];
+	UT_LIST_BASE_NODE_T(buf_page_t) zip_free[BUF_BUDDY_SIZES_MAX];
 					/*!< buddy free lists */
-#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
-# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
-#endif
+//#if BUF_BUDDY_HIGH != UNIV_PAGE_SIZE
+//# error "BUF_BUDDY_HIGH != UNIV_PAGE_SIZE"
+//#endif
 #if BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE
 # error "BUF_BUDDY_LOW > PAGE_ZIP_MIN_SIZE"
 #endif

=== modified file 'storage/xtradb/include/buf0buf.ic'
--- a/storage/xtradb/include/buf0buf.ic	2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/include/buf0buf.ic	2010-04-28 14:35:00 +0000
@@ -35,7 +35,7 @@ Created 11/5/1995 Heikki Tuuri
 #include "buf0flu.h"
 #include "buf0lru.h"
 #include "buf0rea.h"
-
+#include "srv0srv.h"
 /********************************************************************//**
 Reads the freed_page_clock of a buffer block.
 @return	freed_page_clock */
@@ -581,6 +581,12 @@ buf_block_get_frame(
 /*================*/
 	const buf_block_t*	block)	/*!< in: pointer to the control block */
 {
+	ut_a(srv_pass_corrupt_table || block);
+
+	if (srv_pass_corrupt_table && !block) {
+		return(0);
+	}
+
 	ut_ad(block);
 
 	switch (buf_block_get_state(block)) {

=== modified file 'storage/xtradb/include/buf0types.h'
--- a/storage/xtradb/include/buf0types.h	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/buf0types.h	2010-03-22 20:42:52 +0000
@@ -70,6 +70,7 @@ enum buf_io_fix {
 					buddy system; must be at least
 					sizeof(buf_page_t) */
 #define BUF_BUDDY_SIZES		(UNIV_PAGE_SIZE_SHIFT - BUF_BUDDY_LOW_SHIFT)
+#define BUF_BUDDY_SIZES_MAX	(UNIV_PAGE_SIZE_SHIFT_MAX - BUF_BUDDY_LOW_SHIFT)
 					/*!< number of buddy sizes */
 
 /** twice the maximum block size of the buddy system;

=== modified file 'storage/xtradb/include/dict0dict.h'
--- a/storage/xtradb/include/dict0dict.h	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/dict0dict.h	2010-03-22 20:42:52 +0000
@@ -1164,6 +1164,15 @@ void
 dict_close(void);
 /*============*/
 
+/*************************************************************************
+set is_corrupt flag by space_id*/
+
+void
+dict_table_set_corrupt_by_space(
+/*============================*/
+	ulint	space_id,
+	ibool	need_mutex);
+
 #ifndef UNIV_NONINL
 #include "dict0dict.ic"
 #endif

=== modified file 'storage/xtradb/include/dict0mem.h'
--- a/storage/xtradb/include/dict0mem.h	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/dict0mem.h	2010-03-22 20:42:52 +0000
@@ -521,6 +521,7 @@ struct dict_table_struct{
 				the AUTOINC lock on this table. */
 				/* @} */
 	/*----------------------*/
+	ibool		is_corrupt;
 #endif /* !UNIV_HOTBACKUP */
 
 #ifdef UNIV_DEBUG

=== modified file 'storage/xtradb/include/fil0fil.h'
--- a/storage/xtradb/include/fil0fil.h	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/fil0fil.h	2010-03-22 20:42:52 +0000
@@ -116,6 +116,7 @@ extern fil_addr_t	fil_addr_null;
 #define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID  34 /*!< starting from 4.1.x this
 					contains the space id of the page */
 #define FIL_PAGE_DATA		38	/*!< start of the data on the page */
+#define FIL_PAGE_DATA_ALIGN_32	40
 /* @} */
 /** File page trailer @{ */
 #define FIL_PAGE_END_LSN_OLD_CHKSUM 8	/*!< the low 4 bytes of this are used
@@ -748,6 +749,19 @@ ulint
 fil_system_hash_nodes(void);
 /*========================*/
 
+/*************************************************************************
+functions to access is_corrupt flag of fil_space_t*/
+
+ibool
+fil_space_is_corrupt(
+/*=================*/
+	ulint	space_id);
+
+void
+fil_space_set_corrupt(
+/*==================*/
+	ulint	space_id);
+
 typedef	struct fil_space_struct	fil_space_t;
 
 #endif

=== modified file 'storage/xtradb/include/fut0fut.ic'
--- a/storage/xtradb/include/fut0fut.ic	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/fut0fut.ic	2010-03-22 20:42:52 +0000
@@ -23,6 +23,7 @@ File-based utilities
 Created 12/13/1995 Heikki Tuuri
 ***********************************************************************/
 
+#include "srv0srv.h"
 #include "sync0rw.h"
 #include "buf0buf.h"
 
@@ -48,6 +49,12 @@ fut_get_ptr(
 	ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
 
 	block = buf_page_get(space, zip_size, addr.page, rw_latch, mtr);
+
+	if (srv_pass_corrupt_table && !block) {
+		return(0);
+	}
+	ut_a(block);
+
 	ptr = buf_block_get_frame(block) + addr.boffset;
 
 	buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);

=== modified file 'storage/xtradb/include/page0cur.h'
--- a/storage/xtradb/include/page0cur.h	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/page0cur.h	2010-03-22 20:42:52 +0000
@@ -293,6 +293,22 @@ page_cur_open_on_rnd_user_rec(
 /*==========================*/
 	buf_block_t*	block,	/*!< in: page */
 	page_cur_t*	cursor);/*!< out: page cursor */
+
+UNIV_INTERN
+void
+page_cur_open_on_nth_user_rec(
+/*==========================*/
+	buf_block_t*	block,	/*!< in: page */
+	page_cur_t*	cursor,	/*!< out: page cursor */
+	ulint		nth);
+
+UNIV_INTERN
+ibool
+page_cur_open_on_rnd_user_rec_after_nth(
+/*==========================*/
+	buf_block_t*	block,	/*!< in: page */
+	page_cur_t*	cursor,	/*!< out: page cursor */
+	ulint		nth);
 #endif /* !UNIV_HOTBACKUP */
 /***********************************************************//**
 Parses a log record of a record insert on a page.

=== modified file 'storage/xtradb/include/page0types.h'
--- a/storage/xtradb/include/page0types.h	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/page0types.h	2010-03-22 20:42:52 +0000
@@ -56,8 +56,9 @@ page0*.h includes rem0rec.h and may incl
 
 /** Number of supported compressed page sizes */
 #define PAGE_ZIP_NUM_SSIZE (UNIV_PAGE_SIZE_SHIFT - PAGE_ZIP_MIN_SIZE_SHIFT + 2)
-#if PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)
-# error "PAGE_ZIP_NUM_SSIZE > (1 << PAGE_ZIP_SSIZE_BITS)"
+#define PAGE_ZIP_NUM_SSIZE_MAX (UNIV_PAGE_SIZE_SHIFT_MAX - PAGE_ZIP_MIN_SIZE_SHIFT + 2)
+#if PAGE_ZIP_NUM_SSIZE_MAX > (1 << PAGE_ZIP_SSIZE_BITS)
+# error "PAGE_ZIP_NUM_SSIZE_MAX > (1 << PAGE_ZIP_SSIZE_BITS)"
 #endif
 
 /** Compressed page descriptor */
@@ -98,7 +99,7 @@ struct page_zip_stat_struct {
 typedef struct page_zip_stat_struct page_zip_stat_t;
 
 /** Statistics on compression, indexed by page_zip_des_struct::ssize - 1 */
-extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
+extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE_MAX - 1];
 
 /**********************************************************************//**
 Write the "deleted" flag of a record on a compressed page.  The flag must

=== modified file 'storage/xtradb/include/srv0srv.h'
--- a/storage/xtradb/include/srv0srv.h	2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/include/srv0srv.h	2010-04-28 14:35:00 +0000
@@ -227,6 +227,7 @@ extern ulint	srv_stats_update_need_lock;
 
 extern ibool	srv_use_doublewrite_buf;
 extern ibool	srv_use_checksums;
+extern ibool	srv_fast_checksum;
 
 extern ibool	srv_set_thread_priorities;
 extern int	srv_query_thread_priority;
@@ -247,6 +248,7 @@ extern ulong	srv_adaptive_checkpoint;
 
 extern ulong	srv_expand_import;
 extern ulint	srv_relax_table_creation;
+extern ulint	srv_pass_corrupt_table;
 
 extern ulong	srv_extra_rsegments;
 extern ulong	srv_dict_size_limit;

=== modified file 'storage/xtradb/include/trx0sys.h'
--- a/storage/xtradb/include/trx0sys.h	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/include/trx0sys.h	2010-03-22 20:42:52 +0000
@@ -487,9 +487,9 @@ in size */
 /** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
 #define TRX_SYS_MYSQL_LOG_MAGIC_N	873422344
 
-#if UNIV_PAGE_SIZE < 4096
-# error "UNIV_PAGE_SIZE < 4096"
-#endif
+//#if UNIV_PAGE_SIZE < 4096
+//# error "UNIV_PAGE_SIZE < 4096"
+//#endif
 /** The offset of the MySQL replication info in the trx system header;
 this contains the same fields as TRX_SYS_MYSQL_LOG_INFO below */
 #define TRX_SYS_MYSQL_MASTER_LOG_INFO	(UNIV_PAGE_SIZE - 2000)

=== modified file 'storage/xtradb/include/univ.i'
--- a/storage/xtradb/include/univ.i	2010-04-28 13:53:04 +0000
+++ b/storage/xtradb/include/univ.i	2010-04-28 14:35:00 +0000
@@ -47,7 +47,7 @@ Created 1/20/1994 Heikki Tuuri
 #define INNODB_VERSION_MAJOR	1
 #define INNODB_VERSION_MINOR	0
 #define INNODB_VERSION_BUGFIX	6
-#define PERCONA_INNODB_VERSION	9.1
+#define PERCONA_INNODB_VERSION	10
 
 /* The following is the InnoDB version as shown in
 SELECT plugin_version FROM information_schema.plugins;
@@ -288,9 +288,13 @@ management to ensure correct alignment f
 */
 
 /* The 2-logarithm of UNIV_PAGE_SIZE: */
-#define UNIV_PAGE_SIZE_SHIFT	14
+/* #define UNIV_PAGE_SIZE_SHIFT	14 */
+#define UNIV_PAGE_SIZE_SHIFT_MAX	14
+#define UNIV_PAGE_SIZE_SHIFT	srv_page_size_shift
 /* The universal page size of the database */
-#define UNIV_PAGE_SIZE		(1u << UNIV_PAGE_SIZE_SHIFT)
+/* #define UNIV_PAGE_SIZE		(1u << UNIV_PAGE_SIZE_SHIFT) */
+#define UNIV_PAGE_SIZE		srv_page_size
+#define UNIV_PAGE_SIZE_MAX	(1u << UNIV_PAGE_SIZE_SHIFT_MAX)
 
 /* Maximum number of parallel threads in a parallelized operation */
 #define UNIV_MAX_PARALLELISM	32
@@ -383,7 +387,7 @@ number indicate that a field contains a 
 stored part of the field in the tablespace. The length field then
 contains the sum of the following flag and the locally stored len. */
 
-#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE)
+#define UNIV_EXTERN_STORAGE_FIELD (UNIV_SQL_NULL - UNIV_PAGE_SIZE_MAX)
 
 /* Some macros to improve branch prediction and reduce cache misses */
 #if defined(__GNUC__) && (__GNUC__ > 2) && ! defined(__INTEL_COMPILER)
@@ -486,4 +490,6 @@ typedef void* os_thread_ret_t;
 	UNIV_MEM_ALLOC(addr, size);			\
 } while (0)
 
+extern ulint	srv_page_size_shift;
+extern ulint	srv_page_size;
 #endif

=== modified file 'storage/xtradb/include/ut0rnd.h'
--- a/storage/xtradb/include/ut0rnd.h	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0rnd.h	2010-03-22 20:42:52 +0000
@@ -124,6 +124,13 @@ ut_fold_binary(
 	const byte*	str,	/*!< in: string of bytes */
 	ulint		len)	/*!< in: length */
 	__attribute__((pure));
+UNIV_INLINE
+ulint
+ut_fold_binary_32(
+/*==============*/
+	const byte*	str,	/*!< in: string of bytes */
+	ulint		len)	/*!< in: length */
+	__attribute__((pure));
 /***********************************************************//**
 Looks for a prime number slightly greater than the given argument.
 The prime is chosen so that it is not near any power of 2.

=== modified file 'storage/xtradb/include/ut0rnd.ic'
--- a/storage/xtradb/include/ut0rnd.ic	2009-09-07 10:22:53 +0000
+++ b/storage/xtradb/include/ut0rnd.ic	2010-03-22 20:42:52 +0000
@@ -228,3 +228,28 @@ ut_fold_binary(
 
 	return(fold);
 }
+
+UNIV_INLINE
+ulint
+ut_fold_binary_32(
+/*==============*/
+	const byte*	str,	/*!< in: string of bytes */
+	ulint		len)	/*!< in: length */
+{
+	const ib_uint32_t*	str_end = (const ib_uint32_t*) (str + len);
+	const ib_uint32_t*	str_32 = (const ib_uint32_t*) str;
+	ulint			fold = 0;
+
+	ut_ad(str);
+	/* This function is only for word-aligned data */
+	ut_ad(len % 4 == 0);
+	ut_ad((ulint)str % 4 == 0);
+
+	while (str_32 < str_end) {
+		fold = ut_fold_ulint_pair(fold, (ulint)(*str_32));
+
+		str_32++;
+	}
+
+	return(fold);
+}

=== modified file 'storage/xtradb/lock/lock0lock.c'
--- a/storage/xtradb/lock/lock0lock.c	2010-03-18 15:25:47 +0000
+++ b/storage/xtradb/lock/lock0lock.c	2010-03-22 20:42:52 +0000
@@ -3364,26 +3364,23 @@ lock_deadlock_recursive(
 		bit_no = lock_rec_find_set_bit(wait_lock);
 
 		ut_a(bit_no != ULINT_UNDEFINED);
-                
-                /* get the starting point for the search for row level locks 
-                   since we are scanning from the front of the list */
-                lock = lock_rec_get_first_on_page_addr(wait_lock->un_member.rec_lock.space, 
-                                                       wait_lock->un_member.rec_lock.page_no);
-	}
-        else {
-                /* table level locks use a two-way linked list so scanning backwards is OK */
-                lock = UT_LIST_GET_PREV(un_member.tab_lock.locks,
-						lock);
-        }
+	}
 
 	/* Look at the locks ahead of wait_lock in the lock queue */
 
 	for (;;) {
+		if (lock_get_type_low(lock) & LOCK_TABLE) {
 
+			lock = UT_LIST_GET_PREV(un_member.tab_lock.locks,
+						lock);
+		} else {
+			ut_ad(lock_get_type_low(lock) == LOCK_REC);
+			ut_a(bit_no != ULINT_UNDEFINED);
+
+			lock = (lock_t*) lock_rec_get_prev(lock, bit_no);
+		}
 
-                /* reached the original lock in the queue for row level locks
-                   or past beginning of the list for table level locks */
-		if (lock == NULL || lock == wait_lock) {
+		if (lock == NULL) {
 			/* We can mark this subtree as searched */
 			trx->deadlock_mark = 1;
 
@@ -3508,17 +3505,6 @@ lock_deadlock_recursive(
 				}
 			}
 		}
-
-                /* next lock to check */
-                if (lock_get_type_low(lock) & LOCK_TABLE) {
-			lock = UT_LIST_GET_PREV(un_member.tab_lock.locks,
-						lock);
-		} else {
-			ut_ad(lock_get_type_low(lock) == LOCK_REC);
-			ut_a(bit_no != ULINT_UNDEFINED);
-
-			lock = (lock_t*) lock_rec_get_next(bit_no, lock);
-		}
 	}/* end of the 'for (;;)'-loop */
 }
 

=== modified file 'storage/xtradb/log/log0log.c'
--- a/storage/xtradb/log/log0log.c	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/log/log0log.c	2010-03-22 20:42:52 +0000
@@ -608,7 +608,9 @@ log_group_calc_lsn_offset(
 
 	offset = (gr_lsn_size_offset + difference) % group_size;
 
+	if (sizeof(ulint) == 4) {
 	ut_a(offset < (((ib_int64_t) 1) << 32)); /* offset must be < 4 GB */
+	}
 
 	/* fprintf(stderr,
 	"Offset is %lu gr_lsn_offset is %lu difference is %lu\n",
@@ -1805,6 +1807,7 @@ log_group_checkpoint(
 	mach_write_to_4(buf + LOG_CHECKPOINT_LOG_BUF_SIZE, log_sys->buf_size);
 
 #ifdef UNIV_LOG_ARCHIVE
+#error "UNIV_LOG_ARCHIVE could not be enabled"
 	if (log_sys->archiving_state == LOG_ARCH_OFF) {
 		archived_lsn = IB_ULONGLONG_MAX;
 	} else {
@@ -1818,7 +1821,9 @@ log_group_checkpoint(
 
 	mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, archived_lsn);
 #else /* UNIV_LOG_ARCHIVE */
-	mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN, IB_ULONGLONG_MAX);
+	mach_write_ull(buf + LOG_CHECKPOINT_ARCHIVED_LSN,
+			(ib_uint64_t)log_group_calc_lsn_offset(
+				log_sys->next_checkpoint_lsn, group));
 #endif /* UNIV_LOG_ARCHIVE */
 
 	for (i = 0; i < LOG_MAX_N_GROUPS; i++) {

=== modified file 'storage/xtradb/log/log0recv.c'
--- a/storage/xtradb/log/log0recv.c	2010-03-31 20:50:54 +0000
+++ b/storage/xtradb/log/log0recv.c	2010-04-28 14:35:00 +0000
@@ -680,8 +680,22 @@ recv_find_max_checkpoint(
 
 			group->lsn = mach_read_ull(
 				buf + LOG_CHECKPOINT_LSN);
+
+#ifdef UNIV_LOG_ARCHIVE
+#error "UNIV_LOG_ARCHIVE could not be enabled"
+#endif
+			{
+			ib_uint64_t tmp_lsn_offset = mach_read_ull(
+					buf + LOG_CHECKPOINT_ARCHIVED_LSN);
+				if (sizeof(ulint) != 4
+				    && tmp_lsn_offset != IB_ULONGLONG_MAX) {
+					group->lsn_offset = (ulint) tmp_lsn_offset;
+				} else {
 			group->lsn_offset = mach_read_from_4(
 				buf + LOG_CHECKPOINT_OFFSET);
+				}
+			}
+
 			checkpoint_no = mach_read_ull(
 				buf + LOG_CHECKPOINT_NO);
 

=== modified file 'storage/xtradb/page/page0cur.c'
--- a/storage/xtradb/page/page0cur.c	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/page/page0cur.c	2010-03-22 20:42:52 +0000
@@ -564,6 +564,74 @@ page_cur_open_on_rnd_user_rec(
 	} while (rnd--);
 }
 
+UNIV_INTERN
+void
+page_cur_open_on_nth_user_rec(
+/*==========================*/
+	buf_block_t*	block,	/*!< in: page */
+	page_cur_t*	cursor,	/*!< out: page cursor */
+	ulint		nth)
+{
+	ulint	n_recs = page_get_n_recs(buf_block_get_frame(block));
+
+	page_cur_set_before_first(block, cursor);
+
+	if (UNIV_UNLIKELY(n_recs == 0)) {
+
+		return;
+	}
+
+	nth--;
+
+	if (nth >= n_recs) {
+		nth = n_recs - 1;
+	}
+
+	do {
+		page_cur_move_to_next(cursor);
+	} while (nth--);
+}
+
+UNIV_INTERN
+ibool
+page_cur_open_on_rnd_user_rec_after_nth(
+/*==========================*/
+	buf_block_t*	block,	/*!< in: page */
+	page_cur_t*	cursor,	/*!< out: page cursor */
+	ulint		nth)
+{
+	ulint	rnd;
+	ulint	n_recs = page_get_n_recs(buf_block_get_frame(block));
+	ibool	ret;
+
+	page_cur_set_before_first(block, cursor);
+
+	if (UNIV_UNLIKELY(n_recs == 0)) {
+
+		return (FALSE);
+	}
+
+	nth--;
+
+	if (nth >= n_recs) {
+		nth = n_recs - 1;
+	}
+
+	rnd = (ulint) (nth + page_cur_lcg_prng() % (n_recs - nth));
+
+	if (rnd == nth) {
+		ret = TRUE;
+	} else {
+		ret = FALSE;
+	}
+
+	do {
+		page_cur_move_to_next(cursor);
+	} while (rnd--);
+
+	return (ret);
+}
+
 /***********************************************************//**
 Writes the log record of a record insert on a page. */
 static

=== modified file 'storage/xtradb/page/page0zip.c'
--- a/storage/xtradb/page/page0zip.c	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/page/page0zip.c	2010-03-22 20:42:52 +0000
@@ -49,7 +49,7 @@ Created June 2005 by Marko Makela
 
 #ifndef UNIV_HOTBACKUP
 /** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
-UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
+UNIV_INTERN page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE_MAX - 1];
 #endif /* !UNIV_HOTBACKUP */
 
 /* Please refer to ../include/page0zip.ic for a description of the

=== modified file 'storage/xtradb/row/row0ins.c'
--- a/storage/xtradb/row/row0ins.c	2010-01-15 15:58:25 +0000
+++ b/storage/xtradb/row/row0ins.c	2010-04-28 14:35:00 +0000
@@ -1340,6 +1340,12 @@ run_again:
 		const rec_t*		rec = btr_pcur_get_rec(&pcur);
 		const buf_block_t*	block = btr_pcur_get_block(&pcur);
 
+		if (srv_pass_corrupt_table && !block) {
+			err = DB_CORRUPTION;
+			break;
+		}
+		ut_a(block);
+
 		if (page_rec_is_infimum(rec)) {
 
 			goto next_rec;

=== modified file 'storage/xtradb/row/row0merge.c'
--- a/storage/xtradb/row/row0merge.c	2010-01-06 12:00:14 +0000
+++ b/storage/xtradb/row/row0merge.c	2010-03-22 20:42:52 +0000
@@ -92,7 +92,7 @@ This buffer is used for writing or readi
 row_merge_block_t.  Thus, it must be able to hold one merge record,
 whose maximum size is the same as the minimum size of
 row_merge_block_t. */
-typedef byte	mrec_buf_t[UNIV_PAGE_SIZE];
+typedef byte	mrec_buf_t[UNIV_PAGE_SIZE_MAX];
 
 /** @brief Merge record in row_merge_block_t.
 
@@ -1216,6 +1216,13 @@ row_merge_read_clustered_index(
 
 		if (UNIV_LIKELY(has_next)) {
 			rec = btr_pcur_get_rec(&pcur);
+
+			if (srv_pass_corrupt_table && !rec) {
+				err = DB_CORRUPTION;
+				goto err_exit;
+			}
+			ut_a(rec);
+
 			offsets = rec_get_offsets(rec, clust_index, NULL,
 						  ULINT_UNDEFINED, &row_heap);
 

=== modified file 'storage/xtradb/row/row0sel.c'
--- a/storage/xtradb/row/row0sel.c	2010-01-15 21:12:30 +0000
+++ b/storage/xtradb/row/row0sel.c	2010-04-28 14:35:00 +0000
@@ -3766,6 +3766,13 @@ rec_loop:
 	/* PHASE 4: Look for matching records in a loop */
 
 	rec = btr_pcur_get_rec(pcur);
+
+	if (srv_pass_corrupt_table && !rec) {
+		err = DB_CORRUPTION;
+		goto lock_wait_or_error;
+	}
+	ut_a(rec);
+
 	ut_ad(!!page_rec_is_comp(rec) == comp);
 #ifdef UNIV_SEARCH_DEBUG
 	/*

=== modified file 'storage/xtradb/srv/srv0srv.c'
--- a/storage/xtradb/srv/srv0srv.c	2010-01-15 19:48:33 +0000
+++ b/storage/xtradb/srv/srv0srv.c	2010-04-28 14:35:00 +0000
@@ -224,6 +224,10 @@ UNIV_INTERN ulint	srv_n_file_io_threads	
 UNIV_INTERN ulint	srv_n_read_io_threads	= ULINT_MAX;
 UNIV_INTERN ulint	srv_n_write_io_threads	= ULINT_MAX;
 
+/* The universal page size of the database */
+UNIV_INTERN ulint	srv_page_size_shift	= 0;
+UNIV_INTERN ulint	srv_page_size		= 0;
+
 /* User settable value of the number of pages that must be present
 in the buffer cache and accessed sequentially for InnoDB to trigger a
 readahead request. */
@@ -386,6 +390,7 @@ UNIV_INTERN ulint	srv_stats_update_need_
 
 UNIV_INTERN ibool	srv_use_doublewrite_buf	= TRUE;
 UNIV_INTERN ibool	srv_use_checksums = TRUE;
+UNIV_INTERN ibool	srv_fast_checksum = FALSE;
 
 UNIV_INTERN ibool	srv_set_thread_priorities = TRUE;
 UNIV_INTERN int	srv_query_thread_priority = 0;
@@ -406,6 +411,7 @@ UNIV_INTERN ulong	srv_adaptive_checkpoin
 
 UNIV_INTERN ulong	srv_expand_import = 0; /* 0:disable 1:enable */
 UNIV_INTERN ulint	srv_relax_table_creation = 0; /* 0:disable 1:enable */
+UNIV_INTERN ulint	srv_pass_corrupt_table = 0; /* 0:disable 1:enable */
 
 UNIV_INTERN ulong	srv_extra_rsegments = 0; /* extra rseg for users */
 UNIV_INTERN ulong	srv_dict_size_limit = 0;
@@ -2559,6 +2565,7 @@ srv_master_thread(
 	srv_main_thread_process_no = os_proc_get_number();
 	srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
 
+
 	mutex_enter(&kernel_mutex);
 
 	srv_table_reserve_slot(SRV_MASTER);

=== modified file 'storage/xtradb/srv/srv0start.c'
--- a/storage/xtradb/srv/srv0start.c	2010-01-17 08:41:43 +0000
+++ b/storage/xtradb/srv/srv0start.c	2010-04-28 14:35:00 +0000
@@ -1352,10 +1352,12 @@ innobase_start_or_create_for_mysql(void)
 	}
 #endif /* UNIV_LOG_ARCHIVE */
 
-	if (srv_n_log_files * srv_log_file_size >= 262144) {
+	if (sizeof(ulint) == 4
+	    && srv_n_log_files * srv_log_file_size
+	       >= ((ulint)1 << (32 - UNIV_PAGE_SIZE_SHIFT))) {
 		fprintf(stderr,
 			"InnoDB: Error: combined size of log files"
-			" must be < 4 GB\n");
+			" must be < 4 GB on 32-bit systems\n");
 
 		return(DB_ERROR);
 	}
@@ -1364,7 +1366,7 @@ innobase_start_or_create_for_mysql(void)
 
 	for (i = 0; i < srv_n_data_files; i++) {
 #ifndef __WIN__
-		if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
+		if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= ((ulint)1 << (32 - UNIV_PAGE_SIZE_SHIFT))) {
 			fprintf(stderr,
 				"InnoDB: Error: file size must be < 4 GB"
 				" with this MySQL binary\n"
@@ -1809,6 +1811,13 @@ innobase_start_or_create_for_mysql(void)
 
 	os_fast_mutex_free(&srv_os_test_mutex);
 
+	if (!srv_file_per_table_original_value
+	    && srv_pass_corrupt_table) {
+		fprintf(stderr, "InnoDB: Warning:"
+			" innodb_file_per_table is diabled."
+			" So innodb_pass_corrupt_table doesn't make sence\n");
+	}
+
 	if (srv_print_verbose_log) {
 		ut_print_timestamp(stderr);
 		fprintf(stderr,