Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.80) (envelope-from ) id 1a8oTe-00060Q-AO for pgsql-hackers@arkaria.postgresql.org; Tue, 15 Dec 2015 12:13:10 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84) (envelope-from ) id 1a8oTd-0006h4-LG for pgsql-hackers@arkaria.postgresql.org; Tue, 15 Dec 2015 12:13:09 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84) (envelope-from ) id 1a8oTc-0006gx-Se for pgsql-hackers@postgresql.org; Tue, 15 Dec 2015 12:13:09 +0000 Received: from newmail.postgrespro.ru ([93.174.131.138] helo=mail.postgrespro.ru) by makus.postgresql.org with esmtp (Exim 4.84) (envelope-from ) id 1a8oTV-00080l-Uh for pgsql-hackers@postgresql.org; Tue, 15 Dec 2015 12:13:07 +0000 Received: from fujitsu (unknown [192.168.27.1]) by mail.postgrespro.ru (Postfix) with ESMTPSA id 1EC0E21C4B7C; Tue, 15 Dec 2015 15:13:01 +0300 (MSK) Date: Tue, 15 Dec 2015 15:11:19 +0300 From: Aleksander Alekseev To: Tom Lane Cc: pgsql-hackers@postgresql.org Subject: Re: Patch: fix lock contention for HASHHDR.mutex Message-ID: <20151215151119.1dbd27d1@fujitsu> In-Reply-To: <772.1449847830@sss.pgh.pa.us> References: <20151211170001.78ded9d7@fujitsu> <772.1449847830@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="MP_/Qgr/aJNZjXDJ+6zR1m4kz_D" X-Pg-Spam-Score: -1.9 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org --MP_/Qgr/aJNZjXDJ+6zR1m4kz_D Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Hello, Tom. I was exploring this issue further and discovered something strange. "PROCLOCK hash" and "LOCK hash" are hash tables in shared memory. All memory for these tables is in fact pre-allocated. But for some reason these two tables are created (lock.c:394) with init_size =/= max_size. It causes small overhead on calling memory allocator after hash table creation and additional locking/unlocking. I checked all other hash tables created via ShmemInitHash. All of these tables have init_size == max_size. I suggest to create "PROCLOCK hash" and "LOCK hash" with init_size == max_size too (see attached patch). Granted this change doesn't cause any noticeable performance improvements according to pgbench. Nevertheless it looks like a very right thing to do which at least doesn't make anything worse. If this patch seems to be OK next logical step I believe would be to remove init_size parameter in ShmemInitHash procedure since in practice it always equals max_size. On Fri, 11 Dec 2015 10:30:30 -0500 Tom Lane wrote: > Aleksander Alekseev writes: > > Turns out PostgreSQL can spend a lot of time waiting for a lock in > > this particular place, especially if you are running PostgreSQL on > > 60-core server. Which obviously is a pretty bad sign. > > ... > > I managed to fix this behaviour by modifying choose_nelem_alloc > > procedure in dynahash.c (see attached patch). > > TBH, this is just voodoo. I don't know why this change would have > made any impact on lock acquisition performance, and neither do you, > and the odds are good that it's pure chance that it changed > anything. One likely theory is that you managed to shift around > memory allocations so that something aligned on a cacheline boundary > when it hadn't before. But, of course, the next patch that changes > allocations anywhere in shared memory could change that back. There > are lots of effects like this that appear or disappear based on > seemingly unrelated code changes when you're measuring edge-case > performance. > > The patch is not necessarily bad in itself. As time goes by and > machines get bigger, it can make sense to allocate more memory at a > time to reduce memory management overhead. But arguing for it on the > basis that it fixes lock allocation behavior with 60 cores is just > horsepucky. What you were measuring there was steady-state hash > table behavior, not the speed of the allocate-some-more-memory code > path. > > regards, tom lane > > --MP_/Qgr/aJNZjXDJ+6zR1m4kz_D Content-Type: text/x-patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=lock-contention-v2.patch diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index 76fc615..86d2f88 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -373,16 +373,14 @@ void InitLocks(void) { HASHCTL info; - long init_table_size, - max_table_size; + long shmem_table_size; bool found; /* * Compute init/max size to request for lock hashtables. Note these * calculations must agree with LockShmemSize! */ - max_table_size = NLOCKENTS(); - init_table_size = max_table_size / 2; + shmem_table_size = NLOCKENTS(); /* * Allocate hash table for LOCK structs. This stores per-locked-object @@ -394,14 +392,13 @@ InitLocks(void) info.num_partitions = NUM_LOCK_PARTITIONS; LockMethodLockHash = ShmemInitHash("LOCK hash", - init_table_size, - max_table_size, + shmem_table_size, + shmem_table_size, &info, HASH_ELEM | HASH_BLOBS | HASH_PARTITION); /* Assume an average of 2 holders per lock */ - max_table_size *= 2; - init_table_size *= 2; + shmem_table_size *= 2; /* * Allocate hash table for PROCLOCK structs. This stores @@ -413,8 +410,8 @@ InitLocks(void) info.num_partitions = NUM_LOCK_PARTITIONS; LockMethodProcLockHash = ShmemInitHash("PROCLOCK hash", - init_table_size, - max_table_size, + shmem_table_size, + shmem_table_size, &info, HASH_ELEM | HASH_FUNCTION | HASH_PARTITION); --MP_/Qgr/aJNZjXDJ+6zR1m4kz_D Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers --MP_/Qgr/aJNZjXDJ+6zR1m4kz_D--