Skip to content

Commit

Permalink
Unlogged index fix v14 (#259)
Browse files Browse the repository at this point in the history
* Avoid errors when accessing indexes of unlogge tables after compute restart

* Address review complaints: add comment to mdopenfork

* Initialize unlogged index undex eclusive lock
  • Loading branch information
knizhnik authored and Matthias van de Meent committed Feb 23, 2023
1 parent 1b8c35b commit a9f5034
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 3 deletions.
38 changes: 37 additions & 1 deletion src/backend/optimizer/util/plancat.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "access/xlog.h"
#include "catalog/catalog.h"
#include "catalog/heap.h"
#include "catalog/index.h"
#include "catalog/pg_am.h"
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic_ext.h"
Expand All @@ -46,6 +47,8 @@
#include "rewrite/rewriteManip.h"
#include "statistics/statistics.h"
#include "storage/bufmgr.h"
#include "storage/buf_internals.h"
#include "storage/lmgr.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
#include "utils/partcache.h"
Expand Down Expand Up @@ -80,6 +83,39 @@ static void set_baserel_partition_key_exprs(Relation relation,
static void set_baserel_partition_constraint(Relation relation,
RelOptInfo *rel);

static bool
is_index_valid(Relation index, LOCKMODE lmode)
{
if (!index->rd_index->indisvalid)
return false;

if (index->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
{
while (true)
{
Buffer metapage = ReadBuffer(index, 0);
bool isNew = PageIsNew(BufferGetPage(metapage));
ReleaseBuffer(metapage);
if (isNew)
{
Relation heap;
if (lmode != ExclusiveLock)
{
UnlockRelation(index, lmode);
LockRelation(index, ExclusiveLock);
lmode = ExclusiveLock;
continue;
}
DropRelFileNodesAllBuffers(&index->rd_smgr, 1);
heap = RelationIdGetRelation(index->rd_index->indrelid);
index->rd_indam->ambuild(heap, index, BuildIndexInfo(index));
RelationClose(heap);
}
break;
}
}
return true;
}

/*
* get_relation_info -
Expand Down Expand Up @@ -221,7 +257,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
* still needs to insert into "invalid" indexes, if they're marked
* indisready.
*/
if (!index->indisvalid)
if (!is_index_valid(indexRelation, lmode))
{
index_close(indexRelation, NoLock);
continue;
Expand Down
25 changes: 23 additions & 2 deletions src/backend/storage/smgr/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,13 @@ mdopenfork(SMgrRelation reln, ForkNumber forknum, int behavior)

fd = PathNameOpenFile(path, O_RDWR | PG_BINARY);

/*
* NEON: unlogged relation files are lost after compute restart - we need to implicitly recreate them
* to allow data insertion
*/
if (fd < 0 && (behavior & EXTENSION_CREATE))
fd = PathNameOpenFile(path, O_RDWR | O_CREAT | PG_BINARY);

if (fd < 0)
{
if ((behavior & EXTENSION_RETURN_NULL) &&
Expand Down Expand Up @@ -652,9 +659,23 @@ mdread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
reln->smgr_rnode.node.relNode,
reln->smgr_rnode.backend);

/* NEON: md smgr is used in Neon for unlogged and temp relations.
* After compute node restart their data is deleted but unlogged tables are still present in system catalog.
* This is a difference with Vanilla Postgres where unlogged relations are truncated only after abnormal termination.
* To avoid "could not open file" we have to use EXTENSION_RETURN_NULL hear instead of EXTENSION_FAIL
*/
v = _mdfd_getseg(reln, forknum, blocknum, false,
EXTENSION_FAIL | EXTENSION_CREATE_RECOVERY);

RelFileNodeBackendIsTemp(reln->smgr_rnode)
? EXTENSION_FAIL | EXTENSION_CREATE_RECOVERY
: EXTENSION_RETURN_NULL);
if (v == NULL)
{
char* path = relpath(reln->smgr_rnode, forknum);
(void)PathNameOpenFile(path, O_RDWR | O_CREAT | PG_BINARY);
pfree(path);
MemSet(buffer, 0, BLCKSZ);
return;
}
seekpos = (off_t) BLCKSZ * (blocknum % ((BlockNumber) RELSEG_SIZE));

Assert(seekpos < (off_t) BLCKSZ * RELSEG_SIZE);
Expand Down

0 comments on commit a9f5034

Please sign in to comment.