70{
71
72
73
74
75
78
79 bool heapkeyspace;
80
81 bool readonly;
82
83 bool heapallindexed;
84
85 bool rootdescend;
86
87 bool checkunique;
88
90
92
93
94
95
96
98
100
101
102
103
104
105
107
109
111
112
113
114
115
117
118
119
120
121
122
124 bool previncompletesplit;
125
126
127
128
129
130
132
133 int64 heaptuplespresent;
135
136
137
138
140{
141
143
144
146
147
150
151
152
153
154
156{
160
163
164
165
166
168{
174
177
179 void *
state,
bool readonly);
181 bool heapkeyspace, bool readonly, bool heapallindexed,
182 bool rootdescend, bool checkunique);
240
241
242
243
244
245
246
247
248
249
252{
255
256 args.heapallindexed =
false;
257 args.rootdescend =
false;
258 args.parentcheck =
false;
259 args.checkunique =
false;
260
265
269
271}
272
273
274
275
276
277
278
279
280
281
284{
287
288 args.heapallindexed =
false;
289 args.rootdescend =
false;
290 args.parentcheck =
true;
291 args.checkunique =
false;
292
299
303
305}
306
307
308
309
310static void
312{
314 bool heapkeyspace,
315 allequalimage;
316
320 errmsg(
"index \"%s\" lacks a main relation fork",
322
323
325 if (allequalimage && !heapkeyspace)
328 errmsg(
"index \"%s\" metapage has equalimage field set on unsupported nbtree version",
331 {
333
336 {
338 break;
339 }
340
343 errmsg(
"index \"%s\" metapage incorrectly indicates that deduplication is safe",
346 ?
errhint(
"This is known of \"interval\" indexes last built on a version predating 2023-11.")
347 : 0));
348 }
349
350
352 args->heapallindexed,
args->rootdescend,
args->checkunique);
353}
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378static void
380 bool readonly, bool heapallindexed, bool rootdescend,
381 bool checkunique)
382{
388
389 if (!readonly)
390 elog(
DEBUG1,
"verifying consistency of tree structure for index \"%s\"",
392 else
393 elog(
DEBUG1,
"verifying consistency of tree structure for index \"%s\" with cross-level checks",
395
396
397
398
399
401
402
403
404
407 state->heaprel = heaprel;
408 state->heapkeyspace = heapkeyspace;
409 state->readonly = readonly;
410 state->heapallindexed = heapallindexed;
411 state->rootdescend = rootdescend;
412 state->checkunique = checkunique;
414
415 if (
state->heapallindexed)
416 {
420
421
422
423
424
425
426
427
431
433
435 state->heaptuplespresent = 0;
436
437
438
439
440
441
442
443
445
446
447
448
449
450
451
452
453
454
455
456
457
460 state->snapshot->xmin))
463 errmsg(
"index \"%s\" cannot be verified using transaction snapshot",
465 }
466
467
468
469
470
471
472 if (
state->checkunique)
473 {
475
478 }
479
481 if (
state->rootdescend && !
state->heapkeyspace)
484 errmsg(
"cannot verify that tuples from index \"%s\" can each be found by an independent index search",
486 errhint(
"Only B-Tree version 4 indexes support rootdescend verification.")));
487
488
490 "amcheck context",
493
494
497
498
499
500
501
502
503
504
505
511 errdetail_internal(
"Fast root block %u (level %u) differs from true root block %u (level %u).",
514
515
516
517
518
519
525 {
526
527
528
529
531
535 errmsg(
"index \"%s\" has no valid pages on level below %u or first level",
537
539 }
540
541
542
543
544 if (
state->heapallindexed)
545 {
548
549
550
551
552
553
554
555
558 0,
560 true,
561 true);
562
563
564
565
566
567
568
569
570
571
572
574
575
576
577
578
579
584
585 elog(
DEBUG1,
"verifying that tuples from index \"%s\" are present in \"%s\"",
588
591
596
598 }
599
600
604}
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
626{
627
631
632
635
636
640
641
643
646 " (true root level)" : level.level == 0 ? " (leaf level)" : "");
647
649 state->previncompletesplit =
false;
650
651 do
652 {
653
655
656
657 state->targetblock = current;
660
662
664 {
665
666
667
668
669
670
671
672
673
674
675
679 errmsg(
"downlink or sibling link points to deleted block in index \"%s\"",
683
687 errmsg(
"block %u fell off the end of index \"%s\"",
689 else
695 }
697 {
698
699
700
701
702
703
704
706 {
710 errmsg(
"block %u is not leftmost in index \"%s\"",
712
716 errmsg(
"block %u is not true root in index \"%s\"",
718 }
719
720
721
722
723
724
725
726
727
728
730 {
733
734
741 }
742 else
743 {
744
745
746
747
748
749
752 }
753
754
755
756
757
758
759 }
760
761
762
763
764
765
766
767
768
769
772
773
777 errmsg(
"leftmost down link for level points to block in index \"%s\" whose level is not one level down",
779 errdetail_internal(
"Block pointed to=%u expected level=%u level in pointed to block=%u.",
781
782
784
786
787
791 errmsg(
"circular link chain found in block %u of index \"%s\"",
793
796
798 {
802 }
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
821 {
824
828
831 }
832
833
835 }
836 while (current !=
P_NONE);
837
839 {
843 }
844
845
847
849}
850
851
852static bool
854{
856
858
860 tid,
state->snapshot, slot);
863
865}
866
867
868
869
870
871static void
876{
883
891
894
895 if (
lVis->postingIndex >= 0)
897
900
903 errmsg(
"index uniqueness is violated for index \"%s\"",
905 errdetail(
"Index %s%s and%s%s (point to heap %s and %s) page lsn=%X/%08X.",
908}
909
910
911static void
915{
918
920
921
922
923
924
926 {
928 {
931 {
934 {
937 tid, targetblock,
939 }
940
941
942
943
944
945
947 return;
948
949 lVis->blkno = targetblock;
950 lVis->offset = offset;
951 lVis->postingIndex =
i;
953 }
954 }
955 }
956
957
958
959
960
961
962 else
963 {
966 {
969 {
972 tid, targetblock,
973 offset, -1);
974 }
975
976 lVis->blkno = targetblock;
977 lVis->offset = offset;
979 lVis->postingIndex = -1;
980 }
981 }
982
985 lVis->blkno != targetblock)
986 {
988
989 if (
lVis->postingIndex >= 0)
993 errmsg(
"index uniqueness can not be checked for index tid=(%u,%u) in index \"%s\"",
994 targetblock, offset,
996 errdetail(
"It doesn't have visible heap tids and key is equal to the tid=(%u,%u)%s (points to heap tid=(%u,%u)).",
1000 errhint(
"VACUUM the table and repeat the check.")));
1001 }
1002}
1003
1004
1005
1006
1007
1008
1009
1010static bool
1014{
1018
1019
1020
1021
1022
1024
1026 {
1029
1031
1032
1033
1034
1035
1036
1042 {
1044
1045
1048 errmsg_internal(
"harmless interrupted page deletion detected in index \"%s\"",
1053
1056 }
1057
1059 }
1060
1062}
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099static void
1103{
1104
1106
1107 if (!
state->readonly)
1108 {
1114
1115
1123 {
1124
1125
1126
1127
1128
1129
1130
1132 return;
1133 }
1134
1136
1138 {
1141 state->checkstrategy);
1146
1148 }
1149 else
1150 {
1151
1152
1153
1154
1155
1156
1159 }
1160
1161
1162
1163
1164
1168
1170 {
1171
1174 errmsg_internal(
"harmless concurrent page split detected in index \"%s\"",
1178 state->targetblock)));
1179 return;
1180 }
1181
1182
1183
1184
1185
1186
1187
1188
1190 }
1191
1194 errmsg(
"left link/right link pair in index \"%s\" not in agreement",
1199}
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239static void
1241{
1245
1246
1248
1251
1252 elog(
DEBUG2,
"verifying %u items on %s block %u", max,
1254
1255
1256
1257
1258
1260 {
1263
1264
1269 {
1273 errmsg(
"wrong number of high key index tuple attributes in index \"%s\"",
1280 }
1281 }
1282
1283
1284
1285
1286
1287
1289 offset <= max;
1291 {
1298
1299
1300
1301
1302
1303
1305
1307
1309 state->target, offset);
1312
1313
1314
1315
1316
1317
1318
1322 errmsg(
"index tuple size does not equal lp_len in index \"%s\"",
1325 state->targetblock, offset,
1328 errhint(
"This could be a torn page problem.")));
1329
1330
1332 offset))
1333 {
1337
1343
1346 errmsg(
"wrong number of index tuple attributes in index \"%s\"",
1354 }
1355
1356
1357
1358
1359
1361 {
1362
1363
1364
1365
1366
1368 {
1370 offset,
1373 }
1374 continue;
1375 }
1376
1377
1378
1379
1380
1381
1382
1385 {
1389
1393
1396 errmsg(
"could not find tuple using search from root page in index \"%s\"",
1401 }
1402
1403
1404
1405
1406
1408 {
1411
1413
1415 {
1416
1418
1420 {
1422
1425 errmsg_internal(
"posting list contains misplaced TID in index \"%s\"",
1430 }
1431
1433 }
1434 }
1435
1436
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1466 {
1470
1475
1478 errmsg(
"index row size %zu exceeds maximum for index \"%s\"",
1485 }
1486
1487
1489 {
1491
1493 {
1494
1496 {
1498
1503
1507 }
1508 }
1509 else
1510 {
1514
1517 }
1518 }
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566 scantid =
skey->scantid;
1569
1573 {
1577
1582
1585 errmsg(
"high key invariant violated for index \"%s\"",
1592 }
1593
1594 skey->scantid = scantid;
1595
1596
1597
1598
1599
1600
1601
1604 {
1610
1618
1619
1628
1631 errmsg(
"item order invariant violated for index \"%s\"",
1633 errdetail_internal(
"Lower index tid=%s (points to %s tid=%s) higher index tid=%s (points to %s tid=%s) page lsn=%X/%08X.",
1641 }
1642
1643
1644
1645
1646
1647
1648
1649 if (
state->checkunique &&
state->indexinfo->ii_Unique &&
1652 {
1656 }
1657
1658 if (
state->checkunique &&
state->indexinfo->ii_Unique &&
1660 {
1661
1662 scantid =
skey->scantid;
1663
1664
1665
1666
1667
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1681 {
1684 lVis.postingIndex = -1;
1686 }
1688 {
1691 }
1692 skey->scantid = scantid;
1693 }
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712 if (offset == max)
1713 {
1715
1716
1718
1719
1721
1724 {
1725
1726
1727
1728
1729
1730
1731
1732 if (!
state->readonly)
1733 {
1734
1736
1738
1739
1740
1741
1743 return;
1744 }
1745
1748 errmsg(
"cross page item order invariant violated for index \"%s\"",
1751 state->targetblock, offset,
1753 }
1754
1755
1756
1757
1758
1759 if (
state->checkunique &&
state->indexinfo->ii_Unique &&
1761 {
1763
1764 elog(
DEBUG2,
"check cross page unique condition");
1765
1766
1767
1768
1769
1770
1772
1773
1776 {
1778
1779
1780
1781
1782
1786
1791
1793 {
1795 break;
1796 }
1797
1801 errmsg(
"right block of leaf block is non-leaf for index \"%s\"",
1806
1811
1813
1815 }
1816 }
1817 }
1818
1819
1820
1821
1822
1823
1824
1825
1826
1829 }
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1841 {
1844 }
1845}
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1867{
1874
1875
1877
1878
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1907 for (;;)
1908 {
1910
1913
1915 break;
1916
1917
1918
1919
1920
1923 errmsg_internal(
"level %u sibling page in block %u of index \"%s\" was found deleted or half dead",
1925 errdetail_internal(
"Deleted page found when building scankey from right sibling.")));
1926
1928
1929
1931 }
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2024
2025
2026
2027
2029 {
2030
2034 }
2037 {
2038
2039
2040
2041
2044 }
2045 else
2046 {
2047
2048
2049
2050
2051
2058 }
2059
2060
2061
2062
2063
2066}
2067
2068
2069
2070
2071
2072static bool
2074{
2076 return false;
2077
2078 if (heapkeyspace)
2079 {
2080
2081
2082
2083
2084
2088 return false;
2089 }
2090 else
2091 {
2092
2093
2094
2095
2096
2097
2101 return false;
2102 }
2103
2104 return true;
2105}
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145static void
2150{
2155 bool first = true;
2159
2161 {
2166 }
2167 else
2168 {
2170 }
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2185 {
2186 blkno = downlink;
2188 }
2189
2190
2191 while (true)
2192 {
2193
2194
2195
2196
2198 {
2200 state->previncompletesplit =
false;
2201 return;
2202 }
2203
2204
2208 errmsg(
"can't traverse from downlink %u to downlink %u of index \"%s\"",
2209 state->prevrightlink, downlink,
2211
2212
2215 else
2217
2219
2220
2225 errmsg(
"the first child of leftmost target page is not leftmost of its level in index \"%s\"",
2228 state->targetblock, blkno,
2230
2231
2236 errmsg(
"block found while following rightlinks from child of index \"%s\" has invalid level",
2238 errdetail_internal(
"Block pointed to=%u expected level=%u level in pointed to block=%u.",
2240
2241
2242 if ((!first && blkno ==
state->prevrightlink) || blkno == opaque->
btpo_prev)
2245 errmsg(
"circular link chain found in block %u of index \"%s\"",
2247
2248 if (blkno != downlink && !
P_IGNORE(opaque))
2249 {
2250
2252 }
2253
2255
2256
2257
2258
2259
2261 {
2265
2266
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292 if (blkno == downlink)
2294 else
2296
2298
2300 {
2301
2302
2303
2304
2305
2307 {
2311 errmsg(
"child high key is greater than rightmost pivot key on target level in index \"%s\"",
2314 state->targetblock, blkno,
2317 }
2321 }
2322 else
2323 {
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2341 errmsg(
"can't find left sibling high key in index \"%s\"",
2344 state->targetblock, blkno,
2346 itup =
state->lowkey;
2347 }
2348
2350 {
2353 errmsg(
"mismatch between parent key and child high key in index \"%s\"",
2356 state->targetblock, blkno,
2358 }
2359 }
2360
2361
2362 if (blkno == downlink)
2363 {
2366 return;
2367 }
2368
2369
2371
2372
2375 first = false;
2376 }
2377}
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392static void
2395{
2404
2406 state->target, downlinkoffnum);
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2445
2446
2447
2448
2449
2450
2451
2452
2453
2458
2459
2460
2461
2462
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2493 errmsg(
"downlink to deleted page found in index \"%s\"",
2498
2502 {
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2528 continue;
2529
2531 offset))
2534 errmsg(
"down-link lower bound invariant violated for index \"%s\"",
2536 errdetail_internal(
"Parent block=%u child index tid=(%u,%u) parent page lsn=%X/%08X.",
2539 }
2540
2542}
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557static void
2560{
2569
2572
2573
2575 return;
2576
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2601 {
2604 errmsg_internal(
"harmless interrupted page split detected in index \"%s\"",
2610 return;
2611 }
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2626 errmsg(
"leaf index block lacks downlink in index \"%s\"",
2629 blkno,
2631
2632
2633 elog(
DEBUG1,
"checking for interrupted multi-level deletion due to missing downlink in index \"%s\"",
2635
2640 for (;;)
2641 {
2643
2646
2648 break;
2649
2650
2651 if (
copaque->btpo_level != level - 1)
2654 errmsg_internal(
"downlink points to block in index \"%s\" whose level is not one level down",
2656 errdetail_internal(
"Top parent/under check block=%u block pointed to=%u expected level=%u level in pointed to block=%u.",
2658 level - 1,
copaque->btpo_level)));
2659
2665
2667 }
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2692 errmsg_internal(
"downlink to deleted leaf page found in index \"%s\"",
2694 errdetail_internal(
"Top parent/target block=%u leaf block=%u top parent/under check lsn=%X/%08X.",
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2709 {
2713 return;
2714 }
2715
2718 errmsg(
"internal index block lacks downlink in index \"%s\"",
2723}
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780static void
2783{
2787
2789
2790
2794
2795
2800 errmsg(
"heap tuple (%u,%u) from table \"%s\" lacks matching index tuple within index \"%s\"",
2806 ?
errhint(
"Retrying verification using the function bt_index_parent_check() might provide a more specific error.")
2807 : 0));
2808
2809 state->heaptuplespresent++;
2811
2814}
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2850{
2858
2859
2861
2862
2864 return itup;
2865
2867 {
2869
2871
2872
2877 if (att->attbyval || att->attlen != -1 || isnull[
i])
2878 continue;
2879
2880
2881
2882
2883
2884
2888 errmsg(
"external varlena datum in tuple that references heap row (%u,%u) in index \"%s\"",
2896 {
2897
2898
2899
2900
2901
2903 }
2905 {
2909 }
2910
2911
2912
2913
2914
2916 {
2917
2920
2923
2927 }
2928 }
2929
2930
2931
2932
2933
2935 return itup;
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2953
2954
2958
2960}
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2978{
2980
2981
2983}
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009static bool
3011{
3015
3018
3019
3020
3021
3022
3023
3024
3025
3026
3030
3032 {
3036
3043
3044
3046
3048
3054 }
3055
3057
3059}
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071static inline bool
3073{
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3095}
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106static inline bool
3109{
3112
3114
3115
3118
3119 if (!
key->heapkeyspace)
3121
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3134 {
3140
3144
3145
3148
3149
3152
3154 }
3155
3157}
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169static inline bool
3172{
3174
3176
3178
3180}
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192static inline bool
3195{
3197
3199
3201
3202
3203 if (!
key->heapkeyspace)
3205
3206
3207
3208
3209
3210
3211
3212
3214}
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228static inline bool
3232{
3235
3237
3238
3242
3243
3244 if (!
key->heapkeyspace)
3246
3247
3249 {
3255
3259
3260
3263
3264
3267
3269 }
3270
3272}
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3290{
3295
3297
3298
3299
3300
3301
3303 state->checkstrategy);
3305
3306
3307
3308
3309
3311
3312
3315
3317
3321 errmsg(
"invalid meta page found at block %u in index \"%s\"",
3323
3324
3326 {
3328
3333 errmsg(
"index \"%s\" meta page is corrupt",
3335
3340 errmsg(
"version mismatch in index \"%s\": file version %d, "
3341 "current version %d, minimum supported version %d",
3345
3346
3347 return page;
3348 }
3349
3350
3351
3352
3353
3354
3356 {
3357
3358
3362 errmsg_internal(
"invalid leaf page level %u for block %u in index \"%s\"",
3365
3369 errmsg_internal(
"invalid internal page level 0 for block %u in index \"%s\"",
3370 blocknum,
3372 }
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3397 errmsg(
"Number of items on block %u of index \"%s\" exceeds MaxIndexTuplesPerPage (%u)",
3400
3404 errmsg(
"internal block %u in index \"%s\" lacks high key and/or at least one downlink",
3406
3410 errmsg(
"non-rightmost leaf block %u in index \"%s\" lacks high key item",
3412
3413
3414
3415
3416
3417
3418
3419
3423 errmsg(
"internal page block %u in index \"%s\" is half-dead",
3425 errhint(
"This can be caused by an interrupted VACUUM in version 9.3 or older, before upgrade. Please REINDEX it.")));
3426
3427
3428
3429
3430
3434 errmsg_internal(
"internal page block %u in index \"%s\" has garbage items",
3436
3440 errmsg_internal(
"full transaction id page flag appears in non-deleted block %u in index \"%s\"",
3442
3448
3449 return page;
3450}
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3468{
3470
3472 skey->backward =
true;
3473
3475}
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3493{
3495
3500 errmsg(
"line pointer points past end of tuple space in index \"%s\"",
3506
3507
3508
3509
3510
3511
3516 errmsg(
"invalid line pointer storage in index \"%s\"",
3522
3523 return itemid;
3524}
3525
3526
3527
3528
3529
3533{
3535
3536
3537
3538
3539
3540
3545 errmsg_internal(
"block %u or its right sibling block or child block in index \"%s\" has unexpected pivot tuple",
3548
3552 errmsg_internal(
"block %u or its right sibling block or child block in index \"%s\" has unexpected non-pivot tuple",
3555
3560 errmsg(
"block %u or its right sibling block or child block in index \"%s\" contains non-pivot tuple that lacks a heap TID",
3563
3565}
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3580{
3581
3582
3583
3584
3585
3586
3589
3590
3591 return &itup->
t_tid;
3592}
#define InvalidBlockNumber
static bool BlockNumberIsValid(BlockNumber blockNumber)
void bloom_free(bloom_filter *filter)
bloom_filter * bloom_create(int64 total_elems, int bloom_work_mem, uint64 seed)
double bloom_prop_bits_set(bloom_filter *filter)
bool bloom_lacks_element(bloom_filter *filter, unsigned char *elem, size_t len)
void bloom_add_element(bloom_filter *filter, unsigned char *elem, size_t len)
static Datum values[MAXATTR]
void UnlockReleaseBuffer(Buffer buffer)
Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy)
#define RelationGetNumberOfBlocks(reln)
static Page BufferGetPage(Buffer buffer)
static void LockBuffer(Buffer buffer, BufferLockMode mode)
static bool BufferIsValid(Buffer bufnum)
static ItemId PageGetItemId(Page page, OffsetNumber offsetNumber)
static void * PageGetItem(PageData *page, const ItemIdData *itemId)
static XLogRecPtr PageGetLSN(const PageData *page)
static OffsetNumber PageGetMaxOffsetNumber(const PageData *page)
#define Assert(condition)
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
int errcode(int sqlerrcode)
int int errdetail_internal(const char *fmt,...) pg_attribute_printf(1
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
#define palloc0_object(type)
#define PG_FUNCTION_INFO_V1(funcname)
#define PG_DETOAST_DATUM(datum)
#define PG_GETARG_BOOL(n)
BufferAccessStrategy GetAccessStrategy(BufferAccessStrategyType btype)
#define TOAST_INDEX_TARGET
static TransactionId HeapTupleHeaderGetXmin(const HeapTupleHeaderData *tup)
IndexInfo * BuildIndexInfo(Relation index)
IndexTuple index_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
#define ItemIdGetLength(itemId)
#define ItemIdGetOffset(itemId)
#define ItemIdIsDead(itemId)
#define ItemIdIsUsed(itemId)
#define ItemIdIsRedirected(itemId)
#define ItemIdGetFlags(itemId)
int32 ItemPointerCompare(const ItemPointerData *arg1, const ItemPointerData *arg2)
static OffsetNumber ItemPointerGetOffsetNumber(const ItemPointerData *pointer)
static OffsetNumber ItemPointerGetOffsetNumberNoCheck(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumber(const ItemPointerData *pointer)
static BlockNumber ItemPointerGetBlockNumberNoCheck(const ItemPointerData *pointer)
static void ItemPointerCopy(const ItemPointerData *fromPointer, ItemPointerData *toPointer)
static bool ItemPointerIsValid(const ItemPointerData *pointer)
static bool IndexTupleHasVarwidths(const IndexTupleData *itup)
IndexTupleData * IndexTuple
static Datum index_getattr(IndexTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
static Size IndexTupleSize(const IndexTupleData *itup)
#define MaxIndexTuplesPerPage
void * MemoryContextAlloc(MemoryContext context, Size size)
void MemoryContextReset(MemoryContext context)
void pfree(void *pointer)
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_DEFAULT_SIZES
#define CHECK_FOR_INTERRUPTS()
IndexTuple _bt_form_posting(IndexTuple base, const ItemPointerData *htids, int nhtids)
void _bt_relbuf(Relation rel, Buffer buf)
void _bt_checkpage(Relation rel, Buffer buf)
void _bt_metaversion(Relation rel, bool *heapkeyspace, bool *allequalimage)
#define P_HAS_FULLXID(opaque)
#define P_ISHALFDEAD(opaque)
static uint16 BTreeTupleGetNPosting(IndexTuple posting)
static bool BTreeTupleIsPivot(IndexTuple itup)
#define BTREE_MIN_VERSION
#define P_HAS_GARBAGE(opaque)
#define BTPageGetOpaque(page)
#define P_ISDELETED(opaque)
static BlockNumber BTreeTupleGetTopParent(IndexTuple leafhikey)
#define MaxTIDsPerBTreePage
#define P_FIRSTDATAKEY(opaque)
#define P_RIGHTMOST(opaque)
#define P_INCOMPLETE_SPLIT(opaque)
static ItemPointer BTreeTupleGetPostingN(IndexTuple posting, int n)
static BlockNumber BTreeTupleGetDownLink(IndexTuple pivot)
static ItemPointer BTreeTupleGetMaxHeapTID(IndexTuple itup)
static bool BTreeTupleIsPosting(IndexTuple itup)
#define BTMaxItemSizeNoHeapTid
static ItemPointer BTreeTupleGetHeapTID(IndexTuple itup)
#define BTreeTupleGetNAtts(itup, rel)
OffsetNumber _bt_binsrch_insert(Relation rel, BTInsertState insertstate)
int32 _bt_compare(Relation rel, BTScanInsert key, Page page, OffsetNumber offnum)
BTStack _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, int access, bool returnstack)
BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup)
bool _bt_check_natts(Relation rel, bool heapkeyspace, Page page, OffsetNumber offnum)
bool _bt_allequalimage(Relation rel, bool debugmessage)
#define InvalidOffsetNumber
#define OffsetNumberIsValid(offsetNumber)
#define OffsetNumberNext(offsetNumber)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
FormData_pg_attribute * Form_pg_attribute
#define ERRCODE_DATA_CORRUPTED
uint64 pg_prng_uint64(pg_prng_state *state)
pg_prng_state pg_global_prng_state
#define ERRCODE_T_R_SERIALIZATION_FAILURE
static Pointer DatumGetPointer(Datum X)
#define PointerGetDatum(X)
char * psprintf(const char *fmt,...)
static int cmp(const chr *x, const chr *y, size_t len)
static SMgrRelation RelationGetSmgr(Relation rel)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define IndexRelationGetNumberOfKeyAttributes(relation)
bool smgrexists(SMgrRelation reln, ForkNumber forknum)
Snapshot GetTransactionSnapshot(void)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RegisterSnapshot(Snapshot snapshot)
uint16 * ii_ExclusionStrats
struct HeapTupleData * rd_indextuple
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
static double table_index_build_scan(Relation table_rel, Relation index_rel, IndexInfo *index_info, bool allow_sync, bool progress, IndexBuildCallback callback, void *callback_state, TableScanDesc scan)
static TableScanDesc table_beginscan_strat(Relation rel, Snapshot snapshot, int nkeys, ScanKeyData *key, bool allow_strat, bool allow_sync)
static bool table_tuple_fetch_row_version(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot)
#define TransactionIdIsValid(xid)
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
static Size VARSIZE_ANY(const void *PTR)
static bool VARATT_CAN_MAKE_SHORT(const void *PTR)
static bool VARATT_IS_EXTERNAL(const void *PTR)
static char * VARDATA(const void *PTR)
static Size VARATT_CONVERTED_SHORT_SIZE(const void *PTR)
static bool VARATT_IS_COMPRESSED(const void *PTR)
static void SET_VARSIZE_SHORT(void *PTR, Size len)
void amcheck_lock_relation_and_check(Oid indrelid, Oid am_id, IndexDoCheckCallback check, LOCKMODE lockmode, void *state)
static bool offset_is_negative_infinity(BTPageOpaque opaque, OffsetNumber offset)
static bool bt_leftmost_ignoring_half_dead(BtreeCheckState *state, BlockNumber start, BTPageOpaque start_opaque)
static bool invariant_l_offset(BtreeCheckState *state, BTScanInsert key, OffsetNumber upperbound)
static ItemPointer BTreeTupleGetPointsToTID(IndexTuple itup)
static IndexTuple bt_posting_plain_tuple(IndexTuple itup, int n)
static void bt_target_page_check(BtreeCheckState *state)
static void bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace, bool readonly, bool heapallindexed, bool rootdescend, bool checkunique)
static void bt_report_duplicate(BtreeCheckState *state, BtreeLastVisibleEntry *lVis, ItemPointer nexttid, BlockNumber nblock, OffsetNumber noffset, int nposting)
static bool bt_pivot_tuple_identical(bool heapkeyspace, IndexTuple itup1, IndexTuple itup2)
static bool invariant_leq_offset(BtreeCheckState *state, BTScanInsert key, OffsetNumber upperbound)
Datum bt_index_parent_check(PG_FUNCTION_ARGS)
static void bt_child_highkey_check(BtreeCheckState *state, OffsetNumber target_downlinkoffnum, Page loaded_child, uint32 target_level)
static bool heap_entry_is_visible(BtreeCheckState *state, ItemPointer tid)
static BTScanInsert bt_mkscankey_pivotsearch(Relation rel, IndexTuple itup)
Datum bt_index_check(PG_FUNCTION_ARGS)
static BtreeLevel bt_check_level_from_leftmost(BtreeCheckState *state, BtreeLevel level)
static void bt_downlink_missing_check(BtreeCheckState *state, bool rightsplit, BlockNumber blkno, Page page)
static ItemId PageGetItemIdCareful(BtreeCheckState *state, BlockNumber block, Page page, OffsetNumber offset)
static void bt_tuple_present_callback(Relation index, ItemPointer tid, Datum *values, bool *isnull, bool tupleIsAlive, void *checkstate)
static void bt_index_check_callback(Relation indrel, Relation heaprel, void *state, bool readonly)
static bool bt_rootdescend(BtreeCheckState *state, IndexTuple itup)
static BTScanInsert bt_right_page_check_scankey(BtreeCheckState *state, OffsetNumber *rightfirstoffset)
static bool invariant_g_offset(BtreeCheckState *state, BTScanInsert key, OffsetNumber lowerbound)
#define InvalidBtreeLevel
static Page palloc_btree_page(BtreeCheckState *state, BlockNumber blocknum)
static IndexTuple bt_normalize_tuple(BtreeCheckState *state, IndexTuple itup)
static void bt_recheck_sibling_links(BtreeCheckState *state, BlockNumber btpo_prev_from_target, BlockNumber leftcurrent)
static ItemPointer BTreeTupleGetHeapTIDCareful(BtreeCheckState *state, IndexTuple itup, bool nonpivot)
#define BTreeTupleGetNKeyAtts(itup, rel)
static void bt_child_check(BtreeCheckState *state, BTScanInsert targetkey, OffsetNumber downlinkoffnum)
static void bt_entry_unique_check(BtreeCheckState *state, IndexTuple itup, BlockNumber targetblock, OffsetNumber offset, BtreeLastVisibleEntry *lVis)
static bool invariant_l_nontarget_offset(BtreeCheckState *state, BTScanInsert key, BlockNumber nontargetblock, Page nontarget, OffsetNumber upperbound)
#define IsolationUsesXactSnapshot()
#define LSN_FORMAT_ARGS(lsn)