Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.92) (envelope-from ) id 1jDiXY-0005xw-PB for pgsql-hackers@arkaria.postgresql.org; Mon, 16 Mar 2020 05:43:53 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1jDiXV-0003jD-BS for pgsql-hackers@arkaria.postgresql.org; Mon, 16 Mar 2020 05:43:49 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1jDiXU-0003j5-RM for pgsql-hackers@lists.postgresql.org; Mon, 16 Mar 2020 05:43:49 +0000 Received: from mail-qv1-xf44.google.com ([2607:f8b0:4864:20::f44]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1jDiXR-00054B-E1 for pgsql-hackers@lists.postgresql.org; Mon, 16 Mar 2020 05:43:47 +0000 Received: by mail-qv1-xf44.google.com with SMTP id v38so4153734qvf.6 for ; Sun, 15 Mar 2020 22:43:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=telsasoft-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=Q+MMxF/tnLqgI/vfgNCFgfs2iM+7AJrX4xe0mzVkFMU=; b=nSVlSTyuZJvt3U/Wf+U3r6J4vpNUIlfu/L3AxrFvH8JlQwehSrWkh0lYgVA60nxRDY YyQXPU6usXnY5BnnPGaD0Xxl9o/ip3MZPHgWH9v079tY2X0OF0Zm7qNwOMGUTf2PDcOP CwhRQh3CPeyr2g5ASqe77N0MGkB6Mi9o/F80D9aHKSWszGjYeWKiiaHu0uTrV8bo89fK gH2aZh8hIEx+rbNfKgFCLZ3+V0a7Oyg0SwAY3D71mBiH1dcvVWyjBVJQDPEsbF99wybN 1Z8MPt5dCUvUa71dgml5VZ3mzNXDVu9+66NbWgE82MFnxIhqC3PZA/BkgM6TqqMNWR77 RaLA== 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=Q+MMxF/tnLqgI/vfgNCFgfs2iM+7AJrX4xe0mzVkFMU=; b=KJy9BcrjMOzyZ3EVVb79D+lQkcC2v+HrKAMC1z8lnTgb++XYwulBzJkd+s7KjIPHEM /VjlYXAphDzZzpFzBWNz0wenvmc8kdf26iziZKPIOuqKuFa/edEkDSfj+/ARQqm6yb0J h+Xuc1WA2f9R3fyXT63AW9sX1WMD8v0CjDUv4s0HnsGK6Uts5Ch/u5AY+YX4iNPRXgIj T3pLLm9ZEVXfMwx/9Q0VKlzJM0lH4yH18FL+CKGb1zaqx6bhee7JQ+p1YPm20JgTxvmH /S+qyGQo2GiCXblHZUeWZlQJoMGT2bUD2kCrl7oUAgtIOV3TSXm0Wx8V6oMVHv+5hjf+ rK8Q== X-Gm-Message-State: ANhLgQ30hK7N6l8hUuq0MHKjbJgxNPxJhXDAz3AdgKlCbNsGwFmyrRjJ hiGtdfc2aOCiQsjDKi3DkAoFQg== X-Google-Smtp-Source: ADFU+vsZx5R9PZV6JvXSJ5occKp1HMY68/vSZX0Z4o2mc2tzxNDI9Lh7zac9zUzmdKHABvkBa12sfQ== X-Received: by 2002:a05:6214:1863:: with SMTP id eh3mr18690334qvb.204.1584337424440; Sun, 15 Mar 2020 22:43:44 -0700 (PDT) Received: from pryzbyj (charmander.telsasoft.com. [50.244.222.1]) by smtp.gmail.com with ESMTPSA id m92sm9027353qtd.94.2020.03.15.22.43.43 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 15 Mar 2020 22:43:43 -0700 (PDT) Received: by pryzbyj (Postfix, from userid 1000) id 0EE55800F98; Mon, 16 Mar 2020 00:43:42 -0500 (CDT) Date: Mon, 16 Mar 2020 00:43:41 -0500 From: Justin Pryzby To: Julien Rouhaud , Michael Paquier Cc: Sergei Kornilov , Guillaume Lelarge , pgsql-hackers@lists.postgresql.org Subject: Re: Expose lock group leader pid in pg_stat_activity Message-ID: <20200316054341.GG26184@telsasoft.com> References: <20200116074912.GA98418@paquier.xyz> <20200316042752.GE26184@telsasoft.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200316042752.GE26184@telsasoft.com> User-Agent: Mutt/1.9.4 (2018-02-28) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On Sun, Mar 15, 2020 at 11:27:52PM -0500, Justin Pryzby wrote: > On Tue, Jan 28, 2020 at 12:36:41PM +0100, Julien Rouhaud wrote: > > So, AFAICT the LockHashPartitionLockByProc is required when > > iterating/modifying lockGroupMembers or lockGroupLink, but just > > getting the leader pid should be safe. > > This still seems unsafe: > > git show -U11 -w --patience b025f32e0b src/backend/utils/adt/pgstatfuncs.c > + /* > + * If a PGPROC entry was retrieved, display wait events and lock > + * group leader information if any. To avoid extra overhead, no > + * extra lock is being held, so there is no guarantee of > + * consistency across multiple rows. > + */ > ... > + PGPROC *leader; > ... > + leader = proc->lockGroupLeader; > + if (leader) > + { > # does something guarantee that leader doesn't change ? > + values[29] = Int32GetDatum(leader->pid); > + nulls[29] = false; > } > > Michael seems to have raised the issue: > > On Thu, Jan 16, 2020 at 04:49:12PM +0900, Michael Paquier wrote: > > And actually, the way you are looking at the leader's PID is visibly > > incorrect and inconsistent because the patch takes no shared LWLock on > > the leader using LockHashPartitionLockByProc() followed by > > LWLockAcquire(), no? That's incorrect because it could be perfectly > > possible to crash with this code between the moment you check if > > lockGroupLeader is NULL and the moment you look at > > lockGroupLeader->pid if a process is being stopped in-between and > > removes itself from a lock group in ProcKill(). > > But I don't see how it was addressed ? > > I read this: > > src/backend/storage/lmgr/lock.c: * completely valid. We cannot safely dereference another backend's > src/backend/storage/lmgr/lock.c- * lockGroupLeader field without holding all lock partition locks, and > src/backend/storage/lmgr/lock.c- * it's not worth that.) > > I think if you do: > |LWLockAcquire(&proc->backendLock, LW_SHARED); > ..then it's at least *safe* to access leader->pid, but it may be inconsistent > unless you also call LockHashPartitionLockByProc. > > I wasn't able to produce a crash, so maybe I missed something. I think I see. Julien's v3 patch did this: https://www.postgresql.org/message-id/attachment/106429/pgsa_leader_pid-v3.diff + if (proc->lockGroupLeader) + values[29] = Int32GetDatum(proc->lockGroupLeader->pid); ..which is racy because a proc with a leader might die and be replaced by another proc without a leader between 1 and 2. But the code since v4 does: + leader = proc->lockGroupLeader; + if (leader) + values[29] = Int32GetDatum(leader->pid); ..which is safe because PROCs are allocated in shared memory, so leader is for sure a non-NULL pointer to a PROC. leader->pid may be read inconsistently, which is what the comment says: "no extra lock is being held". -- Justin