⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clog.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
 */voidStartupCLOG(void){	TransactionId xid = ShmemVariableCache->nextXid;	int			pageno = TransactionIdToPage(xid);	LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);	/*	 * Initialize our idea of the latest page number.	 */	ClogCtl->shared->latest_page_number = pageno;	/*	 * Zero out the remainder of the current clog page.  Under normal	 * circumstances it should be zeroes already, but it seems at least	 * theoretically possible that XLOG replay will have settled on a nextXID	 * value that is less than the last XID actually used and marked by the	 * previous database lifecycle (since subtransaction commit writes clog	 * but makes no WAL entry).  Let's just be safe. (We need not worry about	 * pages beyond the current one, since those will be zeroed when first	 * used.  For the same reason, there is no need to do anything when	 * nextXid is exactly at a page boundary; and it's likely that the	 * "current" page doesn't exist yet in that case.)	 */	if (TransactionIdToPgIndex(xid) != 0)	{		int			byteno = TransactionIdToByte(xid);		int			bshift = TransactionIdToBIndex(xid) * CLOG_BITS_PER_XACT;		int			slotno;		char	   *byteptr;		slotno = SimpleLruReadPage(ClogCtl, pageno, false, xid);		byteptr = ClogCtl->shared->page_buffer[slotno] + byteno;		/* Zero so-far-unused positions in the current byte */		*byteptr &= (1 << bshift) - 1;		/* Zero the rest of the page */		MemSet(byteptr + 1, 0, BLCKSZ - byteno - 1);		ClogCtl->shared->page_dirty[slotno] = true;	}	LWLockRelease(CLogControlLock);}/* * This must be called ONCE during postmaster or standalone-backend shutdown */voidShutdownCLOG(void){	/* Flush dirty CLOG pages to disk */	SimpleLruFlush(ClogCtl, false);}/* * Perform a checkpoint --- either during shutdown, or on-the-fly */voidCheckPointCLOG(void){	/* Flush dirty CLOG pages to disk */	SimpleLruFlush(ClogCtl, true);}/* * Make sure that CLOG has room for a newly-allocated XID. * * NB: this is called while holding XidGenLock.  We want it to be very fast * most of the time; even when it's not so fast, no actual I/O need happen * unless we're forced to write out a dirty clog or xlog page to make room * in shared memory. */voidExtendCLOG(TransactionId newestXact){	int			pageno;	/*	 * No work except at first XID of a page.  But beware: just after	 * wraparound, the first XID of page zero is FirstNormalTransactionId.	 */	if (TransactionIdToPgIndex(newestXact) != 0 &&		!TransactionIdEquals(newestXact, FirstNormalTransactionId))		return;	pageno = TransactionIdToPage(newestXact);	LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);	/* Zero the page and make an XLOG entry about it */	ZeroCLOGPage(pageno, true);	LWLockRelease(CLogControlLock);}/* * Remove all CLOG segments before the one holding the passed transaction ID * * Before removing any CLOG data, we must flush XLOG to disk, to ensure * that any recently-emitted HEAP_FREEZE records have reached disk; otherwise * a crash and restart might leave us with some unfrozen tuples referencing * removed CLOG data.  We choose to emit a special TRUNCATE XLOG record too. * Replaying the deletion from XLOG is not critical, since the files could * just as well be removed later, but doing so prevents a long-running hot * standby server from acquiring an unreasonably bloated CLOG directory. * * Since CLOG segments hold a large number of transactions, the opportunity to * actually remove a segment is fairly rare, and so it seems best not to do * the XLOG flush unless we have confirmed that there is a removable segment. */voidTruncateCLOG(TransactionId oldestXact){	int			cutoffPage;	/*	 * The cutoff point is the start of the segment containing oldestXact. We	 * pass the *page* containing oldestXact to SimpleLruTruncate.	 */	cutoffPage = TransactionIdToPage(oldestXact);	/* Check to see if there's any files that could be removed */	if (!SlruScanDirectory(ClogCtl, cutoffPage, false))		return;					/* nothing to remove */	/* Write XLOG record and flush XLOG to disk */	WriteTruncateXlogRec(cutoffPage);	/* Now we can remove the old CLOG segment(s) */	SimpleLruTruncate(ClogCtl, cutoffPage);}/* * Decide which of two CLOG page numbers is "older" for truncation purposes. * * We need to use comparison of TransactionIds here in order to do the right * thing with wraparound XID arithmetic.  However, if we are asked about * page number zero, we don't want to hand InvalidTransactionId to * TransactionIdPrecedes: it'll get weird about permanent xact IDs.  So, * offset both xids by FirstNormalTransactionId to avoid that. */static boolCLOGPagePrecedes(int page1, int page2){	TransactionId xid1;	TransactionId xid2;	xid1 = ((TransactionId) page1) * CLOG_XACTS_PER_PAGE;	xid1 += FirstNormalTransactionId;	xid2 = ((TransactionId) page2) * CLOG_XACTS_PER_PAGE;	xid2 += FirstNormalTransactionId;	return TransactionIdPrecedes(xid1, xid2);}/* * Write a ZEROPAGE xlog record */static voidWriteZeroPageXlogRec(int pageno){	XLogRecData rdata;	rdata.data = (char *) (&pageno);	rdata.len = sizeof(int);	rdata.buffer = InvalidBuffer;	rdata.next = NULL;	(void) XLogInsert(RM_CLOG_ID, CLOG_ZEROPAGE, &rdata);}/* * Write a TRUNCATE xlog record * * We must flush the xlog record to disk before returning --- see notes * in TruncateCLOG(). */static voidWriteTruncateXlogRec(int pageno){	XLogRecData rdata;	XLogRecPtr	recptr;	rdata.data = (char *) (&pageno);	rdata.len = sizeof(int);	rdata.buffer = InvalidBuffer;	rdata.next = NULL;	recptr = XLogInsert(RM_CLOG_ID, CLOG_TRUNCATE, &rdata);	XLogFlush(recptr);}/* * CLOG resource manager's routines */voidclog_redo(XLogRecPtr lsn, XLogRecord *record){	uint8		info = record->xl_info & ~XLR_INFO_MASK;	if (info == CLOG_ZEROPAGE)	{		int			pageno;		int			slotno;		memcpy(&pageno, XLogRecGetData(record), sizeof(int));		LWLockAcquire(CLogControlLock, LW_EXCLUSIVE);		slotno = ZeroCLOGPage(pageno, false);		SimpleLruWritePage(ClogCtl, slotno, NULL);		Assert(!ClogCtl->shared->page_dirty[slotno]);		LWLockRelease(CLogControlLock);	}	else if (info == CLOG_TRUNCATE)	{		int			pageno;		memcpy(&pageno, XLogRecGetData(record), sizeof(int));		/*		 * During XLOG replay, latest_page_number isn't set up yet; insert a		 * suitable value to bypass the sanity test in SimpleLruTruncate.		 */		ClogCtl->shared->latest_page_number = pageno;		SimpleLruTruncate(ClogCtl, pageno);	}	else		elog(PANIC, "clog_redo: unknown op code %u", info);}voidclog_desc(StringInfo buf, uint8 xl_info, char *rec){	uint8		info = xl_info & ~XLR_INFO_MASK;	if (info == CLOG_ZEROPAGE)	{		int			pageno;		memcpy(&pageno, rec, sizeof(int));		appendStringInfo(buf, "zeropage: %d", pageno);	}	else if (info == CLOG_TRUNCATE)	{		int			pageno;		memcpy(&pageno, rec, sizeof(int));		appendStringInfo(buf, "truncate before: %d", pageno);	}	else		appendStringInfo(buf, "UNKNOWN");}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -