greenplumn storage_database 源码

  • 2022-08-18
  • 浏览 (317)

greenplumn storage_database 代码

文件路径:/src/backend/catalog/storage_database.c

#include "postgres.h"

#include "access/xlogutils.h"
#include "catalog/pg_database.h"
#include "catalog/storage_database.h"
#include "common/relpath.h"
#include "utils/faultinjector.h"
#include "storage/lmgr.h"

typedef struct PendingDbDelete
{
	DbDirNode	dbDirNode;		/* database dir that needs to be deleted */
	bool		atCommit;		/* T=delete at commit; F=delete at abort */
	struct PendingDbDelete *next;		/* linked-list link */
} PendingDbDelete;

static void dropDatabaseDirectory(DbDirNode *deldb, bool isRedo);

static PendingDbDelete *pendingDbDeletes = NULL; /* head of linked list */
static Oid sessionLockMoveDbOid = InvalidOid;

/*
 * ScheduleDbDirDelete
 * 		Schedule dboid dir removal at transaction commit/abort
 */

void
ScheduleDbDirDelete(Oid db_id, Oid tablespace_oid, bool forCommit)
{
	PendingDbDelete *pending;

	/* Add the relation to the list of stuff to delete at commit */
	pending = (PendingDbDelete *)
		MemoryContextAlloc(TopMemoryContext, sizeof(PendingDbDelete));
	pending->atCommit = forCommit;
	pending->dbDirNode = (DbDirNode)
		{.tablespace = tablespace_oid, .database = db_id};
	pending->next = pendingDbDeletes;
	pendingDbDeletes = pending;
}

void
DoPendingDbDeletes(bool isCommit)
{
	PendingDbDelete *pending;
	PendingDbDelete *next;

	for (pending = pendingDbDeletes; pending != NULL; pending = next)
	{
		next = pending->next;
		/* unlink list entry first, so we don't retry on failure */
		pendingDbDeletes = next;
		/* do deletion if called for */
		if (pending->atCommit == isCommit)
			dropDatabaseDirectory(&pending->dbDirNode,
								  false);

		pfree(pending);
	}
}

void
MoveDbSessionLockAcquire(Oid db_id)
{
	Assert(sessionLockMoveDbOid == InvalidOid);
	LockSharedObjectForSession(DatabaseRelationId, db_id, 0,
							   AccessExclusiveLock);
	sessionLockMoveDbOid = db_id;
}

void
MoveDbSessionLockRelease()
{
	if (sessionLockMoveDbOid == InvalidOid)
		return;
	
	UnlockSharedObjectForSession(DatabaseRelationId, sessionLockMoveDbOid, 0,
							 AccessExclusiveLock);
	DatabaseStorageResetSessionLock();
}

void
DatabaseStorageResetSessionLock()
{
	sessionLockMoveDbOid = InvalidOid;
}

int
GetPendingDbDeletes(bool forCommit, DbDirNode **ptr)
{
	int			ndbs;
	DbDirNode	*dbptr;
	PendingDbDelete *pending;

	ndbs = 0;
	for (pending = pendingDbDeletes; pending != NULL; pending = pending->next)
	{
		if (pending->atCommit == forCommit)
			ndbs++;
	}
	if (ndbs == 0)
	{
		*ptr = NULL;
		return 0;
	}
	dbptr = (DbDirNode *) palloc(ndbs * sizeof(DbDirNode));
	*ptr = dbptr;
	for (pending = pendingDbDeletes; pending != NULL; pending = pending->next)
	{
		if (pending->atCommit == forCommit)
		{
			*dbptr = pending->dbDirNode;
			dbptr++;
		}
	}
	return ndbs;
}

/*
 * This functions contains non-catalog modifications to be performed for movedb().
 * Its called after successfully marking the transaction as committed via pending
 * deletes.
 */
void
DropDatabaseDirectories(DbDirNode *deldbs, int ndeldbs, bool isRedo)
{
	int i;
	for (i = 0; i < ndeldbs; i++)
	{
		dropDatabaseDirectory(&deldbs[i], isRedo);
	}

#ifdef FAULT_INJECTOR
	if(ndeldbs > 0)
		SIMPLE_FAULT_INJECTOR("after_drop_database_directories");
#endif
}

/*
 *	PostPrepare_DatabaseStorage -- Clean up after a successful PREPARE
 *
 * What we have to do here is throw away the in-memory state about pending
 * db deletes. It's all been recorded in the 2PC state file and
 * we no longer need to track it in memory.
 */
void
PostPrepare_DatabaseStorage()
{
	PendingDbDelete *pendingDbDelete;
	PendingDbDelete *nextDbDelete;

	for (pendingDbDelete = pendingDbDeletes; pendingDbDelete != NULL; pendingDbDelete = nextDbDelete)
	{
		nextDbDelete = pendingDbDelete->next;
		pendingDbDeletes = nextDbDelete;
		/* must explicitly free the list entry */
		pfree(pendingDbDelete);
	}

	DatabaseStorageResetSessionLock();
}

static void
dropDatabaseDirectory(DbDirNode *deldb, bool isRedo)
{
	char *dbpath = GetDatabasePath(deldb->database, deldb->tablespace);
	/*
	 * Remove files from the old tablespace
	 */
	if (!rmtree(dbpath, true))
		ereport(WARNING,
				(errmsg("some useless files may be left behind in old database directory \"%s\"",
						dbpath)));

	if (isRedo)
		XLogDropDatabase(deldb->database);
}

相关信息

greenplumn 源码目录

相关文章

greenplumn aclchk 源码

greenplumn aoblkdir 源码

greenplumn aocatalog 源码

greenplumn aoseg 源码

greenplumn aovisimap 源码

greenplumn catalog 源码

greenplumn dependency 源码

greenplumn gp_fastsequence 源码

greenplumn gp_partition_template 源码

greenplumn gp_segment_config 源码

0  赞