> -----Original Message-----
> From: pgsql-hackers-owner@hub.org [mailto:pgsql-hackers-owner@hub.org]On
> Behalf Of Tom Lane
[snip]
>
> regression=# vacuum foo;
> NOTICE: FlushRelationBuffers(foo, 0): block 0 is dirty (private
> 1, global 1)
> VACUUM
>
> This is being caused by the buffer manager changes I recently made
> to avoid doing unnecessary writes at commit. After the DELETE, foo's
> buffer is written to disk, but at that point its (single) tuple is
> marked with an uncommitted xmax transaction. The SELECT verifies the
> tuple is dead and changes its on-row status to xmax-committed, but
> *that change is not forced to disk* (the rationale being that even if
> we crashed without writing the change, it could be done again later).
> Now VACUUM comes along, finds no live tuples, and decides to truncate
> the relation to zero blocks. During the truncation,
> FlushRelationBuffers sees that the buffer it's flushing is still marked
> dirty, and hence emits the above notice.
>
This means vacuum doesn't necessarily flush all dirty buffers of
the target table. Doesn't this break the assumption of pg_upgrade ?
>
> Comments anyone?
>
Some changes around bufmgr seems to be needed.
1) Provide a function which could flush all dirty buffers and vacuum calls the function for example.
or
2) SetBufferCommitInfoNeedsSave() sets SharedBuffer Changed and BufferDirtiedByMe.
and/or
3) Flush dirty buffers even in case of abort.
Regards.
Hiroshi Inoue
Inoue@tpf.co.jp