8

I am getting this error:

'could not obtain a database connection within 5 seconds (waited 5.001017 seconds). The max pool size is currently 16; consider increasing it.'

First I got this error, I bumped up the count from 5 to 16. But it's still happening and i am the only one test out the database. Why is this happening when I am the only user?

I am not on rails btw. I am using:

ActiveRecord::Base.establish_connection ({
    :adapter => 'mysql2',
    :database => 'ck',
    :host => 'localhost',
    :username => 'root',
    :password => '',
    :pool => 16,
    })

and using Sinatra.

Thanks

0xSina
  • 20,973
  • 34
  • 136
  • 253

4 Answers4

12

As Frederick pointed out you need to return opened ActiveRecord connections to the connection pool.

If you're using the Thin server, in threaded mode, then you need to add this to your Sinatra app:

after do
  ActiveRecord::Base.connection.close
end

...instead of using the ConnectionManagement suggestion. The reason is that Thin splits the request processing over 2 threads and the thread that is closing the ActiveRecord connection is not the same as the thread that opened it. As ActiveRecord tracks connections by thread ID it gets confused and won't return connections correctly.

kuwerty
  • 380
  • 4
  • 4
  • @squixy - put this in whatever class in your app extends `Sinatra::Base` – Ramfjord Mar 23 '15 at 19:20
  • 3
    Is there a reason you are using `ActiveRecord::Base.connection.close` instead of `ActiveRecord::Base.clear_active_connections!` as specified in the [docs](http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/ConnectionPool.html)? Is this simply out of date? – Ramfjord Mar 23 '15 at 23:08
5

It sounds like you are not returning connections to the pool at the end of the request. If not then each request that uses the db will consume 1 connection and eventually you'll exhaust the pool and start getting the error messages you describe

Active Record provides a rack middleware to handle this ActiveRecord::ConnectionAdapters::ConnectionManagement, which should take care of things as long as its earlier in the middleware chain than anything that will access active record.

You can also take care of the connection management yourself. The docs have more details but one way of doing it is sticking all of your db accesses in a block like this

ActiveRecord::Base.connection_pool.with_connection do
  ...
end

Which checks out a connection at the start of the block and checks it back in afterwards.

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
1

It's better to use the middleware provided with ActiveRecord:

use ActiveRecord::ConnectionAdapters::ConnectionManagement
Richard Nienaber
  • 10,324
  • 6
  • 55
  • 66
0

As Frederick pointed out you need to return opened ActiveRecord connections to the connection pool.

As kuwerty suggests, when you are using Thin, ConnectionManagement will not return connections to the pool. I suggest that instead of closing the current connection like kuwerty says, you return the connection to the pool like so.

after do
  ActiveRecord::Base.clear_active_connections!
end

For those who want to reproduce the problem, try this example.

EDIT:

I made an explanation of why using middleware ActiveRecord::Connectionadapters::ConnectionManagement won't work with Thin in threaded mode, which you can find here.

Community
  • 1
  • 1
mrrusof
  • 362
  • 2
  • 8