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.96) (envelope-from ) id 1wjgLT-000EnH-0q for pgsql-hackers@arkaria.postgresql.org; Tue, 14 Jul 2026 16:50:59 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wjgLR-004EQr-0X for pgsql-hackers@arkaria.postgresql.org; Tue, 14 Jul 2026 16:50:58 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wjgLQ-004EQj-2R for pgsql-hackers@lists.postgresql.org; Tue, 14 Jul 2026 16:50:57 +0000 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wjgLP-00000000BNi-17M3 for pgsql-hackers@lists.postgresql.org; Tue, 14 Jul 2026 16:50:56 +0000 Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-493c5220cb7so8066585e9.3 for ; Tue, 14 Jul 2026 09:50:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1784047854; x=1784652654; darn=lists.postgresql.org; h=in-reply-to:references:content-transfer-encoding:mime-version:cc :subject:to:from:message-id:date:content-type:from:to:cc:subject :date:message-id:reply-to:content-type; bh=sS6nFb9yW3WeBNLrkXB7fXq4MzhthItSGadhc0I8hys=; b=ZUzjsjBJpjCH9Dq9g6/U/xE+Ls2crCcWMUBSN4rWPWb208ldu3NfOmFx0gEqJRgYAz VW/olRUDTdxzMmNRWHsv6pNI7xy4w2t1ssPcYv5tCx4k5fuBr4SP0QgO51S9Wp2eIgoE pDr0HDtIaUPjf6sN2kHUGv7Socmz5rjXpOCKIAJUFfwl8gq3I+7LmnzuYgZVEK87P5J8 n3s9lAC8gJ5wU0LZmSYnm3ltioaDvsslh2pOYwzwuDTvfC8XEKGw+RTXt3g37VOFlpr9 3ZKXhZPymFJY2G7jJIMedi8P6VH9JUIb2OOHPZM0RanaD4EZRXGUXM4Zoe7ExYzaN27z N3kg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784047854; x=1784652654; h=in-reply-to:references:content-transfer-encoding:mime-version:cc :subject:to:from:message-id:date:content-type:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=sS6nFb9yW3WeBNLrkXB7fXq4MzhthItSGadhc0I8hys=; b=cNWERRCxMOYkBFiRTyXDYcDmx1bldDaD2cyMLmNoLoX85XmUmb+OBt0iDUilxqR6JM jaTl49sLzrjmEow3f9iQ7ZGIb9dGIs0rr3oXpSGQFuCYpo+4cJAU9PpWG/8vqUP9gBUz XCt91ucZnILt+NrGf+Xi/gCRYWfZF+GFMI47Fao+P9j6Gd22pmzod1kpPU9P4Gh8rIbb D4CgMW1Rty4/BA5P8LOfoQ2Ur9vpTWsajlUgVxVVTeV7ku9T0i/vGHZW+IyPNRLPkmtt F4CcDj9De8dnHHrAYcx5cG2Vpf6cJukOm32XUYsslmO8J+fS9Q4btfZj/S3DNKTBMlPV FJ6A== X-Gm-Message-State: AOJu0YzOqhlihHSD1Cg+c5nuCK4Ad0heV8gkG2JZaEV6u2cICOXUc+Cg W8RhpRiIz2dijNtASySoGSrONzoHpcjK6wjHWPSS3pd1IJ4PyTF+QuNy X-Gm-Gg: AfdE7cnfYk1DGHNXoRkyQY0FmbLm0RwqjCoolC1zAOpNS1TByfvODn2tEKYC6sUJE5c 6775vHguNi4JJbKuKUlO+RfP0wyHRojzezVaWYpDWO+ctI62Pi7Ohi3SEVWrMYZmP184EG3i+vI h1sd9EQlzeH5nBfV7nCT7AsWl2IweBVrgdaqymnGwpSJWJW5rJ1tPG07kirs0G/0VKmyg9UvsZC BbvO8UBjQ4T8mXYi+16phmFgND5YXBP/w6An4V1jCAlEOrE3qha/0nXvo+G4NwyxgKagDtAME7/ N8TsAC2B4aFWyCOPjbaRuFRYc6rclBCT9Bt/LwegvGZi2NGEfv/Q4upHE0/4xFKmKUuEU8VvmwH bWDzr8rJqS8DRNfI5eiWxSTMDYqsT/fJhRf8ZxDl4G8oCNDWUMqyYVI+ETi0a9NpRxe1qLumexJ mMAQlOFWTdiCuE/NVzpGZjP2M3rIGsOaGNi+EVdjTNBw== X-Received: by 2002:a05:600c:528d:b0:48f:d5b8:5b07 with SMTP id 5b1f17b1804b1-493f881dde2mr155329665e9.20.1784047854050; Tue, 14 Jul 2026 09:50:54 -0700 (PDT) Received: from localhost ([2a02:169:191:0:349f:3d93:470:ffe3]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-47f462e0cb2sm9503741f8f.0.2026.07.14.09.50.53 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 14 Jul 2026 09:50:53 -0700 (PDT) Content-Type: text/plain; charset=UTF-8 Date: Tue, 14 Jul 2026 18:50:53 +0200 Message-Id: From: "Alberto Piai" To: "Antonin Houska" , "Rahila Syed" Subject: Re: Allow progress tracking of sub-commands Cc: , , , Mime-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Mailer: aerc 0.21.0 References: <106920.1782734246@localhost> <69363.1782919477@localhost> In-Reply-To: <69363.1782919477@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi Antonin and Rahila, thanks for working on this, as a user I find this a worthy improvement. >> /* >> + * Some commands have a sub-command, e.g. REPACK (re)builds indexes. Th= e >> + * target can be different, e.g. when the sub-command builds an index o= n >> + * TOAST relation. >> + */ >> + ProgressCommandType st_progress_command2; >> + Oid st_progress_command_target2; >> + int64 st_progress_param2[PGSTAT_NUM_PROGRESS_PARAM]; >>=20 >> This approach only works for a nesting depth of 2, not for 3 or more >> levels of subcommands, for instance. >> I am not aware of a concrete example of such a command but I think we sh= ould >> keep the design generic enough to accommodate this. ... > The typical problem occurs when REPACK performs reindexing (CREATE_INDEX)= . I > could only think of one case where the depth would be more than 2: an ind= ex > function (executed during the build) running another monitored command. I= n a > development build (with my patch applied), such a case would fire an asse= rtion > in pgstat_progress_start_command(), while in a production build that inne= rmost > command would only overwrite the status of the CREATE INDEX command. I do= n't > consider such a crazy case worth more effort. I tend to agree that (for now, at least) a nesting level of 3 is an edge case, but I have another concern with the current approach: @@ -33,9 +37,30 @@ pgstat_progress_start_command(ProgressCommandType cmdtyp= e, Oid relid) return; PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); - beentry->st_progress_command =3D cmdtype; - beentry->st_progress_command_target =3D relid; - MemSet(&beentry->st_progress_param, 0, sizeof(beentry->st_progress_= param)); + /* Sub-command should not be started w/o parent command. */ + if (beentry->st_progress_command =3D=3D PROGRESS_COMMAND_INVALID) + { + Assert(beentry->st_progress_command2 =3D=3D PROGRESS_COMMAN= D_INVALID); + + beentry->st_progress_command =3D cmdtype; + beentry->st_progress_command_target =3D relid; + MemSet(&beentry->st_progress_param, 0, + sizeof(beentry->st_progress_param)); + } + else if (beentry->st_progress_command2 =3D=3D PROGRESS_COMMAND_INVA= LID) + { + Assert(beentry->st_progress_command !=3D PROGRESS_COMMAND_I= NVALID); + + beentry->st_progress_command2 =3D cmdtype; + beentry->st_progress_command_target2 =3D relid; + MemSet(&beentry->st_progress_param2, 0, + sizeof(beentry->st_progress_param2)); + } + else + { + /* Only one level of nesting is supported. */ + Assert(false); + } PGSTAT_END_WRITE_ACTIVITY(beentry); } The comments of the two macros warn about the fact that they create a critical section, and code within the critical section should be kept as simple as possible because any error would be promoted to PANIC. Now sure, Assert() doesn't matter in production builds, but still I think there is value in getting rid of a possible error path. (And a restart to clean up shared memory would be pretty annoying even in debug builds.) Assuming the start()/end() calls are properly nested (which I'd assume they are given the structure of the if/else conditions in start()/end() in this patch), what about the following (names are all strawmen, as this is just a suggestion): - group command, target and params into a new struct, let's say Progress - track the current level of nesting in the beentry, initially 0 - track an array of Progress structs in the beentry, of MAX_NESTING size (2, for now) Then ...start_command() would do something like the following: PGSTAT_BEGIN_WRITE_ACTIVITY(beentry); beentry->nesting++; if beentry->nesting <=3D MAX_NESTING beentry->progress[beentry->nesting-1].command =3D ... ... PGSTAT_END_WRITE_ACTIVITY(beentry); ...end_command() and the update routines would have to reflect this of course, and any reader would have to be changed. Readers would have to go through an accessor that clamps the index to [0,MAX_NESTING) and make this a noop otherwise. One advantage of this would be that it makes the case of an unsupported nesting level a noop, instead of an error. The main advantage would be that the compiler would yell if we forgot to change a reader. While looking into this for example, I ran into some code in vacuumlazy.c (heap_vacuum_rel()) which writes into st_progress_param directly: appendStringInfo(&buf, _("delay time: %.3f ms\n"), (double) MyBEEntry->st_progress_param[PROGRESS_VACUUM_DELAY_TIME] / 1= 000000.0); Purely theoretical of course, but if this was done by code which could run both as a main command or a subcommand, this would end up writing to the wrong spot. Regarding the maximum level of nesting: right now we could say that anything above 2 is not worth the bytes in MyBEEntry, and if we ever encountered a case where it's worth reporting progress of a second subcommand, this could be raised to 3. What do you think, is something like this feasible? Maybe it would address Rahila's point, while not being too much extra work / complex code. Regards, Alberto --=20 Alberto Piai Sensational AG Z=C3=BCrich, Switzerland