Re: logical decoding : exceeded maxAllocatedDescs for .spill files - Mailing list pgsql-hackers
From | Amit Kapila |
---|---|
Subject | Re: logical decoding : exceeded maxAllocatedDescs for .spill files |
Date | |
Msg-id | CAA4eK1+vrHbCzbk7VvELvzy_9wfeJf8hoUZQQyUOhE750hWTDw@mail.gmail.com Whole thread Raw |
In response to | Re: logical decoding : exceeded maxAllocatedDescs for .spill files (Kuntal Ghosh <kuntalghosh.2007@gmail.com>) |
Responses |
Re: logical decoding : exceeded maxAllocatedDescs for .spill files
|
List | pgsql-hackers |
On Tue, Feb 4, 2020 at 10:15 AM Kuntal Ghosh <kuntalghosh.2007@gmail.com> wrote: > > On Sun, Jan 12, 2020 at 9:51 AM Tom Lane <tgl@sss.pgh.pa.us> wrote: > > > > Tomas Vondra <tomas.vondra@2ndquadrant.com> writes: > > > On Sat, Jan 11, 2020 at 10:53:57PM -0500, Tom Lane wrote: > > >> remind me where the win came from, exactly? > > > > > Well, the problem is that in 10 we allocate tuple data in the main > > > memory ReorderBuffer context, and when the transaction gets decoded we > > > pfree() it. But in AllocSet that only moves the data to the freelists, > > > it does not release it entirely. So with the right allocation pattern > > > (sufficiently diverse chunk sizes) this can easily result in allocation > > > of large amount of memory that is never released. > > > > > I don't know if this is what's happening in this particular test, but I > > > wouldn't be surprised by it. > > > > Nah, don't think I believe that: the test inserts a bunch of tuples, > > but they look like they will all be *exactly* the same size. > > > > CREATE TABLE decoding_test(x integer, y text); > > ... > > > > FOR i IN 1..10 LOOP > > BEGIN > > INSERT INTO decoding_test(x) SELECT generate_series(1,5000); > > EXCEPTION > > when division_by_zero then perform 'dummy'; > > END; > > > I performed the same test in pg11 and reproduced the issue on the > commit prior to a4ccc1cef5a04 (Generational memory allocator). > > ulimit -s 1024 > ulimit -v 300000 > > wal_level = logical > max_replication_slots = 4 > > And executed the following code snippet (shared by Amit Khandekar > earlier in the thread). > .. > > SELECT data from pg_logical_slot_get_changes('test_slot', NULL, NULL) LIMIT 10; > > I got the following error: > ERROR: out of memory > DETAIL: Failed on request of size 8208. > > After that, I applied the "Generational memory allocator" patch and > that solved the issue. From the error message, it is evident that the > underlying code is trying to allocate a MaxTupleSize memory for each > tuple. So, I re-introduced the following lines (which are removed by > a4ccc1cef5a04) on top of the patch: > > --- a/src/backend/replication/logical/reorderbuffer.c > +++ b/src/backend/replication/logical/reorderbuffer.c > @@ -417,6 +417,9 @@ ReorderBufferGetTupleBuf(ReorderBuffer *rb, Size tuple_len) > > alloc_len = tuple_len + SizeofHeapTupleHeader; > > + if (alloc_len < MaxHeapTupleSize) > + alloc_len = MaxHeapTupleSize; > > And, the issue got reproduced with the same error: > WARNING: problem in Generation Tuples: number of free chunks 0 in > block 0x7fe9e9e74010 exceeds 1018 allocated > ..... > ERROR: out of memory > DETAIL: Failed on request of size 8208. > > I don't understand the code well enough to comment whether we can > back-patch only this part of the code. > I don't think we can just back-patch that part of code as it is linked to the way we are maintaining a cache (~8MB) for frequently allocated objects. See the comments around the definition of max_cached_tuplebufs. But probably, we can do something once we reach such a limit, basically, once we know that we have already allocated max_cached_tuplebufs number of tuples of size MaxHeapTupleSize, we don't need to allocate more of that size. Does this make sense? -- With Regards, Amit Kapila. EnterpriseDB: http://www.enterprisedb.com
pgsql-hackers by date: