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 1rT2sk-0002Nm-AN for pgsql-hackers@arkaria.postgresql.org; Thu, 25 Jan 2024 16:47:14 +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 1rT2sj-001PzO-7a for pgsql-hackers@arkaria.postgresql.org; Thu, 25 Jan 2024 16:47:13 +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 1rT2si-001PzE-Sv for pgsql-hackers@lists.postgresql.org; Thu, 25 Jan 2024 16:47:12 +0000 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1rT2sf-003gDc-3x for pgsql-hackers@lists.postgresql.org; Thu, 25 Jan 2024 16:47:11 +0000 Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-40eccf4a91dso15701865e9.2 for ; Thu, 25 Jan 2024 08:47:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=enterprisedb.com; s=google; t=1706201227; x=1706806027; darn=lists.postgresql.org; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=fdprtnBtBLtUx/nQQpVhX3FS9MdeZ4yJyZ2ej3ZUbCA=; b=DA/yRj7uU3UDG2hHySNnY3VOhowbJ03h1DbdrM3Ss+P4VEEtDD2UMBmz/5GP52/5oV HXsq68loGrjeYVHKkawxMlLlYIhVP7Pk+1CcOSkSVpmmkOdsQAJQdcgmOszo+l4vvo+d bLwTV0UFcHh3ORZEE6qlU3JLvRmr8DNRTWboM1EjYxE+pvTS+Ozj9uW9N5gRLUX/lVvS /CUAPJYbemysZXy0m5bBL7f1gbaz4tcuWutALCWL+BqI28CJanPxIQguem3SnuyjbZGZ M5Fx+FRfGlTUrW+zIuajJ3TlwDBaOctG3HFgehq4i8J3+pk+NtPXLYz/9Anv/ENRWXKf +miQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706201227; x=1706806027; h=content-transfer-encoding:in-reply-to:from:references:cc:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fdprtnBtBLtUx/nQQpVhX3FS9MdeZ4yJyZ2ej3ZUbCA=; b=JrGmhUMugxxCZmrQjnd4GYgeZi78Z1E99JvQmZZFhAp8Vd81dMNwWayH6CnYSq1Bjb EQB9IJ1eLwkxdfx3PdqanlAL3QdJU9uSkxSxLVSVbiqMKP6NpKJooe4kdEbWbIGh39Oe rXR/9wpAsciWLV69eE8warb95U18b7KYklLERJl3MXC0fGgx3GMw/1YYjceImR4minGK trmw+WDxZ0tr+vQ4yLR93smwwJNupubyo6FKuztxQ08CGfC75yxPDYxCAZySPNq7hZME NAann7FueZjpk5rIzdO4QPI+8eksR3UGG+zUjKaRRO1+Qm7oIby9WReO71Z5FrVJ0a85 d/0g== X-Gm-Message-State: AOJu0YzKgBRnx3WQFOG1ePG1Vew957a4GzyZbIKPjX7/HFoBx/764jwa RtfohpSx1LfxORRVroor0foisalivombtgIYexbjDutAP4Dzy4paB1VwZGEbd0rBxWroUA6UafQ = X-Google-Smtp-Source: AGHT+IFjhNfgAZKwDl9/WhACnM1WxwUD+j+w+F+CecSTiimkxgaxUoOEGlVNhPhTdWoZV/nO7VYW8w== X-Received: by 2002:a5d:4524:0:b0:333:4c30:dae4 with SMTP id j4-20020a5d4524000000b003334c30dae4mr34759wra.45.1706201227275; Thu, 25 Jan 2024 08:47:07 -0800 (PST) Received: from [10.137.0.18] (ip-86-49-229-30.bb.vodafone.cz. [86.49.229.30]) by smtp.gmail.com with ESMTPSA id m4-20020a5d64a4000000b003392e05fb3esm11803418wrp.24.2024.01.25.08.47.06 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 25 Jan 2024 08:47:06 -0800 (PST) Message-ID: <033fd9c8-2efc-4777-bdc6-59c13ec4a64d@enterprisedb.com> Date: Thu, 25 Jan 2024 17:47:06 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: index prefetching Content-Language: en-US To: Dilip Kumar Cc: Konstantin Knizhnik , PostgreSQL Hackers References: <8ec36f51-b863-60e3-20e2-b9c981c5ce5e@enterprisedb.com> <20231221154352.ijtg6wloa3nowivh@alap3.anarazel.de> <482ec3ff-52ad-415d-96fd-f3832a894023@enterprisedb.com> <8969e2cf-6b23-4682-ab56-b3c0aca877ab@garret.ru> <214d5bbe-21d7-4a63-b62b-91fe84f281f5@enterprisedb.com> <731c8bb7-0662-47a5-a782-5cb631916f1d@enterprisedb.com> <22dbfb04-24e4-49b1-b3fa-5367c8d171d2@garret.ru> <41b959cb-f483-413a-ba5e-f1ac4db0ef0b@garret.ru> <2fda99cb-52b1-432f-b570-d9acbecb42bb@enterprisedb.com> <316ca3df-d1b0-49ce-ba05-56b342b4cefa@garret.ru> <777e981c-bf0c-4eb9-a9e0-42d677e94327@enterprisedb.com> From: Tomas Vondra In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On 1/25/24 11:45, Dilip Kumar wrote: > On Wed, Jan 24, 2024 at 11:43 PM Tomas Vondra > wrote: > >> On 1/22/24 07:35, Konstantin Knizhnik wrote: >>> >>> On 22/01/2024 1:47 am, Tomas Vondra wrote: >>>> h, right. Well, you're right in this case we perhaps could set just one >>>> of those flags, but the "purpose" of the two places is quite different. >>>> >>>> The "prefetch" flag is fully controlled by the prefetcher, and it's up >>>> to it to change it (e.g. I can easily imagine some new logic touching >>>> setting it to "false" for some reason). >>>> >>>> The "data" flag is fully controlled by the custom callbacks, so whatever >>>> the callback stores, will be there. >>>> >>>> I don't think it's worth simplifying this. In particular, I don't think >>>> the callback can assume it can rely on the "prefetch" flag. >>>> >>> Why not to add "all_visible" flag to IndexPrefetchEntry ? If will not >>> cause any extra space overhead (because of alignment), but allows to >>> avoid dynamic memory allocation (not sure if it is critical, but nice to >>> avoid if possible). >>> >> > While reading through the first patch I got some questions, I haven't > read it complete yet but this is what I got so far. > > 1. > +static bool > +IndexPrefetchBlockIsSequential(IndexPrefetch *prefetch, BlockNumber block) > +{ > + int idx; > ... > + if (prefetch->blockItems[idx] != (block - i)) > + return false; > + > + /* Don't prefetch if the block happens to be the same. */ > + if (prefetch->blockItems[idx] == block) > + return false; > + } > + > + /* not sequential, not recently prefetched */ > + return true; > +} > > The above function name is BlockIsSequential but at the end, it > returns true if it is not sequential, seem like a problem? Actually, I think it's the comment that's wrong - the last return is reached only for a sequential pattern (and when the block was not accessed recently). > Also other 2 checks right above the end of the function are returning > false if the block is the same or the pattern is sequential I think > those are wrong too. > Hmmm. You're right this is partially wrong. There are two checks: /* * For a sequential pattern, blocks "k" step ago needs to have block * number by "k" smaller compared to the current block. */ if (prefetch->blockItems[idx] != (block - i)) return false; /* Don't prefetch if the block happens to be the same. */ if (prefetch->blockItems[idx] == block) return false; The first condition is correct - we want to return "false" when the pattern is not sequential. But the second condition is wrong - we want to skip prefetching when the block was already prefetched recently, so this should return true (which is a bit misleading, as it seems to imply the pattern is sequential, when it's not). However, this is harmless, because we then identify this block as recently prefetched in the "full" cache check, so we won't prefetch it anyway. So it's harmless, although a bit more expensive. There's another inefficiency - we stop looking for the same block once we find the first block breaking the non-sequential pattern. Imagine a sequence of blocks 1, 2, 3, 1, 2, 3, ... in which case we never notice the block was recently prefetched, because we always find the break of the sequential pattern. But again, it's harmless, thanks to the full cache of recently prefetched blocks. > 2. > I have noticed that the prefetch history is maintained at the backend > level, but what if multiple backends are trying to fetch the same heap > blocks maybe scanning the same index, so should that be in some shared > structure? I haven't thought much deeper about this from the > implementation POV, but should we think about it, or it doesn't > matter? Yes, the cache is at the backend level - it's a known limitation, but I see it more as a conscious tradeoff. Firstly, while the LRU cache is at backend level, PrefetchBuffer also checks shared buffers for each prefetch request. So with sufficiently large shared buffers we're likely to find it there (and for direct I/O there won't be any other place to check). Secondly, the only other place to check is page cache, but there's no good (sufficiently cheap) way to check that. See the preadv2/nowait experiment earlier in this thread. I suppose we could implement a similar LRU cache for shared memory (and I don't think it'd be very complicated), but I did not plan to do that in this patch unless absolutely necessary. regards -- Tomas Vondra EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company