我一直通过 PostgreSQL 使用 socket.io https://socket.io/docs/v4/postgres-adapter/ (它使用 pg 节点模块和 pool.query )。这已经实现了一些心跳。问题是 NOTIFY 每秒都会在预写日志中触发相当空的提交。
可以避免提交吗?
这很不幸,但我认为这是无法避免的。查看
PreCommit_Notify()
来源:
/*
* Make sure that we have an XID assigned to the current transaction.
* GetCurrentTransactionId is cheap if we already have an XID, but not
* so cheap if we don't, and we'd prefer not to do that work while
* holding NotifyQueueLock.
*/
(void) GetCurrentTransactionId();
/*
* Serialize writers by acquiring a special lock that we hold till
* after commit. This ensures that queue entries appear in commit
* order, and in particular that there are never uncommitted queue
* entries ahead of committed ones, so an uncommitted transaction
* can't block delivery of deliverable notifications.
*
* We use a heavyweight lock so that it'll automatically be released
* after either commit or abort. This also allows deadlocks to be
* detected, though really a deadlock shouldn't be possible here.
*
* The lock is on "database 0", which is pretty ugly but it doesn't
* seem worth inventing a special locktag category just for this.
* (Historical note: before PG 9.0, a similar lock on "database 0" was
* used by the flatfiles mechanism.)
*/
LockSharedObject(DatabaseRelationId, InvalidOid, 0,
AccessExclusiveLock);
锁需要事务 ID,这两个会导致您观察到的 WAL 刷新。
我不知道你在使用
LISTEN
和 NOTIFY
做什么,但也许其他进程间通信方式可以解决这个问题,例如 咨询锁。