Пример #1
0
void
smgr_desc(StringInfo buf, uint8 xl_info, char *rec)
{
	uint8		info = xl_info & ~XLR_INFO_MASK;

	if (info == XLOG_SMGR_CREATE)
	{
		xl_smgr_create *xlrec = (xl_smgr_create *) rec;
		char	   *path = relpathperm(xlrec->rnode, xlrec->forkNum);

		appendStringInfo(buf, "file create: %s", path);
		pfree(path);
	}
	else if (info == XLOG_SMGR_TRUNCATE)
	{
		xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
		char	   *path = relpathperm(xlrec->rnode, MAIN_FORKNUM);

		appendStringInfo(buf, "file truncate: %s to %u blocks", path,
						 xlrec->blkno);
		pfree(path);
	}
	else
		appendStringInfoString(buf, "UNKNOWN");
}
Пример #2
0
/* Forget any invalid pages in a whole database */
static void
forget_invalid_pages_db(Oid dbid)
{
	HASH_SEQ_STATUS status;
	xl_invalid_page *hentry;

	if (invalid_page_tab == NULL)
		return;					/* nothing to do */

	hash_seq_init(&status, invalid_page_tab);

	while ((hentry = (xl_invalid_page *) hash_seq_search(&status)) != NULL)
	{
		if (hentry->key.node.dbNode == dbid)
		{
			if (log_min_messages <= DEBUG2 || client_min_messages <= DEBUG2)
			{
				char	   *path = relpathperm(hentry->key.node, hentry->key.forkno);

				elog(DEBUG2, "page %u of relation %s has been dropped",
					 hentry->key.blkno, path);
				pfree(path);
			}

			if (hash_search(invalid_page_tab,
							(void *) &hentry->key,
							HASH_REMOVE, NULL) == NULL)
				elog(ERROR, "hash table corrupted");
		}
	}
}
Пример #3
0
/* Forget any invalid pages >= minblkno, because they've been dropped */
static void
forget_invalid_pages(struct fnode node, enum fork forkno, block_t minblkno)
{
	struct hseq_status status;
	xl_invalid_page *hentry;

	if (invalid_page_tab == NULL)
		return;					/* nothing to do */

	hseq_init(&status, invalid_page_tab);
	while ((hentry = (xl_invalid_page *) hseq_search(&status)) 
		!= NULL) {
		if (FNODE_EQ(hentry->key.node, node) &&
			hentry->key.forkno == forkno &&
			hentry->key.blkno >= minblkno) {
			if (log_min_messages <= DEBUG2 || 
				client_min_messages <= DEBUG2) {
				char *path = relpathperm(hentry->key.node, forkno);

				elog(DEBUG2, "page %u of relation %s has been"
					" dropped", hentry->key.blkno, path);
				pfree(path);
			}

			if (hsearch(invalid_page_tab, (void*) &hentry->key, H_REMOVE, NULL) == NULL)
				elog(ERROR, "hash table corrupted");
		}
	}
}
Пример #4
0
static void
xact_desc_abort(StringInfo buf, xl_xact_abort *xlrec)
{
	int			i;

	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));
	if (xlrec->nrels > 0)
	{
		appendStringInfoString(buf, "; rels:");
		for (i = 0; i < xlrec->nrels; i++)
		{
			char	   *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);

			appendStringInfo(buf, " %s", path);
			pfree(path);
		}
	}
	if (xlrec->nsubxacts > 0)
	{
		TransactionId *xacts = (TransactionId *)
		&xlrec->xnodes[xlrec->nrels];

		appendStringInfoString(buf, "; subxacts:");
		for (i = 0; i < xlrec->nsubxacts; i++)
			appendStringInfo(buf, " %u", xacts[i]);
	}
}
Пример #5
0
/* Log a reference to an invalid page */
static void
log_invalid_page(RelFileNode node, ForkNumber forkno, BlockNumber blkno,
				 bool present)
{
	xl_invalid_page_key key;
	xl_invalid_page *hentry;
	bool		found;

	/*
	 * Log references to invalid pages at DEBUG1 level.  This allows some
	 * tracing of the cause (note the elog context mechanism will tell us
	 * something about the XLOG record that generated the reference).
	 */
	if (log_min_messages <= DEBUG1 || client_min_messages <= DEBUG1)
	{
		char	   *path = relpathperm(node, forkno);

		if (present)
			elog(DEBUG1, "page %u of relation %s is uninitialized",
				 blkno, path);
		else
			elog(DEBUG1, "page %u of relation %s does not exist",
				 blkno, path);
		pfree(path);
	}

	if (invalid_page_tab == NULL)
	{
		/* create hash table when first needed */
		HASHCTL		ctl;

		memset(&ctl, 0, sizeof(ctl));
		ctl.keysize = sizeof(xl_invalid_page_key);
		ctl.entrysize = sizeof(xl_invalid_page);
		ctl.hash = tag_hash;

		invalid_page_tab = hash_create("XLOG invalid-page table",
									   100,
									   &ctl,
									   HASH_ELEM | HASH_FUNCTION);
	}

	/* we currently assume xl_invalid_page_key contains no padding */
	key.node = node;
	key.forkno = forkno;
	key.blkno = blkno;
	hentry = (xl_invalid_page *)
		hash_search(invalid_page_tab, (void *) &key, HASH_ENTER, &found);

	if (!found)
	{
		/* hash_search already filled in the key */
		hentry->present = present;
	}
	else
	{
		/* repeat reference ... leave "present" as it was */
	}
}
Пример #6
0
static void
xact_desc_commit(StringInfo buf, xl_xact_commit *xlrec)
{
	int			i;
	TransactionId *subxacts;

	subxacts = (TransactionId *) &xlrec->xnodes[xlrec->nrels];

	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));

	if (xlrec->nrels > 0)
	{
		appendStringInfo(buf, "; rels:");
		for (i = 0; i < xlrec->nrels; i++)
		{
			char	   *path = relpathperm(xlrec->xnodes[i], MAIN_FORKNUM);

			appendStringInfo(buf, " %s", path);
			pfree(path);
		}
	}
	if (xlrec->nsubxacts > 0)
	{
		appendStringInfo(buf, "; subxacts:");
		for (i = 0; i < xlrec->nsubxacts; i++)
			appendStringInfo(buf, " %u", subxacts[i]);
	}
	if (xlrec->nmsgs > 0)
	{
		SharedInvalidationMessage *msgs;

		msgs = (SharedInvalidationMessage *) &subxacts[xlrec->nsubxacts];

		if (XactCompletionRelcacheInitFileInval(xlrec->xinfo))
			appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
							 xlrec->dbId, xlrec->tsId);

		appendStringInfo(buf, "; inval msgs:");
		for (i = 0; i < xlrec->nmsgs; i++)
		{
			SharedInvalidationMessage *msg = &msgs[i];

			if (msg->id >= 0)
				appendStringInfo(buf, " catcache %d", msg->id);
			else if (msg->id == SHAREDINVALCATALOG_ID)
				appendStringInfo(buf, " catalog %u", msg->cat.catId);
			else if (msg->id == SHAREDINVALRELCACHE_ID)
				appendStringInfo(buf, " relcache %u", msg->rc.relId);
			/* remaining cases not expected, but print something anyway */
			else if (msg->id == SHAREDINVALSMGR_ID)
				appendStringInfo(buf, " smgr");
			else if (msg->id == SHAREDINVALRELMAP_ID)
				appendStringInfo(buf, " relmap");
			else
				appendStringInfo(buf, " unknown id %d", msg->id);
		}
	}
}
Пример #7
0
void
smgr_desc(StringInfo buf, XLogRecord *record)
{
    char	   *rec = XLogRecGetData(record);
    uint8		info = record->xl_info & ~XLR_INFO_MASK;

    if (info == XLOG_SMGR_CREATE)
    {
        xl_smgr_create *xlrec = (xl_smgr_create *) rec;
        char	   *path = relpathperm(xlrec->rnode, xlrec->forkNum);

        appendStringInfo(buf, "%s", path);
        pfree(path);
    }
    else if (info == XLOG_SMGR_TRUNCATE)
    {
        xl_smgr_truncate *xlrec = (xl_smgr_truncate *) rec;
        char	   *path = relpathperm(xlrec->rnode, MAIN_FORKNUM);

        appendStringInfo(buf, "%s to %u blocks", path, xlrec->blkno);
        pfree(path);
    }
}
Пример #8
0
/* Report a reference to an invalid page */
static void
report_invalid_page(int elevel, RelFileNode node, ForkNumber forkno,
					BlockNumber blkno, bool present)
{
	char	   *path = relpathperm(node, forkno);

	if (present)
		elog(elevel, "page %u of relation %s is uninitialized",
			 blkno, path);
	else
		elog(elevel, "page %u of relation %s does not exist",
			 blkno, path);
	pfree(path);
}
Пример #9
0
char *
datasegpath(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
{
	char *path = relpathperm(rnode, forknum);

	if (segno > 0)
	{
		char *segpath = pg_malloc(strlen(path) + 13);
		sprintf(segpath, "%s.%u", path, segno);
		pg_free(path);
		return segpath;
	}
	else
		return path;
}
Пример #10
0
/*
 * A helper function to create the path of a relation file and segment.
 *
 * The returned path is palloc'd
 */
static char *
datasegpath(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
{
	char	   *path;
	char	   *segpath;

	path = relpathperm(rnode, forknum);
	if (segno > 0)
	{
		segpath = psprintf("%s.%u", path, segno);
		pfree(path);
		return segpath;
	}
	else
		return path;
}
Пример #11
0
/* Complain about any remaining invalid-page entries */
void
xlog_check_invalid_pages(void)
{
	struct hseq_status status;
	xl_invalid_page *hentry;
	bool foundone;

	foundone = false;
	if (invalid_page_tab == NULL)
		return;				/* nothing to do */

	hseq_init(&status, invalid_page_tab);

	/*
	 * Our strategy is to emit WARNING messages for all remaining entries 
	 * and only PANIC after we've dumped all the available info.
	 */
	while ((hentry = (xl_invalid_page *)hseq_search(&status)) != NULL) {
		char *path;

		path = relpathperm(hentry->key.node, hentry->key.forkno);
		if (hentry->present)
			elog(WARNING, "page %u of relation %s was"
				" uninitialized", hentry->key.blkno, path);
		else
			elog(WARNING, "page %u of relation %s did not exist",
				 hentry->key.blkno, path);
		pfree(path);
		foundone = true;
	}

	if (foundone)
		elog(PANIC, "WAL contains references to invalid pages");

	hash_destroy(invalid_page_tab);
	invalid_page_tab = NULL;
}
Пример #12
0
static void
xact_desc_commit(StringInfo buf, uint8 info, xl_xact_commit *xlrec, RepOriginId origin_id)
{
	xl_xact_parsed_commit parsed;
	int			i;

	ParseCommitRecord(info, xlrec, &parsed);

	/* If this is a prepared xact, show the xid of the original xact */
	if (TransactionIdIsValid(parsed.twophase_xid))
		appendStringInfo(buf, "%u: ", parsed.twophase_xid);

	appendStringInfoString(buf, timestamptz_to_str(xlrec->xact_time));

	if (parsed.nrels > 0)
	{
		appendStringInfoString(buf, "; rels:");
		for (i = 0; i < parsed.nrels; i++)
		{
			char	   *path = relpathperm(parsed.xnodes[i], MAIN_FORKNUM);

			appendStringInfo(buf, " %s", path);
			pfree(path);
		}
	}
	if (parsed.nsubxacts > 0)
	{
		appendStringInfoString(buf, "; subxacts:");
		for (i = 0; i < parsed.nsubxacts; i++)
			appendStringInfo(buf, " %u", parsed.subxacts[i]);
	}
	if (parsed.nmsgs > 0)
	{
		if (XactCompletionRelcacheInitFileInval(parsed.xinfo))
			appendStringInfo(buf, "; relcache init file inval dbid %u tsid %u",
							 parsed.dbId, parsed.tsId);

		appendStringInfoString(buf, "; inval msgs:");
		for (i = 0; i < parsed.nmsgs; i++)
		{
			SharedInvalidationMessage *msg = &parsed.msgs[i];

			if (msg->id >= 0)
				appendStringInfo(buf, " catcache %d", msg->id);
			else if (msg->id == SHAREDINVALCATALOG_ID)
				appendStringInfo(buf, " catalog %u", msg->cat.catId);
			else if (msg->id == SHAREDINVALRELCACHE_ID)
				appendStringInfo(buf, " relcache %u", msg->rc.relId);
			/* not expected, but print something anyway */
			else if (msg->id == SHAREDINVALSMGR_ID)
				appendStringInfoString(buf, " smgr");
			/* not expected, but print something anyway */
			else if (msg->id == SHAREDINVALRELMAP_ID)
				appendStringInfoString(buf, " relmap");
			else if (msg->id == SHAREDINVALSNAPSHOT_ID)
				appendStringInfo(buf, " snapshot %u", msg->sn.relId);
			else
				appendStringInfo(buf, " unknown id %d", msg->id);
		}
	}

	if (XactCompletionForceSyncCommit(parsed.xinfo))
		appendStringInfo(buf, "; sync");

	if (parsed.xinfo & XACT_XINFO_HAS_ORIGIN)
	{
		appendStringInfo(buf, "; origin: node %u, lsn %X/%X, at %s",
						 origin_id,
						 (uint32)(parsed.origin_lsn >> 32),
						 (uint32)parsed.origin_lsn,
						 timestamptz_to_str(parsed.origin_timestamp));
	}