Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gxy6c-0001ME-CQ for pgsql-performance@arkaria.postgresql.org; Sun, 24 Feb 2019 18:02:26 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1gxy6b-0000Sr-0U for pgsql-performance@arkaria.postgresql.org; Sun, 24 Feb 2019 18:02:25 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gxy6a-0000Sk-El for pgsql-performance@lists.postgresql.org; Sun, 24 Feb 2019 18:02:24 +0000 Received: from gproxy7-pub.mail.unifiedlayer.com ([70.40.196.235]) by makus.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1gxy6S-0005JW-Rp for pgsql-performance@postgresql.org; Sun, 24 Feb 2019 18:02:22 +0000 Received: from cmgw15.unifiedlayer.com (unknown [10.9.0.15]) by gproxy7.mail.unifiedlayer.com (Postfix) with ESMTP id 0E871216743 for ; Sun, 24 Feb 2019 10:45:40 -0700 (MST) Received: from host214.hostmonster.com ([74.220.215.214]) by cmsmtp with ESMTP id xxqNgIZQ1szDUxxqNgaGMN; Sun, 24 Feb 2019 10:45:40 -0700 X-Authority-Reason: nr=8 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=pragmaticdata.com; s=default; h=Content-Type:In-Reply-To:MIME-Version:Date: Message-ID:References:Cc:Subject:From:Sender:Reply-To:To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=ba77zRLQu/OqRPQtnff4g4SwS23I5r9rkqTQeLF8A1Y=; b=aLSaBzPgsCY+2QJdbPgFy7T9j QsATCqxNqz4WmKx+Xx2AcJfo6aQsie5HXLq4NOAdv88Rm+SeMxwOidcVKtaq2jrE4tSx4TCI5gslx Z4/slZCYlUbzhCm9ri0GX6zJBg; Received: from [45.164.1.33] (port=57168 helo=[192.168.9.7]) by host214.hostmonster.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128) (Exim 4.91) (envelope-from ) id 1gxxqM-001xE9-R5 for pgsql-performance@postgresql.org; Sun, 24 Feb 2019 10:45:39 -0700 From: Gunther Subject: Re: Massive parallel queue table causes index deterioration, but REINDEX fails with deadlocks. Cc: postgres performance list References: <33bae6e3-1c5a-77f0-ee99-408fbf0fbb83@gusw.net> Message-ID: Date: Sun, 24 Feb 2019 12:45:34 -0500 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.5.1 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/alternative; boundary="------------460B8DAE19F93E7BAEC49097" Content-Language: en-US X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - host214.hostmonster.com X-AntiAbuse: Original Domain - postgresql.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - gusw.net X-BWhitelist: no X-Source-IP: 45.164.1.33 X-Source-L: No X-Exim-ID: 1gxxqM-001xE9-R5 X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: ([192.168.9.7]) [45.164.1.33]:57168 X-Source-Auth: gunther+pragmaticdata.com X-Email-Count: 2 X-Source-Cap: cHJhZ21hdDE7cHJhZ21hdDE7aG9zdDIxNC5ob3N0bW9uc3Rlci5jb20= X-Local-Domain: yes List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk This is a multi-part message in MIME format. --------------460B8DAE19F93E7BAEC49097 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Thank you all for responding so far. David Rowley  and Justin Pryzby suggested things about autovacuum. But I don't think autovacuum has any helpful role here. I am explicitly doing a vacuum on that table. And it doesn't help at all. Almost not at all. I want to believe that VACUUM FREEZE Queue; will push the database CPU% down again once it is climbing up, and I can do this may be 3 to 4 times, but ultimately I will always have to rebuild the index. But also, none of these vaccuum operations I do takes very long at all. It is just not efficacious at all. Rebuilding the index by building  a new index and removing the old, then rename, and vacuum again, is prone to get stuck. I tried to do it in a transaction. But it says CREATE INDEX can't be done in a transaction. Need to CREATE INDEX CONCURRENTLY ... and I can't even do that in a procedure. If I do it manually by issuing first CREATE INDEX CONCURRENTLY new and then DROP INDEX CONCURRENTLY old,  it might work once, but usually it just gets stuck with two indexes.  Although I noticed that it would actually put CPU back down and improve transaction throughput. I also noticed that after I quit from DROP INDEX CONCURRENTLY old, that index is shown as INVALID \d Queue ... Indexes: "queue_idx_pending" UNIQUE, btree (jobId, action) WHERE pending INVALID "queue_idx_pending2" UNIQUE, btree (jobId, action) WHERE pending INVALID "queue_idx_pending3" UNIQUE, btree (jobId, action) WHERE pending INVALID "queue_idx_pending4" UNIQUE, btree (jobId, action) WHERE pending INVALID "queue_idx_pending5" UNIQUE, btree (jobId, action) WHERE pending INVALID "queue_idx_pending6" UNIQUE, btree (jobId, action) WHERE pending ... and so I keep doing that same routine hands-on, every time that the CPU% creeps above 50% I do CREATE UNIQUE INDEX CONCURRENTLY Queue_idx_pending6 ON Queue(jobId, action) WHERE currentlyOpen; DROP INDEX CONCURRENTLY Queue_idx_pending5; at which place it hangs, I interrupt the DROP command, which leaves the old index behind as "INVALID". VACUUM FREEZE ANALYZE Queue; At this point the db's CPU% dropping below 20% after the new index has been built. Unfortunately this is totally hands on approach I have to do this every 5 minutes or so. And possibly the time between these necessities decreases. It also leads to inefficiency over time, even despite the CPU seemingly recovering. So this isn't sustainable like that (worse because my Internet constantly drops). What I am most puzzled by is that no matter how long I wait, the DROP INDEX CONCURRENTLY never completes. Why is that? Also, the REINDEX command always fails with a deadlock because there is a row lock and a complete table lock involved. I consider this ultimately a bug, or at the very least there is room for improvement. And I am on version 11.1. regards, -Gunther --------------460B8DAE19F93E7BAEC49097 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 8bit

Thank you all for responding so far.

David Rowley  and Justin Pryzby suggested things about autovacuum. But I don't think autovacuum has any helpful role here. I am explicitly doing a vacuum on that table. And it doesn't help at all. Almost not at all.

I want to believe that

VACUUM FREEZE Queue;

will push the database CPU% down again once it is climbing up, and I can do this may be 3 to 4 times, but ultimately I will always have to rebuild the index. But also, none of these vaccuum operations I do takes very long at all. It is just not efficacious at all.

Rebuilding the index by building  a new index and removing the old, then rename, and vacuum again, is prone to get stuck.

I tried to do it in a transaction. But it says CREATE INDEX can't be done in a transaction.

Need to CREATE INDEX CONCURRENTLY ... and I can't even do that in a procedure.

If I do it manually by issuing first CREATE INDEX CONCURRENTLY new and then DROP INDEX CONCURRENTLY old,  it might work once, but usually it just gets stuck with two indexes.  Although I noticed that it would actually put CPU back down and improve transaction throughput.

I also noticed that after I quit from DROP INDEX CONCURRENTLY old, that index is shown as INVALID

\d Queue
 ...
Indexes:
  "queue_idx_pending" UNIQUE, btree (jobId, action) WHERE pending INVALID
  "queue_idx_pending2" UNIQUE, btree (jobId, action) WHERE pending INVALID
  "queue_idx_pending3" UNIQUE, btree (jobId, action) WHERE pending INVALID
  "queue_idx_pending4" UNIQUE, btree (jobId, action) WHERE pending INVALID
  "queue_idx_pending5" UNIQUE, btree (jobId, action) WHERE pending INVALID
  "queue_idx_pending6" UNIQUE, btree (jobId, action) WHERE pending
...

and so I keep doing that same routine hands-on, every time that the CPU% creeps above 50% I do

CREATE UNIQUE INDEX CONCURRENTLY Queue_idx_pending6 ON Queue(jobId, action) WHERE currentlyOpen;
DROP INDEX CONCURRENTLY Queue_idx_pending5;

at which place it hangs, I interrupt the DROP command, which leaves the old index behind as "INVALID".

VACUUM FREEZE ANALYZE Queue;

At this point the db's CPU% dropping below 20% after the new index has been built.

Unfortunately this is totally hands on approach I have to do this every 5 minutes or so. And possibly the time between these necessities decreases. It also leads to inefficiency over time, even despite the CPU seemingly recovering.

So this isn't sustainable like that (worse because my Internet constantly drops).

What I am most puzzled by is that no matter how long I wait, the DROP INDEX CONCURRENTLY never completes. Why is that?

Also, the REINDEX command always fails with a deadlock because there is a row lock and a complete table lock involved.

I consider this ultimately a bug, or at the very least there is room for improvement. And I am on version 11.1.

regards,
-Gunther
--------------460B8DAE19F93E7BAEC49097--