Обсуждение: [HACKERS] CREATE/DROP table in transactional block.

Поиск
Список
Период
Сортировка

[HACKERS] CREATE/DROP table in transactional block.

От
Robson Paniago de Miranda
Дата:
I had a problem creating a table and dropping it in the same
transactional block. After doing that, I had some serious corruptions in
database (i.e. a table was empty before, and, after this transaction,
the backend dumps core when I try a SELECT * from table, and a SELECT
COUNT (*) from table returns a false value (the last I saw was 18...).
    This is a bug or I really can't create and drop a table in the same
transaction?

    Robson.

------------------------------

Re: [HACKERS] CREATE/DROP table in transactional block.

От
"Vadim B. Mikheev"
Дата:
Robson Paniago de Miranda wrote:
>
> I had a problem creating a table and dropping it in the same
> transactional block. After doing that, I had some serious corruptions in
> database (i.e. a table was empty before, and, after this transaction,
> the backend dumps core when I try a SELECT * from table, and a SELECT
> COUNT (*) from table returns a false value (the last I saw was 18...).
>         This is a bug or I really can't create and drop a table in the same
> transaction?

My fault: I added smgrclose to RelationPurgeLocalRelation, but if
local relation already unlinked then it makes SMGR/VFD inconsistent.
Actually problem was in heap.c:heap_destroy():

    /* ----------------
     *  flush the relation from the relcache
     * ----------------
     */
    RelationIdInvalidateRelationCacheByRelationId(rdesc->rd_id);

- - it does nothing here! Neither for local nor for shared relations.
   I added new function into relcache.c which flushes relation from
the relcache and, if relation is local, get rid of the relation from
the newly created relation list - so RelationPurgeLocalRelation
will not see dropped local relations.
   Rule is simple: smgrclose/smgrunlink have to be used together
with flushing relation from the cache!

   It also fixes the next problem:

vac=> \i xxx
begin;
BEGIN
create table test (x int, y int);
CREATE
drop table test;
DROP
select * from ttt;        -- just to get abort
WARN:ttt: Table does not exist.
EOF
vac=> abort;
WARN:cannot unlink test        -- already unlinked, so abort aborted!
vac=> abort;            -- only second abort helps
NOTICE:UserAbortTransactionBlock and not in in-progress state
ABORT

Vadim

------------------------------