Report
Description
On a replica set with a large number of databases/collections (multi-tenant: hundreds of karam_* DBs), logical backup fails in ~32 seconds during getNamespacesSize(), before any dump/upload.
collStats is launched with an unbounded errgroup (one goroutine per collection). The agent Mongo client uses the Go driver default maxPoolSize: 100. The pool fills (idle connections: 0), the next collStats waits exactly 30s, then:
get namespaces size: collStats ".": timed out while checking out a connection from connection pool: context deadline exceeded; total connections: 87–100, maxPoolSize: 100, idle connections: 0, wait duration: 30.000s
Raising backup.timeouts.startingStatus to 2700 does not help. In v2.15.0 doLogical(), getNamespacesSize() runs before reconcileStatus(..., StartingStatus()). The 30s deadline is the driver/pool checkout, not startingStatus.
backup.numParallelCollections also does not help — it applies only to the dump phase, not to getNamespacesSize().
Steps to reproduce
- Replica set with a large namespace count (thousands of collections across many DBs).
- PBM 2.15.0, default agent URI (no
maxPoolSize / timeoutMS / waitQueueTimeoutMS).
pbm config --set backup.timeouts.startingStatus=2700
pbm backup --type=logical --compression=s2
Expected
Logical backup completes. Size-hint collection (getNamespacesSize) should be concurrency-limited (e.g. errgroup.SetLimit using numParallelCollections or a dedicated setting) so it cannot open more in-flight collStats than maxPoolSize.
startingStatus should either wrap this phase or docs should not imply it covers collStats metadata collection when the pool wait is a separate 30s timeout.
Actual
Backup fails at ~32s with the pool timeout above. Snapshot size 0.00B. startingStatus: 2700 is present in pbm config and is never reached.
Environment
- PBM: 2.15.0 (
percona/percona-backup-mongodb:2.15.0)
- MongoDB: Percona Server for MongoDB 8.0.12-4
- Topology: 3-node replica set (no sharding)
- Operator: PSMDB Operator 1.23.0 (sidecar agent)
- Agent URI:
mongodb://...@localhost:27017/?tls=true&... (no pool/timeout params)
- Backup runs on a secondary (default priorities; no
backup.priority)
Code references (v2.15.0)
Suggested fix
In getNamespacesSize, after each errgroup.WithContext:
eg.SetLimit(n) // n = numParallelCollections or a new backup.numParallelCollStats (default <= maxPoolSize, e.g. 8)
Alternatively skip or serialize collStats (size hints are optional for upload). Increasing maxPoolSize alone is not a complete fix if concurrency stays unbounded.
### More about the problem
Starting backup "2026-09-03T22:32:25Z"................................Error: wait for backup status: get namespaces size: collStats "karam_541561215sacsc.imap_messages": timed out while checking out a connection from connection pool: context deadline exceeded; total connections: 87, maxPoolSize: 100, idle connections: 0, wait duration: 30.000006854s
### Steps to reproduce
1.Replica set with a large namespace count (thousands of collections across many DBs).
2.PBM 2.15.0, default agent URI (no maxPoolSize / timeoutMS / waitQueueTimeoutMS).
3.pbm config --set backup.timeouts.startingStatus=2700
4.pbm backup --type=logical --compression=s2
### Versions
1. Kubernetes v1.34.10
2. Operator 1.23.0
3. Database MongoDB 8.0.12-4
### Anything else?
_No response_
Report
Description
On a replica set with a large number of databases/collections (multi-tenant: hundreds of
karam_*DBs), logical backup fails in ~32 seconds duringgetNamespacesSize(), before any dump/upload.collStatsis launched with an unboundederrgroup(one goroutine per collection). The agent Mongo client uses the Go driver defaultmaxPoolSize: 100. The pool fills (idle connections: 0), the nextcollStatswaits exactly 30s, then:get namespaces size: collStats ".": timed out while checking out a connection from connection pool: context deadline exceeded; total connections: 87–100, maxPoolSize: 100, idle connections: 0, wait duration: 30.000s
Raising
backup.timeouts.startingStatusto 2700 does not help. In v2.15.0doLogical(),getNamespacesSize()runs beforereconcileStatus(..., StartingStatus()). The 30s deadline is the driver/pool checkout, notstartingStatus.backup.numParallelCollectionsalso does not help — it applies only to the dump phase, not togetNamespacesSize().Steps to reproduce
maxPoolSize/timeoutMS/waitQueueTimeoutMS).pbm config --set backup.timeouts.startingStatus=2700pbm backup --type=logical --compression=s2Expected
Logical backup completes. Size-hint collection (
getNamespacesSize) should be concurrency-limited (e.g.errgroup.SetLimitusingnumParallelCollectionsor a dedicated setting) so it cannot open more in-flightcollStatsthanmaxPoolSize.startingStatusshould either wrap this phase or docs should not imply it coverscollStatsmetadata collection when the pool wait is a separate 30s timeout.Actual
Backup fails at ~32s with the pool timeout above. Snapshot size
0.00B.startingStatus: 2700is present inpbm configand is never reached.Environment
percona/percona-backup-mongodb:2.15.0)mongodb://...@localhost:27017/?tls=true&...(no pool/timeout params)backup.priority)Code references (v2.15.0)
getNamespacesSize)startingStatusapplied only after size scan: same file,doLogical()→reconcileStatus(..., StartingStatus())SetMaxPoolSize/SetWaitQueueTimeout: https://github.com/percona/percona-backup-mongodb/blob/v2.15.0/pbm/connect/connect.goWaitBackupStart= 33s inpbm/defs/defs.go(not the timer that fired)Suggested fix
In
getNamespacesSize, after eacherrgroup.WithContext: