From: | Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> |
---|---|
To: | Alena Rybakina <a(dot)rybakina(at)postgrespro(dot)ru> |
Cc: | PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org> |
Subject: | Re: Not deleted mentions of the cleared path |
Date: | 2023-10-30 14:36:13 |
Message-ID: | CAExHW5uhc5JVOUExjo24oYLLcJAyD04+BRb080sV08pO_=7w=A@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
On Mon, Oct 30, 2023 at 5:01 PM Alena Rybakina
<a(dot)rybakina(at)postgrespro(dot)ru> wrote:
>
> Hi, hackers!
>
> I have already written about the problem of InvalidPath [0] appearing. I investigated this and found an error in the add_path() function, when we reject a path, we free up the memory of the path, but do not delete various mentions of it (for example, in the ancestor of relation, as in the example below).
>
> Thus, we may face the problem of accessing the freed memory.
>
> I demonstrated this below using gdb when I call a query after running a test in test/regression/sql/create_misc.sql:
>
> Query:
>
> :-- That ALTER TABLE should have added TOAST tables.
>
> SELECT relname, reltoastrelid <> 0 AS has_toast_table
> FROM pg_class
> WHERE oid::regclass IN ('a_star', 'c_star')
> ORDER BY 1;
>
> --UPDATE b_star*
> -- SET a = text 'gazpacho'
> -- WHERE aa > 4;
>
> SELECT class, aa, a FROM a_star*;
>
>
> gdb:
>
> 0x00007ff3f7325fda in epoll_wait (epfd=5, events=0x55bf9ee75c38, maxevents=1, timeout=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
> 30 ../sysdeps/unix/sysv/linux/epoll_wait.c: No such file or directory.
> (gdb) b /home/alena/postgrespro_3/src/backend/optimizer/util/pathnode.c:620
> Breakpoint 1 at 0x55bf9cfe4c65: file pathnode.c, line 621.
> (gdb) c
> Continuing.
>
> Breakpoint 1, add_path (parent_rel=0x55bf9ef7f5c0, new_path=0x55bf9ef7f4e0) at pathnode.c:621
> 621 if (!IsA(new_path, IndexPath))
> (gdb) n
> 622 pfree(new_path);
> (gdb) n
> 624 }
> (gdb) p *new_path
> $1 = {type = T_Invalid, pathtype = T_Invalid, parent = 0x7f7f7f7f7f7f7f7f, pathtarget = 0x7f7f7f7f7f7f7f7f,
> param_info = 0x7f7f7f7f7f7f7f7f, parallel_aware = 127, parallel_safe = 127, parallel_workers = 2139062143,
> rows = 1.3824172084878715e+306, startup_cost = 1.3824172084878715e+306, total_cost = 1.3824172084878715e+306,
> pathkeys = 0x7f7f7f7f7f7f7f7f}
> (gdb) p new_path
> $2 = (Path *) 0x55bf9ef7f4e0
At this point the new_path has not been added to the parent_rel. We do
not set the cheapest* paths while paths are being added. The stack
trace will give you an idea where this is happening.
>
> (gdb) p ((ProjectionPath *)((SortPath*)parent_rel->pathlist->elements [0].ptr_value)->subpath)->path->parent->cheapest_startup_path
> $20 = (struct Path *) 0x55bf9ef7f4e0
This looks familiar though. There was some nearby thread where Tom
Lane, if my memory serves well, provided a case where a path from
lower rel was added to an upper rel without copying or changing its
parent. This very much looks like that case.
--
Best Wishes,
Ashutosh Bapat
From | Date | Subject | |
---|---|---|---|
Next Message | Ashutosh Bapat | 2023-10-30 14:43:30 | Re: Report planning memory in EXPLAIN ANALYZE |
Previous Message | hubert depesz lubaczewski | 2023-10-30 14:14:16 | Re: pgBufferUsage.blk_{read|write}_time are zero although there are pgBufferUsage.local_blks_{read|written} |