From: | Peter Geoghegan <pg(at)bowt(dot)ie> |
---|---|
To: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
Cc: | pgsql-committers <pgsql-committers(at)lists(dot)postgresql(dot)org> |
Subject: | Re: pgsql: Optimize btree insertions for common case of increasing values |
Date: | 2018-03-28 06:03:38 |
Message-ID: | CAH2-WzmpBA3TVtQCkkupVhxJ7DNsaosnmB9Maiogw0K58BKCKg@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-committers |
On Mon, Mar 26, 2018 at 5:10 AM, Andrew Dunstan <andrew(at)dunslane(dot)net> wrote:
> Optimize btree insertions for common case of increasing values
>
> Remember the last page of an index insert if it's the rightmost leaf
> page. If the next entry belongs on and can fit in the remembered page,
> insert the new entry there as long as we can get a lock on the page.
> Otherwise, fall back on the more expensive method of searching for
> the right place to insert the entry.
This code can allocate memory in a critical section, since
RelationSetTargetBlock() can call smgropen():
if (P_ISLEAF(lpageop))
+ {
xlinfo = XLOG_BTREE_INSERT_LEAF;
+
+ /*
+ * Cache the block information if we just inserted into the
+ * rightmost leaf page of the index.
+ */
+ if (P_RIGHTMOST(lpageop))
+ RelationSetTargetBlock(rel, BufferGetBlockNumber(buf));
+ }
rd_smgr can be closed by a relcache flush, so it is in fact possible
that we'll reach smgropen().
As I already pointed out, it's unclear why some of these tests are
used, such as P_INCOMPLETE_SPLIT():
+ /*
+ * Check if the page is still the rightmost leaf page, has enough
+ * free space to accommodate the new tuple, no split is in progress
+ * and the scankey is greater than or equal to the first key on the
+ * page.
+ */
+ if (P_ISLEAF(lpageop) && P_RIGHTMOST(lpageop) &&
+ !P_INCOMPLETE_SPLIT(lpageop) &&
+ !P_IGNORE(lpageop) &&
+ (PageGetFreeSpace(page) > itemsz) &&
+ PageGetMaxOffsetNumber(page) >= P_FIRSTDATAKEY(lpageop) &&
+ _bt_compare(rel, natts, itup_scankey, page,
+ P_FIRSTDATAKEY(lpageop)) > 0)
The BTP_INCOMPLETE_SPLIT bit means that the page's right sibling's
downlink is missing, but how can a rightmost page have a right sibling
in the first place? We don't bother to check that when we already know
the page is rightmost within _bt_moveright() or _bt_findinsertloc().
I also noticed that favorable/favourable is misspelled "favourble".
Also, "workout" is a noun.
This patch was committed in haste, and it shows.
--
Peter Geoghegan
From | Date | Subject | |
---|---|---|---|
Next Message | Andrew Dunstan | 2018-03-28 06:09:49 | Re: pgsql: Fast ALTER TABLE ADD COLUMN with a non-NULL default |
Previous Message | Tom Lane | 2018-03-28 04:48:36 | Re: pgsql: Fast ALTER TABLE ADD COLUMN with a non-NULL default |