Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sF9uh-007ZVt-5b for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Jun 2024 10:00:08 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1sF9uh-00HIwz-7H for pgsql-hackers@arkaria.postgresql.org; Thu, 06 Jun 2024 10:00:07 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1sF9ug-00HIwr-S1 for pgsql-hackers@lists.postgresql.org; Thu, 06 Jun 2024 10:00:06 +0000 Received: from mail-lf1-x12e.google.com ([2a00:1450:4864:20::12e]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1sF9ud-000H0T-On for pgsql-hackers@postgresql.org; Thu, 06 Jun 2024 10:00:06 +0000 Received: by mail-lf1-x12e.google.com with SMTP id 2adb3069b0e04-52b8f5d811aso789355e87.3 for ; Thu, 06 Jun 2024 03:00:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1717668002; x=1718272802; darn=postgresql.org; h=content-transfer-encoding:to:subject:from:content-language :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=aMnJltg0GozqHvxyUs/yR0u7IdCt1pi8aQ4561U4WdA=; b=Y7XwD9XHIzApWkIckUcqKOX0Zf9MDIOK2aOqNx08IuBProsMsBt1qZ+shfaFXgvevT TKF21WEDAA74VM/Cixp/NGIK+5bxGl317OOeuJdLkYj3AbQu9z2dGJqlvh91pqJDKscy BioQFGkPzxgNqggEYTyxeCt709tu+sRDsu23FaukVr8N1Unao0U8zLWBLQvzFg9rSlLm 3B2V1Q8ZpZKNBn4YYRo0fjV8rVYWEEsUojDrshzeGz7ZuAcOQzbfWbJknACqtwfb3HJr U9QH8uvsZeXkGAJhglI9a0RufD2UKiUqXp/NBbCzMHZDSbmjQqQTXRJI8JcbBdJcTkLR oAIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1717668002; x=1718272802; h=content-transfer-encoding:to:subject:from:content-language :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=aMnJltg0GozqHvxyUs/yR0u7IdCt1pi8aQ4561U4WdA=; b=UrANzE9yH7jh9F4r+fBginX00iz6f0twBQUQlH/d3UqMnFEQZmUgD/4v51a3HKsAOF h5sYbPuIj9xmbqiwnmzUkKZbv0nrHwkWD2sag9Guc4lJUb5oKbxNRd+jb0jKTCA/FwBA 6kZy+Bv0ilE6zlwYR5G3e/zDux/OincP0WkC7lnHfETKGMIOg2HIDj+SXqI1JIIUxl4h CYDx6ATAiwiLqa8MRq6iAc9anetx3SRgaWTR/u+xTHpTp3y9DTSGSeceUZJx9aBqE8ML zsKCwUqx++BR0slCU7ER2y5q/XybeU14ixDXaDNdVbyeNOJgVt+FXn8FcuiU51AJyOyM Y5vw== X-Gm-Message-State: AOJu0YySVcdVEQ/D1SjRZ6GMY7ut7xtWzwra4GKFF1wK4S7txApj7I2t s7cvYf/Gim4p/qRD6zAuNE6WoB734kcllvISwoI4wsM6m+E1JSNzi7QE3g== X-Google-Smtp-Source: AGHT+IFGlrC6UTF2qswWjJv0p+h+g6UOW5Ah9p7KXsLXlK8SwIfMSfeJEmySidgA/RTPuz9n0ahFhA== X-Received: by 2002:a05:6512:33d1:b0:51d:9ce:c282 with SMTP id 2adb3069b0e04-52bab4f77b5mr3474578e87.46.1717668002202; Thu, 06 Jun 2024 03:00:02 -0700 (PDT) Received: from [1.0.0.7] ([178.155.25.76]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-52bb41e1da5sm149270e87.23.2024.06.06.03.00.01 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 06 Jun 2024 03:00:01 -0700 (PDT) Message-ID: <7ed10231-ce47-03d5-d3f9-4aea0dc7d5a4@gmail.com> Date: Thu, 6 Jun 2024 13:00:00 +0300 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.4.2 Content-Language: en-US From: Alexander Lakhin Subject: Assert in heapgettup_pagemode() fails due to underlying buffer change To: pgsql-hackers Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hello hackers, I tried to investigate a recent buildfarm test failure: https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=adder&dt=2024-06-04%2003%3A27%3A47  29/295 postgresql:recovery / recovery/026_overwrite_contrecord ERROR            39.55s   exit status 32 log/026_overwrite_contrecord_standby.log TRAP: failed Assert("ItemIdIsNormal(lpp)"), File: "../pgsql/src/backend/access/heap/heapam.c", Line: 1002, PID: 3740958 postgres: standby: bf postgres [local] startup(ExceptionalCondition+0x81)[0x56c60bf9] postgres: standby: bf postgres [local] startup(+0xf776e)[0x5667276e] postgres: standby: bf postgres [local] startup(heap_getnextslot+0x40)[0x56672ee1] postgres: standby: bf postgres [local] startup(+0x11c218)[0x56697218] postgres: standby: bf postgres [local] startup(systable_getnext+0xfa)[0x56697c1a] postgres: standby: bf postgres [local] startup(+0x6d29c7)[0x56c4d9c7] postgres: standby: bf postgres [local] startup(+0x6d372c)[0x56c4e72c] postgres: standby: bf postgres [local] startup(+0x6d8288)[0x56c53288] postgres: standby: bf postgres [local] startup(RelationCacheInitializePhase3+0x149)[0x56c52d71] (It's not the only failure of that ilk in the buildfarm.) and managed to reproduce the failure by running many 026_overwrite_contrecord tests in parallel (with fsync=on). Analyzing the core dump added some info: ... #3  0x0000000000bb43cc in ExceptionalCondition (conditionName=0xc45c77 "ItemIdIsNormal(lpp)",     fileName=0xc45aa8 "heapam.c", lineNumber=1002) at assert.c:66 #4  0x00000000004f7f13 in heapgettup_pagemode (scan=0x19f5660, dir=ForwardScanDirection, nkeys=2, key=0x19f61d0)     at heapam.c:1002 #5  0x00000000004f86d1 in heap_getnextslot (sscan=0x19f5660, direction=ForwardScanDirection, slot=0x19f5da0)     at heapam.c:1307 #6  0x000000000051d028 in table_scan_getnextslot (sscan=0x19f5660, direction=ForwardScanDirection, slot=0x19f5da0)     at ../../../../src/include/access/tableam.h:1081 #7  0x000000000051da80 in systable_getnext (sysscan=0x19f5470) at genam.c:530 #8  0x0000000000ba0937 in RelationBuildTupleDesc (relation=0x7fa004feea88) at relcache.c:572 #9  0x0000000000ba17b9 in RelationBuildDesc (targetRelId=2679, insertIt=true) at relcache.c:1184 #10 0x0000000000ba6520 in load_critical_index (indexoid=2679, heapoid=2610) at relcache.c:4353 #11 0x0000000000ba607d in RelationCacheInitializePhase3 () at relcache.c:4132 #12 0x0000000000bcb704 in InitPostgres (in_dbname=0x196ca30 "postgres", dboid=5, username=0x19a91b8 "law", useroid=0,     flags=1, out_dbname=0x0) at postinit.c:1193 ... (gdb) frame 4 (gdb) p lpp->lp_flags $2 = 1 (gdb) p ItemIdIsNormal(lpp) $12 = 1 So it looks like the Assert had failed when lpp->lp_flags had some other contents... I added the following debugging code: --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -995,10 +995,14 @@ continue_page:                 for (; linesleft > 0; linesleft--, lineindex += dir)                 {                         ItemId          lpp; +                       ItemIdData      iid;                         OffsetNumber lineoff;                         lineoff = scan->rs_vistuples[lineindex];                         lpp = PageGetItemId(page, lineoff); +                       iid = *((ItemIdData *)lpp); + +                       Assert(ItemIdIsNormal(&iid));                         Assert(ItemIdIsNormal(lpp)); and got: ... #2  0x000055b68dc6998c in ExceptionalCondition (conditionName=0x55b68dcfe5f7 "ItemIdIsNormal(&iid)",     fileName=0x55b68dcfe428 "heapam.c", lineNumber=1010) at assert.c:66 #3  0x000055b68d588a78 in heapgettup_pagemode (scan=0x55b68f0905e0, dir=ForwardScanDirection, nkeys=2,     key=0x55b68f091150) at heapam.c:1010 #4  0x000055b68d58930e in heap_getnextslot (sscan=0x55b68f0905e0, direction=ForwardScanDirection, slot=0x55b68f090d20)     at heapam.c:1322 ... (gdb) frame 3 #3  0x000055b68d588a78 in heapgettup_pagemode (...) at heapam.c:1010 1010                            Assert(ItemIdIsNormal(&iid)); (gdb) info locals lpp = 0x7f615c34b0ec iid = {lp_off = 0, lp_flags = 0, lp_len = 0} lineoff = 54 tuple = 0x55b68f090638 page = 0x7f615c34b000 "" (gdb) p *lpp $1 = {lp_off = 3160, lp_flags = 1, lp_len = 136} It seemingly confirms that the underlying memory was changed while being processed in heapgettup_pagemode(). I've tried to add checks for the page buffer content as below: --- a/src/backend/access/heap/heapam.c +++ b/src/backend/access/heap/heapam.c @@ -953,11 +953,15 @@ heapgettup_pagemode(HeapScanDesc scan,      Page        page;      int         lineindex;      int         linesleft; +char    page_copy[BLCKSZ];      if (likely(scan->rs_inited))      {          /* continue from previously returned page/tuple */          page = BufferGetPage(scan->rs_cbuf); +memcpy(page_copy, page, BLCKSZ); +for (int i = 0; i < 100; i++) +Assert(memcmp(page_copy, page, BLCKSZ) == 0);          lineindex = scan->rs_cindex + dir;          if (ScanDirectionIsForward(dir)) @@ -986,6 +990,10 @@ heapgettup_pagemode(HeapScanDesc scan,          /* prune the page and determine visible tuple offsets */          heap_prepare_pagescan((TableScanDesc) scan);          page = BufferGetPage(scan->rs_cbuf); +memcpy(page_copy, page, BLCKSZ); +for (int i = 0; i < 100; i++) +Assert(memcmp(page_copy, page, BLCKSZ) == 0); +          linesleft = scan->rs_ntuples;          lineindex = ScanDirectionIsForward(dir) ? 0 : linesleft - 1; and got the assertion failures even during `make check`: ... #5  0x00005577f29e0bc4 in ExceptionalCondition (     conditionName=conditionName@entry=0x5577f2a4a5d0 "memcmp(page_copy, page, BLCKSZ) == 0",     fileName=fileName@entry=0x5577f2a4aa38 "heapam.c", lineNumber=lineNumber@entry=966) at assert.c:66 #6  0x00005577f24faa68 in heapgettup_pagemode (scan=scan@entry=0x5577f46574e8, dir=ForwardScanDirection, nkeys=0,     key=0x0) at heapam.c:966 ... (gdb) frame 6 #6  0x00005577f24faa68 in heapgettup_pagemode (...) at heapam.c:966 966     Assert(memcmp(page_copy, page, BLCKSZ) == 0); (gdb) p i $1 = 25 Am I missing something or the the page buffer indeed lacks locking there? Best regards, Alexander