From: | Andres Freund <andres(at)anarazel(dot)de> |
---|---|
To: | pgsql-bugs(at)postgresql(dot)org |
Cc: | Alvaro Herrera <alvherre(at)commandprompt(dot)com>, Greg Sabino Mullane <greg(at)endpoint(dot)com> |
Subject: | Re: Unlogged tables cannot be truncated twice |
Date: | 2011-05-30 23:28:37 |
Message-ID: | 201105310128.37288.andres@anarazel.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
On Monday, May 30, 2011 11:18:20 PM Alvaro Herrera wrote:
> Excerpts from Greg Sabino Mullane's message of lun may 30 12:00:43 -0400
2011:
> > Wow, this one took a bit to narrow down. Here's the failing case:
> >
> > # create unlogged table foo (a text);
> > CREATE TABLE
> > # begin;
> > BEGIN
> > #* truncate table foo;
> > TRUNCATE TABLE
> > #* truncate table foo;
> > ERROR: could not create file "base/19131/19183_init": File exists
> >
> > Very reproducible. The column types matter: if the only column
> > is an INT, for example, the problem does not occur.
>
> So 19183 is the toast table OID?
Nope. Its any index.
You can provoke it with:
begin;create unlogged table foo (a int primary key);truncate foo;rollback;
or
begin;create unlogged table foo (a text);truncate foo;rollback;
The problem is this tidbit from tablecmds.c's ExecuteTruncate:
/*
* Normally, we need a transaction-safe truncation here. However, if
* the table was either created in the current (sub)transaction or has
* a new relfilenode in the current (sub)transaction, then we can just
* truncate it in-place, because a rollback would cause the whole
* table or the current physical file to be thrown away anyway.
*/
if (rel->rd_createSubid == mySubid ||
rel->rd_newRelfilenodeSubid == mySubid)
{
/* Immediate, non-rollbackable truncation is OK */
heap_truncate_one_rel(rel);
}
in combination with index.c's index_build:
/*
* If this is an unlogged index, we need to write out an init fork for it.
*/
if (heapRelation->rd_rel->relpersistence == RELPERSISTENCE_UNLOGGED)
{
RegProcedure ambuildempty = indexRelation->rd_am->ambuildempty;
RelationOpenSmgr(indexRelation);
smgrcreate(indexRelation->rd_smgr, INIT_FORKNUM, false);
OidFunctionCall1(ambuildempty, PointerGetDatum(indexRelation));
}
Andres
From | Date | Subject | |
---|---|---|---|
Next Message | Cédric Villemain | 2011-05-30 23:56:05 | Re: Unlogged tables cannot be truncated twice |
Previous Message | Alvaro Herrera | 2011-05-30 21:18:20 | Re: Unlogged tables cannot be truncated twice |