On Wed, 24 Jul 2019 at 16:16, David Rowley <david.row...@2ndquadrant.com> wrote: > > On Wed, 24 Jul 2019 at 15:05, David Rowley <david.row...@2ndquadrant.com> > wrote: > > To be able to reduce the threshold down again we'd need to make a > > hash_get_num_entries(LockMethodLocalHash) call before performing the > > guts of LockReleaseAll(). We could then weight that onto some running > > average counter with a weight of, say... 10, so we react to changes > > fairly quickly, but not instantly. We could then have some sort of > > logic like "rebuild the hash table if running average 4 times less > > than max_bucket" > > > > I've attached a spreadsheet of that idea and the algorithm we could > > use to track the running average. Initially, I've mocked it up a > > series of transactions that use 1000 locks, then at row 123 dropped > > that to 10 locks. If we assume the max_bucket is 1000, then it takes > > until row 136 for the running average to drop below the max_bucket > > count, i.e 13 xacts. There we'd reset there at the init size of 16. If > > the average went up again, then we'd automatically expand the table as > > we do now. To make this work we'd need an additional call to > > hash_get_num_entries(), before we release the locks, so there is more > > overhead. > > Here's a patch with this implemented. I've left a NOTICE in there to > make it easier for people to follow along at home and see when the > lock table is reset.
Here's a more polished version with the debug code removed, complete with benchmarks. -- Test 1. Select 1 record from a 140 partitioned table. Tests creating a large number of locks with a fast query. create table hp (a int, b int) partition by hash(a); select 'create table hp'||x||' partition of hp for values with (modulus 140, remainder ' || x || ');' from generate_series(0,139)x; create index on hp (b); insert into hp select x,x from generate_series(1, 140000) x; analyze hp; select3.sql: select * from hp where b = 1 - Master: $ pgbench -n -f select3.sql -T 60 -M prepared postgres tps = 2098.628975 (excluding connections establishing) tps = 2101.797672 (excluding connections establishing) tps = 2085.317292 (excluding connections establishing) tps = 2094.931999 (excluding connections establishing) tps = 2092.328908 (excluding connections establishing) Patched: $ pgbench -n -f select3.sql -T 60 -M prepared postgres tps = 2101.691459 (excluding connections establishing) tps = 2104.533249 (excluding connections establishing) tps = 2106.499123 (excluding connections establishing) tps = 2104.033459 (excluding connections establishing) tps = 2105.463629 (excluding connections establishing) (I'm surprised there is not more overhead in the additional tracking added to calculate the running average) -- Test 2. Tests a prepared query which will perform a generic plan on the 6th execution then fallback on a custom plan due to it pruning all but one partition. Master suffers from the lock table becoming bloated after locking all partitions when planning the generic plan. create table ht (a int primary key, b int, c int) partition by hash (a); select 'create table ht' || x::text || ' partition of ht for values with (modulus 8192, remainder ' || (x)::text || ');' from generate_series(0,8191) x; \gexec select.sql: \set p 1 select * from ht where a = :p Master: $ pgbench -n -f select.sql -T 60 -M prepared postgres tps = 10207.780843 (excluding connections establishing) tps = 10205.772688 (excluding connections establishing) tps = 10214.896449 (excluding connections establishing) tps = 10157.572153 (excluding connections establishing) tps = 10147.764477 (excluding connections establishing) Patched: $ pgbench -n -f select.sql -T 60 -M prepared postgres tps = 14677.636570 (excluding connections establishing) tps = 14661.437186 (excluding connections establishing) tps = 14647.202877 (excluding connections establishing) tps = 14784.165753 (excluding connections establishing) tps = 14850.355344 (excluding connections establishing) -- David Rowley http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
shrink_bloated_locallocktable_v8.patch
Description: Binary data