@@ -2385,18 +2385,11 @@ page_validate(
2385
2385
the page record type definition */
2386
2386
{
2387
2387
const page_dir_slot_t * slot;
2388
- mem_heap_t * heap;
2389
- byte* buf;
2390
- ulint count;
2391
- ulint own_count;
2392
- ulint rec_own_count;
2393
- ulint slot_no;
2394
- ulint data_size;
2395
2388
const rec_t * rec;
2396
2389
const rec_t * old_rec = NULL ;
2397
2390
ulint offs;
2398
2391
ulint n_slots;
2399
- ibool ret = FALSE ;
2392
+ ibool ret = TRUE ;
2400
2393
ulint i;
2401
2394
ulint* offsets = NULL ;
2402
2395
ulint* old_offsets = NULL ;
@@ -2410,7 +2403,13 @@ page_validate(
2410
2403
if (UNIV_UNLIKELY ((ibool) !!page_is_comp (page)
2411
2404
!= dict_table_is_comp (index->table ))) {
2412
2405
ib::error () << " 'compact format' flag mismatch" ;
2413
- goto func_exit2;
2406
+ func_exit2:
2407
+ ib::error () << " Apparent corruption in space "
2408
+ << page_get_space_id (page) << " page "
2409
+ << page_get_page_no (page)
2410
+ << " of index " << index->name
2411
+ << " of table " << index->table ->name ;
2412
+ return FALSE ;
2414
2413
}
2415
2414
if (page_is_comp (page)) {
2416
2415
if (UNIV_UNLIKELY (!page_simple_validate_new (page))) {
@@ -2435,19 +2434,12 @@ page_validate(
2435
2434
if (max_trx_id == 0 || max_trx_id > sys_max_trx_id) {
2436
2435
ib::error () << " PAGE_MAX_TRX_ID out of bounds: "
2437
2436
<< max_trx_id << " , " << sys_max_trx_id;
2438
- goto func_exit2 ;
2437
+ ret = FALSE ;
2439
2438
}
2440
2439
} else {
2441
2440
ut_ad (srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN);
2442
2441
}
2443
2442
2444
- heap = mem_heap_create (srv_page_size + 200 );
2445
-
2446
- /* The following buffer is used to check that the
2447
- records in the page record heap do not overlap */
2448
-
2449
- buf = static_cast <byte*>(mem_heap_zalloc (heap, srv_page_size));
2450
-
2451
2443
/* Check first that the record heap and the directory do not
2452
2444
overlap. */
2453
2445
@@ -2456,20 +2448,45 @@ page_validate(
2456
2448
if (UNIV_UNLIKELY (!(page_header_get_ptr (page, PAGE_HEAP_TOP)
2457
2449
<= page_dir_get_nth_slot (page, n_slots - 1 )))) {
2458
2450
2459
- ib::warn () << " Record heap and dir overlap on space "
2460
- << page_get_space_id (page) << " page "
2461
- << page_get_page_no (page) << " index " << index->name
2462
- << " , " << page_header_get_ptr (page, PAGE_HEAP_TOP)
2463
- << " , " << page_dir_get_nth_slot (page, n_slots - 1 );
2451
+ ib::warn () << " Record heap and directory overlap" ;
2452
+ goto func_exit2;
2453
+ }
2464
2454
2465
- goto func_exit;
2455
+ switch (uint16_t type = fil_page_get_type (page)) {
2456
+ case FIL_PAGE_RTREE:
2457
+ if (!index->is_spatial ()) {
2458
+ wrong_page_type:
2459
+ ib::warn () << " Wrong page type " << type;
2460
+ ret = FALSE ;
2461
+ }
2462
+ break ;
2463
+ case FIL_PAGE_TYPE_INSTANT:
2464
+ if (index->is_instant ()
2465
+ && page_get_page_no (page) == index->page ) {
2466
+ break ;
2467
+ }
2468
+ goto wrong_page_type;
2469
+ case FIL_PAGE_INDEX:
2470
+ if (index->is_spatial ()) {
2471
+ goto wrong_page_type;
2472
+ }
2473
+ if (index->is_instant ()
2474
+ && page_get_page_no (page) == index->page ) {
2475
+ goto wrong_page_type;
2476
+ }
2477
+ break ;
2478
+ default :
2479
+ goto wrong_page_type;
2466
2480
}
2467
2481
2482
+ /* The following buffer is used to check that the
2483
+ records in the page record heap do not overlap */
2484
+ mem_heap_t * heap = mem_heap_create (srv_page_size + 200 );;
2485
+ byte* buf = static_cast <byte*>(mem_heap_zalloc (heap, srv_page_size));
2486
+
2468
2487
/* Validate the record list in a loop checking also that
2469
2488
it is consistent with the directory. */
2470
- count = 0 ;
2471
- data_size = 0 ;
2472
- own_count = 1 ;
2489
+ ulint count = 0 , data_size = 0 , own_count = 1 , slot_no = 0 ;
2473
2490
slot_no = 0 ;
2474
2491
slot = page_dir_get_nth_slot (page, slot_no);
2475
2492
@@ -2484,11 +2501,13 @@ page_validate(
2484
2501
&& UNIV_UNLIKELY (rec_get_node_ptr_flag (rec)
2485
2502
== page_is_leaf (page))) {
2486
2503
ib::error () << " 'node_ptr' flag mismatch" ;
2487
- goto func_exit;
2504
+ ret = FALSE ;
2505
+ goto next_rec;
2488
2506
}
2489
2507
2490
2508
if (UNIV_UNLIKELY (!page_rec_validate (rec, offsets))) {
2491
- goto func_exit;
2509
+ ret = FALSE ;
2510
+ goto next_rec;
2492
2511
}
2493
2512
2494
2513
/* Check that the records are in the ascending order */
@@ -2500,16 +2519,10 @@ page_validate(
2500
2519
2501
2520
/* For spatial index, on nonleaf leavel, we
2502
2521
allow recs to be equal. */
2503
- bool rtr_equal_nodeptrs =
2504
- (ret == 0 && dict_index_is_spatial (index)
2505
- && !page_is_leaf (page));
2522
+ if (ret <= 0 && !(ret == 0 && index->is_spatial ()
2523
+ && !page_is_leaf (page))) {
2506
2524
2507
- if (ret <= 0 && !rtr_equal_nodeptrs) {
2508
-
2509
- ib::error () << " Records in wrong order on"
2510
- " space " << page_get_space_id (page)
2511
- << " page " << page_get_page_no (page)
2512
- << " index " << index->name ;
2525
+ ib::error () << " Records in wrong order" ;
2513
2526
2514
2527
fputs (" \n InnoDB: previous record " , stderr);
2515
2528
/* For spatial index, print the mbr info.*/
@@ -2530,7 +2543,7 @@ page_validate(
2530
2543
putc (' \n ' , stderr);
2531
2544
}
2532
2545
2533
- goto func_exit ;
2546
+ ret = FALSE ;
2534
2547
}
2535
2548
}
2536
2549
@@ -2550,41 +2563,41 @@ page_validate(
2550
2563
offs = page_offset (rec_get_start (rec, offsets));
2551
2564
i = rec_offs_size (offsets);
2552
2565
if (UNIV_UNLIKELY (offs + i >= srv_page_size)) {
2553
- ib::error () << " Record offset out of bounds" ;
2554
- goto func_exit;
2566
+ ib::error () << " Record offset out of bounds: "
2567
+ << offs << ' +' << i;
2568
+ ret = FALSE ;
2569
+ goto next_rec;
2555
2570
}
2556
-
2557
2571
while (i--) {
2558
2572
if (UNIV_UNLIKELY (buf[offs + i])) {
2559
- /* No other record may overlap this */
2560
- ib::error () << " Record overlaps another" ;
2561
- goto func_exit;
2573
+ ib::error () << " Record overlaps another: "
2574
+ << offs << ' +' << i;
2575
+ ret = FALSE ;
2576
+ break ;
2562
2577
}
2563
-
2564
2578
buf[offs + i] = 1 ;
2565
2579
}
2566
2580
2567
- if (page_is_comp (page)) {
2568
- rec_own_count = rec_get_n_owned_new (rec);
2569
- } else {
2570
- rec_own_count = rec_get_n_owned_old (rec);
2571
- }
2572
-
2573
- if (UNIV_UNLIKELY (rec_own_count != 0 )) {
2581
+ if (ulint rec_own_count = page_is_comp (page)
2582
+ ? rec_get_n_owned_new (rec)
2583
+ : rec_get_n_owned_old (rec)) {
2574
2584
/* This is a record pointed to by a dir slot */
2575
2585
if (UNIV_UNLIKELY (rec_own_count != own_count)) {
2576
- ib::error () << " Wrong owned count "
2577
- << rec_own_count << " , " << own_count;
2578
- goto func_exit;
2586
+ ib::error () << " Wrong owned count at " << offs
2587
+ << " : " << rec_own_count
2588
+ << " , " << own_count;
2589
+ ret = FALSE ;
2579
2590
}
2580
2591
2581
2592
if (page_dir_slot_get_rec (slot) != rec) {
2582
2593
ib::error () << " Dir slot does not"
2583
- " point to right rec" ;
2584
- goto func_exit ;
2594
+ " point to right rec at " << offs ;
2595
+ ret = FALSE ;
2585
2596
}
2586
2597
2587
- page_dir_slot_check (slot);
2598
+ if (ret) {
2599
+ page_dir_slot_check (slot);
2600
+ }
2588
2601
2589
2602
own_count = 0 ;
2590
2603
if (!page_rec_is_supremum (rec)) {
@@ -2593,6 +2606,7 @@ page_validate(
2593
2606
}
2594
2607
}
2595
2608
2609
+ next_rec:
2596
2610
if (page_rec_is_supremum (rec)) {
2597
2611
break ;
2598
2612
}
@@ -2617,14 +2631,14 @@ page_validate(
2617
2631
}
2618
2632
} else if (UNIV_UNLIKELY (rec_get_n_owned_old (rec) == 0 )) {
2619
2633
n_owned_zero:
2620
- ib::error () << " n owned is zero" ;
2621
- goto func_exit ;
2634
+ ib::error () << " n owned is zero at " << offs ;
2635
+ ret = FALSE ;
2622
2636
}
2623
2637
2624
2638
if (UNIV_UNLIKELY (slot_no != n_slots - 1 )) {
2625
2639
ib::error () << " n slots wrong " << slot_no << " "
2626
2640
<< (n_slots - 1 );
2627
- goto func_exit ;
2641
+ ret = FALSE ;
2628
2642
}
2629
2643
2630
2644
if (UNIV_UNLIKELY (ulint (page_header_get_field (page, PAGE_N_RECS))
@@ -2633,65 +2647,57 @@ page_validate(
2633
2647
ib::error () << " n recs wrong "
2634
2648
<< page_header_get_field (page, PAGE_N_RECS)
2635
2649
+ PAGE_HEAP_NO_USER_LOW << " " << (count + 1 );
2636
- goto func_exit ;
2650
+ ret = FALSE ;
2637
2651
}
2638
2652
2639
2653
if (UNIV_UNLIKELY (data_size != page_get_data_size (page))) {
2640
2654
ib::error () << " Summed data size " << data_size
2641
2655
<< " , returned by func " << page_get_data_size (page);
2642
- goto func_exit ;
2656
+ ret = FALSE ;
2643
2657
}
2644
2658
2645
2659
/* Check then the free list */
2646
- rec = page_header_get_ptr (page, PAGE_FREE);
2647
-
2648
- while ( rec != NULL ) {
2660
+ for ( rec = page_header_get_ptr (page, PAGE_FREE);
2661
+ rec;
2662
+ rec = page_rec_get_next_const (rec) ) {
2649
2663
offsets = rec_get_offsets (rec, index, offsets,
2650
2664
page_is_leaf (page),
2651
2665
ULINT_UNDEFINED, &heap);
2652
2666
if (UNIV_UNLIKELY (!page_rec_validate (rec, offsets))) {
2653
-
2654
- goto func_exit ;
2667
+ ret = FALSE ;
2668
+ continue ;
2655
2669
}
2656
2670
2657
2671
count++;
2658
2672
offs = page_offset (rec_get_start (rec, offsets));
2659
2673
i = rec_offs_size (offsets);
2660
2674
if (UNIV_UNLIKELY (offs + i >= srv_page_size)) {
2661
- ib::error () << " Record offset out of bounds" ;
2662
- goto func_exit;
2675
+ ib::error () << " Free record offset out of bounds: "
2676
+ << offs << ' +' << i;
2677
+ ret = FALSE ;
2678
+ continue ;
2663
2679
}
2664
-
2665
2680
while (i--) {
2666
-
2667
2681
if (UNIV_UNLIKELY (buf[offs + i])) {
2668
- ib::error () << " Record overlaps another"
2669
- " in free list" ;
2670
- goto func_exit;
2682
+ ib::error () << " Free record overlaps another: "
2683
+ << offs << ' +' << i;
2684
+ ret = FALSE ;
2685
+ break ;
2671
2686
}
2672
-
2673
2687
buf[offs + i] = 1 ;
2674
2688
}
2675
-
2676
- rec = page_rec_get_next_const (rec);
2677
2689
}
2678
2690
2679
2691
if (UNIV_UNLIKELY (page_dir_get_n_heap (page) != count + 1 )) {
2680
2692
ib::error () << " N heap is wrong "
2681
2693
<< page_dir_get_n_heap (page) << " " << count + 1 ;
2682
- goto func_exit ;
2694
+ ret = FALSE ;
2683
2695
}
2684
2696
2685
- ret = TRUE ;
2686
-
2687
- func_exit:
2688
2697
mem_heap_free (heap);
2689
2698
2690
- if (UNIV_UNLIKELY (ret == FALSE )) {
2691
- func_exit2:
2692
- ib::error () << " Apparent corruption in space "
2693
- << page_get_space_id (page) << " page "
2694
- << page_get_page_no (page) << " index " << index->name ;
2699
+ if (UNIV_UNLIKELY (!ret)) {
2700
+ goto func_exit2;
2695
2701
}
2696
2702
2697
2703
return (ret);
0 commit comments