Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lots of "COMMIT;" in the PostgreSQL log of slow queries

I am trying to optimize the PostgreSQL 9.1 database for a Rails app I am developing. In postgresql.conf I have set

log_min_duration_statement = 200

I then use PgBadger to analyze the log file. The statement which, by far, takes up most of the time is:

COMMIT;

I get no more information than this and I am very confused as to what statement this is. Does anyone know what I can do to get more detailed information about the COMMIT queries? All other queries show the variables used in the statement, SELECT, UPDATE etc. But not the COMMIT queries.

like image 205
lorgartzor Avatar asked Oct 30 '12 08:10

lorgartzor


1 Answers

As @mvp notes, if COMMIT is slow the usual reason is slow fsync()s because every transaction commit must flush data to disk - usually with the fsync() call. That's not the only possible reason for slow commits, though. You might:

  • have slow fsync()s as already noted
  • have slow checkpoints stalling I/O
  • have a commit_delay set - I haven't verified that delayed commits get logged as long running statements, but it seems reasonable

If fsync() is slow, your best option is to re-structure your work so you can run it in fewer larger transactions. A reasonable alternative can be to use a commit_delay to group commits; this will group commits up to improve overall throughput but will actually slow individual transactions down.

Better yet, fix the root of the problem. Upgrade to a RAID controller with battery backed write-back cache or to high-quality SSDs that're power-fail safe. See, ordinary disks can generally do less than one fsync() per rotation, or between 5400 and 15,000 per minute depending on the hard drive. With lots of transactions and lots of commits, that's going to limit your throughput considerably, especially since that's the best case if all they're doing is trivial flushes. By contrast, if you have a durable write cache on a RAID controller or SSD, the OS doesn't need to make sure the data is actually on the hard drive, it only needs to make sure it's reached the durable write cache - which is massively faster because that's usually just some power-protected RAM.

It's possible fsync() isn't the real issue; it could be slow checkpoints. The best way to see is to check the logs to see if there are any complaints about checkpoints happening too frequently or taking too long. You can also enable log_checkpoints to record how long and how frequent checkpoints are.

If checkpoints are taking too long, consider tuning the bgwriter completion target up (see the docs). If they're too frequent, increase checkpoint_segments.

See Tuning your PostgreSQL server for more information.

like image 172
Craig Ringer Avatar answered Oct 28 '22 13:10

Craig Ringer