Re: Optimize LISTEN/NOTIFY - Mailing list pgsql-hackers

From Chao Li
Subject Re: Optimize LISTEN/NOTIFY
Date
Msg-id 798A8F4A-DC41-4FE9-9BED-38E0DF2193F3@gmail.com
Whole thread Raw
In response to Re: Optimize LISTEN/NOTIFY  ("Joel Jacobson" <joel@compiler.org>)
List pgsql-hackers
Hi Joel,


> On Nov 16, 2025, at 05:53, Joel Jacobson <joel@compiler.org> wrote:
>
> The attached v28 is the same as v27, except some comments have been
> fixed to accurately reflect the code.
>
> /Joel<0001-optimize_listen_notify-v28.patch><0002-optimize_listen_notify-v28.patch>

Thanks for the continuous effort on this patch. Finally, I got some time, after revisiting v28 throughoutly, I think
it’smuch better now. Just got 2 more comments: 

1
```
+    if (asyncQueueControl->channelHashDSH == DSHASH_HANDLE_INVALID)
+    {
+        /* Initialize dynamic shared hash table for channel hash */
+        channelDSA = dsa_create(LWTRANCHE_NOTIFY_CHANNEL_HASH);
+        dsa_pin(channelDSA);
+        dsa_pin_mapping(channelDSA);
+        channelHash = dshash_create(channelDSA, &channelDSHParams, NULL);
+
+        /* Store handles in shared memory for other backends to use */
+        asyncQueueControl->channelHashDSA = dsa_get_handle(channelDSA);
+        asyncQueueControl->channelHashDSH =
+            dshash_get_hash_table_handle(channelHash);
+    }
+    else if (!channelHash)
+    {
+        /* Attach to existing dynamic shared hash table */
+        channelDSA = dsa_attach(asyncQueueControl->channelHashDSA);
+        dsa_pin_mapping(channelDSA);
+        channelHash = dshash_attach(channelDSA, &channelDSHParams,
+                                    asyncQueueControl->channelHashDSH,
+                                    NULL);
+    }
```

DSA is created and pinned by the first backend and every backend isa_in_mapping, but I don’t see any unpin, is it a
problem?If unpin is not needed, why are they provided? 

2
```
+            entry = dshash_find(channelHash, &key, false);
+        }
+
+        if (entry == NULL)
+            continue;            /* No listeners registered for this channel */
+
+        listeners = (ProcNumber *) dsa_get_address(channelDSA,
+                                                   entry->listenersArray);
+
+        for (int j = 0; j < entry->numListeners; j++)
+        {
+            ProcNumber    i = listeners[j];
+            int32        pid;
+            QueuePosition pos;
+
+            if (QUEUE_BACKEND_WAKEUP_PENDING(i))
+                continue;
+
+            pos = QUEUE_BACKEND_POS(i);
+            pid = QUEUE_BACKEND_PID(i);
+
+            /* Skip if caught up */
             if (QUEUE_POS_EQUAL(pos, QUEUE_HEAD))
                 continue;
+
+            Assert(pid != InvalidPid);
+
+            QUEUE_BACKEND_WAKEUP_PENDING(i) = true;
+            pids[count] = pid;
+            procnos[count] = i;
+            count++;
         }
-        else
+
+        dshash_release_lock(channelHash, entry);
```

SignalBackends() now holds the dshash entry lock for long time, while other backend’s LISTEN/UNLISTEN all needs to
acquirethe lock. So, my suggestion is to copy the listeners array to local then quickly release the lock. 


Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/







pgsql-hackers by date:

Previous
From: Nazir Bilal Yavuz
Date:
Subject: Re: Speed up COPY FROM text/CSV parsing using SIMD
Next
From: "Hayato Kuroda (Fujitsu)"
Date:
Subject: RE: Parallel Apply