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

📄 ginxlog.c

📁 postgresql8.3.4源码,开源数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
	PageSetTLI(lpage, ThisTimeLineID);	MarkBufferDirty(lbuffer);	if (!data->isLeaf && data->updateBlkno != InvalidBlockNumber)		forgetIncompleteSplit(data->node, data->leftChildBlkno, data->updateBlkno);	if (data->isRootSplit)	{		Buffer		rootBuf = XLogReadBuffer(reln, data->rootBlkno, false);		Page		rootPage = BufferGetPage(rootBuf);		GinInitBuffer(rootBuf, flags & ~GIN_LEAF);		if (data->isData)		{			Assert(data->rootBlkno != GIN_ROOT_BLKNO);			dataFillRoot(NULL, rootBuf, lbuffer, rbuffer);		}		else		{			Assert(data->rootBlkno == GIN_ROOT_BLKNO);			entryFillRoot(NULL, rootBuf, lbuffer, rbuffer);		}		PageSetLSN(rootPage, lsn);		PageSetTLI(rootPage, ThisTimeLineID);		MarkBufferDirty(rootBuf);		UnlockReleaseBuffer(rootBuf);	}	else		pushIncompleteSplit(data->node, data->lblkno, data->rblkno, data->rootBlkno);	UnlockReleaseBuffer(rbuffer);	UnlockReleaseBuffer(lbuffer);}static voidginRedoVacuumPage(XLogRecPtr lsn, XLogRecord *record){	ginxlogVacuumPage *data = (ginxlogVacuumPage *) XLogRecGetData(record);	Relation	reln;	Buffer		buffer;	Page		page;	/* nothing else to do if page was backed up (and no info to do it with) */	if (record->xl_info & XLR_BKP_BLOCK_1)		return;	reln = XLogOpenRelation(data->node);	buffer = XLogReadBuffer(reln, data->blkno, false);	Assert(BufferIsValid(buffer));	page = (Page) BufferGetPage(buffer);	if (GinPageIsData(page))	{		memcpy(GinDataPageGetData(page), XLogRecGetData(record) + sizeof(ginxlogVacuumPage),			   GinSizeOfItem(page) *data->nitem);		GinPageGetOpaque(page)->maxoff = data->nitem;	}	else	{		OffsetNumber i,				   *tod;		IndexTuple	itup = (IndexTuple) (XLogRecGetData(record) + sizeof(ginxlogVacuumPage));		tod = (OffsetNumber *) palloc(sizeof(OffsetNumber) * PageGetMaxOffsetNumber(page));		for (i = FirstOffsetNumber; i <= PageGetMaxOffsetNumber(page); i++)			tod[i - 1] = i;		PageIndexMultiDelete(page, tod, PageGetMaxOffsetNumber(page));		for (i = 0; i < data->nitem; i++)		{			if (PageAddItem(page, (Item) itup, IndexTupleSize(itup), InvalidOffsetNumber, false, false) == InvalidOffsetNumber)				elog(ERROR, "failed to add item to index page in %u/%u/%u",				  data->node.spcNode, data->node.dbNode, data->node.relNode);			itup = (IndexTuple) (((char *) itup) + MAXALIGN(IndexTupleSize(itup)));		}	}	PageSetLSN(page, lsn);	PageSetTLI(page, ThisTimeLineID);	MarkBufferDirty(buffer);	UnlockReleaseBuffer(buffer);}static voidginRedoDeletePage(XLogRecPtr lsn, XLogRecord *record){	ginxlogDeletePage *data = (ginxlogDeletePage *) XLogRecGetData(record);	Relation	reln;	Buffer		buffer;	Page		page;	reln = XLogOpenRelation(data->node);	if (!(record->xl_info & XLR_BKP_BLOCK_1))	{		buffer = XLogReadBuffer(reln, data->blkno, false);		page = BufferGetPage(buffer);		Assert(GinPageIsData(page));		GinPageGetOpaque(page)->flags = GIN_DELETED;		PageSetLSN(page, lsn);		PageSetTLI(page, ThisTimeLineID);		MarkBufferDirty(buffer);		UnlockReleaseBuffer(buffer);	}	if (!(record->xl_info & XLR_BKP_BLOCK_2))	{		buffer = XLogReadBuffer(reln, data->parentBlkno, false);		page = BufferGetPage(buffer);		Assert(GinPageIsData(page));		Assert(!GinPageIsLeaf(page));		PageDeletePostingItem(page, data->parentOffset);		PageSetLSN(page, lsn);		PageSetTLI(page, ThisTimeLineID);		MarkBufferDirty(buffer);		UnlockReleaseBuffer(buffer);	}	if (!(record->xl_info & XLR_BKP_BLOCK_3) && data->leftBlkno != InvalidBlockNumber)	{		buffer = XLogReadBuffer(reln, data->leftBlkno, false);		page = BufferGetPage(buffer);		Assert(GinPageIsData(page));		GinPageGetOpaque(page)->rightlink = data->rightLink;		PageSetLSN(page, lsn);		PageSetTLI(page, ThisTimeLineID);		MarkBufferDirty(buffer);		UnlockReleaseBuffer(buffer);	}}voidgin_redo(XLogRecPtr lsn, XLogRecord *record){	uint8		info = record->xl_info & ~XLR_INFO_MASK;	topCtx = MemoryContextSwitchTo(opCtx);	switch (info)	{		case XLOG_GIN_CREATE_INDEX:			ginRedoCreateIndex(lsn, record);			break;		case XLOG_GIN_CREATE_PTREE:			ginRedoCreatePTree(lsn, record);			break;		case XLOG_GIN_INSERT:			ginRedoInsert(lsn, record);			break;		case XLOG_GIN_SPLIT:			ginRedoSplit(lsn, record);			break;		case XLOG_GIN_VACUUM_PAGE:			ginRedoVacuumPage(lsn, record);			break;		case XLOG_GIN_DELETE_PAGE:			ginRedoDeletePage(lsn, record);			break;		default:			elog(PANIC, "gin_redo: unknown op code %u", info);	}	MemoryContextSwitchTo(topCtx);	MemoryContextReset(opCtx);}static voiddesc_node(StringInfo buf, RelFileNode node, BlockNumber blkno){	appendStringInfo(buf, "node: %u/%u/%u blkno: %u",					 node.spcNode, node.dbNode, node.relNode, blkno);}voidgin_desc(StringInfo buf, uint8 xl_info, char *rec){	uint8		info = xl_info & ~XLR_INFO_MASK;	switch (info)	{		case XLOG_GIN_CREATE_INDEX:			appendStringInfo(buf, "Create index, ");			desc_node(buf, *(RelFileNode *) rec, GIN_ROOT_BLKNO);			break;		case XLOG_GIN_CREATE_PTREE:			appendStringInfo(buf, "Create posting tree, ");			desc_node(buf, ((ginxlogCreatePostingTree *) rec)->node, ((ginxlogCreatePostingTree *) rec)->blkno);			break;		case XLOG_GIN_INSERT:			appendStringInfo(buf, "Insert item, ");			desc_node(buf, ((ginxlogInsert *) rec)->node, ((ginxlogInsert *) rec)->blkno);			appendStringInfo(buf, " offset: %u nitem: %u isdata: %c isleaf %c isdelete %c updateBlkno:%u",							 ((ginxlogInsert *) rec)->offset,							 ((ginxlogInsert *) rec)->nitem,							 (((ginxlogInsert *) rec)->isData) ? 'T' : 'F',							 (((ginxlogInsert *) rec)->isLeaf) ? 'T' : 'F',							 (((ginxlogInsert *) rec)->isDelete) ? 'T' : 'F',							 ((ginxlogInsert *) rec)->updateBlkno				);			break;		case XLOG_GIN_SPLIT:			appendStringInfo(buf, "Page split, ");			desc_node(buf, ((ginxlogSplit *) rec)->node, ((ginxlogSplit *) rec)->lblkno);			appendStringInfo(buf, " isrootsplit: %c", (((ginxlogSplit *) rec)->isRootSplit) ? 'T' : 'F');			break;		case XLOG_GIN_VACUUM_PAGE:			appendStringInfo(buf, "Vacuum page, ");			desc_node(buf, ((ginxlogVacuumPage *) rec)->node, ((ginxlogVacuumPage *) rec)->blkno);			break;		case XLOG_GIN_DELETE_PAGE:			appendStringInfo(buf, "Delete page, ");			desc_node(buf, ((ginxlogDeletePage *) rec)->node, ((ginxlogDeletePage *) rec)->blkno);			break;		default:			elog(PANIC, "gin_desc: unknown op code %u", info);	}}voidgin_xlog_startup(void){	incomplete_splits = NIL;	opCtx = AllocSetContextCreate(CurrentMemoryContext,								  "GIN recovery temporary context",								  ALLOCSET_DEFAULT_MINSIZE,								  ALLOCSET_DEFAULT_INITSIZE,								  ALLOCSET_DEFAULT_MAXSIZE);}static voidginContinueSplit(ginIncompleteSplit *split){	GinBtreeData btree;	Relation	reln;	Buffer		buffer;	GinBtreeStack stack;	/*	 * elog(NOTICE,"ginContinueSplit root:%u l:%u r:%u",  split->rootBlkno,	 * split->leftBlkno, split->rightBlkno);	 */	reln = XLogOpenRelation(split->node);	buffer = XLogReadBuffer(reln, split->leftBlkno, false);	if (split->rootBlkno == GIN_ROOT_BLKNO)	{		prepareEntryScan(&btree, reln, (Datum) 0, NULL);		btree.entry = ginPageGetLinkItup(buffer);	}	else	{		Page		page = BufferGetPage(buffer);		prepareDataScan(&btree, reln);		PostingItemSetBlockNumber(&(btree.pitem), split->leftBlkno);		if (GinPageIsLeaf(page))			btree.pitem.key = *(ItemPointerData *) GinDataPageGetItem(page,											 GinPageGetOpaque(page)->maxoff);		else			btree.pitem.key = ((PostingItem *) GinDataPageGetItem(page,									   GinPageGetOpaque(page)->maxoff))->key;	}	btree.rightblkno = split->rightBlkno;	stack.blkno = split->leftBlkno;	stack.buffer = buffer;	stack.off = InvalidOffsetNumber;	stack.parent = NULL;	findParents(&btree, &stack, split->rootBlkno);	ginInsertValue(&btree, stack.parent);	UnlockReleaseBuffer(buffer);}voidgin_xlog_cleanup(void){	ListCell   *l;	MemoryContext topCtx;	topCtx = MemoryContextSwitchTo(opCtx);	foreach(l, incomplete_splits)	{		ginIncompleteSplit *split = (ginIncompleteSplit *) lfirst(l);		ginContinueSplit(split);		MemoryContextReset(opCtx);	}	MemoryContextSwitchTo(topCtx);	MemoryContextDelete(opCtx);	incomplete_splits = NIL;}boolgin_safe_restartpoint(void){	if (incomplete_splits)		return false;	return true;}

⌨️ 快捷键说明

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