Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jpbQE-000757-UI for pgsql-hackers@arkaria.postgresql.org; Sun, 28 Jun 2020 17:48:55 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1jpbQD-0001V7-EZ for pgsql-hackers@arkaria.postgresql.org; Sun, 28 Jun 2020 17:48:53 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jpbQD-0001Ur-3I for pgsql-hackers@lists.postgresql.org; Sun, 28 Jun 2020 17:48:53 +0000 Received: from mail-pj1-x1042.google.com ([2607:f8b0:4864:20::1042]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1jpbQ3-00022y-6w for pgsql-hackers@postgresql.org; Sun, 28 Jun 2020 17:48:51 +0000 Received: by mail-pj1-x1042.google.com with SMTP id gc9so563426pjb.2 for ; Sun, 28 Jun 2020 10:48:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb-com.20150623.gappssmtp.com; s=20150623; h=mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=vz1uX9+PTjLz0ln6k9DJ+jZiKsLbPDtHnwsSaB4dS0M=; b=gnV3RC270PbAnvzZLJJOkFKZVAEAxHwXsW0TEhYmrMae3E4OVDLrEydAQtXXOOUNiS tKBw48P7xYHoqK1pKkyYkV3eOibn8FmybK2ZzoxGTvzsm7Q9g063BqxDGWyznLwpACk/ RGr314TBQXspkaUHFc5t0JIZrJOBS1N3oDJr0kpssdTFxcMT7wBqATGbAZUw3VjhRGs0 38KqoukeUtYFxFohcWu/R3IvkwushrJ0UZ4Npn+tIk5dHu4pmWfny5Y5StMc67r4lRYI RivStWhfUJW0XKdWRmdumY8iRYtYYl+7gogiUCYw3ETwMExyMZQK2Nt5XBLGJNIgA1wK djWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:subject:from:in-reply-to:date:cc :content-transfer-encoding:message-id:references:to; bh=vz1uX9+PTjLz0ln6k9DJ+jZiKsLbPDtHnwsSaB4dS0M=; b=PGSM5wz+tlGEi87odPcU9HaXAaIUfSUJfJvRgCFizJye+OmACZcPcVDI70+FxWfFFc viIbEUQzG8ILseyOHt/1zqYj7B6gXkbxbC9VjNCHDNvM9F4840qmg5pghtGCLrKY6xWK GFClSS3mAU2h9onFEzf3k313ek8G5QPteG5ZQA+YZe86tBZzW94qnDOHnShn31vrRBSZ XkM+df5GZdTs4c17237CcZntXa4q1MEzSOFbZfSi+Hlm0yKRS/QUo+oN4QqNVIOg/bPG jkFzA20TatG/cfc1fUTainKNqQgaZkPqbuoDHAql0+Z/YacceSrhM0PosTQN6SGfbb+L /qHg== X-Gm-Message-State: AOAM533gv2I6AznpwJadiEQh0x63yBpxXHtv1vzHvlSVLUueRF1Df8O8 BJ0ZrCrY92rGXwjw0quudS9UXtRr39a7GUUOTUpM4roRdRFY7qbG2aV5dO7g26GO4xIqUa1vhX2 aoAWBUoAWSSyvppvphXepm1tj7vimRbEkgr8Tyn9WVJr3EaH9y2lic56P+heDxjESBYNy/osKKp 29gq6jt+j/I6KpmwRnznuswQm4tavCrEjMt/pW X-Google-Smtp-Source: ABdhPJyHGiKBvf/NNxtVUBOAzlfSAXpHeFlQx+zGmqye5Y9QMJLEk/m8SLsCD8duNjriRletHkvAIw== X-Received: by 2002:a17:90b:4c44:: with SMTP id np4mr12744810pjb.63.1593366520178; Sun, 28 Jun 2020 10:48:40 -0700 (PDT) Received: from [192.168.0.29] (24-113-193-150.wavecable.com. [24.113.193.150]) by smtp.gmail.com with ESMTPSA id 199sm22312046pgc.79.2020.06.28.10.48.39 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sun, 28 Jun 2020 10:48:39 -0700 (PDT) Content-Type: text/plain; charset=utf-8 Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.80.23.2.2\)) Subject: Re: new heapcheck contrib module From: Mark Dilger In-Reply-To: Date: Sun, 28 Jun 2020 10:48:38 -0700 Cc: Robert Haas , Peter Geoghegan , Andres Freund , PostgreSQL-development Content-Transfer-Encoding: quoted-printable Message-Id: <0C0349EB-DD85-4DA8-82C7-DF70AB714592@enterprisedb.com> References: <12ED3DA8-25F0-4B68-937D-D907CFBF08E7@enterprisedb.com> <20200420194210.sevnpi4lyghoanxi@alap3.anarazel.de> <23E60C3C-C20A-4508-84AC-E0CEA59E784A@enterprisedb.com> <5F743835-3399-419C-8324-2D424237E999@enterprisedb.com> <885D2EC9-7D06-4903-A17D-72C184A1E1C5@enterprisedb.com> <5CC85F28-F210-47AC-8DA8-EC4E82AF3FD5@enterprisedb.com> To: Dilip Kumar X-Mailer: Apple Mail (2.3608.80.23.2.2) X-CLOUD-SEC-AV-Info: enterprisedb,google_mail,monitor X-CLOUD-SEC-AV-Sent: true X-Gm-Spam: 0 X-Gm-Phishy: 0 List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk > On Jun 28, 2020, at 9:05 AM, Dilip Kumar = wrote: >=20 > Some more comments on v9_0001. > 1. > + LWLockAcquire(XidGenLock, LW_SHARED); > + nextFullXid =3D ShmemVariableCache->nextFullXid; > + ctx.oldestValidXid =3D ShmemVariableCache->oldestXid; > + LWLockRelease(XidGenLock); > + ctx.nextKnownValidXid =3D XidFromFullTransactionId(nextFullXid); > ... > ... > + > + for (ctx.blkno =3D startblock; ctx.blkno < endblock; ctx.blkno++) > + { > + int32 mapbits; > + OffsetNumber maxoff; > + PageHeader ph; > + > + /* Optionally skip over all-frozen or all-visible blocks */ > + if (skip_all_frozen || skip_all_visible) > + { > + mapbits =3D (int32) visibilitymap_get_status(ctx.rel, ctx.blkno, > + &vmbuffer); > + if (skip_all_visible && (mapbits & VISIBILITYMAP_ALL_VISIBLE) !=3D = 0) > + continue; > + if (skip_all_frozen && (mapbits & VISIBILITYMAP_ALL_FROZEN) !=3D 0) > + continue; > + } > + > + /* Read and lock the next page. */ > + ctx.buffer =3D ReadBufferExtended(ctx.rel, MAIN_FORKNUM, ctx.blkno, > + RBM_NORMAL, ctx.bstrategy); > + LockBuffer(ctx.buffer, BUFFER_LOCK_SHARE); >=20 > I might be missing something, but it appears that first we are getting > the nextFullXid and after that, we are scanning the block by block. > So while we are scanning the block if the nextXid is advanced and it > has updated some tuple in the heap pages, then it seems the current > logic will complain about out of range xid. I did not test this > behavior so please point me to the logic which is protecting this. We know the oldest valid Xid cannot advance, because we hold a lock that = would prevent it from doing so. We cannot know that the newest Xid will = not advance, but when we see an Xid beyond the end of the known valid = range, we check its validity, and either report it as a corruption or = advance our idea of the newest valid Xid, depending on that check. That = logic is in TransactionIdValidInRel. > 2. > /* > * Helper function to construct the TupleDesc needed by verify_heapam. > */ > static TupleDesc > verify_heapam_tupdesc(void) >=20 > =46rom function name, it appeared that it is verifying tuple = descriptor > but this is just creating the tuple descriptor. In amcheck--1.2--1.3.sql we define a function named verify_heapam which = returns a set of records. This is the tuple descriptor for that = function. I understand that the name can be parsed as = verify_(heapam_tupdesc), but it is meant as (verify_heapam)_tupdesc. Do = you have a name you would prefer? > 3. > + /* Optionally skip over all-frozen or all-visible blocks */ > + if (skip_all_frozen || skip_all_visible) > + { > + mapbits =3D (int32) visibilitymap_get_status(ctx.rel, ctx.blkno, > + &vmbuffer); > + if (skip_all_visible && (mapbits & VISIBILITYMAP_ALL_VISIBLE) !=3D = 0) > + continue; > + if (skip_all_frozen && (mapbits & VISIBILITYMAP_ALL_FROZEN) !=3D 0) > + continue; > + } >=20 > Here, do we want to test that in VM the all visible bit is set whereas > on the page it is not set? That can lead to a wrong result in an > index-only scan. If the caller has specified that the corruption check should skip over = all-frozen or all-visible data, then we cannot load the page that the VM = claims is all-frozen or all-visible without defeating the purpose of the = caller having specified these options. Without loading the page, we = cannot check the page's header bits. When not skipping all-visible or all-frozen blocks, we might like to pin = both the heap page and the visibility map page in order to compare the = two, being careful not to hold a pin on the one while performing I/O on = the other. See for example the logic in heap_delete(). But I'm not = sure what guarantees the system makes about agreement between these two = bits. Certainly, the VM should not claim a page is all visible when it = isn't, but are we guaranteed that a page that is all-visible will always = have its all-visible bit set? I don't know if (possibly transient) = disagreement between these two bits constitutes corruption. Perhaps = others following this thread can advise? > 4. One cosmetic comment >=20 > + /* Skip non-varlena values, but update offset first */ > .. > + > + /* Ok, we're looking at a varlena attribute. */ >=20 > Throughout the patch, I have noticed that some of your single-line > comments have "full stop" whereas other don't. Can we keep them > consistent? I try to use a "full stop" at the end of sentences, but not at the end = of sentence fragments. To me, a "full stop" means that a sentence has = reached its conclusion. I don't intentionally use one at the end of a = fragment, unless the fragment precedes a full sentence, in which case = the "full stop" is needed to separate the two. Of course, I may have = violated my own rule in a few places, but before I submit a v10 patch = with comment punctuation changes, perhaps we can agree on what the rule = is? (This has probably been discussed before and agreed before. A link = to the appropriate email thread would be sufficient.) For example: /* red, green, or blue */ /* set to pink */ /* set to blue. We have not closed the file. */ /* At this point, we have chosen the color. */ The first comment is not a sentence, but the fourth is. The third = comment is a fragment followed by a full sentence, and a "full stop" = separates the two. As for the second comment, as I recall, verb phrases = can be interpreted as a full sentence, as in "Close the door!", when = they are meant as commands to the listener, but not otherwise. "set to = pink" is not a command to the reader, but rather a description of what = the code is doing at that point, so I think of it as a mere verb phrase = and not a full sentence. Making matters even more complicated, portions of the logic in = verify_heapam were taken from sections of code that would ereport(), = elog(), or Assert() on corruption, and when I took such code, I = sometimes also took the comments in unmodified form. That means that my = normal commenting rules don't apply, as I'm not the comment author in = such cases. =E2=80=94 Mark Dilger EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company