mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Call _bt_fixroot() from _bt_insertonpg.
This commit is contained in:
		@@ -8,7 +8,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * IDENTIFICATION
 | 
					 * IDENTIFICATION
 | 
				
			||||||
 *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.77 2001/01/26 01:24:31 vadim Exp $
 | 
					 *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.78 2001/01/29 07:28:16 vadim Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -34,7 +34,10 @@ typedef struct
 | 
				
			|||||||
	int		best_delta;			/* best size delta so far */
 | 
						int		best_delta;			/* best size delta so far */
 | 
				
			||||||
} FindSplitData;
 | 
					} FindSplitData;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern bool FixBTree;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Buffer _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release);
 | 
					Buffer _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release);
 | 
				
			||||||
 | 
					static void _bt_fixtree(Relation rel, BlockNumber blkno, BTStack stack);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Buffer _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf);
 | 
					static Buffer _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -477,10 +480,55 @@ _bt_insertonpg(Relation rel,
 | 
				
			|||||||
			BTItem		ritem;
 | 
								BTItem		ritem;
 | 
				
			||||||
			Buffer		pbuf;
 | 
								Buffer		pbuf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			/* Set up a phony stack entry if we haven't got a real one */
 | 
								/* If root page was splitted */
 | 
				
			||||||
			if (stack == (BTStack) NULL)
 | 
								if (stack == (BTStack) NULL)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				elog(DEBUG, "btree: concurrent ROOT page split");
 | 
									elog(DEBUG, "btree: concurrent ROOT page split");
 | 
				
			||||||
 | 
									/*
 | 
				
			||||||
 | 
									 * If root page splitter failed to create new root page
 | 
				
			||||||
 | 
									 * then old root' btpo_parent still points to metapage.
 | 
				
			||||||
 | 
									 * We have to fix root page in this case.
 | 
				
			||||||
 | 
									 */
 | 
				
			||||||
 | 
									if (lpageop->btpo_parent == BTREE_METAPAGE)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										if (!FixBTree)
 | 
				
			||||||
 | 
											elog(ERROR, "bt_insertonpg: no root page found");
 | 
				
			||||||
 | 
										_bt_wrtbuf(rel, rbuf);
 | 
				
			||||||
 | 
										_bt_wrtnorelbuf(rel, buf);
 | 
				
			||||||
 | 
										while(! P_LEFTMOST(lpageop))
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											BlockNumber		blkno = lpageop->btpo_prev;
 | 
				
			||||||
 | 
											LockBuffer(buf, BUFFER_LOCK_UNLOCK);
 | 
				
			||||||
 | 
											ReleaseBuffer(buf);
 | 
				
			||||||
 | 
											buf = _bt_getbuf(rel, blkno, BT_WRITE);
 | 
				
			||||||
 | 
											page = BufferGetPage(buf);
 | 
				
			||||||
 | 
											lpageop = (BTPageOpaque) PageGetSpecialPointer(page);
 | 
				
			||||||
 | 
											/*
 | 
				
			||||||
 | 
											 * If someone else already created parent pages
 | 
				
			||||||
 | 
											 * then it's time for _bt_fixtree() to check upper
 | 
				
			||||||
 | 
											 * levels and fix them, if required.
 | 
				
			||||||
 | 
											 */
 | 
				
			||||||
 | 
											if (lpageop->btpo_parent != BTREE_METAPAGE)
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
 | 
												blkno = lpageop->btpo_parent;
 | 
				
			||||||
 | 
												_bt_relbuf(rel, buf, BT_WRITE);
 | 
				
			||||||
 | 
												_bt_fixtree(rel, blkno, NULL);
 | 
				
			||||||
 | 
												goto formres;
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										/*
 | 
				
			||||||
 | 
										 * Ok, we are on the leftmost page, it's write locked
 | 
				
			||||||
 | 
										 * by us and its btpo_parent points to meta page - time
 | 
				
			||||||
 | 
										 * for _bt_fixroot().
 | 
				
			||||||
 | 
										 */
 | 
				
			||||||
 | 
										 buf = _bt_fixroot(rel, buf, true);
 | 
				
			||||||
 | 
										 _bt_relbuf(rel, buf, BT_WRITE);
 | 
				
			||||||
 | 
										goto formres;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									/*
 | 
				
			||||||
 | 
									 * Set up a phony stack entry if we haven't got a real one
 | 
				
			||||||
 | 
									 */
 | 
				
			||||||
				stack = &fakestack;
 | 
									stack = &fakestack;
 | 
				
			||||||
				stack->bts_blkno = lpageop->btpo_parent;
 | 
									stack->bts_blkno = lpageop->btpo_parent;
 | 
				
			||||||
				stack->bts_offset = InvalidOffsetNumber;
 | 
									stack->bts_offset = InvalidOffsetNumber;
 | 
				
			||||||
@@ -537,6 +585,7 @@ _bt_insertonpg(Relation rel,
 | 
				
			|||||||
		_bt_wrtbuf(rel, buf);
 | 
							_bt_wrtbuf(rel, buf);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					formres:;
 | 
				
			||||||
	/* by here, the new tuple is inserted at itup_blkno/itup_off */
 | 
						/* by here, the new tuple is inserted at itup_blkno/itup_off */
 | 
				
			||||||
	res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
 | 
						res = (InsertIndexResult) palloc(sizeof(InsertIndexResultData));
 | 
				
			||||||
	ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
 | 
						ItemPointerSet(&(res->pointerData), itup_blkno, itup_off);
 | 
				
			||||||
@@ -1414,8 +1463,7 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
 | 
				
			|||||||
	 * created with _bt_newroot() - rootbuf, - and buf we've used
 | 
						 * created with _bt_newroot() - rootbuf, - and buf we've used
 | 
				
			||||||
	 * for last insert ops - buf. If rootbuf != buf then we have to
 | 
						 * for last insert ops - buf. If rootbuf != buf then we have to
 | 
				
			||||||
	 * create at least one more level. And if "release" is TRUE
 | 
						 * create at least one more level. And if "release" is TRUE
 | 
				
			||||||
	 * (ie we've already created some levels) then we give up
 | 
						 * then we give up oldrootbuf.
 | 
				
			||||||
	 * oldrootbuf.
 | 
					 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (release)
 | 
						if (release)
 | 
				
			||||||
		_bt_relbuf(rel, oldrootbuf, BT_WRITE);
 | 
							_bt_relbuf(rel, oldrootbuf, BT_WRITE);
 | 
				
			||||||
@@ -1429,6 +1477,12 @@ _bt_fixroot(Relation rel, Buffer oldrootbuf, bool release)
 | 
				
			|||||||
	return(rootbuf);
 | 
						return(rootbuf);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					_bt_fixtree(Relation rel, BlockNumber blkno, BTStack stack)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						elog(ERROR, "bt_fixtree: unimplemented , yet");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 *	_bt_pgaddtup() -- add a tuple to a particular page in the index.
 | 
					 *	_bt_pgaddtup() -- add a tuple to a particular page in the index.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * IDENTIFICATION
 | 
					 * IDENTIFICATION
 | 
				
			||||||
 *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.48 2001/01/26 01:24:31 vadim Exp $
 | 
					 *	  $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtpage.c,v 1.49 2001/01/29 07:28:17 vadim Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *	NOTES
 | 
					 *	NOTES
 | 
				
			||||||
 *	   Postgres btree pages look like ordinary relation pages.	The opaque
 | 
					 *	   Postgres btree pages look like ordinary relation pages.	The opaque
 | 
				
			||||||
@@ -257,6 +257,7 @@ check_parent:;
 | 
				
			|||||||
				/* handle concurrent fix of root page */
 | 
									/* handle concurrent fix of root page */
 | 
				
			||||||
				if (rootopaque->btpo_parent == BTREE_METAPAGE)	/* unupdated! */
 | 
									if (rootopaque->btpo_parent == BTREE_METAPAGE)	/* unupdated! */
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
 | 
										elog(NOTICE, "bt_getroot: fixing root page");
 | 
				
			||||||
					newrootbuf = _bt_fixroot(rel, rootbuf, true);
 | 
										newrootbuf = _bt_fixroot(rel, rootbuf, true);
 | 
				
			||||||
					LockBuffer(newrootbuf, BUFFER_LOCK_UNLOCK);
 | 
										LockBuffer(newrootbuf, BUFFER_LOCK_UNLOCK);
 | 
				
			||||||
					LockBuffer(newrootbuf, BT_READ);
 | 
										LockBuffer(newrootbuf, BT_READ);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user