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 1qGy7e-0007Ne-1o for pgsql-hackers@arkaria.postgresql.org; Wed, 05 Jul 2023 08:44:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1qGy7a-0004mP-Qa for pgsql-hackers@arkaria.postgresql.org; Wed, 05 Jul 2023 08:44:22 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1qGy7a-0004mD-BY for pgsql-hackers@lists.postgresql.org; Wed, 05 Jul 2023 08:44:22 +0000 Received: from mail-pj1-x102f.google.com ([2607:f8b0:4864:20::102f]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1qGy7T-0028Y1-2J for pgsql-hackers@lists.postgresql.org; Wed, 05 Jul 2023 08:44:20 +0000 Received: by mail-pj1-x102f.google.com with SMTP id 98e67ed59e1d1-262e619fbb9so3059605a91.3 for ; Wed, 05 Jul 2023 01:44:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1688546654; x=1691138654; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=vIA943C5Zf3rRJp7o0Py+J5aPST8zG0HJgsljSOcndA=; b=LWxJqkhIhzvHThKPLsI5dNz9EF7NxL6dPvHnISzEnSmZiszpXQoM3KPgNBBKK8YbFh X9a4E+xj5GJUozathGzL6DBOCTInB3UIpkS2JBmKR5VVS53clA2s4Qg7zL69DojJR8yl CtTQLGW/7PEfuD0Q2hDQkhgzObA4RqZhfAhrwxZ9/23WB9MM6hpnr6Uojri6RfVQtJoa Q5WU0fOOjiJaDnK5C0RIP6ZTDhguj0feTLWCJIPcE98VKJjqQVrv1iGnUNNRmlUtYT0H WY1XQOJ7vHt7865R/hkAF2VLPtFCn4M89elZ0LJhQYfHcGzSR/TvrBFlPxh0hKn+3was sDZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1688546654; x=1691138654; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=vIA943C5Zf3rRJp7o0Py+J5aPST8zG0HJgsljSOcndA=; b=M43mmUEb5RLVp9HnG2ugrAJZ+Ltth1PQzG26QtJ7EiSnCDaOOaG2uBQ/wqq2Df+Wg2 EkmZqfTX3jVnTMRs4Xk3abzc4Xxv/iaP53eINa7qJ46l9ZqhtWN26NjQ/7umedmrP4ny ow15IyR3o9LZCGpSRVY+G2TQiR9Uw7Iv8y+9R5JXSk/Ug/G18th4zkKzqgfn9lCP0iLT tGWQyE3/VScgrRclUzSUw280rbg4oB/7DJdQfP3g8BvqQkktl5R/UfcX+AuGjIpcEHTm qGfx4BX6PjQGL/D/ugJKN0qzfkqp8+N+jzDUWfMQvArSsWfxbilr96Lcm24ozRFZl1V8 MIQQ== X-Gm-Message-State: ABy/qLZRuFLyU6ja5YDMBmHIn+F/O2Lp70zSk3ffB7Jum68xTzCYxxkP Cdf812fJ7yLhAF2xkjDmlk2LKfru8dRgELgjM8g= X-Google-Smtp-Source: APBJJlEhz25JEAy9kEVW/37J41bb2A9ABCHXoFi+bPYtA1S/MUpDh1z5H2+BMqh9dA6jFsV4KzP0ElRMAw8EKeJdd+k= X-Received: by 2002:a17:90b:238e:b0:263:5efe:617 with SMTP id mr14-20020a17090b238e00b002635efe0617mr11113568pjb.40.1688546653904; Wed, 05 Jul 2023 01:44:13 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: From: Matthias van de Meent Date: Wed, 5 Jul 2023 10:44:00 +0200 Message-ID: Subject: Re: Parallel CREATE INDEX for BRIN indexes To: Tomas Vondra Cc: PostgreSQL Hackers Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, 5 Jul 2023 at 00:08, Tomas Vondra wrote: > > > > On 7/4/23 23:53, Matthias van de Meent wrote: > > On Thu, 8 Jun 2023 at 14:55, Tomas Vondra wrote: > >> > >> Hi, > >> > >> Here's a WIP patch allowing parallel CREATE INDEX for BRIN indexes. The > >> infrastructure (starting workers etc.) is "inspired" by the BTREE code > >> (i.e. copied from that and massaged a bit to call brin stuff). > > > > Nice work. > > > >> In both cases _brin_end_parallel then reads the summaries from worker > >> files, and adds them into the index. In 0001 this is fairly simple, > >> although we could do one more improvement and sort the ranges by range > >> start to make the index nicer (and possibly a bit more efficient). This > >> should be simple, because the per-worker results are already sorted like > >> that (so a merge sort in _brin_end_parallel would be enough). > > > > I see that you manually built the passing and sorting of tuples > > between workers, but can't we use the parallel tuplesort > > infrastructure for that? It already has similar features in place and > > improves code commonality. > > > > Maybe. I wasn't that familiar with what parallel tuplesort can and can't > do, and the little I knew I managed to forget since I wrote this patch. > Which similar features do you have in mind? > > The workers are producing the results in "start_block" order, so if they > pass that to the leader, it probably can do the usual merge sort. > > >> For 0002 it's a bit more complicated, because with a single parallel > >> scan brinbuildCallbackParallel can't decide if a range is assigned to a > >> different worker or empty. And we want to generate summaries for empty > >> ranges in the index. We could either skip such range during index build, > >> and then add empty summaries in _brin_end_parallel (if needed), or add > >> them and then merge them using "union". > >> > >> > >> I just realized there's a third option to do this - we could just do > >> regular parallel scan (with no particular regard to pagesPerRange), and > >> then do "union" when merging results from workers. It doesn't require > >> the sequence of TID scans, and the union would also handle the empty > >> ranges. The per-worker results might be much larger, though, because > >> each worker might produce up to the "full" BRIN index. > > > > Would it be too much effort to add a 'min_chunk_size' argument to > > table_beginscan_parallel (or ParallelTableScanDesc) that defines the > > minimum granularity of block ranges to be assigned to each process? I > > think that would be the most elegant solution that would require > > relatively little effort: table_block_parallelscan_nextpage already > > does parallel management of multiple chunk sizes, and I think this > > modification would fit quite well in that code. > > > > I'm confused. Isn't that pretty much exactly what 0002 does? I mean, > that passes pagesPerRange to table_parallelscan_initialize(), so that > each pagesPerRange is assigned to a single worker. Huh, I overlooked that one... Sorry for that. > The trouble I described above is that the scan returns tuples, and the > consumer has no idea what was the chunk size or how many other workers > are there. Imagine you get a tuple from block 1, and then a tuple from > block 1000. Does that mean that the blocks in between are empty or that > they were processed by some other worker? If the unit of work for parallel table scans is the index's pages_per_range, then I think we can just fill in expected-but-missing ranges as 'empty' in the parallel leader during index loading, like the first of the two solutions you proposed. Kind regards, Matthias van de Meent Neon (https://neon.tech/)