Feb 27 02:57:41 slurm postgres[12345]: [3-1] LOG: automatic vacuum of table "activemq.public.activemq_msgs": index scans: 0
Feb 27 02:57:41 slurm postgres[12345]: [3-2] #011pages: 0 removed, 14002 remain
Feb 27 02:57:41 slurm postgres[12345]: [3-3] #011tuples: 0 removed, 58897 remain
activemq=# select xact_start, query from pg_stat_activity where xact_start is not null and datname='activemq';
xact_start | query
-------------------------------+-----------------------------------------------------------------------------------------------------
2014-02-27 01:24:13.677693+00 | UPDATE ACTIVEMQ_LOCK SET TIME = $1 WHERE ID = 1
If you look at the xact_start timestamp, you'll see that this query has been running since ActiveMQ started. You can also see the locks it creates:
activemq=# select n_live_tup, n_dead_tup, relname, relid from pg_stat_user_tables order by n_dead_tup desc;
n_live_tup | n_dead_tup | relname | relid ------------+------------+---------------+-------
628 | 58903 | activemq_msgs | 16387
4 | 0 | activemq_acks | 16398
1 | 0 | activemq_lock | 16419
activemq=# select locktype, mode from pg_locks where relation = 16419;
locktype | mode
----------+------------------
relation | RowShareLock
relation | RowExclusiveLock
Again, as long as this transaction is running holding the ActiveMQ lock, (auto)vacuum cannot reclaim any dead tuples for this entire database.
Fortunately, ActiveMQ has a workable solution for this problem in version 5.7 and later in the form of the Lease Database Locker. Instead of starting a transaction and blocking forever, instead the master will create a short-lived transaction and lock long enough to try to get a leased lock, which it will periodically renew (with timing that you specify in the configuration; see the ActiveMQ documentation for an example). So long as the lock keeps renewing, the slave won't try to take over. Your failover time, then, depends on the duration of the lease; it won't be nearly-instantaneous as it would in the case of a lock held when ActiveMQ exits (though it could be faster than a transaction ending after a socket times out due to an unclean exit).
Because the locking transactions come and go, rather than persisting forever, the autovacuum process is able to reap your dead tuples.
So the moral of the story is this: if you're using PostgreSQL as the persistent store for ActiveMQ, make sure you configure the Lease Database Locker in your persistenceAdapter configuration. Otherwise, PostgreSQL will never be able to vacuum out old tuples and you may suffer performance degradation and a database that bloats in size forever (or until you stop ActiveMQ, run a vacuum, and restart it).