Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bhJY9-0007ch-EP for pgsql-hackers@arkaria.postgresql.org; Tue, 06 Sep 2016 16:48:41 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1bhJY8-0005th-Pb for pgsql-hackers@arkaria.postgresql.org; Tue, 06 Sep 2016 16:48:40 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1bhJY7-0005qS-B0 for pgsql-hackers@postgresql.org; Tue, 06 Sep 2016 16:48:39 +0000 Received: from newmail.postgrespro.ru ([93.174.131.138] helo=mail.postgrespro.ru) by makus.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bhJY2-0006pr-Q6 for pgsql-hackers@postgresql.org; Tue, 06 Sep 2016 16:48:38 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.postgrespro.ru (Postfix) with ESMTP id E545F21C283E; Tue, 6 Sep 2016 19:48:31 +0300 (MSK) X-Virus-Scanned: Debian amavisd-new at postgrespro.ru Received: from mail.postgrespro.ru ([127.0.0.1]) by localhost (mail.postgrespro.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id D_kSKTh1LBVz; Tue, 6 Sep 2016 19:48:31 +0300 (MSK) Received: from [192.168.27.34] (unknown [192.168.27.1]) by mail.postgrespro.ru (Postfix) with ESMTPSA id AD01F21C2831; Tue, 6 Sep 2016 19:48:31 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=postgrespro.ru; s=mail; t=1473180511; bh=qcqdP4/eWfL1T4nXNvDZAp1S3fVLy4eaUKd5uxknyqQ=; h=From:Subject:To:References:Cc:Date:In-Reply-To; b=SCn6lNkKhJlQPcDiyeCREOgs2bdNR1J4hfIeRP1WazaPf3VfiQLzh801jnj1ppBlV nntfal5Co9X7iFHtERd2OH3YXkeBe33V9DoIMChXvvx0djspnr+xjvcGCl/a2hQk5f UtL/dcPuShipqNBZE3uQAS369qIjNX9MwVoZMEW8= From: Anastasia Lubennikova Subject: Re: WIP: Covering + unique indexes. To: Amit Kapila References: <56168952.4010101@postgrespro.ru> <20160814171131.21390.75752.pgcf@coridan.postgresql.org> Cc: Andrey Borodin , pgsql-hackers , Anastasia Lubennikova Message-ID: Date: Tue, 6 Sep 2016 19:48:31 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------4F65F546808092FB37F761DB" X-Pg-Spam-Score: -3.1 (---) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org This is a multi-part message in MIME format. --------------4F65F546808092FB37F761DB Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit 28.08.2016 09:13, Amit Kapila: > On Mon, Aug 15, 2016 at 8:15 PM, Anastasia Lubennikova > wrote: > @@ -590,7 +622,14 @@ _bt_buildadd(BTWriteState *wstate, BTPageState > *state, IndexTuple itup) > if (last_off == P_HIKEY) > { > Assert(state->btps_minkey == NULL); > - state->btps_minkey = CopyIndexTuple(itup); > + /* > + * Truncate the tuple that we're going to insert > + * into the parent page as a downlink > + */ > > + if (indnkeyatts != indnatts && P_ISLEAF(pageop)) > + state->btps_minkey = index_truncate_tuple(wstate->index, itup); > + else > + state->btps_minkey = CopyIndexTuple(itup); > > It seems that above code always ensure that for leaf pages, high key > is a truncated tuple. What is less clear is if that is true, why you > need to re-ensure it again for the old page in below code: Thank you for the question. Investigation took a long time) As far as I understand, the code above only applies to the first tuple of each level. While the code you have quoted below truncates high keys for all other pages. There is a comment that clarifies situation: /* * If the new item is the first for its page, stash a copy for later. Note * this will only happen for the first item on a level; on later pages, * the first item for a page is copied from the prior page in the code * above. */ So the patch is correct. We can go further and remove this index_truncate_tuple() call, because the first key of any inner (or root) page doesn't need any key at all. It simply points out to the leftmost page of the level below. But it's not a bug, because truncation of one tuple per level doesn't add any considerable overhead. So I want to leave the patch in its current state. > @@ -510,6 +513,8 @@ _bt_buildadd(BTWriteState *wstate, BTPageState > *state, IndexTuple itup) > { > .. > + if (indnkeyatts != indnatts && P_ISLEAF(opageop)) > + { > + /* > + * It's essential to truncate High key here. > + * The purpose is not just to save more space on this particular page, > + * but to keep whole b-tree structure consistent. Subsequent insertions > + * assume that hikey is already truncated, and so they should not > + * worry about it, when copying the high key into the parent page > + * as a downlink. > + * NOTE It is not crutial for reliability in present, > + * but maybe it will be that in the future. > + */ > + keytup = index_truncate_tuple(wstate->index, oitup); > + > + /* delete "wrong" high key, insert keytup as P_HIKEY. */ > + PageIndexTupleDelete(opage, P_HIKEY); > + > + if (!_bt_pgaddtup(opage, IndexTupleSize(keytup), keytup, P_HIKEY)) > + elog(ERROR, "failed to rewrite compressed item in index \"%s\"", > + RelationGetRelationName(wstate->index)); > + } > + > .. > .. -- Anastasia Lubennikova Postgres Professional:http://www.postgrespro.com The Russian Postgres Company --------------4F65F546808092FB37F761DB Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit 28.08.2016 09:13, Amit Kapila:
On Mon, Aug 15, 2016 at 8:15 PM, Anastasia Lubennikova
<a.lubennikova@postgrespro.ru> wrote:
@@ -590,7 +622,14 @@ _bt_buildadd(BTWriteState *wstate, BTPageState
*state, IndexTuple itup)
  if (last_off == P_HIKEY)
  {
  Assert(state->btps_minkey == NULL);
- state->btps_minkey = CopyIndexTuple(itup);
+ /*
+ * Truncate the tuple that we're going to insert
+ * into the parent page as a downlink
+ */

+ if (indnkeyatts != indnatts && P_ISLEAF(pageop))
+ state->btps_minkey = index_truncate_tuple(wstate->index, itup);
+ else
+ state->btps_minkey = CopyIndexTuple(itup);

It seems that above code always ensure that for leaf pages, high key
is a truncated tuple.  What is less clear is if that is true, why you
need to re-ensure it again for the old  page in below code:

Thank you for the question. Investigation took a long time)

As far as I understand, the code above only applies to
the first tuple of each level. While the code you have quoted below
truncates high keys for all other pages.

There is a comment that clarifies situation:
    /*
     * If the new item is the first for its page, stash a copy for later. Note
     * this will only happen for the first item on a level; on later pages,
     * the first item for a page is copied from the prior page in the code
     * above.
     */


So the patch is correct.
We can go further and remove this index_truncate_tuple() call, because
the first key of any inner (or root) page doesn't need any key at all.
It simply points out to the leftmost page of the level below.
But it's not a bug, because truncation of one tuple per level doesn't
add any considerable overhead. So I want to leave the patch in its current state.

@@ -510,6 +513,8 @@ _bt_buildadd(BTWriteState *wstate, BTPageState
*state, IndexTuple itup)
{
..
+ if (indnkeyatts != indnatts && P_ISLEAF(opageop))
+ {
+ /*
+ * It's essential to truncate High key here.
+ * The purpose is not just to save more space on this particular page,
+ * but to keep whole b-tree structure consistent. Subsequent insertions
+ * assume that hikey is already truncated, and so they should not
+ * worry about it, when copying the high key into the parent page
+ * as a downlink.
+ * NOTE It is not crutial for reliability in present,
+ * but maybe it will be that in the future.
+ */
+ keytup = index_truncate_tuple(wstate->index, oitup);
+
+ /*  delete "wrong" high key, insert keytup as P_HIKEY. */
+ PageIndexTupleDelete(opage, P_HIKEY);
+
+ if (!_bt_pgaddtup(opage, IndexTupleSize(keytup), keytup, P_HIKEY))
+ elog(ERROR, "failed to rewrite compressed item in index \"%s\"",
+ RelationGetRelationName(wstate->index));
+ }
+
..
..


-- 
Anastasia Lubennikova
Postgres Professional: http://www.postgrespro.com
The Russian Postgres Company
--------------4F65F546808092FB37F761DB--