Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 0a64b45

Browse files
committed
Fix handling of non-upgraded B-tree metapages
857f9c3 bumps B-tree metapage version while upgrade is performed "on the fly" when needed. However, some asserts fired when old version metapage was cached to rel->rd_amcache. Despite new metadata fields are never used from rel->rd_amcache, that needs to be fixed. This patch introduces metadata upgrade during its caching, which fills unavailable fields with their default values. contrib/pageinspect is also patched to handle non-upgraded metapages in the same way. Author: Alexander Korotkov
1 parent 01b88b4 commit 0a64b45

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

contrib/pageinspect/btreefuncs.c

+15-2
Original file line numberDiff line numberDiff line change
@@ -555,8 +555,21 @@ bt_metap(PG_FUNCTION_ARGS)
555555
values[j++] = psprintf("%d", metad->btm_level);
556556
values[j++] = psprintf("%d", metad->btm_fastroot);
557557
values[j++] = psprintf("%d", metad->btm_fastlevel);
558-
values[j++] = psprintf("%u", metad->btm_oldest_btpo_xact);
559-
values[j++] = psprintf("%lf", metad->btm_last_cleanup_num_heap_tuples);
558+
559+
/*
560+
* Get values of extended metadata if available, use default values
561+
* otherwise.
562+
*/
563+
if (metad->btm_version == BTREE_VERSION)
564+
{
565+
values[j++] = psprintf("%u", metad->btm_oldest_btpo_xact);
566+
values[j++] = psprintf("%lf", metad->btm_last_cleanup_num_heap_tuples);
567+
}
568+
else
569+
{
570+
values[j++] = "0";
571+
values[j++] = "-1";
572+
}
560573

561574
tuple = BuildTupleFromCStrings(TupleDescGetAttInMetadata(tupleDesc),
562575
values);

src/backend/access/nbtree/nbtpage.c

+41-6
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "storage/predicate.h"
3434
#include "utils/snapmgr.h"
3535

36+
static void _bt_cachemetadata(Relation rel, BTMetaPageData *metad);
3637
static bool _bt_mark_page_halfdead(Relation rel, Buffer buf, BTStack stack);
3738
static bool _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf,
3839
bool *rightsib_empty);
@@ -105,6 +106,44 @@ _bt_upgrademetapage(Page page)
105106
((char *) metad + sizeof(BTMetaPageData)) - (char *) page;
106107
}
107108

109+
/*
110+
* Cache metadata from meta page to rel->rd_amcache.
111+
*/
112+
static void
113+
_bt_cachemetadata(Relation rel, BTMetaPageData *metad)
114+
{
115+
/* We assume rel->rd_amcache was already freed by caller */
116+
Assert(rel->rd_amcache == NULL);
117+
rel->rd_amcache = MemoryContextAlloc(rel->rd_indexcxt,
118+
sizeof(BTMetaPageData));
119+
120+
/*
121+
* Meta page should be of supported version (should be already checked by
122+
* caller).
123+
*/
124+
Assert(metad->btm_version >= BTREE_MIN_VERSION &&
125+
metad->btm_version <= BTREE_VERSION);
126+
127+
if (metad->btm_version == BTREE_VERSION)
128+
{
129+
/* Last version of meta-data, no need to upgrade */
130+
memcpy(rel->rd_amcache, metad, sizeof(BTMetaPageData));
131+
}
132+
else
133+
{
134+
BTMetaPageData *cached_metad = (BTMetaPageData *) rel->rd_amcache;
135+
136+
/*
137+
* Upgrade meta-data: copy available information from meta-page and
138+
* fill new fields with default values.
139+
*/
140+
memcpy(rel->rd_amcache, metad, offsetof(BTMetaPageData, btm_oldest_btpo_xact));
141+
cached_metad->btm_version = BTREE_VERSION;
142+
cached_metad->btm_oldest_btpo_xact = InvalidTransactionId;
143+
cached_metad->btm_last_cleanup_num_heap_tuples = -1.0;
144+
}
145+
}
146+
108147
/*
109148
* _bt_update_meta_cleanup_info() -- Update cleanup-related information in
110149
* the metapage.
@@ -403,9 +442,7 @@ _bt_getroot(Relation rel, int access)
403442
/*
404443
* Cache the metapage data for next time
405444
*/
406-
rel->rd_amcache = MemoryContextAlloc(rel->rd_indexcxt,
407-
sizeof(BTMetaPageData));
408-
memcpy(rel->rd_amcache, metad, sizeof(BTMetaPageData));
445+
_bt_cachemetadata(rel, metad);
409446

410447
/*
411448
* We are done with the metapage; arrange to release it via first
@@ -604,9 +641,7 @@ _bt_getrootheight(Relation rel)
604641
/*
605642
* Cache the metapage data for next time
606643
*/
607-
rel->rd_amcache = MemoryContextAlloc(rel->rd_indexcxt,
608-
sizeof(BTMetaPageData));
609-
memcpy(rel->rd_amcache, metad, sizeof(BTMetaPageData));
644+
_bt_cachemetadata(rel, metad);
610645

611646
_bt_relbuf(rel, metabuf);
612647
}

0 commit comments

Comments
 (0)