]> git.pld-linux.org Git - packages/mysql.git/blame - innodb_pass_corrupt_table.patch
- disable response-time-distribution patch on arch which has no atomic builtins even...
[packages/mysql.git] / innodb_pass_corrupt_table.patch
CommitLineData
b4e1fa2c
AM
1# name : innodb_pass_corrupt_table.patch
2# introduced : 11 or before
3# maintainer : Yasufumi
4#
5#!!! notice !!!
6# Any small change to this file in the main branch
7# should be done or reviewed by the maintainer!
8diff -ruN a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
9--- a/storage/innobase/btr/btr0btr.c 2010-11-03 07:01:13.000000000 +0900
10+++ b/storage/innobase/btr/btr0btr.c 2010-12-04 15:38:18.110513593 +0900
11822e22 11@@ -691,6 +691,12 @@
b4e1fa2c
AM
12 root_page_no = dict_index_get_page(index);
13
14 block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
15+
16+ if (srv_pass_corrupt_table && !block) {
17+ return(0);
18+ }
19+ ut_a(block);
20+
21 ut_a((ibool)!!page_is_comp(buf_block_get_frame(block))
22 == dict_table_is_comp(index->table));
23 #ifdef UNIV_BTR_DEBUG
11822e22 24@@ -977,6 +983,12 @@
b4e1fa2c
AM
25
26 root = btr_root_get(index, &mtr);
27
28+ if (srv_pass_corrupt_table && !root) {
29+ mtr_commit(&mtr);
30+ return(0);
31+ }
32+ ut_a(root);
33+
34 if (flag == BTR_N_LEAF_PAGES) {
35 seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
36
11822e22 37@@ -1433,6 +1445,13 @@
b4e1fa2c
AM
38 mtr_start(&mtr);
39
40 root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
41+
42+ if (srv_pass_corrupt_table && !root) {
43+ mtr_commit(&mtr);
44+ return;
45+ }
46+ ut_a(root);
47+
48 #ifdef UNIV_BTR_DEBUG
49 ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
50 + root, space));
11822e22 51@@ -1455,6 +1474,12 @@
b4e1fa2c
AM
52 mtr_start(&mtr);
53
54 root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
55+
56+ if (srv_pass_corrupt_table && !root) {
57+ mtr_commit(&mtr);
58+ return;
59+ }
60+ ut_a(root);
61 #ifdef UNIV_BTR_DEBUG
62 ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
63 + root, space));
11822e22 64@@ -1488,6 +1513,11 @@
b4e1fa2c
AM
65
66 block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
67
68+ if (srv_pass_corrupt_table && !block) {
69+ return;
70+ }
71+ ut_a(block);
72+
73 btr_search_drop_page_hash_index(block);
74
75 header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
76diff -ruN a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
77--- a/storage/innobase/btr/btr0cur.c 2010-12-03 17:30:16.239038936 +0900
78+++ b/storage/innobase/btr/btr0cur.c 2010-12-04 15:38:18.114551906 +0900
df1b5770 79@@ -250,6 +250,11 @@
b4e1fa2c
AM
80 case BTR_MODIFY_LEAF:
81 mode = latch_mode == BTR_SEARCH_LEAF ? RW_S_LATCH : RW_X_LATCH;
82 get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
83+
84+ if (srv_pass_corrupt_table && !get_block) {
85+ return;
86+ }
87+ ut_a(get_block);
88 #ifdef UNIV_BTR_DEBUG
89 ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
90 #endif /* UNIV_BTR_DEBUG */
df1b5770 91@@ -263,6 +268,11 @@
b4e1fa2c
AM
92 get_block = btr_block_get(space, zip_size,
93 left_page_no,
94 RW_X_LATCH, mtr);
95+
96+ if (srv_pass_corrupt_table && !get_block) {
97+ return;
98+ }
99+ ut_a(get_block);
100 #ifdef UNIV_BTR_DEBUG
101 ut_a(page_is_comp(get_block->frame)
102 == page_is_comp(page));
df1b5770 103@@ -274,6 +284,11 @@
b4e1fa2c
AM
104
105 get_block = btr_block_get(space, zip_size, page_no,
106 RW_X_LATCH, mtr);
107+
108+ if (srv_pass_corrupt_table && !get_block) {
109+ return;
110+ }
111+ ut_a(get_block);
112 #ifdef UNIV_BTR_DEBUG
113 ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
114 #endif /* UNIV_BTR_DEBUG */
df1b5770 115@@ -285,6 +300,11 @@
b4e1fa2c
AM
116 get_block = btr_block_get(space, zip_size,
117 right_page_no,
118 RW_X_LATCH, mtr);
119+
120+ if (srv_pass_corrupt_table && !get_block) {
121+ return;
122+ }
123+ ut_a(get_block);
124 #ifdef UNIV_BTR_DEBUG
125 ut_a(page_is_comp(get_block->frame)
126 == page_is_comp(page));
df1b5770 127@@ -306,6 +326,11 @@
b4e1fa2c
AM
128 get_block = btr_block_get(space, zip_size,
129 left_page_no, mode, mtr);
130 cursor->left_block = get_block;
131+
132+ if (srv_pass_corrupt_table && !get_block) {
133+ return;
134+ }
135+ ut_a(get_block);
136 #ifdef UNIV_BTR_DEBUG
137 ut_a(page_is_comp(get_block->frame)
138 == page_is_comp(page));
df1b5770 139@@ -316,6 +341,11 @@
b4e1fa2c
AM
140 }
141
142 get_block = btr_block_get(space, zip_size, page_no, mode, mtr);
143+
144+ if (srv_pass_corrupt_table && !get_block) {
145+ return;
146+ }
147+ ut_a(get_block);
148 #ifdef UNIV_BTR_DEBUG
149 ut_a(page_is_comp(get_block->frame) == page_is_comp(page));
150 #endif /* UNIV_BTR_DEBUG */
df1b5770 151@@ -588,6 +618,19 @@
b4e1fa2c
AM
152 file, line, mtr);
153
154 if (block == NULL) {
155+ if (srv_pass_corrupt_table
156+ && buf_mode != BUF_GET_IF_IN_POOL
157+ && buf_mode != BUF_GET_IF_IN_POOL_OR_WATCH) {
158+ page_cursor->block = 0;
159+ page_cursor->rec = 0;
160+ if (estimate) {
161+ cursor->path_arr->nth_rec = ULINT_UNDEFINED;
162+ }
163+ goto func_exit;
164+ }
165+ ut_a(buf_mode == BUF_GET_IF_IN_POOL
166+ || buf_mode == BUF_GET_IF_IN_POOL_OR_WATCH);
167+
168 /* This must be a search to perform an insert/delete
169 mark/ delete; try using the insert/delete buffer */
170
df1b5770 171@@ -662,6 +705,16 @@
b4e1fa2c
AM
172 block->check_index_page_at_flush = TRUE;
173 page = buf_block_get_frame(block);
174
175+ if (srv_pass_corrupt_table && !page) {
176+ page_cursor->block = 0;
177+ page_cursor->rec = 0;
178+ if (estimate) {
179+ cursor->path_arr->nth_rec = ULINT_UNDEFINED;
180+ }
181+ goto func_exit;
182+ }
183+ ut_a(page);
184+
185 if (rw_latch != RW_NO_LATCH) {
186 #ifdef UNIV_ZIP_DEBUG
187 const page_zip_des_t* page_zip
df1b5770 188@@ -866,6 +919,17 @@
b4e1fa2c
AM
189 RW_NO_LATCH, NULL, BUF_GET,
190 file, line, mtr);
191 page = buf_block_get_frame(block);
192+
193+ if (srv_pass_corrupt_table && !page) {
194+ page_cursor->block = 0;
195+ page_cursor->rec = 0;
196+ if (estimate) {
197+ cursor->path_arr->nth_rec = ULINT_UNDEFINED;
198+ }
199+ break;
200+ }
201+ ut_a(page);
202+
203 ut_ad(index->id == btr_page_get_index_id(page));
204
205 block->check_index_page_at_flush = TRUE;
df1b5770 206@@ -986,6 +1050,14 @@
b4e1fa2c
AM
207 RW_NO_LATCH, NULL, BUF_GET,
208 file, line, mtr);
209 page = buf_block_get_frame(block);
210+
211+ if (srv_pass_corrupt_table && !page) {
212+ page_cursor->block = 0;
213+ page_cursor->rec = 0;
214+ break;
215+ }
216+ ut_a(page);
217+
218 ut_ad(index->id == btr_page_get_index_id(page));
219
220 if (height == ULINT_UNDEFINED) {
df1b5770 221@@ -1199,6 +1271,12 @@
b4e1fa2c
AM
222 *big_rec = NULL;
223
224 block = btr_cur_get_block(cursor);
225+
226+ if (srv_pass_corrupt_table && !block) {
227+ return(DB_CORRUPTION);
228+ }
229+ ut_a(block);
230+
231 page = buf_block_get_frame(block);
232 index = cursor->index;
233 zip_size = buf_block_get_zip_size(block);
11822e22 234@@ -2925,6 +3003,11 @@
b4e1fa2c
AM
235
236 block = btr_cur_get_block(cursor);
237
238+ if (srv_pass_corrupt_table && !block) {
239+ return(DB_CORRUPTION);
240+ }
241+ ut_a(block);
242+
243 ut_ad(page_is_leaf(buf_block_get_frame(block)));
244
245 rec = btr_cur_get_rec(cursor);
11822e22 246@@ -3628,6 +3711,11 @@
b4e1fa2c
AM
247
248 page = btr_cur_get_page(&cursor);
249
250+ if (srv_pass_corrupt_table && !page) {
251+ break;
252+ }
253+ ut_a(page);
254+
df1b5770
AM
255 rec = page_rec_get_next(page_get_infimum_rec(page));
256
257 if (!page_rec_is_supremum(rec)) {
b4e1fa2c
AM
258diff -ruN a/storage/innobase/btr/btr0pcur.c b/storage/innobase/btr/btr0pcur.c
259--- a/storage/innobase/btr/btr0pcur.c 2010-11-03 07:01:13.000000000 +0900
260+++ b/storage/innobase/btr/btr0pcur.c 2010-12-04 15:38:18.116563877 +0900
261@@ -32,7 +32,7 @@
262 #include "ut0byte.h"
263 #include "rem0cmp.h"
264 #include "trx0trx.h"
265-
266+#include "srv0srv.h"
267 /**************************************************************//**
268 Allocates memory for a persistent cursor object and initializes the cursor.
269 @return own: persistent cursor */
270@@ -102,6 +102,12 @@
271 ut_ad(cursor->latch_mode != BTR_NO_LATCHES);
272
273 block = btr_pcur_get_block(cursor);
274+
275+ if (srv_pass_corrupt_table && !block) {
276+ return;
277+ }
278+ ut_a(block);
279+
280 index = btr_cur_get_index(btr_pcur_get_btr_cur(cursor));
281
282 page_cursor = btr_pcur_get_page_cur(cursor);
283@@ -419,6 +425,15 @@
284 next_block = btr_block_get(space, zip_size, next_page_no,
285 cursor->latch_mode, mtr);
286 next_page = buf_block_get_frame(next_block);
287+
288+ if (srv_pass_corrupt_table && !next_page) {
289+ btr_leaf_page_release(btr_pcur_get_block(cursor),
290+ cursor->latch_mode, mtr);
291+ btr_pcur_get_page_cur(cursor)->block = 0;
292+ btr_pcur_get_page_cur(cursor)->rec = 0;
293+ return;
294+ }
295+ ut_a(next_page);
296 #ifdef UNIV_BTR_DEBUG
297 ut_a(page_is_comp(next_page) == page_is_comp(page));
298 ut_a(btr_page_get_prev(next_page, mtr)
299diff -ruN a/storage/innobase/btr/btr0sea.c b/storage/innobase/btr/btr0sea.c
300--- a/storage/innobase/btr/btr0sea.c 2010-12-03 15:49:59.166193407 +0900
301+++ b/storage/innobase/btr/btr0sea.c 2010-12-04 15:38:18.118548961 +0900
302@@ -42,7 +42,7 @@
303 #include "btr0pcur.h"
304 #include "btr0btr.h"
305 #include "ha0ha.h"
306-
307+#include "srv0srv.h"
308 /** Flag: has the search system been enabled?
309 Protected by btr_search_latch and btr_search_enabled_mutex. */
310 UNIV_INTERN char btr_search_enabled = TRUE;
311@@ -607,6 +607,11 @@
312
313 block = btr_cur_get_block(cursor);
314
315+ if (srv_pass_corrupt_table && !block) {
316+ return;
317+ }
318+ ut_a(block);
319+
320 /* NOTE that the following two function calls do NOT protect
321 info or block->n_fields etc. with any semaphore, to save CPU time!
322 We cannot assume the fields are consistent when we return from
323diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
324--- a/storage/innobase/buf/buf0buf.c 2010-12-04 15:37:50.554565654 +0900
325+++ b/storage/innobase/buf/buf0buf.c 2010-12-04 15:38:18.119548922 +0900
326@@ -52,6 +52,7 @@
327 #include "log0recv.h"
328 #include "page0zip.h"
329 #include "trx0trx.h"
330+#include "srv0start.h"
331
332 /* prototypes for new functions added to ha_innodb.cc */
333 trx_t* innobase_get_trx();
334@@ -1131,6 +1132,11 @@
335 ready = buf_flush_ready_for_replace(&block->page);
336 mutex_exit(&block->mutex);
337
338+ if (block->page.is_corrupt) {
339+ /* corrupt page may remain, it can be skipped */
340+ break;
341+ }
342+
343 if (!ready) {
344
345 return(block);
df1b5770 346@@ -2478,6 +2484,14 @@
b4e1fa2c
AM
347 return(NULL);
348 }
349
350+ if (srv_pass_corrupt_table) {
351+ if (bpage->is_corrupt) {
352+ rw_lock_s_unlock(&buf_pool->page_hash_latch);
353+ return(NULL);
354+ }
355+ }
356+ ut_a(!(bpage->is_corrupt));
357+
358 block_mutex = buf_page_get_mutex_enter(bpage);
359
360 rw_lock_s_unlock(&buf_pool->page_hash_latch);
df1b5770 361@@ -3024,6 +3038,14 @@
b4e1fa2c
AM
362 return(NULL);
363 }
364
365+ if (srv_pass_corrupt_table) {
366+ if (block->page.is_corrupt) {
367+ mutex_exit(block_mutex);
368+ return(NULL);
369+ }
370+ }
371+ ut_a(!(block->page.is_corrupt));
372+
373 switch (buf_block_get_state(block)) {
374 buf_page_t* bpage;
375 ibool success;
11822e22 376@@ -3693,6 +3715,7 @@
b4e1fa2c
AM
377 bpage->newest_modification = 0;
378 bpage->oldest_modification = 0;
379 HASH_INVALIDATE(bpage, hash);
380+ bpage->is_corrupt = FALSE;
df1b5770 381 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
b4e1fa2c 382 bpage->file_page_was_freed = FALSE;
df1b5770 383 #endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */
11822e22 384@@ -4203,7 +4226,8 @@
b4e1fa2c
AM
385 void
386 buf_page_io_complete(
387 /*=================*/
388- buf_page_t* bpage) /*!< in: pointer to the block in question */
389+ buf_page_t* bpage, /*!< in: pointer to the block in question */
390+ trx_t* trx)
391 {
392 enum buf_io_fix io_type;
393 buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
11822e22 394@@ -4282,6 +4306,7 @@
b4e1fa2c
AM
395 (ulong) bpage->offset);
396 }
397
398+ if (!srv_pass_corrupt_table || !bpage->is_corrupt) {
399 /* From version 3.23.38 up we store the page checksum
400 to the 4 first bytes of the page end lsn field */
401
11822e22 402@@ -4323,6 +4348,19 @@
d8778560 403 REFMAN "forcing-innodb-recovery.html\n"
b4e1fa2c
AM
404 "InnoDB: about forcing recovery.\n", stderr);
405
406+ if (srv_pass_corrupt_table && !trx_sys_sys_space(bpage->space)
407+ && bpage->space < SRV_LOG_SPACE_FIRST_ID) {
408+ fprintf(stderr,
409+ "InnoDB: space %u will be treated as corrupt.\n",
410+ bpage->space);
411+ fil_space_set_corrupt(bpage->space);
412+ if (trx && trx->dict_operation_lock_mode == 0) {
413+ dict_table_set_corrupt_by_space(bpage->space, TRUE);
414+ } else {
415+ dict_table_set_corrupt_by_space(bpage->space, FALSE);
416+ }
417+ bpage->is_corrupt = TRUE;
418+ } else
419 if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
420 fputs("InnoDB: Ending processing because of"
421 " a corrupt database page.\n",
11822e22 422@@ -4330,6 +4368,7 @@
b4e1fa2c
AM
423 exit(1);
424 }
425 }
426+ } /**/
427
428 if (recv_recovery_is_on()) {
429 /* Pages must be uncompressed for crash recovery. */
11822e22 430@@ -4339,8 +4378,11 @@
b4e1fa2c
AM
431
432 if (uncompressed && !recv_no_ibuf_operations) {
433 ibuf_merge_or_delete_for_page(
434+ /* Delete possible entries, if bpage is_corrupt */
435+ (srv_pass_corrupt_table && bpage->is_corrupt) ? NULL :
436 (buf_block_t*) bpage, bpage->space,
437 bpage->offset, buf_page_get_zip_size(bpage),
438+ (srv_pass_corrupt_table && bpage->is_corrupt) ? FALSE :
439 TRUE);
440 }
441 }
442diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
443--- a/storage/innobase/buf/buf0rea.c 2010-12-04 15:37:50.557553380 +0900
444+++ b/storage/innobase/buf/buf0rea.c 2010-12-04 15:41:09.784467585 +0900
445@@ -193,12 +193,19 @@
446 ((buf_block_t*) bpage)->frame, bpage, trx);
447 }
448 thd_wait_end(NULL);
449+
450+ if (srv_pass_corrupt_table) {
451+ if (*err != DB_SUCCESS) {
452+ bpage->is_corrupt = TRUE;
453+ }
454+ } else {
455 ut_a(*err == DB_SUCCESS);
456+ }
457
458 if (sync) {
459 /* The i/o is already completed when we arrive from
460 fil_read */
461- buf_page_io_complete(bpage);
462+ buf_page_io_complete(bpage, trx);
463 }
464
465 return(1);
466diff -ruN a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
467--- a/storage/innobase/dict/dict0dict.c 2010-12-03 17:30:16.248987063 +0900
468+++ b/storage/innobase/dict/dict0dict.c 2010-12-04 15:45:23.808513973 +0900
d8778560
AM
469@@ -55,6 +55,7 @@
470 #include "srv0srv.h" /* srv_lower_case_table_names */
b4e1fa2c 471 #include "m_ctype.h" /* my_isspace() */
d8778560 472 #include "ha_prototypes.h" /* innobase_strcasecmp(), innobase_casedn_str()*/
b4e1fa2c
AM
473+#include "srv0start.h" /* SRV_LOG_SPACE_FIRST_ID */
474
475 #include <ctype.h>
476
d8778560 477@@ -751,7 +752,7 @@
b4e1fa2c
AM
478
479 mutex_exit(&(dict_sys->mutex));
480
481- if (table != NULL) {
482+ if (table != NULL && !table->is_corrupt) {
483 /* If table->ibd_file_missing == TRUE, this will
484 print an error message and return without doing
485 anything. */
d8778560 486@@ -1294,7 +1295,7 @@
b4e1fa2c
AM
487 + dict_sys->size) > srv_dict_size_limit ) {
488 prev_table = UT_LIST_GET_PREV(table_LRU, table);
489
490- if (table == self || table->n_mysql_handles_opened)
491+ if (table == self || table->n_mysql_handles_opened || table->is_corrupt)
492 goto next_loop;
493
494 cached_foreign_tables = 0;
df1b5770 495@@ -4333,6 +4334,12 @@
b4e1fa2c
AM
496 heap = mem_heap_create(1000);
497
498 while (index) {
499+ if (table->is_corrupt) {
500+ ut_a(srv_pass_corrupt_table);
501+ mem_heap_free(heap);
502+ return(FALSE);
503+ }
504+
505 size = btr_get_size(index, BTR_TOTAL_SIZE);
506
507 index->stat_index_size = size;
11822e22 508@@ -4480,6 +4487,12 @@
b4e1fa2c
AM
509 heap = mem_heap_create(1000);
510
511 while (index) {
512+ if (table->is_corrupt) {
513+ ut_a(srv_pass_corrupt_table);
514+ mem_heap_free(heap);
515+ return;
516+ }
517+
518 /*===========================================*/
519 {
520 dict_table_t* sys_stats;
11822e22 521@@ -4666,6 +4679,12 @@
b4e1fa2c
AM
522 || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
523 && dict_index_is_clust(index)))) {
524 ulint size;
525+
526+ if (table->is_corrupt) {
527+ ut_a(srv_pass_corrupt_table);
528+ return;
529+ }
530+
531 size = btr_get_size(index, BTR_TOTAL_SIZE);
532
533 index->stat_index_size = size;
11822e22 534@@ -5462,4 +5481,42 @@
b4e1fa2c
AM
535 rw_lock_free(&dict_table_stats_latches[i]);
536 }
537 }
538+
539+/*************************************************************************
540+set is_corrupt flag by space_id*/
541+
542+void
543+dict_table_set_corrupt_by_space(
544+/*============================*/
545+ ulint space_id,
546+ ibool need_mutex)
547+{
548+ dict_table_t* table;
549+ ibool found = FALSE;
550+
551+ ut_a(!trx_sys_sys_space(space_id) && space_id < SRV_LOG_SPACE_FIRST_ID);
552+
553+ if (need_mutex)
554+ mutex_enter(&(dict_sys->mutex));
555+
556+ table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
557+
558+ while (table) {
559+ if (table->space == space_id) {
560+ table->is_corrupt = TRUE;
561+ found = TRUE;
562+ }
563+
564+ table = UT_LIST_GET_NEXT(table_LRU, table);
565+ }
566+
567+ if (need_mutex)
568+ mutex_exit(&(dict_sys->mutex));
569+
570+ if (!found) {
571+ fprintf(stderr, "InnoDB: space to be marked as "
572+ "crashed was not found for id %lu.\n",
573+ (ulong) space_id);
574+ }
575+}
576 #endif /* !UNIV_HOTBACKUP */
577diff -ruN a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c
578--- a/storage/innobase/dict/dict0mem.c 2010-11-03 07:01:13.000000000 +0900
579+++ b/storage/innobase/dict/dict0mem.c 2010-12-04 15:38:18.126549463 +0900
11822e22 580@@ -97,6 +97,8 @@
b4e1fa2c
AM
581 /* The number of transactions that are either waiting on the
582 AUTOINC lock or have been granted the lock. */
583 table->n_waiting_or_granted_auto_inc_locks = 0;
584+
585+ table->is_corrupt = FALSE;
586 #endif /* !UNIV_HOTBACKUP */
587
588 ut_d(table->magic_n = DICT_TABLE_MAGIC_N);
589diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
590--- a/storage/innobase/fil/fil0fil.c 2010-12-04 15:37:50.564551587 +0900
591+++ b/storage/innobase/fil/fil0fil.c 2010-12-04 15:38:18.128549252 +0900
592@@ -233,6 +233,7 @@
593 file we have written to */
594 ibool is_in_unflushed_spaces; /*!< TRUE if this space is
595 currently in unflushed_spaces */
596+ ibool is_corrupt;
597 UT_LIST_NODE_T(fil_space_t) space_list;
598 /*!< list of all spaces */
599 ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
d8778560 600@@ -1291,6 +1292,8 @@
b4e1fa2c
AM
601 ut_fold_string(name), space);
602 space->is_in_unflushed_spaces = FALSE;
603
604+ space->is_corrupt = FALSE;
605+
606 UT_LIST_ADD_LAST(space_list, fil_system->space_list, space);
607
608 mutex_exit(&fil_system->mutex);
d8778560 609@@ -4945,6 +4948,22 @@
b4e1fa2c
AM
610 ut_a(byte_offset % OS_FILE_LOG_BLOCK_SIZE == 0);
611 ut_a((len % OS_FILE_LOG_BLOCK_SIZE) == 0);
612
613+ if (srv_pass_corrupt_table && space->is_corrupt) {
614+ /* should ignore i/o for the crashed space */
615+ mutex_enter(&fil_system->mutex);
616+ fil_node_complete_io(node, fil_system, type);
617+ mutex_exit(&fil_system->mutex);
618+ if (mode == OS_AIO_NORMAL) {
619+ ut_a(space->purpose == FIL_TABLESPACE);
620+ buf_page_io_complete(message, trx);
621+ }
622+ if (type == OS_FILE_READ) {
623+ return(DB_TABLESPACE_DELETED);
624+ } else {
625+ return(DB_SUCCESS);
626+ }
627+ } else {
628+ ut_a(!space->is_corrupt);
629 #ifdef UNIV_HOTBACKUP
630 /* In ibbackup do normal i/o, not aio */
631 if (type == OS_FILE_READ) {
d8778560 632@@ -4959,6 +4978,8 @@
b4e1fa2c
AM
633 ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
634 offset_low, offset_high, len, node, message, trx);
635 #endif
636+ } /**/
637+
638 ut_a(ret);
639
640 if (mode == OS_AIO_SYNC) {
d8778560 641@@ -5100,7 +5121,7 @@
b4e1fa2c
AM
642
643 if (fil_node->space->purpose == FIL_TABLESPACE) {
644 srv_set_io_thread_op_info(segment, "complete io for buf page");
645- buf_page_io_complete(message);
646+ buf_page_io_complete(message, NULL);
647 } else {
648 srv_set_io_thread_op_info(segment, "complete io for log");
649 log_io_complete(message);
d8778560 650@@ -5454,3 +5475,46 @@
b4e1fa2c
AM
651 return 0;
652 }
653 }
654+
655+/*************************************************************************
656+functions to access is_corrupt flag of fil_space_t*/
657+
658+ibool
659+fil_space_is_corrupt(
660+/*=================*/
661+ ulint space_id)
662+{
663+ fil_space_t* space;
664+ ibool ret = FALSE;
665+
666+ mutex_enter(&fil_system->mutex);
667+
668+ space = fil_space_get_by_id(space_id);
669+
670+ if (space && space->is_corrupt) {
671+ ret = TRUE;
672+ }
673+
674+ mutex_exit(&fil_system->mutex);
675+
676+ return(ret);
677+}
678+
679+void
680+fil_space_set_corrupt(
681+/*==================*/
682+ ulint space_id)
683+{
684+ fil_space_t* space;
685+
686+ mutex_enter(&fil_system->mutex);
687+
688+ space = fil_space_get_by_id(space_id);
689+
690+ if (space) {
691+ space->is_corrupt = TRUE;
692+ }
693+
694+ mutex_exit(&fil_system->mutex);
695+}
696+
697diff -ruN a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
698--- a/storage/innobase/fsp/fsp0fsp.c 2010-12-04 15:37:50.569480615 +0900
699+++ b/storage/innobase/fsp/fsp0fsp.c 2010-12-04 15:38:18.131550103 +0900
700@@ -369,6 +369,12 @@
701 ut_ad(id || !zip_size);
702
703 block = buf_page_get(id, zip_size, 0, RW_X_LATCH, mtr);
704+
705+ if (srv_pass_corrupt_table && !block) {
706+ return(0);
707+ }
708+ ut_a(block);
709+
710 header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
711 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
712
713@@ -787,6 +793,12 @@
714 fsp_header_t* sp_header;
715
716 block = buf_page_get(space, zip_size, 0, RW_X_LATCH, mtr);
717+
718+ if (srv_pass_corrupt_table && !block) {
719+ return(0);
720+ }
721+ ut_a(block);
722+
723 buf_block_dbg_add_level(block, SYNC_FSP_PAGE);
724
725 sp_header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
726@@ -1866,6 +1878,11 @@
727 {
728 fseg_inode_t* inode;
729
730+ if (srv_pass_corrupt_table && !page) {
731+ return(ULINT_UNDEFINED);
732+ }
733+ ut_a(page);
734+
735 for (; i < FSP_SEG_INODES_PER_PAGE(zip_size); i++) {
736
737 inode = fsp_seg_inode_page_get_nth_inode(
738@@ -1979,6 +1996,11 @@
739
740 page = buf_block_get_frame(block);
741
742+ if (srv_pass_corrupt_table && !page) {
743+ return(0);
744+ }
745+ ut_a(page);
746+
747 n = fsp_seg_inode_page_find_free(page, 0, zip_size, mtr);
748
749 ut_a(n != ULINT_UNDEFINED);
750@@ -2072,6 +2094,11 @@
751
752 inode = fut_get_ptr(space, zip_size, inode_addr, RW_X_LATCH, mtr);
753
754+ if (srv_pass_corrupt_table && !inode) {
755+ return(0);
756+ }
757+ ut_a(inode);
758+
759 if (UNIV_UNLIKELY(!mach_read_from_8(inode + FSEG_ID))) {
760
761 inode = NULL;
762@@ -2098,7 +2125,7 @@
763 {
764 fseg_inode_t* inode
765 = fseg_inode_try_get(header, space, zip_size, mtr);
766- ut_a(inode);
767+ ut_a(srv_pass_corrupt_table || inode);
768 return(inode);
769 }
770
771@@ -3304,6 +3331,11 @@
772
773 descr = xdes_get_descriptor(space, zip_size, page, mtr);
774
775+ if (srv_pass_corrupt_table && !descr) {
776+ /* The page may be corrupt. pass it. */
777+ return;
778+ }
779+
780 ut_a(descr);
781 if (xdes_get_bit(descr, XDES_FREE_BIT, page % FSP_EXTENT_SIZE, mtr)) {
782 fputs("InnoDB: Dump of the tablespace extent descriptor: ",
783@@ -3551,6 +3583,11 @@
784
785 descr = xdes_get_descriptor(space, zip_size, header_page, mtr);
786
787+ if (srv_pass_corrupt_table && !descr) {
788+ /* The page may be corrupt. pass it. */
789+ return(TRUE);
790+ }
791+
792 /* Check that the header resides on a page which has not been
793 freed yet */
794
795@@ -3635,6 +3672,12 @@
796
797 inode = fseg_inode_get(header, space, zip_size, mtr);
798
799+ if (srv_pass_corrupt_table && !inode) {
800+ /* ignore the corruption */
801+ return(TRUE);
802+ }
803+ ut_a(inode);
804+
805 descr = fseg_get_first_extent(inode, space, zip_size, mtr);
806
807 if (descr != NULL) {
808diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
809--- a/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:37:50.578486593 +0900
810+++ b/storage/innobase/handler/ha_innodb.cc 2010-12-04 15:38:18.137549396 +0900
df1b5770 811@@ -3947,6 +3947,12 @@
b4e1fa2c
AM
812 DBUG_RETURN(1);
813 }
814
815+ if (share->ib_table && share->ib_table->is_corrupt) {
816+ free_share(share);
817+
818+ DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
819+ }
820+
821 /* Create buffers for packing the fields of a record. Why
822 table->reclength did not work here? Obviously, because char
823 fields when packed actually became 1 byte longer, when we also
df1b5770 824@@ -3974,6 +3980,19 @@
b4e1fa2c
AM
825 /* Get pointer to a table object in InnoDB dictionary cache */
826 ib_table = dict_table_get(norm_name, TRUE);
827
828+ if (ib_table && ib_table->is_corrupt) {
829+ free_share(share);
830+ my_free(upd_buff);
831+
832+ DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE);
833+ }
834+
835+ if (share->ib_table) {
836+ ut_a(share->ib_table == ib_table);
837+ } else {
838+ share->ib_table = ib_table;
839+ }
840+
841 if (NULL == ib_table) {
842 if (is_part && retries < 10) {
843 ++retries;
df1b5770 844@@ -5138,6 +5157,10 @@
b4e1fa2c
AM
845
846 ha_statistic_increment(&SSV::ha_write_count);
847
848+ if (share->ib_table->is_corrupt) {
849+ DBUG_RETURN(HA_ERR_CRASHED);
850+ }
851+
852 if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
853 table->timestamp_field->set_time();
854
df1b5770 855@@ -5355,6 +5378,10 @@
b4e1fa2c
AM
856 func_exit:
857 innobase_active_small();
858
859+ if (share->ib_table->is_corrupt) {
860+ DBUG_RETURN(HA_ERR_CRASHED);
861+ }
862+
863 DBUG_RETURN(error_result);
864 }
865
df1b5770 866@@ -5531,6 +5558,10 @@
b4e1fa2c
AM
867
868 ha_statistic_increment(&SSV::ha_update_count);
869
870+ if (share->ib_table->is_corrupt) {
871+ DBUG_RETURN(HA_ERR_CRASHED);
872+ }
873+
874 if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
875 table->timestamp_field->set_time();
876
df1b5770 877@@ -5620,6 +5651,10 @@
b4e1fa2c
AM
878
879 innobase_active_small();
880
881+ if (share->ib_table->is_corrupt) {
882+ DBUG_RETURN(HA_ERR_CRASHED);
883+ }
884+
885 DBUG_RETURN(error);
886 }
887
df1b5770 888@@ -5641,6 +5676,10 @@
b4e1fa2c
AM
889
890 ha_statistic_increment(&SSV::ha_delete_count);
891
892+ if (share->ib_table->is_corrupt) {
893+ DBUG_RETURN(HA_ERR_CRASHED);
894+ }
895+
896 if (!prebuilt->upd_node) {
897 row_get_prebuilt_update_vector(prebuilt);
898 }
df1b5770 899@@ -5667,6 +5706,10 @@
b4e1fa2c
AM
900
901 innobase_active_small();
902
903+ if (share->ib_table->is_corrupt) {
904+ DBUG_RETURN(HA_ERR_CRASHED);
905+ }
906+
907 DBUG_RETURN(error);
908 }
909
df1b5770 910@@ -5906,6 +5949,10 @@
b4e1fa2c
AM
911
912 ha_statistic_increment(&SSV::ha_read_key_count);
913
914+ if (share->ib_table->is_corrupt) {
915+ DBUG_RETURN(HA_ERR_CRASHED);
916+ }
917+
918 index = prebuilt->index;
919
920 if (UNIV_UNLIKELY(index == NULL)) {
df1b5770 921@@ -5971,6 +6018,10 @@
b4e1fa2c
AM
922 ret = DB_UNSUPPORTED;
923 }
924
925+ if (share->ib_table->is_corrupt) {
926+ DBUG_RETURN(HA_ERR_CRASHED);
927+ }
928+
929 switch (ret) {
930 case DB_SUCCESS:
931 error = 0;
df1b5770 932@@ -6086,6 +6137,10 @@
b4e1fa2c
AM
933 {
934 DBUG_ENTER("change_active_index");
935
936+ if (share->ib_table->is_corrupt) {
937+ DBUG_RETURN(HA_ERR_CRASHED);
938+ }
939+
940 ut_ad(user_thd == ha_thd());
941 ut_a(prebuilt->trx == thd_to_trx(user_thd));
942
df1b5770 943@@ -6176,6 +6231,10 @@
b4e1fa2c
AM
944
945 DBUG_ENTER("general_fetch");
946
947+ if (share->ib_table->is_corrupt) {
948+ DBUG_RETURN(HA_ERR_CRASHED);
949+ }
950+
951 ut_a(prebuilt->trx == thd_to_trx(user_thd));
952
953 innodb_srv_conc_enter_innodb(prebuilt->trx);
df1b5770 954@@ -6185,6 +6244,10 @@
b4e1fa2c
AM
955
956 innodb_srv_conc_exit_innodb(prebuilt->trx);
957
958+ if (share->ib_table->is_corrupt) {
959+ DBUG_RETURN(HA_ERR_CRASHED);
960+ }
961+
962 switch (ret) {
963 case DB_SUCCESS:
964 error = 0;
df1b5770 965@@ -7455,10 +7518,18 @@
b4e1fa2c
AM
966
967 update_thd(ha_thd());
968
969+ if (share->ib_table->is_corrupt) {
970+ DBUG_RETURN(HA_ERR_CRASHED);
971+ }
972+
973 /* Truncate the table in InnoDB */
974
975 error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
976
977+ if (share->ib_table->is_corrupt) {
978+ DBUG_RETURN(HA_ERR_CRASHED);
979+ }
980+
981 error = convert_error_code_to_mysql(error, prebuilt->table->flags,
982 NULL);
983
df1b5770 984@@ -7963,6 +8034,16 @@
b4e1fa2c
AM
985 return(ranges + (double) rows / (double) total_rows * time_for_scan);
986 }
987
988+UNIV_INTERN
989+bool
990+ha_innobase::is_corrupt() const
991+{
992+ if (share->ib_table)
993+ return ((bool)share->ib_table->is_corrupt);
994+ else
995+ return (FALSE);
996+}
997+
998 /*********************************************************************//**
999 Calculates the key number used inside MySQL for an Innobase index. We will
1000 first check the "index translation table" for a match of the index to get
df1b5770 1001@@ -8140,7 +8221,7 @@
b4e1fa2c
AM
1002 ib_table = prebuilt->table;
1003
1004 if (flag & HA_STATUS_TIME) {
1005- if (called_from_analyze || innobase_stats_on_metadata) {
1006+ if ((called_from_analyze || innobase_stats_on_metadata) && !share->ib_table->is_corrupt) {
1007 /* In sql_show we call with this flag: update
1008 then statistics so that they are up-to-date */
1009
11822e22 1010@@ -8433,10 +8514,18 @@
b4e1fa2c
AM
1011 THD* thd, /*!< in: connection thread handle */
1012 HA_CHECK_OPT* check_opt) /*!< in: currently ignored */
1013 {
1014+ if (share->ib_table->is_corrupt) {
1015+ return(HA_ADMIN_CORRUPT);
1016+ }
1017+
1018 /* Simply call ::info() with all the flags */
1019 info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE,
1020 true /* called from analyze */);
1021
1022+ if (share->ib_table->is_corrupt) {
1023+ return(HA_ADMIN_CORRUPT);
1024+ }
1025+
1026 return(0);
1027 }
1028
11822e22 1029@@ -8618,6 +8707,10 @@
b4e1fa2c
AM
1030 my_error(ER_QUERY_INTERRUPTED, MYF(0));
1031 }
1032
1033+ if (share->ib_table->is_corrupt) {
1034+ return(HA_ADMIN_CORRUPT);
1035+ }
1036+
1037 DBUG_RETURN(is_ok ? HA_ADMIN_OK : HA_ADMIN_CORRUPT);
1038 }
1039
11822e22 1040@@ -9388,6 +9481,10 @@
b4e1fa2c
AM
1041
1042 update_thd(thd);
1043
1044+ if (share->ib_table->is_corrupt) {
1045+ DBUG_RETURN(HA_ERR_CRASHED);
1046+ }
1047+
1048 if (prebuilt->table->ibd_file_missing && !thd_tablespace_op(thd)) {
1049 ut_print_timestamp(stderr);
1050 fprintf(stderr,
11822e22 1051@@ -11787,6 +11884,25 @@
b4e1fa2c
AM
1052 "0 (the default) disables automatic dumps.",
1053 NULL, NULL, 0, 0, UINT_MAX32, 0);
1054
a9ee80b9
ER
1055+const char *corrupt_table_action_names[]=
1056+{
1057+ "assert", /* 0 */
1058+ "warn", /* 1 */
1059+ NullS
1060+};
1061+TYPELIB corrupt_table_action_typelib=
1062+{
1063+ array_elements(corrupt_table_action_names) - 1, "corrupt_table_action_typelib",
1064+ corrupt_table_action_names, NULL
1065+};
1066+static MYSQL_SYSVAR_ENUM(corrupt_table_action, srv_pass_corrupt_table,
b4e1fa2c 1067+ PLUGIN_VAR_RQCMDARG,
a9ee80b9 1068+ "Warn corruptions of user tables as 'corrupt table' instead of not crashing itself, "
b4e1fa2c
AM
1069+ "when used with file_per_table. "
1070+ "All file io for the datafile after detected as corrupt are disabled, "
1071+ "except for the deletion.",
a9ee80b9 1072+ NULL, NULL, 0, &corrupt_table_action_typelib);
b4e1fa2c
AM
1073+
1074 static struct st_mysql_sys_var* innobase_system_variables[]= {
1075 MYSQL_SYSVAR(additional_mem_pool_size),
1076 MYSQL_SYSVAR(autoextend_increment),
11822e22 1077@@ -11873,6 +11989,7 @@
b4e1fa2c
AM
1078 MYSQL_SYSVAR(purge_threads),
1079 MYSQL_SYSVAR(purge_batch_size),
11822e22 1080 MYSQL_SYSVAR(rollback_segments),
a9ee80b9 1081+ MYSQL_SYSVAR(corrupt_table_action),
b4e1fa2c
AM
1082 NULL
1083 };
1084
1085diff -ruN a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
1086--- a/storage/innobase/handler/ha_innodb.h 2010-11-03 07:01:13.000000000 +0900
1087+++ b/storage/innobase/handler/ha_innodb.h 2010-12-04 15:38:18.159588579 +0900
1088@@ -52,6 +52,7 @@
1089 innodb_idx_translate_t idx_trans_tbl; /*!< index translation
1090 table between MySQL and
1091 Innodb */
1092+ dict_table_t* ib_table;
1093 } INNOBASE_SHARE;
1094
1095
1096@@ -135,6 +136,7 @@
1097 int close(void);
1098 double scan_time();
1099 double read_time(uint index, uint ranges, ha_rows rows);
1100+ bool is_corrupt() const;
1101
1102 int write_row(uchar * buf);
1103 int update_row(const uchar * old_data, uchar * new_data);
1104diff -ruN a/storage/innobase/include/btr0btr.ic b/storage/innobase/include/btr0btr.ic
1105--- a/storage/innobase/include/btr0btr.ic 2010-11-03 07:01:13.000000000 +0900
1106+++ b/storage/innobase/include/btr0btr.ic 2010-12-04 15:38:18.162515035 +0900
1107@@ -28,7 +28,7 @@
1108 #include "mtr0mtr.h"
1109 #include "mtr0log.h"
1110 #include "page0zip.h"
1111-
1112+#include "srv0srv.h"
1113 #define BTR_MAX_NODE_LEVEL 50 /*!< Maximum B-tree page level
1114 (not really a hard limit).
1115 Used in debug assertions
1116@@ -55,7 +55,9 @@
1117 block = buf_page_get_gen(space, zip_size, page_no, mode,
1118 NULL, BUF_GET, file, line, mtr);
1119
1120- if (mode != RW_NO_LATCH) {
1121+ ut_a(srv_pass_corrupt_table || block);
1122+
1123+ if (block && mode != RW_NO_LATCH) {
1124
1125 buf_block_dbg_add_level(block, SYNC_TREE_NODE);
1126 }
1127diff -ruN a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
1128--- a/storage/innobase/include/buf0buf.h 2010-12-03 15:49:59.218956083 +0900
1129+++ b/storage/innobase/include/buf0buf.h 2010-12-04 15:38:18.164513667 +0900
d8778560 1130@@ -984,7 +984,7 @@
b4e1fa2c
AM
1131 const buf_block_t* block) /*!< in: pointer to the control block */
1132 __attribute__((pure));
1133 #else /* UNIV_DEBUG */
1134-# define buf_block_get_frame(block) (block)->frame
1135+# define buf_block_get_frame(block) (block ? (block)->frame : 0)
1136 #endif /* UNIV_DEBUG */
1137 /*********************************************************************//**
1138 Gets the space id of a block.
d8778560 1139@@ -1116,7 +1116,8 @@
b4e1fa2c
AM
1140 void
1141 buf_page_io_complete(
1142 /*=================*/
1143- buf_page_t* bpage); /*!< in: pointer to the block in question */
1144+ buf_page_t* bpage, /*!< in: pointer to the block in question */
1145+ trx_t* trx);
1146 /********************************************************************//**
1147 Calculates a folded value of a file page address to use in the page hash
1148 table.
d8778560 1149@@ -1431,6 +1432,7 @@
b4e1fa2c
AM
1150 0 if the block was never accessed
1151 in the buffer pool */
1152 /* @} */
1153+ ibool is_corrupt;
df1b5770 1154 # if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
b4e1fa2c
AM
1155 ibool file_page_was_freed;
1156 /*!< this is set to TRUE when fsp
1157diff -ruN a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic
1158--- a/storage/innobase/include/buf0buf.ic 2010-12-03 15:49:59.221956024 +0900
1159+++ b/storage/innobase/include/buf0buf.ic 2010-12-04 15:38:18.167513925 +0900
1160@@ -34,7 +34,7 @@
1161 #include "buf0flu.h"
1162 #include "buf0lru.h"
1163 #include "buf0rea.h"
1164-
1165+#include "srv0srv.h"
1166 /*********************************************************************//**
1167 Gets the current size of buffer buf_pool in bytes.
1168 @return size in bytes */
11822e22 1169@@ -619,6 +619,12 @@
b4e1fa2c
AM
1170 /*================*/
1171 const buf_block_t* block) /*!< in: pointer to the control block */
1172 {
1173+ ut_a(srv_pass_corrupt_table || block);
1174+
1175+ if (srv_pass_corrupt_table && !block) {
1176+ return(0);
1177+ }
1178+
1179 ut_ad(block);
1180
1181 switch (buf_block_get_state(block)) {
1182diff -ruN a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
1183--- a/storage/innobase/include/dict0dict.h 2010-12-03 17:30:16.306955940 +0900
1184+++ b/storage/innobase/include/dict0dict.h 2010-12-04 15:38:18.169513750 +0900
11822e22 1185@@ -1245,6 +1245,15 @@
b4e1fa2c
AM
1186 dict_close(void);
1187 /*============*/
1188
1189+/*************************************************************************
1190+set is_corrupt flag by space_id*/
1191+
1192+void
1193+dict_table_set_corrupt_by_space(
1194+/*============================*/
1195+ ulint space_id,
1196+ ibool need_mutex);
1197+
1198 #ifndef UNIV_NONINL
1199 #include "dict0dict.ic"
1200 #endif
1201diff -ruN a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
1202--- a/storage/innobase/include/dict0mem.h 2010-11-03 07:01:13.000000000 +0900
1203+++ b/storage/innobase/include/dict0mem.h 2010-12-04 15:38:18.171513956 +0900
11822e22 1204@@ -636,6 +636,7 @@
b4e1fa2c
AM
1205 the AUTOINC lock on this table. */
1206 /* @} */
1207 /*----------------------*/
1208+ ibool is_corrupt;
1209 #endif /* !UNIV_HOTBACKUP */
1210
1211 #ifdef UNIV_DEBUG
1212diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
1213--- a/storage/innobase/include/fil0fil.h 2010-12-04 15:35:29.175520016 +0900
1214+++ b/storage/innobase/include/fil0fil.h 2010-12-04 15:38:18.172483391 +0900
d8778560 1215@@ -749,6 +749,19 @@
b4e1fa2c
AM
1216 fil_system_hash_nodes(void);
1217 /*========================*/
1218
1219+/*************************************************************************
1220+functions to access is_corrupt flag of fil_space_t*/
1221+
1222+ibool
1223+fil_space_is_corrupt(
1224+/*=================*/
1225+ ulint space_id);
1226+
1227+void
1228+fil_space_set_corrupt(
1229+/*==================*/
1230+ ulint space_id);
1231+
1232 typedef struct fil_space_struct fil_space_t;
1233
1234 #endif
1235diff -ruN a/storage/innobase/include/fut0fut.ic b/storage/innobase/include/fut0fut.ic
1236--- a/storage/innobase/include/fut0fut.ic 2010-11-03 07:01:13.000000000 +0900
1237+++ b/storage/innobase/include/fut0fut.ic 2010-12-04 15:38:18.174481728 +0900
1238@@ -23,6 +23,7 @@
1239 Created 12/13/1995 Heikki Tuuri
1240 ***********************************************************************/
1241
1242+#include "srv0srv.h"
1243 #include "sync0rw.h"
1244 #include "buf0buf.h"
1245
1246@@ -48,6 +49,12 @@
1247 ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
1248
1249 block = buf_page_get(space, zip_size, addr.page, rw_latch, mtr);
1250+
1251+ if (srv_pass_corrupt_table && !block) {
1252+ return(0);
1253+ }
1254+ ut_a(block);
1255+
1256 ptr = buf_block_get_frame(block) + addr.boffset;
1257
1258 buf_block_dbg_add_level(block, SYNC_NO_ORDER_CHECK);
1259diff -ruN a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h
1260--- a/storage/innobase/include/page0page.h 2010-11-03 07:01:13.000000000 +0900
1261+++ b/storage/innobase/include/page0page.h 2010-12-04 15:38:18.175514037 +0900
1262@@ -500,7 +500,7 @@
1263 page_is_leaf(
1264 /*=========*/
1265 const page_t* page) /*!< in: page */
1266- __attribute__((nonnull, pure));
1267+ __attribute__((pure));
1268 /************************************************************//**
1269 Gets the pointer to the next record on the page.
1270 @return pointer to next record */
1271diff -ruN a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic
1272--- a/storage/innobase/include/page0page.ic 2010-11-03 07:01:13.000000000 +0900
1273+++ b/storage/innobase/include/page0page.ic 2010-12-04 15:38:18.177482672 +0900
1274@@ -274,6 +274,9 @@
1275 /*=========*/
1276 const page_t* page) /*!< in: page */
1277 {
1278+ if (!page) {
1279+ return(FALSE);
1280+ }
1281 return(!*(const uint16*) (page + (PAGE_HEADER + PAGE_LEVEL)));
1282 }
1283
1284diff -ruN a/storage/innobase/include/page0zip.h b/storage/innobase/include/page0zip.h
1285--- a/storage/innobase/include/page0zip.h 2010-11-03 07:01:13.000000000 +0900
1286+++ b/storage/innobase/include/page0zip.h 2010-12-04 15:38:18.179513974 +0900
1287@@ -114,7 +114,7 @@
1288 const page_t* page, /*!< in: uncompressed page */
1289 dict_index_t* index, /*!< in: index of the B-tree node */
1290 mtr_t* mtr) /*!< in: mini-transaction, or NULL */
1291- __attribute__((nonnull(1,2,3)));
1292+ __attribute__((nonnull(1,3)));
1293
1294 /**********************************************************************//**
1295 Decompress a page. This function should tolerate errors on the compressed
1296diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
1297--- a/storage/innobase/include/srv0srv.h 2010-12-04 15:37:50.591516341 +0900
1298+++ b/storage/innobase/include/srv0srv.h 2010-12-04 15:38:18.180563749 +0900
df1b5770 1299@@ -243,6 +243,7 @@
b4e1fa2c
AM
1300 extern ulint srv_adaptive_flushing_method;
1301
1302 extern ulint srv_expand_import;
1303+extern ulint srv_pass_corrupt_table;
1304
b4e1fa2c 1305 extern ulint srv_dict_size_limit;
11822e22 1306 /*-------------------------------------------*/
b4e1fa2c
AM
1307diff -ruN a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c
1308--- a/storage/innobase/page/page0zip.c 2010-11-03 07:01:13.000000000 +0900
1309+++ b/storage/innobase/page/page0zip.c 2010-12-04 15:38:18.195515935 +0900
1310@@ -1153,6 +1153,10 @@
1311 FILE* logfile = NULL;
1312 #endif
1313
1314+ if (!page) {
1315+ return(FALSE);
1316+ }
1317+
1318 ut_a(page_is_comp(page));
1319 ut_a(fil_page_get_type(page) == FIL_PAGE_INDEX);
1320 ut_ad(page_simple_validate_new((page_t*) page));
1321diff -ruN a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
1322--- a/storage/innobase/row/row0ins.c 2010-11-03 07:01:13.000000000 +0900
1323+++ b/storage/innobase/row/row0ins.c 2010-12-04 15:38:18.198514028 +0900
1324@@ -1335,6 +1335,12 @@
1325 const rec_t* rec = btr_pcur_get_rec(&pcur);
1326 const buf_block_t* block = btr_pcur_get_block(&pcur);
1327
1328+ if (srv_pass_corrupt_table && !block) {
1329+ err = DB_CORRUPTION;
1330+ break;
1331+ }
1332+ ut_a(block);
1333+
1334 if (page_rec_is_infimum(rec)) {
1335
1336 continue;
1337diff -ruN a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c
1338--- a/storage/innobase/row/row0merge.c 2010-12-03 17:30:16.330986655 +0900
1339+++ b/storage/innobase/row/row0merge.c 2010-12-04 15:38:18.201513966 +0900
1340@@ -1245,6 +1245,13 @@
1341
1342 if (UNIV_LIKELY(has_next)) {
1343 rec = btr_pcur_get_rec(&pcur);
1344+
1345+ if (srv_pass_corrupt_table && !rec) {
1346+ err = DB_CORRUPTION;
1347+ goto err_exit;
1348+ }
1349+ ut_a(rec);
1350+
1351 offsets = rec_get_offsets(rec, clust_index, NULL,
1352 ULINT_UNDEFINED, &row_heap);
1353
1354diff -ruN a/storage/innobase/row/row0sel.c b/storage/innobase/row/row0sel.c
1355--- a/storage/innobase/row/row0sel.c 2010-11-03 07:01:13.000000000 +0900
1356+++ b/storage/innobase/row/row0sel.c 2010-12-04 15:38:18.205551115 +0900
1357@@ -3848,6 +3848,13 @@
1358 /* PHASE 4: Look for matching records in a loop */
1359
1360 rec = btr_pcur_get_rec(pcur);
1361+
1362+ if (srv_pass_corrupt_table && !rec) {
1363+ err = DB_CORRUPTION;
1364+ goto lock_wait_or_error;
1365+ }
1366+ ut_a(rec);
1367+
1368 ut_ad(!!page_rec_is_comp(rec) == comp);
1369 #ifdef UNIV_SEARCH_DEBUG
1370 /*
1371diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
1372--- a/storage/innobase/srv/srv0srv.c 2010-12-04 15:37:50.602481253 +0900
1373+++ b/storage/innobase/srv/srv0srv.c 2010-12-04 15:38:18.209513823 +0900
11822e22 1374@@ -437,6 +437,7 @@
b4e1fa2c
AM
1375 UNIV_INTERN ulint srv_adaptive_flushing_method = 0; /* 0: native 1: estimate 2: keep_average */
1376
1377 UNIV_INTERN ulint srv_expand_import = 0; /* 0:disable 1:enable */
1378+UNIV_INTERN ulint srv_pass_corrupt_table = 0; /* 0:disable 1:enable */
1379
b4e1fa2c 1380 UNIV_INTERN ulint srv_dict_size_limit = 0;
11822e22 1381 /*-------------------------------------------*/
b4e1fa2c
AM
1382diff -ruN a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
1383--- a/storage/innobase/srv/srv0start.c 2010-12-04 15:37:50.605491300 +0900
1384+++ b/storage/innobase/srv/srv0start.c 2010-12-04 15:38:18.212513722 +0900
11822e22 1385@@ -2150,6 +2150,13 @@
b4e1fa2c
AM
1386
1387 os_fast_mutex_free(&srv_os_test_mutex);
1388
1389+ if (!srv_file_per_table_original_value
1390+ && srv_pass_corrupt_table) {
1391+ fprintf(stderr, "InnoDB: Warning:"
d8778560
AM
1392+ " The option innodb_file_per_table is disabled,"
1393+ " so using the option innodb_pass_corrupt_table doesn't make sense.\n");
b4e1fa2c
AM
1394+ }
1395+
1396 if (srv_print_verbose_log) {
1397 ut_print_timestamp(stderr);
1398 fprintf(stderr,
This page took 4.828011 seconds and 4 git commands to generate.