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 1kVzFZ-0004Jq-FQ for pgsql-hackers@arkaria.postgresql.org; Fri, 23 Oct 2020 15:45:05 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kVzFX-0001zB-26 for pgsql-hackers@arkaria.postgresql.org; Fri, 23 Oct 2020 15:45:03 +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 1kVzFW-0001z3-Ja for pgsql-hackers@lists.postgresql.org; Fri, 23 Oct 2020 15:45:02 +0000 Received: from mail1.dalibo.net ([51.159.93.128] helo=mail.dalibo.com) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kVzFP-0007Uf-DE for pgsql-hackers@postgresql.org; Fri, 23 Oct 2020 15:45:02 +0000 Received: from firost (larco.ioguix.net [82.66.0.6]) by mail.dalibo.com (Postfix) with ESMTPSA id 5C9A71FB0B; Fri, 23 Oct 2020 17:44:53 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=dalibo.com; s=a; t=1603467893; bh=B+qMEo7fr04X6tk9PPAe1tv9cTmakN0NIKScQXwpBEk=; h=Date:From:To:Subject:From; b=IaUoaALFdzjlbJJD6dcPxMfkTFROamv2Hax1SdjYFFgscrrP7DClcId244i73t3En gUDqdffLghe8DeSXpRGzhjeWCD/Ew25kVGQ3xf/3lnRn5/K+RKxKqHdpeof1hZegMW GfZbi/YasDxTpt3aDGzlRossmg8Y8cQOvFslgXvU= Date: Fri, 23 Oct 2020 17:44:51 +0200 From: Jehan-Guillaume de Rorthais To: PostgreSQL-development , Peter Geoghegan Subject: vacuum -vs reltuples on insert only index Message-ID: <20201023174451.69e358f1@firost> Organization: Dalibo MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk Hello, I've found a behavior change with pg_class.reltuples on btree index. With only insert activity on a table, when an index is processed, its related reltuples is set to 0. Here is a demo script: -- force index cleanup set vacuum_cleanup_index_scale_factor to 0; drop table if exists t; create table t as select i from generate_series(1, 100) i; create index t_i on t(i); -- after index creation its reltuples is correct select reltuples from pg_class where relname = 't_i' -- result: reltuples | 100 -- vacuum set index reltuples to 0 vacuum t; select reltuples from pg_class where relname = 't_i' -- result: reltuples | 0 -- analyze set it back to correct value analyze t; select reltuples from pg_class where relname = 't_i' -- result: reltuples | 100 -- insert + vacuum reset it again to 0 insert into t values(101); vacuum (verbose off, analyze on, index_cleanup on) t; select reltuples from pg_class where relname = 't_i' -- result: reltuples | 0 -- delete + vacuum set it back to correct value delete from t where i=10; vacuum (verbose off, analyze on, index_cleanup on) t; select reltuples from pg_class where relname = 't_i' -- result: reltuples | 100 -- and back to 0 again with insert+vacuum insert into t values(102); vacuum (verbose off, analyze on, index_cleanup on) t; select reltuples from pg_class where relname = 't_i' -- result: reltuples | 0 Before 0d861bbb70, btvacuumpage was adding to relation stats the number of leaving lines in the block using: stats->num_index_tuples += maxoff - minoff + 1; After 0d861bbb70, it is set using new variable nhtidslive: stats->num_index_tuples += nhtidslive However, nhtidslive is only incremented if callback (IndexBulkDeleteCallback) is set, which seems not to be the case on select-only workload. A naive fix might be to use "maxoff - minoff + 1" when callback==NULL. Thoughts? Regards,