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 1wmSJF-000nMp-1p for pgsql-hackers@arkaria.postgresql.org; Wed, 22 Jul 2026 08:28:10 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wmSJE-00B1CH-22 for pgsql-hackers@arkaria.postgresql.org; Wed, 22 Jul 2026 08:28:08 +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.96) (envelope-from ) id 1wmSJE-00B1C8-0w for pgsql-hackers@lists.postgresql.org; Wed, 22 Jul 2026 08:28:07 +0000 Received: from mail-wm1-x329.google.com ([2a00:1450:4864:20::329]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1wmSJB-00000000Zj6-2SEB for pgsql-hackers@lists.postgresql.org; Wed, 22 Jul 2026 08:28:07 +0000 Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-49550ec592cso19727615e9.0 for ; Wed, 22 Jul 2026 01:28:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cybertec.at; s=google; t=1784708883; x=1785313683; darn=lists.postgresql.org; h=message-id:date:content-transfer-encoding:content-id:content-type :mime-version:comments:references:in-reply-to:subject:cc:to:from :from:to:cc:subject:date:message-id:reply-to:content-type; bh=7jA6qpnBJi89kxCdS8scWwO6Y3qK90GDVZVgNUOmZ/g=; b=TqaMAzrZjpzjB/LCERxhTZxZkgHTpqKS3s0Ip5cRGaYacIKrFJx2tZlDHhu7/IVb0v wObE1W611ujBJCX1LlTAQ1xKGJB48lDlpSRrFMGKD/QrWG/aXngOI6PupIRKvcM1C8EP qiH5O86+4nWkl9BU6vuDvAMz8YA1ptBgACXwPKF54yr7omzKiG1Aov0j1GZ1VYjXJxVQ CURD4BieADhBr2CnYTrpcuK+R1deQsii4jMZ7dljSAbneqztoA+bvkjaQ6LeeC6Q16as r62whinIOR1Qa1wy9oepArIK0AXpWuS7In86iEcJpguclrJ3heTPqazHfowSL/PPSpJw mk3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1784708883; x=1785313683; h=message-id:date:content-transfer-encoding:content-id:content-type :mime-version:comments:references:in-reply-to:subject:cc:to:from :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to:content-type; bh=7jA6qpnBJi89kxCdS8scWwO6Y3qK90GDVZVgNUOmZ/g=; b=nQeQgJfSA5SdNsyyEcYRfIdQiG26EugMfY6oGTEklQ+d9uYES+3q5Bndga5Cx8Gy+V YbsPa9XGuOLYjJaVJXiLfYZPSyJu7faMxMXpkXKvF4mJwQnvMhhNrgGVcMfd1kou6jQe HQJNDxT2GLOy58kUZtnH7HVfzuEi0BPPhoQo4sk0Up4ta37aQjjYjPgwqbVx9E8VF8nP 7LCgwY092hvosQYTFU8xiHYkAm20+eF94mnNRCceSmdnncqtosNhFRbuBlmV8etpPhvJ nXeBOU3Os4YPmW0Kn+VqO9GgjAuZrbKLJ7zLE6tJ+mlHVBGnXY9J9+WSLZ8UZTd9OiE3 HAhg== X-Forwarded-Encrypted: i=1; AHgh+Rp/TzVmpwwpszjTXBFuH2Ard2VJhxWtfcBnnZWvaoKfTd8By/Z3GSSfLbFW3iLwSwqXMFyuomJ4y/A2EFJL@lists.postgresql.org X-Gm-Message-State: AOJu0YzMvqLdMf1RYiNhmO6dRnd4qisCJabP1RVgTrOcVbAjc/VDqLzV GEbveDnqegSH2Kxc6/mT/39k7G/eTjb5w6ffWAC8IcQZX6ep3IFTal7VNGoCebmodAQ= X-Gm-Gg: AR+sD10HFwxr1hREhr3DSj9Z/F+zCVf0jVfI4OwIjhilJ46gAAYNDWEaEs52b0CBkAC stzG3M1MGi7a+hOatrw/8+htWD9z46QiHSGx/EWF8IAe9qMlMe+QhS+aufbF58UdRwKHokRw/in 2akcEz9y1jwL09fs6Z9KSIe67n31ovj1zPF61Z8I+F95dnXSSaHzfXJ56F3iWJgAQRNIaAGct3+ 0Fvu67HLQnwibxZysLEf/Wo5NUkqCxUgDKnZz0/H4nOGO00K4r0uLCqXGEdrGmmeC3UB11S71jR NMiSwds+oZZFixJDVGJ+xOXlmUljt7Z/crFs634DkqTb6gfLmnvzsnlk0rBNIuYZW4BkjENb6lu f+iibHR5fUmRYz8ir8f7kmdpTAr3G/qyYh6zCE2ZE7HzsRdLSorB8pTX4z/OTFqnz9V84eV+SnI cIJIK4za6vNv2kQJ4= X-Received: by 2002:a05:600c:3510:b0:493:b4a3:5ab0 with SMTP id 5b1f17b1804b1-4956a50fd4cmr30678015e9.13.1784708882667; Wed, 22 Jul 2026 01:28:02 -0700 (PDT) Received: from localhost (109-81-170-190.rct.o2.cz. [109.81.170.190]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4956b01a758sm43241285e9.4.2026.07.22.01.28.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Jul 2026 01:28:02 -0700 (PDT) From: Antonin Houska To: "Alberto Piai" cc: "Rahila Syed" , pgsql-hackers@lists.postgresql.org, bharath.rupireddyforpostgres@gmail.com, mihailnikalayeu@gmail.com, adam8157@gmail.com Subject: Re: Allow progress tracking of sub-commands In-reply-to: References: <106920.1782734246@localhost> <69363.1782919477@localhost> Comments: In-reply-to "Alberto Piai" message dated "Tue, 14 Jul 2026 18:50:53 +0200." X-Mailer: MH-E 8.6+git; nmh 1.8; GNU Emacs 28.3 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <10152.1784708881.1@localhost> Content-Transfer-Encoding: quoted-printable Date: Wed, 22 Jul 2026 10:28:01 +0200 Message-ID: <10153.1784708881@localhost> List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Alberto Piai wrote: > 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.= The > >> + * target can be different, e.g. when the sub-command builds an inde= x on > >> + * TOAST relation. > >> + */ > >> + ProgressCommandType st_progress_command2; > >> + Oid st_progress_command_target2; > >> + int64 st_progress_param2[PGSTAT_NUM_PROGRESS_PARAM]; > >> = > >> 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= should > >> keep the design generic enough to accommodate this. > ... > > The typical problem occurs when REPACK performs reindexing (CREATE_IND= EX). I > > could only think of one case where the depth would be more than 2: an = index > > function (executed during the build) running another monitored command= . In a > > development build (with my patch applied), such a case would fire an a= ssertion > > in pgstat_progress_start_command(), while in a production build that i= nnermost > > command would only overwrite the status of the CREATE INDEX command. I= don'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 cmd= type, 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_progre= ss_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_COM= MAND_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_I= NVALID) > + { > + Assert(beentry->st_progress_command !=3D PROGRESS_COMMAN= D_INVALID); > + > + 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. The patch only adds an if-else construct, but the other lines added are ju= st variants of the existing ones. So I don't think the patch increases the ri= sk of an error ERROR (promoted to PANIC). > (And a restart to clean up shared memory would be pretty annoying even i= n > debug builds.) If Assert() fires, then what I consider annoying is the bug that caused it= , not the restart. Restart could be a problem if I wanted the other regressi= on tests to complete before fixing the bug. However that doesn't make much se= nse to me because all the regression tests should be run again as soon as the = bug is fixed. > 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. Now that I compare my approach to yours, I'm not really opposed to this. T= he fact that the coding is more generic doesn't imply that MAX_NESTING needs = to be very large. > One advantage of this would be that it makes the case of an unsupported > nesting level a noop, instead of an error. I don't see an advantage exactly here: my patch does not raise ERROR, and = I think that Assert() is needed to check the nesting level even if it's implemented in your way. > The main advantage would be that the compiler would yell if we forgot to > change a reader. Not sure I understand the difference. Can you please describe the situatio= n w/o this advantage, i.e. w/o the compiler errors? > 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] = / 1000000.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. This looks like reading rather than writing, but I think I understand what= you mean. > 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. Yes, we should be careful because MAX_NESTING items of the array would be allocated for every single backend. > 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. Yes, I think it's worth at least a prototype. Do you want to adjust my pat= ch yourself or should I do? Thanks for your review anyway! -- = Antonin Houska Web: https://www.cybertec-postgresql.com