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

📄 nbtxlog.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!BufferIsValid(buffer))		return;	page = (Page) BufferGetPage(buffer);	if (XLByteLE(lsn, PageGetLSN(page)))	{		UnlockReleaseBuffer(buffer);		return;	}	if (record->xl_len > SizeOfBtreeDelete)	{		OffsetNumber *unused;		OffsetNumber *unend;		unused = (OffsetNumber *) ((char *) xlrec + SizeOfBtreeDelete);		unend = (OffsetNumber *) ((char *) xlrec + record->xl_len);		PageIndexMultiDelete(page, unused, unend - unused);	}	/*	 * Mark the page as not containing any LP_DEAD items --- see comments in	 * _bt_delitems().	 */	opaque = (BTPageOpaque) PageGetSpecialPointer(page);	opaque->btpo_flags &= ~BTP_HAS_GARBAGE;	PageSetLSN(page, lsn);	PageSetTLI(page, ThisTimeLineID);	MarkBufferDirty(buffer);	UnlockReleaseBuffer(buffer);}static voidbtree_xlog_delete_page(uint8 info, XLogRecPtr lsn, XLogRecord *record){	xl_btree_delete_page *xlrec = (xl_btree_delete_page *) XLogRecGetData(record);	Relation	reln;	BlockNumber parent;	BlockNumber target;	BlockNumber leftsib;	BlockNumber rightsib;	Buffer		buffer;	Page		page;	BTPageOpaque pageop;	reln = XLogOpenRelation(xlrec->target.node);	parent = ItemPointerGetBlockNumber(&(xlrec->target.tid));	target = xlrec->deadblk;	leftsib = xlrec->leftblk;	rightsib = xlrec->rightblk;	/* parent page */	if (!(record->xl_info & XLR_BKP_BLOCK_1))	{		buffer = XLogReadBuffer(reln, parent, false);		if (BufferIsValid(buffer))		{			page = (Page) BufferGetPage(buffer);			pageop = (BTPageOpaque) PageGetSpecialPointer(page);			if (XLByteLE(lsn, PageGetLSN(page)))			{				UnlockReleaseBuffer(buffer);			}			else			{				OffsetNumber poffset;				poffset = ItemPointerGetOffsetNumber(&(xlrec->target.tid));				if (poffset >= PageGetMaxOffsetNumber(page))				{					Assert(info == XLOG_BTREE_DELETE_PAGE_HALF);					Assert(poffset == P_FIRSTDATAKEY(pageop));					PageIndexTupleDelete(page, poffset);					pageop->btpo_flags |= BTP_HALF_DEAD;				}				else				{					ItemId		itemid;					IndexTuple	itup;					OffsetNumber nextoffset;					Assert(info != XLOG_BTREE_DELETE_PAGE_HALF);					itemid = PageGetItemId(page, poffset);					itup = (IndexTuple) PageGetItem(page, itemid);					ItemPointerSet(&(itup->t_tid), rightsib, P_HIKEY);					nextoffset = OffsetNumberNext(poffset);					PageIndexTupleDelete(page, nextoffset);				}				PageSetLSN(page, lsn);				PageSetTLI(page, ThisTimeLineID);				MarkBufferDirty(buffer);				UnlockReleaseBuffer(buffer);			}		}	}	/* Fix left-link of right sibling */	if (!(record->xl_info & XLR_BKP_BLOCK_2))	{		buffer = XLogReadBuffer(reln, rightsib, false);		if (BufferIsValid(buffer))		{			page = (Page) BufferGetPage(buffer);			if (XLByteLE(lsn, PageGetLSN(page)))			{				UnlockReleaseBuffer(buffer);			}			else			{				pageop = (BTPageOpaque) PageGetSpecialPointer(page);				pageop->btpo_prev = leftsib;				PageSetLSN(page, lsn);				PageSetTLI(page, ThisTimeLineID);				MarkBufferDirty(buffer);				UnlockReleaseBuffer(buffer);			}		}	}	/* Fix right-link of left sibling, if any */	if (!(record->xl_info & XLR_BKP_BLOCK_3))	{		if (leftsib != P_NONE)		{			buffer = XLogReadBuffer(reln, leftsib, false);			if (BufferIsValid(buffer))			{				page = (Page) BufferGetPage(buffer);				if (XLByteLE(lsn, PageGetLSN(page)))				{					UnlockReleaseBuffer(buffer);				}				else				{					pageop = (BTPageOpaque) PageGetSpecialPointer(page);					pageop->btpo_next = rightsib;					PageSetLSN(page, lsn);					PageSetTLI(page, ThisTimeLineID);					MarkBufferDirty(buffer);					UnlockReleaseBuffer(buffer);				}			}		}	}	/* Rewrite target page as empty deleted page */	buffer = XLogReadBuffer(reln, target, true);	Assert(BufferIsValid(buffer));	page = (Page) BufferGetPage(buffer);	_bt_pageinit(page, BufferGetPageSize(buffer));	pageop = (BTPageOpaque) PageGetSpecialPointer(page);	pageop->btpo_prev = leftsib;	pageop->btpo_next = rightsib;	pageop->btpo.xact = FrozenTransactionId;	pageop->btpo_flags = BTP_DELETED;	pageop->btpo_cycleid = 0;	PageSetLSN(page, lsn);	PageSetTLI(page, ThisTimeLineID);	MarkBufferDirty(buffer);	UnlockReleaseBuffer(buffer);	/* Update metapage if needed */	if (info == XLOG_BTREE_DELETE_PAGE_META)	{		xl_btree_metadata md;		memcpy(&md, (char *) xlrec + SizeOfBtreeDeletePage,			   sizeof(xl_btree_metadata));		_bt_restore_meta(reln, lsn,						 md.root, md.level,						 md.fastroot, md.fastlevel);	}	/* Forget any completed deletion */	forget_matching_deletion(xlrec->target.node, target);	/* If parent became half-dead, remember it for deletion */	if (info == XLOG_BTREE_DELETE_PAGE_HALF)		log_incomplete_deletion(xlrec->target.node, parent);}static voidbtree_xlog_newroot(XLogRecPtr lsn, XLogRecord *record){	xl_btree_newroot *xlrec = (xl_btree_newroot *) XLogRecGetData(record);	Relation	reln;	Buffer		buffer;	Page		page;	BTPageOpaque pageop;	BlockNumber downlink = 0;	reln = XLogOpenRelation(xlrec->node);	buffer = XLogReadBuffer(reln, xlrec->rootblk, true);	Assert(BufferIsValid(buffer));	page = (Page) BufferGetPage(buffer);	_bt_pageinit(page, BufferGetPageSize(buffer));	pageop = (BTPageOpaque) PageGetSpecialPointer(page);	pageop->btpo_flags = BTP_ROOT;	pageop->btpo_prev = pageop->btpo_next = P_NONE;	pageop->btpo.level = xlrec->level;	if (xlrec->level == 0)		pageop->btpo_flags |= BTP_LEAF;	pageop->btpo_cycleid = 0;	if (record->xl_len > SizeOfBtreeNewroot)	{		IndexTuple	itup;		_bt_restore_page(page,						 (char *) xlrec + SizeOfBtreeNewroot,						 record->xl_len - SizeOfBtreeNewroot);		/* extract downlink to the right-hand split page */		itup = (IndexTuple) PageGetItem(page, PageGetItemId(page, P_FIRSTKEY));		downlink = ItemPointerGetBlockNumber(&(itup->t_tid));		Assert(ItemPointerGetOffsetNumber(&(itup->t_tid)) == P_HIKEY);	}	PageSetLSN(page, lsn);	PageSetTLI(page, ThisTimeLineID);	MarkBufferDirty(buffer);	UnlockReleaseBuffer(buffer);	_bt_restore_meta(reln, lsn,					 xlrec->rootblk, xlrec->level,					 xlrec->rootblk, xlrec->level);	/* Check to see if this satisfies any incomplete insertions */	if (record->xl_len > SizeOfBtreeNewroot)		forget_matching_split(xlrec->node, downlink, true);}voidbtree_redo(XLogRecPtr lsn, XLogRecord *record){	uint8		info = record->xl_info & ~XLR_INFO_MASK;	switch (info)	{		case XLOG_BTREE_INSERT_LEAF:			btree_xlog_insert(true, false, lsn, record);			break;		case XLOG_BTREE_INSERT_UPPER:			btree_xlog_insert(false, false, lsn, record);			break;		case XLOG_BTREE_INSERT_META:			btree_xlog_insert(false, true, lsn, record);			break;		case XLOG_BTREE_SPLIT_L:			btree_xlog_split(true, false, lsn, record);			break;		case XLOG_BTREE_SPLIT_R:			btree_xlog_split(false, false, lsn, record);			break;		case XLOG_BTREE_SPLIT_L_ROOT:			btree_xlog_split(true, true, lsn, record);			break;		case XLOG_BTREE_SPLIT_R_ROOT:			btree_xlog_split(false, true, lsn, record);			break;		case XLOG_BTREE_DELETE:			btree_xlog_delete(lsn, record);			break;		case XLOG_BTREE_DELETE_PAGE:		case XLOG_BTREE_DELETE_PAGE_META:		case XLOG_BTREE_DELETE_PAGE_HALF:			btree_xlog_delete_page(info, lsn, record);			break;		case XLOG_BTREE_NEWROOT:			btree_xlog_newroot(lsn, record);			break;		default:			elog(PANIC, "btree_redo: unknown op code %u", info);	}}static voidout_target(StringInfo buf, xl_btreetid *target){	appendStringInfo(buf, "rel %u/%u/%u; tid %u/%u",			 target->node.spcNode, target->node.dbNode, target->node.relNode,					 ItemPointerGetBlockNumber(&(target->tid)),					 ItemPointerGetOffsetNumber(&(target->tid)));}voidbtree_desc(StringInfo buf, uint8 xl_info, char *rec){	uint8		info = xl_info & ~XLR_INFO_MASK;	switch (info)	{		case XLOG_BTREE_INSERT_LEAF:			{				xl_btree_insert *xlrec = (xl_btree_insert *) rec;				appendStringInfo(buf, "insert: ");				out_target(buf, &(xlrec->target));				break;			}		case XLOG_BTREE_INSERT_UPPER:			{				xl_btree_insert *xlrec = (xl_btree_insert *) rec;				appendStringInfo(buf, "insert_upper: ");				out_target(buf, &(xlrec->target));				break;			}		case XLOG_BTREE_INSERT_META:			{				xl_btree_insert *xlrec = (xl_btree_insert *) rec;				appendStringInfo(buf, "insert_meta: ");				out_target(buf, &(xlrec->target));				break;			}		case XLOG_BTREE_SPLIT_L:			{				xl_btree_split *xlrec = (xl_btree_split *) rec;				appendStringInfo(buf, "split_l: rel %u/%u/%u ",								 xlrec->node.spcNode, xlrec->node.dbNode,								 xlrec->node.relNode);				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,								 xlrec->level, xlrec->firstright);				break;			}		case XLOG_BTREE_SPLIT_R:			{				xl_btree_split *xlrec = (xl_btree_split *) rec;				appendStringInfo(buf, "split_r: rel %u/%u/%u ",								 xlrec->node.spcNode, xlrec->node.dbNode,								 xlrec->node.relNode);				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,								 xlrec->level, xlrec->firstright);				break;			}		case XLOG_BTREE_SPLIT_L_ROOT:			{				xl_btree_split *xlrec = (xl_btree_split *) rec;				appendStringInfo(buf, "split_l_root: rel %u/%u/%u ",								 xlrec->node.spcNode, xlrec->node.dbNode,								 xlrec->node.relNode);				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,								 xlrec->level, xlrec->firstright);				break;			}		case XLOG_BTREE_SPLIT_R_ROOT:			{				xl_btree_split *xlrec = (xl_btree_split *) rec;				appendStringInfo(buf, "split_r_root: rel %u/%u/%u ",								 xlrec->node.spcNode, xlrec->node.dbNode,								 xlrec->node.relNode);				appendStringInfo(buf, "left %u, right %u, next %u, level %u, firstright %d",							   xlrec->leftsib, xlrec->rightsib, xlrec->rnext,								 xlrec->level, xlrec->firstright);				break;			}		case XLOG_BTREE_DELETE:			{				xl_btree_delete *xlrec = (xl_btree_delete *) rec;				appendStringInfo(buf, "delete: rel %u/%u/%u; blk %u",								 xlrec->node.spcNode, xlrec->node.dbNode,								 xlrec->node.relNode, xlrec->block);				break;			}		case XLOG_BTREE_DELETE_PAGE:		case XLOG_BTREE_DELETE_PAGE_META:		case XLOG_BTREE_DELETE_PAGE_HALF:			{				xl_btree_delete_page *xlrec = (xl_btree_delete_page *) rec;				appendStringInfo(buf, "delete_page: ");				out_target(buf, &(xlrec->target));				appendStringInfo(buf, "; dead %u; left %u; right %u",							xlrec->deadblk, xlrec->leftblk, xlrec->rightblk);				break;			}		case XLOG_BTREE_NEWROOT:			{				xl_btree_newroot *xlrec = (xl_btree_newroot *) rec;				appendStringInfo(buf, "newroot: rel %u/%u/%u; root %u lev %u",								 xlrec->node.spcNode, xlrec->node.dbNode,								 xlrec->node.relNode,								 xlrec->rootblk, xlrec->level);				break;			}		default:			appendStringInfo(buf, "UNKNOWN");			break;	}}voidbtree_xlog_startup(void){	incomplete_actions = NIL;}voidbtree_xlog_cleanup(void){	ListCell   *l;	foreach(l, incomplete_actions)	{		bt_incomplete_action *action = (bt_incomplete_action *) lfirst(l);		Relation	reln;		reln = XLogOpenRelation(action->node);		if (action->is_split)		{			/* finish an incomplete split */			Buffer		lbuf,						rbuf;			Page		lpage,						rpage;			BTPageOpaque lpageop,						rpageop;			bool		is_only;			lbuf = XLogReadBuffer(reln, action->leftblk, false);			/* failure is impossible because we wrote this page earlier */			if (!BufferIsValid(lbuf))				elog(PANIC, "btree_xlog_cleanup: left block unfound");			lpage = (Page) BufferGetPage(lbuf);			lpageop = (BTPageOpaque) PageGetSpecialPointer(lpage);			rbuf = XLogReadBuffer(reln, action->rightblk, false);			/* failure is impossible because we wrote this page earlier */			if (!BufferIsValid(rbuf))				elog(PANIC, "btree_xlog_cleanup: right block unfound");			rpage = (Page) BufferGetPage(rbuf);			rpageop = (BTPageOpaque) PageGetSpecialPointer(rpage);			/* if the pages are all of their level, it's a only-page split */			is_only = P_LEFTMOST(lpageop) && P_RIGHTMOST(rpageop);			_bt_insert_parent(reln, lbuf, rbuf, NULL,							  action->is_root, is_only);		}		else		{			/* finish an incomplete deletion (of a half-dead page) */			Buffer		buf;			buf = XLogReadBuffer(reln, action->delblk, false);			if (BufferIsValid(buf))				if (_bt_pagedel(reln, buf, NULL, true) == 0)					elog(PANIC, "btree_xlog_cleanup: _bt_pagdel failed");		}	}	incomplete_actions = NIL;}boolbtree_safe_restartpoint(void){	if (incomplete_actions)		return false;	return true;}

⌨️ 快捷键说明

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