@@ -3703,6 +3703,8 @@ CountUserBackends(Oid roleid)
37033703 * backend startup. The caller should normally hold an exclusive lock on the
37043704 * target DB before calling this, which is one reason we mustn't wait
37053705 * indefinitely.
3706+ *
3707+ * If databaseId is InvalidOid, count all non-bgworker backends in a cluster.
37063708 */
37073709bool
37083710CountOtherDBBackends (Oid databaseId , int * nbackends , int * nprepared )
@@ -3732,8 +3734,22 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
37323734 PGPROC * proc = & allProcs [pgprocno ];
37333735 uint8 statusFlags = ProcGlobal -> statusFlags [index ];
37343736
3735- if (proc -> databaseId != databaseId )
3736- continue ;
3737+ if (databaseId != InvalidOid )
3738+ {
3739+ if (proc -> databaseId != databaseId )
3740+ continue ;
3741+ }
3742+ else
3743+ {
3744+ if (proc -> isBackgroundWorker )
3745+ {
3746+ if (proc -> pid == 0 )
3747+ (* nprepared )++ ;
3748+
3749+ continue ; /* do not count background workers */
3750+ }
3751+ }
3752+
37373753 if (proc == MyProc )
37383754 continue ;
37393755
@@ -3781,6 +3797,8 @@ CountOtherDBBackends(Oid databaseId, int *nbackends, int *nprepared)
37813797 *
37823798 * If the target database has a prepared transaction or permissions checks
37833799 * fail for a connection, this fails without terminating anything.
3800+ *
3801+ * If databaseId is InvalidOid, terminate all backends in a cluster.
37843802 */
37853803void
37863804TerminateOtherDBBackends (Oid databaseId )
@@ -3797,7 +3815,7 @@ TerminateOtherDBBackends(Oid databaseId)
37973815 int pgprocno = arrayP -> pgprocnos [i ];
37983816 PGPROC * proc = & allProcs [pgprocno ];
37993817
3800- if (proc -> databaseId != databaseId )
3818+ if (databaseId != InvalidOid && proc -> databaseId != databaseId )
38013819 continue ;
38023820 if (proc == MyProc )
38033821 continue ;
@@ -3811,14 +3829,25 @@ TerminateOtherDBBackends(Oid databaseId)
38113829 LWLockRelease (ProcArrayLock );
38123830
38133831 if (nprepared > 0 )
3814- ereport (ERROR ,
3832+ {
3833+ if (databaseId != InvalidOid )
3834+ ereport (ERROR ,
38153835 (errcode (ERRCODE_OBJECT_IN_USE ),
38163836 errmsg ("database \"%s\" is being used by prepared transactions" ,
38173837 get_database_name (databaseId )),
38183838 errdetail_plural ("There is %d prepared transaction using the database." ,
38193839 "There are %d prepared transactions using the database." ,
38203840 nprepared ,
38213841 nprepared )));
3842+ else
3843+ ereport (ERROR ,
3844+ (errcode (ERRCODE_OBJECT_IN_USE ),
3845+ errmsg ("cluster is being used by prepared transactions" ),
3846+ errdetail_plural ("There is %d prepared transaction using the cluster." ,
3847+ "There are %d prepared transactions using the cluster." ,
3848+ nprepared ,
3849+ nprepared )));
3850+ }
38223851
38233852 if (pids )
38243853 {
0 commit comments