Monday, June 30, 2008

Re: [HACKERS] Confusing message in log file

Bruce Momjian escribió:
> Gurjeet Singh wrote:

> > May 14 21:38:40 sfphotodb001 postgres[29658]: [19-1] 2008-05-14 21:38:40
> > PDTLOG: received SIGHUP, reloading configuration files
> > May 14 21:38:40 sfphotodb001 postgres[29658]: [20-1] 2008-05-14 21:38:40
> > PDTLOG: parameter "shared_buffers" cannot be changed after server start;
> > configuration file change ignored

> > What's confusing about this is that the second message says
> > 'configuration file change ignored', so I expect the changed (newly enabled)
> > archive_command to not take effect. But in fact, it does take effect.
> >
> > The message probably should be rephrased to say that this setting
> > (shared_buffers) will not be changed.
>
> Actually, no one else has been confused by this wording before, and I
> can't think of better wording that doesn't sound redundant.

Perhaps this is because not enough people have seen it. I agree that
the message should specify that only this setting has been ignored.

In any case, this seems a case of stuffing too much in the primary
message. I think it should be something like

errmsg("parameter \"shared_buffer\" change in configuration file ignored"),
errdetail("This parameter cannot be changed after server start.")

--
Alvaro Herrera

http://www.CommandPrompt.com/
The PostgreSQL Company - Command Prompt, Inc.

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Re: [HACKERS] Confusing message in log file

Tom Lane wrote:
> Bruce Momjian <bruce@momjian.us> writes:
> > Gurjeet Singh wrote:
> >> May 14 21:38:40 sfphotodb001 postgres[29658]: [20-1] 2008-05-14 21:38:40
> >> PDTLOG: parameter "shared_buffers" cannot be changed after server start;
> >> configuration file change ignored
> >>
> >> The message probably should be rephrased to say that this setting
> >> (shared_buffers) will not be changed.
>
> > Actually, no one else has been confused by this wording before, and I
> > can't think of better wording that doesn't sound redundant.
>
> How about "... after server start; change ignored" ?
> Or "attempted change ignored" ?

Yea, I like "change ignored" rather than mentioning the configuration
file.

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Re: [HACKERS] Confusing message in log file

Bruce Momjian <bruce@momjian.us> writes:
> Gurjeet Singh wrote:
>> May 14 21:38:40 sfphotodb001 postgres[29658]: [20-1] 2008-05-14 21:38:40
>> PDTLOG: parameter "shared_buffers" cannot be changed after server start;
>> configuration file change ignored
>>
>> The message probably should be rephrased to say that this setting
>> (shared_buffers) will not be changed.

> Actually, no one else has been confused by this wording before, and I
> can't think of better wording that doesn't sound redundant.

How about "... after server start; change ignored" ?
Or "attempted change ignored" ?

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Re: [HACKERS] Adding variables for segment_size, wal_segment_size and block sizes

Bernd Helmle wrote:
> Now that we have customizable segment sizes for heap and WAL at compilation
> time i would like to have some runtime variables to query that information
> (besides pg_controldata). I can imagine to have the following names:
>
> segment_size: Reports heap segment size
> wal_segment_size: Reports wal segment size
> block_size: Available yet
> wal_block_size: wal block size
>
> I'd like to implement them if we agree on them

Bernd, have you made any progress on this?

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Re: [HACKERS] Confusing message in log file

Gurjeet Singh wrote:
> Hi All,
>
> I changed the postgresql.conf file (of an 8.2.4 server), and issued
> relaod using pg_reload_config(). Following are the messages I see in the log
> files:
>
> May 14 21:38:40 sfphotodb001 postgres[29658]: [19-1] 2008-05-14 21:38:40
> PDTLOG: received SIGHUP, reloading configuration files
> May 14 21:38:40 sfphotodb001 postgres[29658]: [20-1] 2008-05-14 21:38:40
> PDTLOG: parameter "shared_buffers" cannot be changed after server start;
> configuration file change ignored
> May 14 21:39:03 sfphotodb001 postgres[22928]: [21-1] 2008-05-14 21:39:03
> PDTLOG: archived transaction log file "0000000100000E23000000C8"
>
>
> What's confusing about this is that the second message says
> 'configuration file change ignored', so I expect the changed (newly enabled)
> archive_command to not take effect. But in fact, it does take effect.
>
> The message probably should be rephrased to say that this setting
> (shared_buffers) will not be changed.

Actually, no one else has been confused by this wording before, and I
can't think of better wording that doesn't sound redundant.

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Re: [PATCHES] [HACKERS] Hint Bits and Write I/O

Index: src/backend/access/gist/gistget.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/gist/gistget.c,v
retrieving revision 1.73
diff -c -r1.73 gistget.c
*** src/backend/access/gist/gistget.c 12 May 2008 00:00:44 -0000 1.73
--- src/backend/access/gist/gistget.c 30 Jun 2008 22:05:43 -0000
***************
*** 49,55 ****
/* page unchanged, so all is simple */
offset = ItemPointerGetOffsetNumber(iptr);
ItemIdMarkDead(PageGetItemId(p, offset));
! SetBufferCommitInfoNeedsSave(buffer);
LockBuffer(buffer, GIST_UNLOCK);
break;
}
--- 49,55 ----
/* page unchanged, so all is simple */
offset = ItemPointerGetOffsetNumber(iptr);
ItemIdMarkDead(PageGetItemId(p, offset));
! SetBufferCommitInfoNeedsSave(buffer, true);
LockBuffer(buffer, GIST_UNLOCK);
break;
}
***************
*** 64,70 ****
{
/* found */
ItemIdMarkDead(PageGetItemId(p, offset));
! SetBufferCommitInfoNeedsSave(buffer);
LockBuffer(buffer, GIST_UNLOCK);
if (buffer != so->curbuf)
ReleaseBuffer(buffer);
--- 64,70 ----
{
/* found */
ItemIdMarkDead(PageGetItemId(p, offset));
! SetBufferCommitInfoNeedsSave(buffer, true);
LockBuffer(buffer, GIST_UNLOCK);
if (buffer != so->curbuf)
ReleaseBuffer(buffer);
Index: src/backend/access/hash/hash.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/hash/hash.c,v
retrieving revision 1.103
diff -c -r1.103 hash.c
*** src/backend/access/hash/hash.c 12 May 2008 00:00:44 -0000 1.103
--- src/backend/access/hash/hash.c 30 Jun 2008 22:05:43 -0000
***************
*** 242,251 ****

/*
* Since this can be redone later if needed, it's treated the same
! * as a commit-hint-bit status update for heap tuples: we mark the
! * buffer dirty but don't make a WAL log entry.
*/
! SetBufferCommitInfoNeedsSave(so->hashso_curbuf);
}

/*
--- 242,251 ----

/*
* Since this can be redone later if needed, it's treated the same
! * as a commit-hint-bit status update for heap tuples: we don't make
! * a WAL log entry, and mark the page for a flexible dirty write.
*/
! SetBufferCommitInfoNeedsSave(so->hashso_curbuf, true);
}

/*
Index: src/backend/access/heap/heapam.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/heap/heapam.c,v
retrieving revision 1.259
diff -c -r1.259 heapam.c
*** src/backend/access/heap/heapam.c 12 Jun 2008 09:12:30 -0000 1.259
--- src/backend/access/heap/heapam.c 30 Jun 2008 22:05:43 -0000
***************
*** 1533,1539 ****
*/
if (all_dead && *all_dead &&
HeapTupleSatisfiesVacuum(heapTuple.t_data, RecentGlobalXmin,
! buffer) != HEAPTUPLE_DEAD)
*all_dead = false;

/*
--- 1533,1539 ----
*/
if (all_dead && *all_dead &&
HeapTupleSatisfiesVacuum(heapTuple.t_data, RecentGlobalXmin,
! buffer, true) != HEAPTUPLE_DEAD)
*all_dead = false;

/*
***************
*** 1717,1726 ****
{
if (TransactionIdDidCommit(xid))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! xid);
else
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
}
}

--- 1717,1726 ----
{
if (TransactionIdDidCommit(xid))
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! xid, true);
else
HeapTupleSetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, true);
}
}

Index: src/backend/access/heap/pruneheap.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/heap/pruneheap.c,v
retrieving revision 1.14
diff -c -r1.14 pruneheap.c
*** src/backend/access/heap/pruneheap.c 12 Jun 2008 09:12:30 -0000 1.14
--- src/backend/access/heap/pruneheap.c 30 Jun 2008 22:05:43 -0000
***************
*** 267,274 ****
{
/*
* If we didn't prune anything, but have found a new value for the
! * pd_prune_xid field, update it and mark the buffer dirty.
! * This is treated as a non-WAL-logged hint.
*
* Also clear the "page is full" flag if it is set, since there's no
* point in repeating the prune/defrag process until something else
--- 267,274 ----
{
/*
* If we didn't prune anything, but have found a new value for the
! * pd_prune_xid field, update it and mark the buffer for a flexible
! * dirty write. This is treated as a non-WAL-logged hint.
*
* Also clear the "page is full" flag if it is set, since there's no
* point in repeating the prune/defrag process until something else
***************
*** 279,285 ****
{
((PageHeader) page)->pd_prune_xid = prstate.new_prune_xid;
PageClearFull(page);
! SetBufferCommitInfoNeedsSave(buffer);
}
}

--- 279,285 ----
{
((PageHeader) page)->pd_prune_xid = prstate.new_prune_xid;
PageClearFull(page);
! SetBufferCommitInfoNeedsSave(buffer, true);
}
}

***************
*** 391,397 ****
* either here or while following a chain below. Whichever path
* gets there first will mark the tuple unused.
*/
! if (HeapTupleSatisfiesVacuum(htup, OldestXmin, buffer)
== HEAPTUPLE_DEAD && !HeapTupleHeaderIsHotUpdated(htup))
{
heap_prune_record_unused(prstate, rootoffnum);
--- 391,397 ----
* either here or while following a chain below. Whichever path
* gets there first will mark the tuple unused.
*/
! if (HeapTupleSatisfiesVacuum(htup, OldestXmin, buffer, true)
== HEAPTUPLE_DEAD && !HeapTupleHeaderIsHotUpdated(htup))
{
heap_prune_record_unused(prstate, rootoffnum);
***************
*** 469,475 ****
*/
tupdead = recent_dead = false;

! switch (HeapTupleSatisfiesVacuum(htup, OldestXmin, buffer))
{
case HEAPTUPLE_DEAD:
tupdead = true;
--- 469,475 ----
*/
tupdead = recent_dead = false;

! switch (HeapTupleSatisfiesVacuum(htup, OldestXmin, buffer, true))
{
case HEAPTUPLE_DEAD:
tupdead = true;
Index: src/backend/access/index/indexam.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/index/indexam.c,v
retrieving revision 1.108
diff -c -r1.108 indexam.c
*** src/backend/access/index/indexam.c 12 May 2008 00:00:45 -0000 1.108
--- src/backend/access/index/indexam.c 30 Jun 2008 22:05:43 -0000
***************
*** 597,607 ****
* If we can't see it, maybe no one else can either. Check to see
* if the tuple is dead to all transactions. If we find that all
* the tuples in the HOT chain are dead, we'll signal the index AM
! * to not return that TID on future indexscans.
*/
if (scan->xs_hot_dead &&
HeapTupleSatisfiesVacuum(heapTuple->t_data, RecentGlobalXmin,
! scan->xs_cbuf) != HEAPTUPLE_DEAD)
scan->xs_hot_dead = false;

/*
--- 597,610 ----
* If we can't see it, maybe no one else can either. Check to see
* if the tuple is dead to all transactions. If we find that all
* the tuples in the HOT chain are dead, we'll signal the index AM
! * to not return that TID on future indexscans. We can be flexible
! * about writing the hint bits because once the index AM has been
! * told to return that TID it is unlikely that the tuple will be
! * re-accessed, except by a seq scan.
*/
if (scan->xs_hot_dead &&
HeapTupleSatisfiesVacuum(heapTuple->t_data, RecentGlobalXmin,
! scan->xs_cbuf, true) != HEAPTUPLE_DEAD)
scan->xs_hot_dead = false;

/*
Index: src/backend/access/nbtree/nbtinsert.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/nbtree/nbtinsert.c,v
retrieving revision 1.167
diff -c -r1.167 nbtinsert.c
*** src/backend/access/nbtree/nbtinsert.c 11 Jun 2008 08:38:56 -0000 1.167
--- src/backend/access/nbtree/nbtinsert.c 30 Jun 2008 22:05:43 -0000
***************
*** 305,319 ****
/*
* The conflicting tuple (or whole HOT chain) is dead to
* everyone, so we may as well mark the index entry
! * killed.
*/
ItemIdMarkDead(curitemid);
opaque->btpo_flags |= BTP_HAS_GARBAGE;
/* be sure to mark the proper buffer dirty... */
if (nbuf != InvalidBuffer)
! SetBufferCommitInfoNeedsSave(nbuf);
else
! SetBufferCommitInfoNeedsSave(buf);
}
}
}
--- 305,319 ----
/*
* The conflicting tuple (or whole HOT chain) is dead to
* everyone, so we may as well mark the index entry
! * killed, though with a flexibile dirty write.
*/
ItemIdMarkDead(curitemid);
opaque->btpo_flags |= BTP_HAS_GARBAGE;
/* be sure to mark the proper buffer dirty... */
if (nbuf != InvalidBuffer)
! SetBufferCommitInfoNeedsSave(nbuf, true);
else
! SetBufferCommitInfoNeedsSave(buf, true);
}
}
}
Index: src/backend/access/nbtree/nbtree.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/nbtree/nbtree.c,v
retrieving revision 1.160
diff -c -r1.160 nbtree.c
*** src/backend/access/nbtree/nbtree.c 12 May 2008 00:00:45 -0000 1.160
--- src/backend/access/nbtree/nbtree.c 30 Jun 2008 22:05:43 -0000
***************
*** 902,908 ****
opaque->btpo_cycleid == vstate->cycleid)
{
opaque->btpo_cycleid = 0;
! SetBufferCommitInfoNeedsSave(buf);
}
}

--- 902,908 ----
opaque->btpo_cycleid == vstate->cycleid)
{
opaque->btpo_cycleid = 0;
! SetBufferCommitInfoNeedsSave(buf, true);
}
}

Index: src/backend/access/nbtree/nbtutils.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/access/nbtree/nbtutils.c,v
retrieving revision 1.90
diff -c -r1.90 nbtutils.c
*** src/backend/access/nbtree/nbtutils.c 12 May 2008 00:00:45 -0000 1.90
--- src/backend/access/nbtree/nbtutils.c 30 Jun 2008 22:05:43 -0000
***************
*** 1161,1168 ****

/*
* Since this can be redone later if needed, it's treated the same as a
! * commit-hint-bit status update for heap tuples: we mark the buffer dirty
! * but don't make a WAL log entry.
*
* Whenever we mark anything LP_DEAD, we also set the page's
* BTP_HAS_GARBAGE flag, which is likewise just a hint.
--- 1161,1168 ----

/*
* Since this can be redone later if needed, it's treated the same as a
! * commit-hint-bit status update for heap tuples: we don't make a WAL log
! * entry, though we mark the page for a flexible dirty write.
*
* Whenever we mark anything LP_DEAD, we also set the page's
* BTP_HAS_GARBAGE flag, which is likewise just a hint.
***************
*** 1170,1176 ****
if (killedsomething)
{
opaque->btpo_flags |= BTP_HAS_GARBAGE;
! SetBufferCommitInfoNeedsSave(so->currPos.buf);
}

if (!haveLock)
--- 1170,1176 ----
if (killedsomething)
{
opaque->btpo_flags |= BTP_HAS_GARBAGE;
! SetBufferCommitInfoNeedsSave(so->currPos.buf, true);
}

if (!haveLock)
Index: src/backend/catalog/index.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/catalog/index.c,v
retrieving revision 1.299
diff -c -r1.299 index.c
*** src/backend/catalog/index.c 12 May 2008 20:01:59 -0000 1.299
--- src/backend/catalog/index.c 30 Jun 2008 22:05:43 -0000
***************
*** 1572,1582 ****
* since caller should hold ShareLock on the relation, but let's
* be conservative about it. (This remark is still correct even
* with HOT-pruning: our pin on the buffer prevents pruning.)
*/
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);

switch (HeapTupleSatisfiesVacuum(heapTuple->t_data, OldestXmin,
! scan->rs_cbuf))
{
case HEAPTUPLE_DEAD:
/* Definitely dead, we can ignore it */
--- 1572,1583 ----
* since caller should hold ShareLock on the relation, but let's
* be conservative about it. (This remark is still correct even
* with HOT-pruning: our pin on the buffer prevents pruning.)
+ * We're flexible on hint bit writes here also.
*/
LockBuffer(scan->rs_cbuf, BUFFER_LOCK_SHARE);

switch (HeapTupleSatisfiesVacuum(heapTuple->t_data, OldestXmin,
! scan->rs_cbuf, true))
{
case HEAPTUPLE_DEAD:
/* Definitely dead, we can ignore it */
Index: src/backend/commands/analyze.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/commands/analyze.c,v
retrieving revision 1.122
diff -c -r1.122 analyze.c
*** src/backend/commands/analyze.c 8 Jun 2008 22:00:47 -0000 1.122
--- src/backend/commands/analyze.c 30 Jun 2008 22:05:43 -0000
***************
*** 392,398 ****
}

/*
! * Acquire the sample rows
*/
rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple));
numrows = acquire_sample_rows(onerel, rows, targrows,
--- 392,399 ----
}

/*
! * Acquire the sample rows. Set hints with flexibility only if we
! * are running ANALYZE without VACUUM.
*/
rows = (HeapTuple *) palloc(targrows * sizeof(HeapTuple));
numrows = acquire_sample_rows(onerel, rows, targrows,
***************
*** 928,936 ****
targtuple.t_data = (HeapTupleHeader) PageGetItem(targpage, itemid);
targtuple.t_len = ItemIdGetLength(itemid);

switch (HeapTupleSatisfiesVacuum(targtuple.t_data,
OldestXmin,
! targbuffer))
{
case HEAPTUPLE_LIVE:
sample_it = true;
--- 929,941 ----
targtuple.t_data = (HeapTupleHeader) PageGetItem(targpage, itemid);
targtuple.t_len = ItemIdGetLength(itemid);

+ /*
+ * We are flexible about setting hint bits because we want
+ * to reduce the I/O overhead for larger tables
+ */
switch (HeapTupleSatisfiesVacuum(targtuple.t_data,
OldestXmin,
! targbuffer, true))
{
case HEAPTUPLE_LIVE:
sample_it = true;
Index: src/backend/commands/cluster.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/commands/cluster.c,v
retrieving revision 1.176
diff -c -r1.176 cluster.c
*** src/backend/commands/cluster.c 12 May 2008 20:01:59 -0000 1.176
--- src/backend/commands/cluster.c 30 Jun 2008 22:05:43 -0000
***************
*** 789,796 ****

LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);

switch (HeapTupleSatisfiesVacuum(tuple->t_data, OldestXmin,
! scan->xs_cbuf))
{
case HEAPTUPLE_DEAD:
/* Definitely dead */
--- 789,800 ----

LockBuffer(scan->xs_cbuf, BUFFER_LOCK_SHARE);

+ /*
+ * We can be flexible about setting hint bits because we are
+ * going to rewrite the whole table anyway
+ */
switch (HeapTupleSatisfiesVacuum(tuple->t_data, OldestXmin,
! scan->xs_cbuf, true))
{
case HEAPTUPLE_DEAD:
/* Definitely dead */
Index: src/backend/commands/vacuum.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/commands/vacuum.c,v
retrieving revision 1.375
diff -c -r1.375 vacuum.c
*** src/backend/commands/vacuum.c 5 Jun 2008 15:47:32 -0000 1.375
--- src/backend/commands/vacuum.c 30 Jun 2008 22:05:43 -0000
***************
*** 1474,1480 ****
tuple.t_len = ItemIdGetLength(itemid);
ItemPointerSet(&(tuple.t_self), blkno, offnum);

! switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin, buf))
{
case HEAPTUPLE_LIVE:
/* Tuple is good --- but let's do some validity checks */
--- 1474,1484 ----
tuple.t_len = ItemIdGetLength(itemid);
ItemPointerSet(&(tuple.t_self), blkno, offnum);

! /*
! * There is no flexibility here for hint bit setting. All
! * hints must be set and written.
! */
! switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin, buf, false))
{
case HEAPTUPLE_LIVE:
/* Tuple is good --- but let's do some validity checks */
***************
*** 2164,2169 ****
--- 2168,2175 ----
* been removed, and perhaps even replaced by a MOVED_IN
* tuple. We don't want to include any DEAD tuples in the
* chain, so we have to recheck HeapTupleSatisfiesVacuum.
+ * There is no flexibility here for hint bit setting. All
+ * hints must be set and written.
*/
while (!(tp.t_data->t_infomask & (HEAP_XMAX_INVALID |
HEAP_IS_LOCKED)) &&
***************
*** 2218,2224 ****
LockBuffer(nextBuf, BUFFER_LOCK_SHARE);
nextTstatus = HeapTupleSatisfiesVacuum(nextTdata,
OldestXmin,
! nextBuf);
if (nextTstatus == HEAPTUPLE_DEAD ||
nextTstatus == HEAPTUPLE_INSERT_IN_PROGRESS)
{
--- 2224,2230 ----
LockBuffer(nextBuf, BUFFER_LOCK_SHARE);
nextTstatus = HeapTupleSatisfiesVacuum(nextTdata,
OldestXmin,
! nextBuf, false);
if (nextTstatus == HEAPTUPLE_DEAD ||
nextTstatus == HEAPTUPLE_INSERT_IN_PROGRESS)
{
Index: src/backend/commands/vacuumlazy.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/commands/vacuumlazy.c,v
retrieving revision 1.107
diff -c -r1.107 vacuumlazy.c
*** src/backend/commands/vacuumlazy.c 12 May 2008 00:00:48 -0000 1.107
--- src/backend/commands/vacuumlazy.c 30 Jun 2008 22:05:43 -0000
***************
*** 451,457 ****

tupgone = false;

! switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin, buf))
{
case HEAPTUPLE_DEAD:

--- 451,461 ----

tupgone = false;

! /*
! * There is no flexibility here for hint bit setting. All
! * hints must be set and written.
! */
! switch (HeapTupleSatisfiesVacuum(tuple.t_data, OldestXmin, buf, false))
{
case HEAPTUPLE_DEAD:

Index: src/backend/storage/buffer/buf_init.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/storage/buffer/buf_init.c,v
retrieving revision 1.80
diff -c -r1.80 buf_init.c
*** src/backend/storage/buffer/buf_init.c 1 Jan 2008 19:45:51 -0000 1.80
--- src/backend/storage/buffer/buf_init.c 30 Jun 2008 22:13:32 -0000
***************
*** 112,117 ****
--- 112,118 ----
CLEAR_BUFFERTAG(buf->tag);
buf->flags = 0;
buf->usage_count = 0;
+ buf->hint_count = 0;
buf->refcount = 0;
buf->wait_backend_pid = 0;

Index: src/backend/storage/buffer/bufmgr.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/storage/buffer/bufmgr.c,v
retrieving revision 1.232
diff -c -r1.232 bufmgr.c
*** src/backend/storage/buffer/bufmgr.c 12 Jun 2008 09:12:31 -0000 1.232
--- src/backend/storage/buffer/bufmgr.c 30 Jun 2008 22:17:20 -0000
***************
*** 84,90 ****
static void PinBuffer_Locked(volatile BufferDesc *buf);
static void UnpinBuffer(volatile BufferDesc *buf, bool fixOwner);
static void BufferSync(int flags);
! static int SyncOneBuffer(int buf_id, bool skip_recently_used);
static void WaitIO(volatile BufferDesc *buf);
static bool StartBufferIO(volatile BufferDesc *buf, bool forInput);
static void TerminateBufferIO(volatile BufferDesc *buf, bool clear_dirty,
--- 84,90 ----
static void PinBuffer_Locked(volatile BufferDesc *buf);
static void UnpinBuffer(volatile BufferDesc *buf, bool fixOwner);
static void BufferSync(int flags);
! static int SyncOneBuffer(int buf_id, bool LRU_scan);
static void WaitIO(volatile BufferDesc *buf);
static bool StartBufferIO(volatile BufferDesc *buf, bool forInput);
static void TerminateBufferIO(volatile BufferDesc *buf, bool clear_dirty,
***************
*** 492,498 ****
* won't prevent hint-bit updates). We will recheck the dirty bit
* after re-locking the buffer header.
*/
! if (oldFlags & BM_DIRTY)
{
/*
* We need a share-lock on the buffer contents to write it out
--- 492,498 ----
* won't prevent hint-bit updates). We will recheck the dirty bit
* after re-locking the buffer header.
*/
! if (oldFlags & BM_DIRTY || buf->hint_count > 0)
{
/*
* We need a share-lock on the buffer contents to write it out
***************
*** 680,685 ****
--- 680,686 ----
buf->flags &= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_CHECKPOINT_NEEDED | BM_IO_ERROR);
buf->flags |= BM_TAG_VALID;
buf->usage_count = 1;
+ buf->hint_count = 0;

UnlockBufHdr(buf);

***************
*** 790,795 ****
--- 791,797 ----
CLEAR_BUFFERTAG(buf->tag);
buf->flags = 0;
buf->usage_count = 0;
+ buf->hint_count = 0;

UnlockBufHdr(buf);

***************
*** 1428,1434 ****
/*
* SyncOneBuffer -- process a single buffer during syncing.
*
! * If skip_recently_used is true, we don't write currently-pinned buffers, nor
* buffers marked recently used, as these are not replacement candidates.
*
* Returns a bitmask containing the following flag bits:
--- 1430,1436 ----
/*
* SyncOneBuffer -- process a single buffer during syncing.
*
! * If LRU_scan is true, we don't write currently-pinned buffers, nor
* buffers marked recently used, as these are not replacement candidates.
*
* Returns a bitmask containing the following flag bits:
***************
*** 1442,1448 ****
* Note: caller must have done ResourceOwnerEnlargeBuffers.
*/
static int
! SyncOneBuffer(int buf_id, bool skip_recently_used)
{
volatile BufferDesc *bufHdr = &BufferDescriptors[buf_id];
int result = 0;
--- 1444,1450 ----
* Note: caller must have done ResourceOwnerEnlargeBuffers.
*/
static int
! SyncOneBuffer(int buf_id, bool LRU_scan)
{
volatile BufferDesc *bufHdr = &BufferDescriptors[buf_id];
int result = 0;
***************
*** 1460,1473 ****

if (bufHdr->refcount == 0 && bufHdr->usage_count == 0)
result |= BUF_REUSABLE;
! else if (skip_recently_used)
{
/* Caller told us not to write recently-used buffers */
UnlockBufHdr(bufHdr);
return result;
}

! if (!(bufHdr->flags & BM_VALID) || !(bufHdr->flags & BM_DIRTY))
{
/* It's clean, so nothing to do */
UnlockBufHdr(bufHdr);
--- 1462,1477 ----

if (bufHdr->refcount == 0 && bufHdr->usage_count == 0)
result |= BUF_REUSABLE;
! else if (LRU_scan)
{
/* Caller told us not to write recently-used buffers */
UnlockBufHdr(bufHdr);
return result;
}

! if (!(bufHdr->flags & BM_VALID) ||
! !(bufHdr->flags & BM_DIRTY ||
! (LRU_scan && bufHdr->hint_count > 0)))
{
/* It's clean, so nothing to do */
UnlockBufHdr(bufHdr);
***************
*** 2163,2169 ****
* to be associated with a WAL-entry-creating action.
*/
void
! SetBufferCommitInfoNeedsSave(Buffer buffer)
{
volatile BufferDesc *bufHdr;

--- 2167,2173 ----
* to be associated with a WAL-entry-creating action.
*/
void
! SetBufferCommitInfoNeedsSave(Buffer buffer, bool flexible)
{
volatile BufferDesc *bufHdr;

***************
*** 2173,2178 ****
--- 2177,2187 ----
if (BufferIsLocal(buffer))
{
MarkLocalBufferDirty(buffer);
+
+ #ifdef BGW_DEBUG
+ if (bufHdr->hint_count < UINT8_MAX)
+ bufHdr->hint_count++;
+ #endif
return;
}

***************
*** 2194,2205 ****
if ((bufHdr->flags & (BM_DIRTY | BM_JUST_DIRTIED)) !=
(BM_DIRTY | BM_JUST_DIRTIED))
{
! LockBufHdr(bufHdr);
! Assert(bufHdr->refcount > 0);
! if (!(bufHdr->flags & BM_DIRTY) && VacuumCostActive)
! VacuumCostBalance += VacuumCostPageDirty;
! bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
! UnlockBufHdr(bufHdr);
}
}

--- 2203,2232 ----
if ((bufHdr->flags & (BM_DIRTY | BM_JUST_DIRTIED)) !=
(BM_DIRTY | BM_JUST_DIRTIED))
{
! if (flexible)
! {
! /*
! * If the buffer isn't dirty yet then update the hint_count
! * without holding the buffer header spin lock. It doesn't really
! * matter if we get the wrong result since hint_count is used
! * as a hint anyway, never for anything that needs to be correct.
! */
! if (bufHdr->hint_count < UINT8_MAX)
! bufHdr->hint_count++;
! }
! else
! {
! LockBufHdr(bufHdr);
! Assert(bufHdr->refcount > 0);
! if (!(bufHdr->flags & BM_DIRTY) && VacuumCostActive)
! VacuumCostBalance += VacuumCostPageDirty;
! bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
! #ifdef BGW_DEBUG
! if (bufHdr->hint_count < UINT8_MAX)
! bufHdr->hint_count++;
! #endif
! UnlockBufHdr(bufHdr);
! }
}
}

Index: src/backend/storage/buffer/localbuf.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/storage/buffer/localbuf.c,v
retrieving revision 1.80
diff -c -r1.80 localbuf.c
*** src/backend/storage/buffer/localbuf.c 12 Jun 2008 09:12:31 -0000 1.80
--- src/backend/storage/buffer/localbuf.c 30 Jun 2008 22:13:25 -0000
***************
*** 280,285 ****
--- 280,286 ----
CLEAR_BUFFERTAG(bufHdr->tag);
bufHdr->flags = 0;
bufHdr->usage_count = 0;
+ bufHdr->hint_count = 0;
}
}
}
Index: src/backend/utils/time/tqual.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/utils/time/tqual.c,v
retrieving revision 1.110
diff -c -r1.110 tqual.c
*** src/backend/utils/time/tqual.c 26 Mar 2008 16:20:47 -0000 1.110
--- src/backend/utils/time/tqual.c 30 Jun 2008 22:08:30 -0000
***************
*** 84,90 ****
*/
static inline void
SetHintBits(HeapTupleHeader tuple, Buffer buffer,
! uint16 infomask, TransactionId xid)
{
if (TransactionIdIsValid(xid))
{
--- 84,90 ----
*/
static inline void
SetHintBits(HeapTupleHeader tuple, Buffer buffer,
! uint16 infomask, TransactionId xid, bool flexible)
{
if (TransactionIdIsValid(xid))
{
***************
*** 96,102 ****
}

tuple->t_infomask |= infomask;
! SetBufferCommitInfoNeedsSave(buffer);
}

/*
--- 96,102 ----
}

tuple->t_infomask |= infomask;
! SetBufferCommitInfoNeedsSave(buffer, flexible);
}

/*
***************
*** 107,115 ****
*/
void
HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
! uint16 infomask, TransactionId xid)
{
! SetHintBits(tuple, buffer, infomask, xid);
}


--- 107,115 ----
*/
void
HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
! uint16 infomask, TransactionId xid, bool flexible)
{
! SetHintBits(tuple, buffer, infomask, xid, flexible);
}


***************
*** 156,166 ****
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
--- 156,166 ----
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, false);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
***************
*** 173,183 ****
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 173,183 ----
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, false);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
}
***************
*** 196,202 ****
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

--- 196,202 ----
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

***************
*** 206,217 ****
return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple));
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 206,217 ----
return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple), false);
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
}
***************
*** 249,255 ****
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

--- 249,255 ----
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

***************
*** 258,269 ****
if (tuple->t_infomask & HEAP_IS_LOCKED)
{
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple));
return false;
}

--- 258,269 ----
if (tuple->t_infomask & HEAP_IS_LOCKED)
{
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple), false);
return false;
}

***************
*** 327,337 ****
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
--- 327,337 ----
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, false);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
***************
*** 344,354 ****
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 344,354 ----
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, false);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
}
***************
*** 370,376 ****
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

--- 370,376 ----
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

***************
*** 383,394 ****
return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple));
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 383,394 ----
return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple), false);
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
}
***************
*** 429,435 ****
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

--- 429,435 ----
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

***************
*** 438,449 ****
if (tuple->t_infomask & HEAP_IS_LOCKED)
{
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple));
return false;
}

--- 438,449 ----
if (tuple->t_infomask & HEAP_IS_LOCKED)
{
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple), false);
return false;
}

***************
*** 491,501 ****
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
--- 491,501 ----
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, true);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, true);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
***************
*** 508,518 ****
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 508,518 ----
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, true);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, true);
return false;
}
}
***************
*** 549,554 ****
--- 549,556 ----
* the case where the tuple is share-locked by a MultiXact, even if the
* MultiXact includes the current transaction. Callers that want to
* distinguish that case must test for it themselves.)
+ *
+ * We are flexible with hint bit setting in all cases here.
*/
HTSU_Result
HeapTupleSatisfiesUpdate(HeapTupleHeader tuple, CommandId curcid,
***************
*** 570,580 ****
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return HeapTupleInvisible;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
--- 572,582 ----
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, true);
return HeapTupleInvisible;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, true);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
***************
*** 587,597 ****
return HeapTupleInvisible;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return HeapTupleInvisible;
}
}
--- 589,599 ----
return HeapTupleInvisible;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, true);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, true);
return HeapTupleInvisible;
}
}
***************
*** 613,619 ****
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return HeapTupleMayBeUpdated;
}

--- 615,621 ----
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, true);
return HeapTupleMayBeUpdated;
}

***************
*** 626,637 ****
return HeapTupleInvisible;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple));
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return HeapTupleInvisible;
}
}
--- 628,639 ----
return HeapTupleInvisible;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple), true);
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, true);
return HeapTupleInvisible;
}
}
***************
*** 656,662 ****
if (MultiXactIdIsRunning(HeapTupleHeaderGetXmax(tuple)))
return HeapTupleBeingUpdated;
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return HeapTupleMayBeUpdated;
}

--- 658,664 ----
if (MultiXactIdIsRunning(HeapTupleHeaderGetXmax(tuple)))
return HeapTupleBeingUpdated;
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, true);
return HeapTupleMayBeUpdated;
}

***************
*** 677,683 ****
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return HeapTupleMayBeUpdated;
}

--- 679,685 ----
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, true);
return HeapTupleMayBeUpdated;
}

***************
*** 686,697 ****
if (tuple->t_infomask & HEAP_IS_LOCKED)
{
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return HeapTupleMayBeUpdated;
}

SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple));
return HeapTupleUpdated; /* updated by other */
}

--- 688,699 ----
if (tuple->t_infomask & HEAP_IS_LOCKED)
{
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, true);
return HeapTupleMayBeUpdated;
}

SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple), true);
return HeapTupleUpdated; /* updated by other */
}

***************
*** 737,747 ****
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
--- 739,749 ----
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, false);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
***************
*** 754,764 ****
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 756,766 ----
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, false);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
}
***************
*** 777,783 ****
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

--- 779,785 ----
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

***************
*** 791,802 ****
}
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple));
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 793,804 ----
}
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple), false);
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
}
***************
*** 837,843 ****
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

--- 839,845 ----
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

***************
*** 846,857 ****
if (tuple->t_infomask & HEAP_IS_LOCKED)
{
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple));
return false; /* updated by other */
}

--- 848,859 ----
if (tuple->t_infomask & HEAP_IS_LOCKED)
{
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, false);
return true;
}

SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple), false);
return false; /* updated by other */
}

***************
*** 875,880 ****
--- 877,884 ----
* (Notice, however, that the tuple status hint bits will be updated on the
* basis of the true state of the transaction, even if we then pretend we
* can't see it.)
+ *
+ * We are flexible with hint bit setting in all cases here.
*/
bool
HeapTupleSatisfiesMVCC(HeapTupleHeader tuple, Snapshot snapshot,
***************
*** 896,906 ****
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
--- 900,910 ----
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, true);
return false;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, true);
}
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
***************
*** 913,923 ****
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 917,927 ----
return false;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, false);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, false);
return false;
}
}
***************
*** 939,945 ****
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

--- 943,949 ----
{
/* deleting subtransaction must have aborted */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, true);
return true;
}

***************
*** 952,963 ****
return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple));
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return false;
}
}
--- 956,967 ----
return false;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple), true);
else
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, true);
return false;
}
}
***************
*** 999,1011 ****
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return true;
}

/* xmax transaction committed */
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple));
}

/*
--- 1003,1015 ----
{
/* it must have aborted or crashed */
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, true);
return true;
}

/* xmax transaction committed */
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple), true);
}

/*
***************
*** 1032,1038 ****
*/
HTSV_Result
HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
! Buffer buffer)
{
/*
* Has inserting transaction committed?
--- 1036,1042 ----
*/
HTSV_Result
HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin,
! Buffer buffer, bool flexible)
{
/*
* Has inserting transaction committed?
***************
*** 1055,1065 ****
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return HEAPTUPLE_DEAD;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
{
--- 1059,1069 ----
if (TransactionIdDidCommit(xvac))
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, flexible);
return HEAPTUPLE_DEAD;
}
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, flexible);
}
else if (tuple->t_infomask & HEAP_MOVED_IN)
{
***************
*** 1071,1081 ****
return HEAPTUPLE_INSERT_IN_PROGRESS;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return HEAPTUPLE_DEAD;
}
}
--- 1075,1085 ----
return HEAPTUPLE_INSERT_IN_PROGRESS;
if (TransactionIdDidCommit(xvac))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! InvalidTransactionId, flexible);
else
{
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, flexible);
return HEAPTUPLE_DEAD;
}
}
***************
*** 1090,1103 ****
}
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple));
else
{
/*
* Not in Progress, Not Committed, so either Aborted or crashed
*/
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId);
return HEAPTUPLE_DEAD;
}

--- 1094,1107 ----
}
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmin(tuple)))
SetHintBits(tuple, buffer, HEAP_XMIN_COMMITTED,
! HeapTupleHeaderGetXmin(tuple), flexible);
else
{
/*
* Not in Progress, Not Committed, so either Aborted or crashed
*/
SetHintBits(tuple, buffer, HEAP_XMIN_INVALID,
! InvalidTransactionId, flexible);
return HEAPTUPLE_DEAD;
}

***************
*** 1144,1150 ****
* never actually update it.
*/
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
}
return HEAPTUPLE_LIVE;
}
--- 1148,1154 ----
* never actually update it.
*/
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, flexible);
}
return HEAPTUPLE_LIVE;
}
***************
*** 1162,1175 ****
return HEAPTUPLE_DELETE_IN_PROGRESS;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple));
else
{
/*
* Not in Progress, Not Committed, so either Aborted or crashed
*/
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId);
return HEAPTUPLE_LIVE;
}

--- 1166,1179 ----
return HEAPTUPLE_DELETE_IN_PROGRESS;
else if (TransactionIdDidCommit(HeapTupleHeaderGetXmax(tuple)))
SetHintBits(tuple, buffer, HEAP_XMAX_COMMITTED,
! HeapTupleHeaderGetXmax(tuple), flexible);
else
{
/*
* Not in Progress, Not Committed, so either Aborted or crashed
*/
SetHintBits(tuple, buffer, HEAP_XMAX_INVALID,
! InvalidTransactionId, flexible);
return HEAPTUPLE_LIVE;
}

Index: src/include/storage/buf_internals.h
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/storage/buf_internals.h,v
retrieving revision 1.96
diff -c -r1.96 buf_internals.h
*** src/include/storage/buf_internals.h 12 Jun 2008 09:12:31 -0000 1.96
--- src/include/storage/buf_internals.h 30 Jun 2008 22:08:30 -0000
***************
*** 128,134 ****
{
BufferTag tag; /* ID of page contained in buffer */
BufFlags flags; /* see bit definitions above */
! uint16 usage_count; /* usage counter for clock sweep code */
unsigned refcount; /* # of backends holding pins on buffer */
int wait_backend_pid; /* backend PID of pin-count waiter */

--- 128,135 ----
{
BufferTag tag; /* ID of page contained in buffer */
BufFlags flags; /* see bit definitions above */
! uint8 usage_count; /* usage counter for clock sweep code */
! uint8 hint_count; /* hint counter for clock sweep code */
unsigned refcount; /* # of backends holding pins on buffer */
int wait_backend_pid; /* backend PID of pin-count waiter */

Index: src/include/storage/bufmgr.h
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/storage/bufmgr.h,v
retrieving revision 1.113
diff -c -r1.113 bufmgr.h
*** src/include/storage/bufmgr.h 12 Jun 2008 09:12:31 -0000 1.113
--- src/include/storage/bufmgr.h 30 Jun 2008 22:08:30 -0000
***************
*** 177,183 ****
extern Size BufferShmemSize(void);
extern RelFileNode BufferGetFileNode(Buffer buffer);

! extern void SetBufferCommitInfoNeedsSave(Buffer buffer);

extern void UnlockBuffers(void);
extern void LockBuffer(Buffer buffer, int mode);
--- 177,183 ----
extern Size BufferShmemSize(void);
extern RelFileNode BufferGetFileNode(Buffer buffer);

! extern void SetBufferCommitInfoNeedsSave(Buffer buffer, bool flexible);

extern void UnlockBuffers(void);
extern void LockBuffer(Buffer buffer, int mode);
Index: src/include/utils/tqual.h
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/utils/tqual.h,v
retrieving revision 1.73
diff -c -r1.73 tqual.h
*** src/include/utils/tqual.h 26 Mar 2008 21:10:39 -0000 1.73
--- src/include/utils/tqual.h 30 Jun 2008 22:08:30 -0000
***************
*** 82,90 ****
extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTupleHeader tuple,
CommandId curcid, Buffer buffer);
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
! TransactionId OldestXmin, Buffer buffer);

extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
! uint16 infomask, TransactionId xid);

#endif /* TQUAL_H */
--- 82,90 ----
extern HTSU_Result HeapTupleSatisfiesUpdate(HeapTupleHeader tuple,
CommandId curcid, Buffer buffer);
extern HTSV_Result HeapTupleSatisfiesVacuum(HeapTupleHeader tuple,
! TransactionId OldestXmin, Buffer buffer, bool flexible);

extern void HeapTupleSetHintBits(HeapTupleHeader tuple, Buffer buffer,
! uint16 infomask, TransactionId xid, bool flexible);

#endif /* TQUAL_H */
On Fri, 2008-06-27 at 16:02 +0100, Simon Riggs wrote:
> The patch splits into two parts:
> * the machinery to *not* dirty a page when we set hints
> * behaviour modifications now that we can tell the difference between
> dirty and hinted pages
>
> Nobody has yet come up with any comments about the first half, which is
> good. The second part is clearly where much debate will occur. I'm going
> to literally split the patch into two, so we can get the machinery into
> CVS and then fiddle and argue over the second part over next few months.

The first "half" is actually quite large, but that makes it even more
sensible to commit this part now.

The enclosed patch introduces the machinery by which we might later
optimise hint bit setting. It differentiates between hint bit setting
and block dirtying, when the distinction can safely be made. It acts
safely during VACUUM and correctly during checkpoint. In all other
respects it emulates current behaviour.

The actual tuning patch can be discussed later, probably at length.
Later patches will be fairly small in comparison and so various people
can fairly easily come up with their own favoured modifications for
testing.

--
Simon Riggs

www.2ndQuadrant.com

PostgreSQL Training, Services and Support

Re: [HACKERS] [GENERAL] Surprising syntax error

Marc Munro wrote:
-- Start of PGP signed section.
> The statement:
>
> revoke all on view internal.all_objects from public;
>
> yields a syntax error. The docs show that the word "view" is not
> acceptable in this statement which is fine but the surprising thing is
> that:
>
> ? revoke all on table internal.all_objects from public;
>
> works fine even though all_objects is a view and not a table.
>
> Now that I know about it, this doesn't bother me but it was a surprise
> and I wonder whether the the parser/planner/whatever should be a bit
> smarter about allowing the word table to apply to non-tables, and
> whether the word view ought to be allowed.

Yes, I can confirm this behavior on CVS HEAD, and it is odd:

test=> CREATE SCHEMA internal;
CREATE SCHEMA
test=> CREATE VIEW internal.all_objects AS SELECT 1;
CREATE VIEW
test=> REVOKE ALL ON VIEW internal.all_objects FROM PUBLIC;
ERROR: syntax ERROR AT OR near "internal"
LINE 1: REVOKE ALL ON VIEW internal.all_objects FROM PUBLIC;
^
test=> REVOKE ALL ON TABLE internal.all_objects FROM PUBLIC;
REVOKE

Is there a downside to adding "VIEW" in parser/gram.y:privilege_target?

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Re: [BUGS] Recovery failed on a backup with " lock AccessShareLock on object 16477/244169/0 is already held"

Thanks for the quick reply Tom. I'll be updating my PG version to one
with a fix for bug #3245 so hopefully we won't see this anymore.

> BTW, what's with the bizarre "Local time zone must be set--see zic
> manual" where the timezone should be? Are you intentionally selecting
> the "Factory" zone?

I don't think I've put the correct timezone file in /etc/localtime so
it is using some default file from the Gentoo install.

John

On Mon, Jun 30, 2008 at 12:26 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> "John Smith" <sodgodofall@gmail.com> writes:
>> 2008-06-17 23:53:53.206 Local time zone must be set--see zic manual
>> page PANIC: failed to re-find shared lock object
>> 2008-06-17 23:53:53.207 Local time zone must be set--see zic manual
>> page STATEMENT: commit prepared '148969' ;
>
>> I believe this panic is probably bug #3245 based on the description of
>> that bug - http://archives.postgresql.org/pgsql-bugs/2007-04/msg00075.php
>
> Yeah, looks like it to me too.
>
>> At this point I attempted to do a recovery using the continuous
>> archive backup on the warm standby system. Instead of recovering
>> correctly it encountered this FATAL error where a AccessSharedLock was
>> already held.
>> 2008-06-18 00:05:34.298 Local time zone must be set--see zic manual
>> page FATAL: lock AccessShareLock on object 16477/244169/0 is already
>> held
>> 2008-06-18 00:05:34.299 Local time zone must be set--see zic manual
>> page LOG: startup process (PID 17377) exited with exit code 1
>> 2008-06-18 00:05:34.299 Local time zone must be set--see zic manual
>> page LOG: aborting startup due to startup process failure
>
>> Is this FATAL error seen on recovery a different bug or is it just a
>> direct result of bug #3245?
>
> It probably is the same bug. The underlying cause of that bug is
> explained here:
> http://archives.postgresql.org/pgsql-bugs/2007-04/msg00129.php
> I think what you are seeing is just a variant case caused by the same
> lock being written out to the twophase file twice. In any case there's
> probably little point in digging further until you've updated to a
> version with that fix --- if you still see the problem afterward,
> we can look closer.
>
> BTW, what's with the bizarre "Local time zone must be set--see zic
> manual" where the timezone should be? Are you intentionally selecting
> the "Factory" zone?
>
> regards, tom lane
>

--
Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-bugs

Re: [HACKERS] odd output in restore mode

Dave Page wrote:
> On Sun, May 18, 2008 at 1:38 PM, Andrew Dunstan <andrew@dunslane.net> wrote:
> >
> > I don't know how you tested,
>
> Copy a large file across a relatively slow network, and check the size
> on the destination drive before it finishes.
>
> > but could you please repeat the test with
> > GnuWin32's cp.exe? If it doesn't preallocate the space then I think our way
> > forward is reasonably clear:
>
> It does not pre-allocate.
>
> > . we recommend its use for Windows archive_command settings
> > . we provide the delay kluge as switchable behaviour on Windows instead of
> > having it always on.
>
> Sounds reasonable to me.

Are there any changes we need to make here?

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Re: [HACKERS] odd output in restore mode

Index: src/backend/access/transam/xlog.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.314
diff -c -c -r1.314 xlog.c
*** src/backend/access/transam/xlog.c 12 Jun 2008 09:12:30 -0000 1.314
--- src/backend/access/transam/xlog.c 30 Jun 2008 22:10:07 -0000
***************
*** 4523,4535 ****
/*
* does nothing if a recovery_target is not also set
*/
! if (strcmp(tok2, "true") == 0)
! recoveryTargetInclusive = true;
! else
! {
! recoveryTargetInclusive = false;
! tok2 = "false";
! }
ereport(LOG,
(errmsg("recovery_target_inclusive = %s", tok2)));
}
--- 4523,4532 ----
/*
* does nothing if a recovery_target is not also set
*/
! if (!parse_bool(tok2, &recoveryTargetInclusive))
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("parameter \"recovery_target_inclusive\" requires a Boolean value")));
ereport(LOG,
(errmsg("recovery_target_inclusive = %s", tok2)));
}
***************
*** 4538,4550 ****
/*
* does nothing if a recovery_target is not also set
*/
! if (strcmp(tok2, "true") == 0)
! recoveryLogRestartpoints = true;
! else
! {
! recoveryLogRestartpoints = false;
! tok2 = "false";
! }
ereport(LOG,
(errmsg("log_restartpoints = %s", tok2)));
}
--- 4535,4544 ----
/*
* does nothing if a recovery_target is not also set
*/
! if (!parse_bool(tok2, &recoveryLogRestartpoints))
! ereport(ERROR,
! (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
! errmsg("parameter \"log_restartpoints\" requires a Boolean value")));
ereport(LOG,
(errmsg("log_restartpoints = %s", tok2)));
}
Index: src/backend/utils/misc/guc.c
===================================================================
RCS file: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v
retrieving revision 1.457
diff -c -c -r1.457 guc.c
*** src/backend/utils/misc/guc.c 30 Jun 2008 10:58:47 -0000 1.457
--- src/backend/utils/misc/guc.c 30 Jun 2008 22:10:07 -0000
***************
*** 3991,3997 ****
* If the string parses okay, return true, else false.
* If okay and result is not NULL, return the value in *result.
*/
! static bool
parse_bool(const char *value, bool *result)
{
size_t len = strlen(value);
--- 3991,3997 ----
* If the string parses okay, return true, else false.
* If okay and result is not NULL, return the value in *result.
*/
! bool
parse_bool(const char *value, bool *result)
{
size_t len = strlen(value);
Index: src/include/utils/guc.h
===================================================================
RCS file: /cvsroot/pgsql/src/include/utils/guc.h,v
retrieving revision 1.96
diff -c -c -r1.96 guc.h
*** src/include/utils/guc.h 28 May 2008 09:04:06 -0000 1.96
--- src/include/utils/guc.h 30 Jun 2008 22:10:07 -0000
***************
*** 223,228 ****
--- 223,229 ----
extern void AtEOXact_GUC(bool isCommit, int nestLevel);
extern void BeginReportingGUCOptions(void);
extern void ParseLongOption(const char *string, char **name, char **value);
+ extern bool parse_bool(const char *value, bool *result);
extern bool set_config_option(const char *name, const char *value,
GucContext context, GucSource source,
GucAction action, bool changeVal);
Andrew Dunstan wrote:
>
> I have just been working on setting up a continuous recovery failover
> system, and noticed some odd log lines, shown below. (Using 8.3).
>
> First note that our parsing of recovery.conf in xlog.c is pretty bad,
> and at least we need to document the quirks if it's not going to be
> fixed. log_restartpoints is said to be boolean, but when I set it to an
> unquoted true I got a fatal error, while a quoted 'on' sets it to false,
> as seen. Ick. What is more, I apparently managed to get the recovery

I have fixed the boolean problem with the attached, applied patch. It
exposes guc.c::parse_bool() for use in xlog.c.

I assume all the other problems you reported have been corrected.

--
Bruce Momjian <bruce@momjian.us>

http://momjian.us

EnterpriseDB

http://enterprisedb.com

+ If your life is a hard drive, Christ can be your backup. +

[COMMITTERS] pgsql: Fix recovery.conf boolean variables to take the same range of

Log Message:
-----------
Fix recovery.conf boolean variables to take the same range of string
values as postgresql.conf.

Modified Files:
--------------
pgsql/src/backend/access/transam:
xlog.c (r1.314 -> r1.315)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/access/transam/xlog.c?r1=1.314&r2=1.315)
pgsql/src/backend/utils/misc:
guc.c (r1.457 -> r1.458)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/backend/utils/misc/guc.c?r1=1.457&r2=1.458)
pgsql/src/include/utils:
guc.h (r1.96 -> r1.97)
(http://anoncvs.postgresql.org/cvsweb.cgi/pgsql/src/include/utils/guc.h?r1=1.96&r2=1.97)

--
Sent via pgsql-committers mailing list (pgsql-committers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-committers

Re: [NOVICE] Adding to a date

Mike Ellsworth wrote:
> I was beginning to create some financial functions for calculating
> Future Values, PV's, etc...
>
> I'm hoping there is a way to:
> 1) Date of birth + xx years - with a result of date (Result 1)
> 2) Subtract now or an assumed date from Result 1 to get Result 2
>
Problems like 1 and 2 are easy - use "intervals".

select '1943-06-30'::date + '65 years'::interval;
2008-06-30 00:00:00

select current_date + '65 years'::interval;
2073-06-30 00:00:00


> 3) Divide by ~ 365.25 for years, which would be 'periods' in the function.
>

select ('2008-06-30'::date - '1943-06-30'::date)/365.25;

65.0020533880903491

Though there may be a better method for this. I'd need to poke around in
the date arithmetic.

Cheers,
Steve


--
Sent via pgsql-novice mailing list (pgsql-novice@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-novice

Fwd: [NOVICE] Adding to a date

Sorry, forgot to include the group in my reply...


---------- Forwarded message ----------
From: Harold A. Giménez Ch. <harold.gimenez@gmail.com>
Date: Mon, Jun 30, 2008 at 5:51 PM
Subject: Re: [NOVICE] Adding to a date
To: Mike Ellsworth <younicycle@gmail.com>


Intervals might help...for example:

timestamp '2001-09-28 01:00' + interval '23 hours' = timestamp
'2001-09-29 00:00:00'

Taken from here:
http://www.postgresql.org/docs/8.3/interactive/functions-datetime.html


On Mon, Jun 30, 2008 at 5:44 PM, Mike Ellsworth <younicycle@gmail.com> wrote:
>
> I was beginning to create some financial functions for calculating
> Future Values, PV's, etc -for basic retirement planning.
> example:
>
> CREATE OR REPLACE FUNCTION lotsa.FVPMT(payment double precision,
> interestRate double precision, periods double precision)
> RETURNS double precision AS
> $BODY$
> BEGIN
> return payment*(pow(1+interestRate, periods)-1)/interestRate;
> END;
> $BODY$
> LANGUAGE 'plpgsql' VOLATILE
>
> periods seems to be a problem. Usually, I'd be getting birth_date
> from a file, but I'm not finding a way to
> add 65 years - or 67 or whatever, to get the period between now (or an
> assumed date) and retirement.
>
> I'm hoping there is a way to:
> 1) Date of birth + xx years - with a result of date (Result 1)
> 2) Subtract now or an assumed date from Result 1 to get Result 2
> 3) Divide by ~ 365.25 for years, which would be 'periods' in the function.
>
> I've gotten around it, but it sure seems pretty messy:
> Greatest(FVPMT(test_fv.pmt, test_fv.i_rate,
> (23741.25-(test_fv.start_date-test_fv.dob))/365.25),0)
>
> where the 23741.25 is 65* 365.25.
>
> Any help would be appreciated. I've read all of what would seem to be
> appropriate.
> Doesn't mean I understood it, but I read it.
>
> I'm not concerned about being off by a day or 2.
> Small potatoes compared to the variations rate of return will undergo.
>
> Thanks
>
> --
> Sent via pgsql-novice mailing list (pgsql-novice@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-novice

--
Sent via pgsql-novice mailing list (pgsql-novice@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-novice

[NOVICE] Adding to a date

I was beginning to create some financial functions for calculating
Future Values, PV's, etc -for basic retirement planning.
example:

CREATE OR REPLACE FUNCTION lotsa.FVPMT(payment double precision,
interestRate double precision, periods double precision)
RETURNS double precision AS
$BODY$
BEGIN
return payment*(pow(1+interestRate, periods)-1)/interestRate;
END;
$BODY$
LANGUAGE 'plpgsql' VOLATILE

periods seems to be a problem. Usually, I'd be getting birth_date
from a file, but I'm not finding a way to
add 65 years - or 67 or whatever, to get the period between now (or an
assumed date) and retirement.

I'm hoping there is a way to:
1) Date of birth + xx years - with a result of date (Result 1)
2) Subtract now or an assumed date from Result 1 to get Result 2
3) Divide by ~ 365.25 for years, which would be 'periods' in the function.

I've gotten around it, but it sure seems pretty messy:
Greatest(FVPMT(test_fv.pmt, test_fv.i_rate,
(23741.25-(test_fv.start_date-test_fv.dob))/365.25),0)

where the 23741.25 is 65* 365.25.

Any help would be appreciated. I've read all of what would seem to be
appropriate.
Doesn't mean I understood it, but I read it.

I'm not concerned about being off by a day or 2.
Small potatoes compared to the variations rate of return will undergo.

Thanks

--
Sent via pgsql-novice mailing list (pgsql-novice@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-novice

Re: [HACKERS] Fairly serious bug induced by latest guc enum changes

Bruce Momjian <bruce@momjian.us> writes:
> Tom Lane wrote:
>> No, my point was that there are three possible states of sync_bit and
>> your patch only accounted for transitions between two of 'em.

> Did this every get addressed? I don't see a commit for it.

I thought it got fixed here:

2008-05-14 10:02 mha

* src/backend/access/transam/xlog.c: Remove the special variable
for open_sync_bit used in O_SYNC and O_DSYNC modes, replacing it
with a call to a function that derives it from the sync_method
variable, now that it has distinct values for these two cases.

This means that assign_xlog_sync_method() no longer changes any
settings, thus fixing the bug introduced in the change to use a guc
enum for wal_sync_method.

Hmm ... or at least more or less fixed. Seems like there's no provision
to close and reopen the file if enableFsync changes. Not sure if that's
worth worrying about.

regards, tom lane

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Re: [PATCHES] [HACKERS] get_relation_stats_hook()

Index: src/backend/optimizer/util/plancat.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/optimizer/util/plancat.c,v
retrieving revision 1.146
diff -c -r1.146 plancat.c
*** src/backend/optimizer/util/plancat.c 12 May 2008 00:00:49 -0000 1.146
--- src/backend/optimizer/util/plancat.c 30 Jun 2008 19:52:27 -0000
***************
*** 27,32 ****
--- 27,33 ----
#include "nodes/makefuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/plancat.h"
+ #include "optimizer/planhook.h"
#include "optimizer/predtest.h"
#include "optimizer/prep.h"
#include "parser/parse_expr.h"
***************
*** 45,52 ****
/* GUC parameter */
bool constraint_exclusion = false;

! /* Hook for plugins to get control in get_relation_info() */
! get_relation_info_hook_type get_relation_info_hook = NULL;


static List *get_relation_constraints(PlannerInfo *root,
--- 46,55 ----
/* GUC parameter */
bool constraint_exclusion = false;

! /* Hook for plugins to get planner info, defined in planhook.h */
! get_relation_info_hook_type get_relation_info_hook = NULL;
! get_relation_stats_hook_type get_relation_stats_hook = NULL;
! get_relation_avg_width_hook_type get_relation_avg_width_hook = NULL;


static List *get_relation_constraints(PlannerInfo *root,
Index: src/backend/utils/adt/selfuncs.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/utils/adt/selfuncs.c,v
retrieving revision 1.249
diff -c -r1.249 selfuncs.c
*** src/backend/utils/adt/selfuncs.c 12 May 2008 00:00:51 -0000 1.249
--- src/backend/utils/adt/selfuncs.c 30 Jun 2008 19:52:52 -0000
***************
*** 87,92 ****
--- 87,93 ----
#include "optimizer/pathnode.h"
#include "optimizer/paths.h"
#include "optimizer/plancat.h"
+ #include "optimizer/planhook.h"
#include "optimizer/predtest.h"
#include "optimizer/restrictinfo.h"
#include "optimizer/var.h"
***************
*** 3749,3755 ****
}
else if (rte->rtekind == RTE_RELATION)
{
! vardata->statsTuple = SearchSysCache(STATRELATT,
ObjectIdGetDatum(rte->relid),
Int16GetDatum(var->varattno),
0, 0);
--- 3750,3761 ----
}
else if (rte->rtekind == RTE_RELATION)
{
! if (get_relation_stats_hook)
! vardata->statsTuple = (*get_relation_stats_hook)
! (ObjectIdGetDatum(rte->relid),
! Int16GetDatum(var->varattno));
! else
! vardata->statsTuple = SearchSysCache(STATRELATT,
ObjectIdGetDatum(rte->relid),
Int16GetDatum(var->varattno),
0, 0);
***************
*** 3869,3878 ****
index->indpred == NIL)
vardata->isunique = true;
/* Has it got stats? */
! vardata->statsTuple = SearchSysCache(STATRELATT,
! ObjectIdGetDatum(index->indexoid),
! Int16GetDatum(pos + 1),
! 0, 0);
if (vardata->statsTuple)
break;
}
--- 3875,3889 ----
index->indpred == NIL)
vardata->isunique = true;
/* Has it got stats? */
! if (get_relation_stats_hook)
! vardata->statsTuple = (*get_relation_stats_hook)
! (ObjectIdGetDatum(index->indexoid),
! Int16GetDatum(pos + 1));
! else
! vardata->statsTuple = SearchSysCache(STATRELATT,
! ObjectIdGetDatum(index->indexoid),
! Int16GetDatum(pos + 1),
! 0, 0);
if (vardata->statsTuple)
break;
}
***************
*** 5507,5516 ****
colnum = 1;
}

! tuple = SearchSysCache(STATRELATT,
! ObjectIdGetDatum(relid),
! Int16GetDatum(colnum),
! 0, 0);

if (HeapTupleIsValid(tuple))
{
--- 5518,5532 ----
colnum = 1;
}

! if (get_relation_stats_hook)
! tuple = (*get_relation_stats_hook) (
! ObjectIdGetDatum(relid),
! Int16GetDatum(colnum));
! else
! tuple = SearchSysCache(STATRELATT,
! ObjectIdGetDatum(relid),
! Int16GetDatum(colnum),
! 0, 0);

if (HeapTupleIsValid(tuple))
{
Index: src/backend/utils/cache/lsyscache.c
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/backend/utils/cache/lsyscache.c,v
retrieving revision 1.157
diff -c -r1.157 lsyscache.c
*** src/backend/utils/cache/lsyscache.c 13 Apr 2008 20:51:21 -0000 1.157
--- src/backend/utils/cache/lsyscache.c 30 Jun 2008 19:54:46 -0000
***************
*** 27,32 ****
--- 27,33 ----
#include "catalog/pg_proc.h"
#include "catalog/pg_statistic.h"
#include "catalog/pg_type.h"
+ #include "optimizer/planhook.h"
#include "miscadmin.h"
#include "nodes/makefuncs.h"
#include "utils/array.h"
***************
*** 2457,2462 ****
--- 2458,2468 ----
{
HeapTuple tp;

+ if (get_relation_avg_width_hook)
+ return (*get_relation_avg_width_hook) (
+ ObjectIdGetDatum(relid),
+ Int16GetDatum(attnum));
+
tp = SearchSysCache(STATRELATT,
ObjectIdGetDatum(relid),
Int16GetDatum(attnum),
Index: src/include/optimizer/plancat.h
===================================================================
RCS file: /home/sriggs/pg/REPOSITORY/pgsql/src/include/optimizer/plancat.h,v
retrieving revision 1.49
diff -c -r1.49 plancat.h
*** src/include/optimizer/plancat.h 1 Apr 2008 00:48:33 -0000 1.49
--- src/include/optimizer/plancat.h 30 Jun 2008 13:41:48 -0000
***************
*** 17,30 ****
#include "nodes/relation.h"
#include "utils/rel.h"

- /* Hook for plugins to get control in get_relation_info() */
- typedef void (*get_relation_info_hook_type) (PlannerInfo *root,
- Oid relationObjectId,
- bool inhparent,
- RelOptInfo *rel);
- extern PGDLLIMPORT get_relation_info_hook_type get_relation_info_hook;
-
-
extern void get_relation_info(PlannerInfo *root, Oid relationObjectId,
bool inhparent, RelOptInfo *rel);

--- 17,22 ----
/*-------------------------------------------------------------------------
*
* planhook.h
* prototypes for plan hooks
*
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/planhook.h,v 1.48 2008/03/15 20:46:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef PLANHOOK_H
#define PLANHOOK_H

#include "access/htup.h"
#include "nodes/relation.h"
#include "utils/rel.h"

/* Hook for plugins to get control in get_relation_info() */
typedef void (*get_relation_info_hook_type) (PlannerInfo *root,
Oid relationObjectId,
bool inhparent,
RelOptInfo *rel);
extern PGDLLIMPORT get_relation_info_hook_type get_relation_info_hook;

/*
* The following hooks are called per-attribute in later stages of the
* planner because this detailed information is not stored in the RelOptInfo
* data structure. The APIs emulate stats data access from pg_statistic,
* rather than attempting a more abstract form.
*/
typedef HeapTuple (*get_relation_stats_hook_type) (Datum relid, Datum attnum);
extern PGDLLIMPORT get_relation_stats_hook_type get_relation_stats_hook;

typedef int32 (*get_relation_avg_width_hook_type) (Datum relid, Datum attnum);
extern PGDLLIMPORT get_relation_avg_width_hook_type get_relation_avg_width_hook;

#endif /* PLANHOOK_H */
On Thu, 2008-06-26 at 12:50 -0400, Tom Lane wrote:
> Simon Riggs <simon@2ndquadrant.com> writes:
> >> Surely you didn't mean ALL calls. Please be more specific about what
> >> you're proposing.
>
> > The statistics relation STATRELATT is accessed in a few places in the
> > planner. Since it is in the syscache it is accessed directly from there.
> > I would like to add hooks so that stats data can come from somewhere
> > else other than the syscache for tables, just as we can already do with
> > get_relation_stats_hook().
>
> Well, defining the hooks as replacing STATRELATT lookups seems the wrong
> level of abstraction. What if you want to insert stats that can't be
> represented by the current pg_statistic definition? Even if there's no
> functional limitation, cons'ing up a dummy pg_statistic tuple seems the
> hard way to do it --- we didn't define get_relation_info_hook as working
> by supplying made-up catalog rows. Furthermore, many of the interesting
> cases that someone might want to hook into are code paths that don't
> even try to look up a pg_statistic row because they know there won't be
> one, such as two out of the three cases in examine_variable().
>
> I think you need to move up a level, and perhaps refactor some of the
> existing code to make it easier to inject made-up stats.

I've looked at ways of refactoring this, but the hooks provided here
complement the existing functionality fairly well.

We could add per column info to RelOptInfo, though toasted stats data is
always going to be difficult to handle.

There are other ways of doing this
1. replace selfuncs directly via the catalog
2. put in a hook for each selfunc at top level
3. decide an abstract API we would like to support

1 is possible now, 2 can still be done whether or not this patch is
accepted and I will likely submit a patch for that also, though 3 is too
open ended to pursue right now, IMHO.

Also, this patch can be backpatched more easily, to allow helping
current issues.

--
Simon Riggs

www.2ndQuadrant.com

PostgreSQL Training, Services and Support

Re: [GENERAL] Max array size

"Postgres User" <postgres.developer@gmail.com> writes:
> Does anyone know the maximum number of elements allowed in a
> one-dimensional array? It looks like my script may add at least a
> couple million, not sure if it will hit a limit...

You'd hit the 1GB field size limit before you hit anything else,
at least in terms of hard limits. But the *practical* limit is likely
to be a whole lot less, especially if you are talking about a
variable-width datatype. Indexing into such a large array would
perform poorly.

I'd counsel redesigning your data representation. You'll be a lot
happier with the performance of a table with a couple million rows
than with an array with a couple million entries.

regards, tom lane

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general