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 {
340 errmsg(
"index \"%s\" metapage incorrectly indicates that deduplication is safe",
343 ?
errhint(
"This is known of \"interval\" indexes last built on a version predating 2023-11.")
344 : 0));
345 }
346 }
347
348
350 args->heapallindexed,
args->rootdescend,
args->checkunique);
351}
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376static void
378 bool readonly, bool heapallindexed, bool rootdescend,
379 bool checkunique)
380{
386
387 if (!readonly)
388 elog(
DEBUG1,
"verifying consistency of tree structure for index \"%s\"",
390 else
391 elog(
DEBUG1,
"verifying consistency of tree structure for index \"%s\" with cross-level checks",
393
394
395
396
397
399
400
401
402
405 state->heaprel = heaprel;
406 state->heapkeyspace = heapkeyspace;
407 state->readonly = readonly;
408 state->heapallindexed = heapallindexed;
409 state->rootdescend = rootdescend;
410 state->checkunique = checkunique;
412
413 if (
state->heapallindexed)
414 {
418
419
420
421
422
423
424
425
429
431
433 state->heaptuplespresent = 0;
434
435
436
437
438
439
440
441
443
444
445
446
447
448
449
450
451
452
453
454
455
458 state->snapshot->xmin))
461 errmsg(
"index \"%s\" cannot be verified using transaction snapshot",
463 }
464
465
466
467
468
469
470 if (
state->checkunique)
471 {
473
476 }
477
479 if (
state->rootdescend && !
state->heapkeyspace)
482 errmsg(
"cannot verify that tuples from index \"%s\" can each be found by an independent index search",
484 errhint(
"Only B-Tree version 4 indexes support rootdescend verification.")));
485
486
488 "amcheck context",
491
492
495
496
497
498
499
500
501
502
503
509 errdetail_internal(
"Fast root block %u (level %u) differs from true root block %u (level %u).",
512
513
514
515
516
517
523 {
524
525
526
527
529
533 errmsg(
"index \"%s\" has no valid pages on level below %u or first level",
535
537 }
538
539
540
541
542 if (
state->heapallindexed)
543 {
546
547
548
549
550
551
552
553
556 0,
558 true,
559 true);
560
561
562
563
564
565
566
567
568
569
570
572
573
574
575
576
577
582
583 elog(
DEBUG1,
"verifying that tuples from index \"%s\" are present in \"%s\"",
586
589
594
596 }
597
598
602}
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
624{
625
629
630
633
634
638
639
641
644 " (true root level)" : level.level == 0 ? " (leaf level)" : "");
645
647 state->previncompletesplit =
false;
648
649 do
650 {
651
653
654
655 state->targetblock = current;
658
660
662 {
663
664
665
666
667
668
669
670
671
672
673
677 errmsg(
"downlink or sibling link points to deleted block in index \"%s\"",
681
685 errmsg(
"block %u fell off the end of index \"%s\"",
687 else
693 }
695 {
696
697
698
699
700
701
702
704 {
708 errmsg(
"block %u is not leftmost in index \"%s\"",
710
714 errmsg(
"block %u is not true root in index \"%s\"",
716 }
717
718
719
720
721
722
723
724
725
726
728 {
731
732
739 }
740 else
741 {
742
743
744
745
746
747
750 }
751
752
753
754
755
756
757 }
758
759
760
761
762
763
764
765
766
767
770
771
775 errmsg(
"leftmost down link for level points to block in index \"%s\" whose level is not one level down",
777 errdetail_internal(
"Block pointed to=%u expected level=%u level in pointed to block=%u.",
779
780
782
784
785
789 errmsg(
"circular link chain found in block %u of index \"%s\"",
791
794
796 {
800 }
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
819 {
822
826
829 }
830
831
833 }
834 while (current !=
P_NONE);
835
837 {
841 }
842
843
845
847}
848
849
850static bool
852{
854
856
858 tid,
state->snapshot, slot);
861
863}
864
865
866
867
868
869static void
874{
881
889
892
893 if (
lVis->postingIndex >= 0)
895
898
901 errmsg(
"index uniqueness is violated for index \"%s\"",
903 errdetail(
"Index %s%s and%s%s (point to heap %s and %s) page lsn=%X/%08X.",
906}
907
908
909static void
913{
916
918
919
920
921
922
924 {
926 {
929 {
932 {
935 tid, targetblock,
937 }
938
939
940
941
942
943
945 return;
946
947 lVis->blkno = targetblock;
948 lVis->offset = offset;
949 lVis->postingIndex =
i;
951 }
952 }
953 }
954
955
956
957
958
959
960 else
961 {
964 {
967 {
970 tid, targetblock,
971 offset, -1);
972 }
973
974 lVis->blkno = targetblock;
975 lVis->offset = offset;
977 lVis->postingIndex = -1;
978 }
979 }
980
983 lVis->blkno != targetblock)
984 {
986
987 if (
lVis->postingIndex >= 0)
991 errmsg(
"index uniqueness can not be checked for index tid=(%u,%u) in index \"%s\"",
992 targetblock, offset,
994 errdetail(
"It doesn't have visible heap tids and key is equal to the tid=(%u,%u)%s (points to heap tid=(%u,%u)).",
998 errhint(
"VACUUM the table and repeat the check.")));
999 }
1000}
1001
1002
1003
1004
1005
1006
1007
1008static bool
1012{
1016
1017
1018
1019
1020
1022
1024 {
1027
1029
1030
1031
1032
1033
1034
1040 {
1042
1043
1046 errmsg_internal(
"harmless interrupted page deletion detected in index \"%s\"",
1051
1054 }
1055
1057 }
1058
1060}
1061
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
1097static void
1101{
1102
1104
1105 if (!
state->readonly)
1106 {
1112
1113
1121 {
1122
1123
1124
1125
1126
1127
1128
1130 return;
1131 }
1132
1134
1136 {
1139 state->checkstrategy);
1144
1146 }
1147 else
1148 {
1149
1150
1151
1152
1153
1154
1157 }
1158
1159
1160
1161
1162
1166
1168 {
1169
1172 errmsg_internal(
"harmless concurrent page split detected in index \"%s\"",
1176 state->targetblock)));
1177 return;
1178 }
1179
1180
1181
1182
1183
1184
1185
1186
1188 }
1189
1192 errmsg(
"left link/right link pair in index \"%s\" not in agreement",
1197}
1198
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
1237static void
1239{
1243
1244
1246
1249
1250 elog(
DEBUG2,
"verifying %u items on %s block %u", max,
1252
1253
1254
1255
1256
1258 {
1261
1262
1267 {
1271 errmsg(
"wrong number of high key index tuple attributes in index \"%s\"",
1278 }
1279 }
1280
1281
1282
1283
1284
1285
1287 offset <= max;
1289 {
1296
1297
1298
1299
1300
1301
1303
1305
1307 state->target, offset);
1310
1311
1312
1313
1314
1315
1316
1320 errmsg(
"index tuple size does not equal lp_len in index \"%s\"",
1323 state->targetblock, offset,
1326 errhint(
"This could be a torn page problem.")));
1327
1328
1330 offset))
1331 {
1335
1341
1344 errmsg(
"wrong number of index tuple attributes in index \"%s\"",
1352 }
1353
1354
1355
1356
1357
1359 {
1360
1361
1362
1363
1364
1366 {
1368 offset,
1371 }
1372 continue;
1373 }
1374
1375
1376
1377
1378
1379
1380
1383 {
1387
1391
1394 errmsg(
"could not find tuple using search from root page in index \"%s\"",
1399 }
1400
1401
1402
1403
1404
1406 {
1409
1411
1413 {
1414
1416
1418 {
1420
1423 errmsg_internal(
"posting list contains misplaced TID in index \"%s\"",
1428 }
1429
1431 }
1432 }
1433
1434
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1464 {
1468
1473
1476 errmsg(
"index row size %zu exceeds maximum for index \"%s\"",
1483 }
1484
1485
1487 {
1489
1491 {
1492
1494 {
1496
1501
1505 }
1506 }
1507 else
1508 {
1512
1515 }
1516 }
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 scantid =
skey->scantid;
1567
1571 {
1575
1580
1583 errmsg(
"high key invariant violated for index \"%s\"",
1590 }
1591
1592 skey->scantid = scantid;
1593
1594
1595
1596
1597
1598
1599
1602 {
1608
1616
1617
1626
1629 errmsg(
"item order invariant violated for index \"%s\"",
1631 errdetail_internal(
"Lower index tid=%s (points to %s tid=%s) higher index tid=%s (points to %s tid=%s) page lsn=%X/%08X.",
1639 }
1640
1641
1642
1643
1644
1645
1646
1647 if (
state->checkunique &&
state->indexinfo->ii_Unique &&
1650 {
1654 }
1655
1656 if (
state->checkunique &&
state->indexinfo->ii_Unique &&
1658 {
1659
1660 scantid =
skey->scantid;
1661
1662
1663
1664
1665
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1679 {
1682 lVis.postingIndex = -1;
1684 }
1686 {
1689 }
1690 skey->scantid = scantid;
1691 }
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710 if (offset == max)
1711 {
1713
1714
1716
1717
1719
1722 {
1723
1724
1725
1726
1727
1728
1729
1730 if (!
state->readonly)
1731 {
1732
1734
1736
1737
1738
1739
1741 return;
1742 }
1743
1746 errmsg(
"cross page item order invariant violated for index \"%s\"",
1749 state->targetblock, offset,
1751 }
1752
1753
1754
1755
1756
1757 if (
state->checkunique &&
state->indexinfo->ii_Unique &&
1759 {
1761
1762 elog(
DEBUG2,
"check cross page unique condition");
1763
1764
1765
1766
1767
1768
1770
1771
1774 {
1776
1777
1778
1779
1780
1784
1789
1791 {
1793 break;
1794 }
1795
1799 errmsg(
"right block of leaf block is non-leaf for index \"%s\"",
1804
1809
1811
1813 }
1814 }
1815 }
1816
1817
1818
1819
1820
1821
1822
1823
1824
1827 }
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1839 {
1842 }
1843}
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1865{
1872
1873
1875
1876
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1905 for (;;)
1906 {
1908
1911
1913 break;
1914
1915
1916
1917
1918
1921 errmsg_internal(
"level %u sibling page in block %u of index \"%s\" was found deleted or half dead",
1923 errdetail_internal(
"Deleted page found when building scankey from right sibling.")));
1924
1926
1927
1929 }
1930
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
2022
2023
2024
2025
2027 {
2028
2032 }
2035 {
2036
2037
2038
2039
2042 }
2043 else
2044 {
2045
2046
2047
2048
2049
2056 }
2057
2058
2059
2060
2061
2064}
2065
2066
2067
2068
2069
2070static bool
2072{
2074 return false;
2075
2076 if (heapkeyspace)
2077 {
2078
2079
2080
2081
2082
2086 return false;
2087 }
2088 else
2089 {
2090
2091
2092
2093
2094
2095
2099 return false;
2100 }
2101
2102 return true;
2103}
2104
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
2143static void
2148{
2153 bool first = true;
2157
2159 {
2164 }
2165 else
2166 {
2168 }
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2183 {
2184 blkno = downlink;
2186 }
2187
2188
2189 while (true)
2190 {
2191
2192
2193
2194
2196 {
2198 state->previncompletesplit =
false;
2199 return;
2200 }
2201
2202
2206 errmsg(
"can't traverse from downlink %u to downlink %u of index \"%s\"",
2207 state->prevrightlink, downlink,
2209
2210
2213 else
2215
2217
2218
2223 errmsg(
"the first child of leftmost target page is not leftmost of its level in index \"%s\"",
2226 state->targetblock, blkno,
2228
2229
2234 errmsg(
"block found while following rightlinks from child of index \"%s\" has invalid level",
2236 errdetail_internal(
"Block pointed to=%u expected level=%u level in pointed to block=%u.",
2238
2239
2240 if ((!first && blkno ==
state->prevrightlink) || blkno == opaque->
btpo_prev)
2243 errmsg(
"circular link chain found in block %u of index \"%s\"",
2245
2246 if (blkno != downlink && !
P_IGNORE(opaque))
2247 {
2248
2250 }
2251
2253
2254
2255
2256
2257
2259 {
2263
2264
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290 if (blkno == downlink)
2292 else
2294
2296
2298 {
2299
2300
2301
2302
2303
2305 {
2309 errmsg(
"child high key is greater than rightmost pivot key on target level in index \"%s\"",
2312 state->targetblock, blkno,
2315 }
2319 }
2320 else
2321 {
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2339 errmsg(
"can't find left sibling high key in index \"%s\"",
2342 state->targetblock, blkno,
2344 itup =
state->lowkey;
2345 }
2346
2348 {
2351 errmsg(
"mismatch between parent key and child high key in index \"%s\"",
2354 state->targetblock, blkno,
2356 }
2357 }
2358
2359
2360 if (blkno == downlink)
2361 {
2364 return;
2365 }
2366
2367
2369
2370
2373 first = false;
2374 }
2375}
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390static void
2393{
2402
2404 state->target, downlinkoffnum);
2407
2408
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
2443
2444
2445
2446
2447
2448
2449
2450
2451
2456
2457
2458
2459
2460
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2491 errmsg(
"downlink to deleted page found in index \"%s\"",
2496
2500 {
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2526 continue;
2527
2529 offset))
2532 errmsg(
"down-link lower bound invariant violated for index \"%s\"",
2534 errdetail_internal(
"Parent block=%u child index tid=(%u,%u) parent page lsn=%X/%08X.",
2537 }
2538
2540}
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555static void
2558{
2567
2570
2571
2573 return;
2574
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2599 {
2602 errmsg_internal(
"harmless interrupted page split detected in index \"%s\"",
2608 return;
2609 }
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2624 errmsg(
"leaf index block lacks downlink in index \"%s\"",
2627 blkno,
2629
2630
2631 elog(
DEBUG1,
"checking for interrupted multi-level deletion due to missing downlink in index \"%s\"",
2633
2638 for (;;)
2639 {
2641
2644
2646 break;
2647
2648
2649 if (
copaque->btpo_level != level - 1)
2652 errmsg_internal(
"downlink points to block in index \"%s\" whose level is not one level down",
2654 errdetail_internal(
"Top parent/under check block=%u block pointed to=%u expected level=%u level in pointed to block=%u.",
2656 level - 1,
copaque->btpo_level)));
2657
2663
2665 }
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2690 errmsg_internal(
"downlink to deleted leaf page found in index \"%s\"",
2692 errdetail_internal(
"Top parent/target block=%u leaf block=%u top parent/under check lsn=%X/%08X.",
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2707 {
2711 return;
2712 }
2713
2716 errmsg(
"internal index block lacks downlink in index \"%s\"",
2721}
2722
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
2778static void
2781{
2785
2787
2788
2792
2793
2798 errmsg(
"heap tuple (%u,%u) from table \"%s\" lacks matching index tuple within index \"%s\"",
2804 ?
errhint(
"Retrying verification using the function bt_index_parent_check() might provide a more specific error.")
2805 : 0));
2806
2807 state->heaptuplespresent++;
2809
2812}
2813
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
2848{
2856
2857
2859
2860
2862 return itup;
2863
2865 {
2867
2869
2870
2875 if (
att->attbyval ||
att->attlen != -1 || isnull[
i])
2876 continue;
2877
2878
2879
2880
2881
2882
2886 errmsg(
"external varlena datum in tuple that references heap row (%u,%u) in index \"%s\"",
2894 {
2895
2896
2897
2898
2899
2901 }
2903 {
2907 }
2908
2909
2910
2911
2912
2914 {
2915
2918
2921
2925 }
2926 }
2927
2928
2929
2930
2931
2933 return itup;
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2951
2952
2956
2958}
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2976{
2978
2979
2981}
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007static bool
3009{
3014
3017
3018
3019
3020
3021
3022
3023
3024
3025
3029
3031 {
3035
3042
3043
3045
3047
3053 }
3054
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)
int errmsg_internal(const char *fmt,...)
int errdetail_internal(const char *fmt,...)
int errdetail(const char *fmt,...)
int errhint(const char *fmt,...)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#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)
BTStack _bt_search(Relation rel, Relation heaprel, BTScanInsert key, Buffer *bufP, int access)
OffsetNumber _bt_binsrch_insert(Relation rel, BTInsertState insertstate)
int32 _bt_compare(Relation rel, BTScanInsert key, Page page, OffsetNumber offnum)
void _bt_freestack(BTStack stack)
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 Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum 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 bool VARATT_CAN_MAKE_SHORT(const void *PTR)
static bool VARATT_IS_EXTERNAL(const void *PTR)
static Size VARSIZE(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)