Skip to content

Contention in NpgsqlConnection.GetPoolAndSettings #1749

@shortspider

Description

@shortspider

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:

image

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions