Handle old versioned columnar metapage after binary upgrade (#4956)

* Make VACUUM hint for upgrade scenario actually work

* Suggest using VACUUM if metapage doesn't exist

Plus, suggest upgrading sql version as another option.

* Always force read metapage block

* Fix two typos
pull/5052/head
Onur Tirtir 2021-05-07 17:18:21 +03:00
parent 2e419ea177
commit 2552aee404
3 changed files with 32 additions and 7 deletions

View File

@ -87,6 +87,10 @@ typedef struct PhysicalAddr
#define COLUMNAR_FIRST_STRIPE_ID 1
#define OLD_METAPAGE_VERSION_HINT "Use \"VACUUM\" to upgrade the columnar table format " \
"version or run \"ALTER EXTENSION citus UPDATE\"."
/*
* Map logical offsets to a physical page and offset where the data is kept.
*/
@ -325,7 +329,7 @@ ColumnarStorageGetReservedOffset(Relation rel, bool force)
/*
* ColumnarMetapageNeedsUpgrade - return true if metapage exists and is not
* ColumnarStorageIsCurrent - return true if metapage exists and is not
* the current version.
*/
bool
@ -610,13 +614,27 @@ ColumnarMetapageRead(Relation rel, bool force)
BlockNumber nblocks = smgrnblocks(rel->rd_smgr, MAIN_FORKNUM);
if (nblocks == 0)
{
elog(ERROR, "columnar metapage for relation \"%s\" does not exist",
RelationGetRelationName(rel));
/*
* We only expect this to happen during binary ugrades. This is because,
* in current version of columnar, we immediately create the metapage
* for columnar tables, i.e right after creating the table.
* However in older versions, we were creating metapages lazily, i.e
* when ingesting data to columnar table.
*/
ereport(ERROR, (errmsg("columnar metapage for relation \"%s\" does not exist",
RelationGetRelationName(rel)),
errhint(OLD_METAPAGE_VERSION_HINT)));
}
/*
* Regardless of "force" parameter, always force read metapage block.
* We will check metapage version in ColumnarMetapageCheckVersion
* depending on "force".
*/
bool forceReadBlock = true;
ColumnarMetapage metapage;
ReadFromBlock(rel, COLUMNAR_METAPAGE_BLOCKNO, SizeOfPageHeaderData,
(char *) &metapage, sizeof(ColumnarMetapage), force);
(char *) &metapage, sizeof(ColumnarMetapage), forceReadBlock);
if (!force)
{
@ -786,7 +804,6 @@ ColumnarMetapageCheckVersion(Relation rel, ColumnarMetapage *metapage)
COLUMNAR_VERSION_MAJOR, COLUMNAR_VERSION_MINOR,
RelationGetRelationName(rel),
metapage->versionMajor, metapage->versionMinor),
errhint(
"Use VACUUM to upgrade the columnar table format version.")));
errhint(OLD_METAPAGE_VERSION_HINT)));
}
}

View File

@ -696,6 +696,14 @@ static void
columnar_vacuum_rel(Relation rel, VacuumParams *params,
BufferAccessStrategy bstrategy)
{
/*
* If metapage version of relation is older, then we hint users to VACUUM
* the relation in ColumnarMetapageCheckVersion. So if needed, upgrade
* the metapage before doing anything.
*/
bool isUpgrade = true;
ColumnarStorageUpdateIfNeeded(rel, isUpgrade);
int elevel = (params->options & VACOPT_VERBOSE) ? INFO : DEBUG2;
/* this should have been resolved by vacuum.c until now */

View File

@ -12,7 +12,7 @@ REFERENCES columnar.stripe(storage_id, stripe_num) ON DELETE CASCADE;
-- define columnar_ensure_objects_exist again
#include "../udfs/columnar_ensure_objects_exist/10.0-1.sql"
-- upgrade storage for all columnar relations
-- downgrade storage for all columnar relations
SELECT citus_internal.downgrade_columnar_storage(c.oid) FROM pg_class c, pg_am a
WHERE c.relam = a.oid AND amname = 'columnar';