-
Notifications
You must be signed in to change notification settings - Fork 874
Contention in NpgsqlConnection.GetPoolAndSettings #1749
Description
Steps to reproduce
Run 15000 queries/second on a database with multiple connection pools. CPU will be abnormally high due to contention on a lock to get connection pools.
The issue
On one of our highest traffic databases we have a number of connection pools. In tracking down some recent high CPU issues with perfview we found the following:
What this shows is that ~64% of CPU time was being spent contending for a lock in NpgsqlConnection.GetPoolAndSettings. Looking at that method I can see it's a global (process wide) lock around the dictionary of connection strings to connection pools.
I believe this can be improved by using a ConcurrentDictionary instead of a normal dictionary and a lock. The ConcurrentDictionary will allow for lockless reads (so TryGetValue will take no locks) and when adding/updating a value only the one spicific key will be locked, so traffic to get pool A will not affect people trying to get pool B.
What do you think? If you agree I'd like to submit a PR to implement this.
Further technical details
Npgsql version: 3.2.5
PostgreSQL version: 9.6.2
Operating system: Windows Server 2012 R2
