|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.136 2006/04/25 22:46:05 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.137 2006/05/08 00:00:09 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -700,14 +700,18 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
|
700 | 700 | ropaque = (BTPageOpaque) PageGetSpecialPointer(rightpage);
|
701 | 701 |
|
702 | 702 | /* if we're splitting this page, it won't be the root when we're done */
|
| 703 | + /* also, clear the SPLIT_END flag in both pages */ |
703 | 704 | lopaque->btpo_flags = oopaque->btpo_flags;
|
704 |
| - lopaque->btpo_flags &= ~BTP_ROOT; |
| 705 | + lopaque->btpo_flags &= ~(BTP_ROOT | BTP_SPLIT_END); |
705 | 706 | ropaque->btpo_flags = lopaque->btpo_flags;
|
706 | 707 | lopaque->btpo_prev = oopaque->btpo_prev;
|
707 | 708 | lopaque->btpo_next = BufferGetBlockNumber(rbuf);
|
708 | 709 | ropaque->btpo_prev = BufferGetBlockNumber(buf);
|
709 | 710 | ropaque->btpo_next = oopaque->btpo_next;
|
710 | 711 | lopaque->btpo.level = ropaque->btpo.level = oopaque->btpo.level;
|
| 712 | + /* Since we already have write-lock on both pages, ok to read cycleid */ |
| 713 | + lopaque->btpo_cycleid = _bt_vacuum_cycleid(rel); |
| 714 | + ropaque->btpo_cycleid = lopaque->btpo_cycleid; |
711 | 715 |
|
712 | 716 | /*
|
713 | 717 | * If the page we're splitting is not the rightmost page at its level in
|
@@ -836,6 +840,21 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
|
836 | 840 | sopaque = (BTPageOpaque) PageGetSpecialPointer(spage);
|
837 | 841 | if (sopaque->btpo_prev != ropaque->btpo_prev)
|
838 | 842 | elog(PANIC, "right sibling's left-link doesn't match");
|
| 843 | + /* |
| 844 | + * Check to see if we can set the SPLIT_END flag in the right-hand |
| 845 | + * split page; this can save some I/O for vacuum since it need not |
| 846 | + * proceed to the right sibling. We can set the flag if the right |
| 847 | + * sibling has a different cycleid: that means it could not be part |
| 848 | + * of a group of pages that were all split off from the same ancestor |
| 849 | + * page. If you're confused, imagine that page A splits to A B and |
| 850 | + * then again, yielding A C B, while vacuum is in progress. Tuples |
| 851 | + * originally in A could now be in either B or C, hence vacuum must |
| 852 | + * examine both pages. But if D, our right sibling, has a different |
| 853 | + * cycleid then it could not contain any tuples that were in A when |
| 854 | + * the vacuum started. |
| 855 | + */ |
| 856 | + if (sopaque->btpo_cycleid != ropaque->btpo_cycleid) |
| 857 | + ropaque->btpo_flags |= BTP_SPLIT_END; |
839 | 858 | }
|
840 | 859 |
|
841 | 860 | /*
|
@@ -1445,6 +1464,7 @@ _bt_newroot(Relation rel, Buffer lbuf, Buffer rbuf)
|
1445 | 1464 | rootopaque->btpo_flags = BTP_ROOT;
|
1446 | 1465 | rootopaque->btpo.level =
|
1447 | 1466 | ((BTPageOpaque) PageGetSpecialPointer(lpage))->btpo.level + 1;
|
| 1467 | + rootopaque->btpo_cycleid = 0; |
1448 | 1468 |
|
1449 | 1469 | /* update metapage data */
|
1450 | 1470 | metad->btm_root = rootblknum;
|
|
0 commit comments