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 1kWYQf-0007Xw-Oc for pgsql-hackers@arkaria.postgresql.org; Sun, 25 Oct 2020 05:18:54 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kWYQe-0005no-CH for pgsql-hackers@arkaria.postgresql.org; Sun, 25 Oct 2020 05:18:52 +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 1kWYQd-0005nh-SE for pgsql-hackers@lists.postgresql.org; Sun, 25 Oct 2020 05:18:52 +0000 Received: from mail-pg1-x543.google.com ([2607:f8b0:4864:20::543]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kWYQT-0001MR-KI for pgsql-hackers@postgresql.org; Sun, 25 Oct 2020 05:18:51 +0000 Received: by mail-pg1-x543.google.com with SMTP id r10so4099775pgb.10 for ; Sat, 24 Oct 2020 22:18:41 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=leadboat.com; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=iO4ERlBwmyuVcn4BwmdHuS6WqgdADCQrcU7bfFKQYWU=; b=QAySokjCeJ1Ic37u7Bf1XEz/Xl0pRVZAv94C1kw/D5L1r67Kt1LjX1HJAEtqDrXK6C lbqqTiX6sUmm8SXGkHIP51wefB+UrY54F0Tu1nrGSY92dd+/DA2T+sZuASd2PNKXbN+i NYJnJ0N2IbcfPLuv6NdJ+9Fo1z94b4UAL9Ao0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=iO4ERlBwmyuVcn4BwmdHuS6WqgdADCQrcU7bfFKQYWU=; b=WG6Sp4weFta6UVLaV6CsTafHMpEKOVhK4XqZOkHf9oXectyGPSwZTlvwip/LkvIXO/ ZqG/Rn+8jT9q4R2CcqNqHk4gHlPUPPhFM4AX3db2fhpHQer7Gb+OpuEz5a+/UWXVbUDz 9kptVNdrQ05+spDsOH5++ywtjgDui4hIDfOz+gewaWJSk0CZnwde1LW0T0Wb5wOm1U7r XVY5nX18KFPE4tVnpS919TzYWREA3lSykt6SKvrVZogZsz92/vHvjneTHrmN5xXndXws 2tdiGtY3cdjyriQNdry3OpQVwna/xgoqP767qzcxfnzuWLozgpXakK26jfjRkFUj/vjA zy/w== X-Gm-Message-State: AOAM532pLI+TYQN2Qtyl6zfaBdXQiLCpZw3HYeO6iSpkyw9R0VlAR5pw f4fjvXtl3b3yutsXTK8p0UejvA== X-Google-Smtp-Source: ABdhPJw1+NsX4WCl0fKP//r74NQgyHKA2P3tZEvpF1lCh3CWmVBzcJweIwusVRTHI1kJ46OPZ05sVw== X-Received: by 2002:a65:52cb:: with SMTP id z11mr8339467pgp.368.1603603119206; Sat, 24 Oct 2020 22:18:39 -0700 (PDT) Received: from rfd.leadboat.com ([2600:1702:a20:5750::43]) by smtp.gmail.com with ESMTPSA id n19sm7648691pfu.24.2020.10.24.22.18.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 24 Oct 2020 22:18:38 -0700 (PDT) Date: Sat, 24 Oct 2020 22:18:36 -0700 From: Noah Misch To: Peter Geoghegan Cc: Andres Freund , Phil Florent , PostgreSQL Hackers Subject: Re: pgstat_report_activity() and parallel CREATE INDEX (was: Parallel index creation & pg_stat_activity) Message-ID: <20201025051836.GC2651494@rfd.leadboat.com> References: <20201014022636.GA1962668@rfd.leadboat.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="ZfOjI3PrQbgiZnxM" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk --ZfOjI3PrQbgiZnxM Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Sat, Oct 17, 2020 at 08:39:35AM -0700, Peter Geoghegan wrote: > On Tue, Oct 13, 2020 at 7:26 PM Noah Misch wrote: > > 1. Disable parallelism for the index build under ExecuteTruncateGuts(). > > Nobody will mourn a performance loss from declining parallelism for an > > empty index, but I feel like this is fixing in the wrong place. > > 2. Make _bt_begin_parallel() and begin_parallel_vacuum() recognize the > > debug_query_string==NULL case and reproduce it on the worker. > > 3. Require bgworkers to set debug_query_string before entering code of vacuum, > > truncate, etc. Logical replication might synthesize a DDL statement, or it > > might just use a constant string. > > > > I tend to prefer (2), but (3) isn't bad. Opinions? > > I also prefer 2. Thanks. Here is the pair of patches I plan to use. The second is equivalent to v0; I just added a log message. --ZfOjI3PrQbgiZnxM Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="null-debug_query_string-v1.patch" Author: Noah Misch Commit: Noah Misch Reproduce debug_query_string==NULL on parallel workers. Certain background workers initiate parallel queries while debug_query_string==NULL, at which point they attempted strlen(NULL) and died to SIGSEGV. Older debug_query_string observers allow NULL, so do likewise in these newer ones. Back-patch to v11, where commit 7de4a1bcc56f494acbd0d6e70781df877dc8ecb5 introduced the first of these. Reviewed by FIXME. Discussion: https://postgr.es/m/20201014022636.GA1962668@rfd.leadboat.com diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c index 4f2f381..34ae8aa 100644 --- a/src/backend/access/heap/vacuumlazy.c +++ b/src/backend/access/heap/vacuumlazy.c @@ -3238,7 +3238,6 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, WalUsage *wal_usage; bool *can_parallel_vacuum; long maxtuples; - char *sharedquery; Size est_shared; Size est_deadtuples; int nindexes_mwm = 0; @@ -3335,9 +3334,14 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, shm_toc_estimate_keys(&pcxt->estimator, 1); /* Finally, estimate PARALLEL_VACUUM_KEY_QUERY_TEXT space */ - querylen = strlen(debug_query_string); - shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); - shm_toc_estimate_keys(&pcxt->estimator, 1); + if (debug_query_string) + { + querylen = strlen(debug_query_string); + shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); + shm_toc_estimate_keys(&pcxt->estimator, 1); + } + else + querylen = 0; /* keep compiler quiet */ InitializeParallelDSM(pcxt); @@ -3382,10 +3386,16 @@ begin_parallel_vacuum(Oid relid, Relation *Irel, LVRelStats *vacrelstats, lps->wal_usage = wal_usage; /* Store query string for workers */ - sharedquery = (char *) shm_toc_allocate(pcxt->toc, querylen + 1); - memcpy(sharedquery, debug_query_string, querylen + 1); - sharedquery[querylen] = '\0'; - shm_toc_insert(pcxt->toc, PARALLEL_VACUUM_KEY_QUERY_TEXT, sharedquery); + if (debug_query_string) + { + char *sharedquery; + + sharedquery = (char *) shm_toc_allocate(pcxt->toc, querylen + 1); + memcpy(sharedquery, debug_query_string, querylen + 1); + sharedquery[querylen] = '\0'; + shm_toc_insert(pcxt->toc, + PARALLEL_VACUUM_KEY_QUERY_TEXT, sharedquery); + } pfree(can_parallel_vacuum); return lps; @@ -3528,7 +3538,7 @@ parallel_vacuum_main(dsm_segment *seg, shm_toc *toc) elog(DEBUG1, "starting parallel vacuum worker for bulk delete"); /* Set debug_query_string for individual workers */ - sharedquery = shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_QUERY_TEXT, false); + sharedquery = shm_toc_lookup(toc, PARALLEL_VACUUM_KEY_QUERY_TEXT, true); debug_query_string = sharedquery; pgstat_report_activity(STATE_RUNNING, debug_query_string); diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index efee867..8730de2 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -1466,7 +1466,6 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) WalUsage *walusage; BufferUsage *bufferusage; bool leaderparticipates = true; - char *sharedquery; int querylen; #ifdef DISABLE_LEADER_PARTICIPATION @@ -1533,9 +1532,14 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) shm_toc_estimate_keys(&pcxt->estimator, 1); /* Finally, estimate PARALLEL_KEY_QUERY_TEXT space */ - querylen = strlen(debug_query_string); - shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); - shm_toc_estimate_keys(&pcxt->estimator, 1); + if (debug_query_string) + { + querylen = strlen(debug_query_string); + shm_toc_estimate_chunk(&pcxt->estimator, querylen + 1); + shm_toc_estimate_keys(&pcxt->estimator, 1); + } + else + querylen = 0; /* keep compiler quiet */ /* Everyone's had a chance to ask for space, so now create the DSM */ InitializeParallelDSM(pcxt); @@ -1599,9 +1603,14 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request) } /* Store query string for workers */ - sharedquery = (char *) shm_toc_allocate(pcxt->toc, querylen + 1); - memcpy(sharedquery, debug_query_string, querylen + 1); - shm_toc_insert(pcxt->toc, PARALLEL_KEY_QUERY_TEXT, sharedquery); + if (debug_query_string) + { + char *sharedquery; + + sharedquery = (char *) shm_toc_allocate(pcxt->toc, querylen + 1); + memcpy(sharedquery, debug_query_string, querylen + 1); + shm_toc_insert(pcxt->toc, PARALLEL_KEY_QUERY_TEXT, sharedquery); + } /* * Allocate space for each worker's WalUsage and BufferUsage; no need to @@ -1806,7 +1815,7 @@ _bt_parallel_build_main(dsm_segment *seg, shm_toc *toc) #endif /* BTREE_BUILD_STATS */ /* Set debug_query_string for individual workers first */ - sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, false); + sharedquery = shm_toc_lookup(toc, PARALLEL_KEY_QUERY_TEXT, true); debug_query_string = sharedquery; /* Report the query string from leader */ --ZfOjI3PrQbgiZnxM Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="worker_spi-debug_query_string-v1.patch" Author: Noah Misch Commit: Noah Misch Set debug_query_string in worker_spi. This makes elog.c emit the string, which is good practice for a background worker that executes SQL strings. Reviewed by FIXME. Discussion: https://postgr.es/m/20201014022636.GA1962668@rfd.leadboat.com diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c index 1c7b17c..daf6c1d 100644 --- a/src/test/modules/worker_spi/worker_spi.c +++ b/src/test/modules/worker_spi/worker_spi.c @@ -113,16 +113,17 @@ initialize_worker_spi(worktable *table) SPI_connect(); PushActiveSnapshot(GetTransactionSnapshot()); pgstat_report_activity(STATE_RUNNING, "initializing worker_spi schema"); /* XXX could we use CREATE SCHEMA IF NOT EXISTS? */ initStringInfo(&buf); appendStringInfo(&buf, "select count(*) from pg_namespace where nspname = '%s'", table->schema); + debug_query_string = buf.data; ret = SPI_execute(buf.data, true, 0); if (ret != SPI_OK_SELECT) elog(FATAL, "SPI_execute failed: error code %d", ret); if (SPI_processed != 1) elog(FATAL, "not a singleton result"); @@ -138,30 +139,32 @@ initialize_worker_spi(worktable *table) appendStringInfo(&buf, "CREATE SCHEMA \"%s\" " "CREATE TABLE \"%s\" (" " type text CHECK (type IN ('total', 'delta')), " " value integer)" "CREATE UNIQUE INDEX \"%s_unique_total\" ON \"%s\" (type) " "WHERE type = 'total'", table->schema, table->name, table->name, table->name); + debug_query_string = buf.data; /* set statement start time */ SetCurrentStatementStartTimestamp(); ret = SPI_execute(buf.data, false, 0); if (ret != SPI_OK_UTILITY) elog(FATAL, "failed to create my schema"); } SPI_finish(); PopActiveSnapshot(); CommitTransactionCommand(); pgstat_report_activity(STATE_IDLE, NULL); + debug_query_string = NULL; } void worker_spi_main(Datum main_arg) { int index = DatumGetInt32(main_arg); worktable *table; StringInfoData buf; @@ -206,16 +209,17 @@ worker_spi_main(Datum main_arg) "UPDATE %s.%s " "SET value = %s.value + total.sum " "FROM total WHERE type = 'total' " "RETURNING %s.value", table->schema, table->name, table->schema, table->name, table->name, table->name); + debug_query_string = buf.data; /* * Main loop: do this until the SIGTERM handler tells us to terminate */ while (!got_sigterm) { int ret; --ZfOjI3PrQbgiZnxM--