Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-12 Thread Tom Lane
[EMAIL PROTECTED] writes:
 - Re uni-directional logs

 Of course. I forgot about PG's non-in-place update mechanisms and the
 use of VACCUUM .. with versioning there are really no undo logging
 necessary. I guess that means that during VACCUUM you might have to
 significant work in indexes ? I'm assuming that you never merge index
 pages.

Yes, VACUUM has to delete dead index entries as well as dead heap
tuples, and there are some fine points about making sure that happens
in a safe order.

I believe the current state of index space recovery is

* btree: recycles emptied index pages via a freelist; can return empty
pages to the OS if they're at the end of the index file, but will not
move pages around to make it possible to return more empty pages.
(This is all new behavior as of 7.4, before we didn't do anything about
reclaiming dead space in btrees.)  Does not try to merge partially-full
pages (this is a possible future improvement but there are concurrency
problems that would need to be solved).

* hash: recycles empty pages via a freelist, never returns them to OS
short of a REINDEX.  I think it does merge partially-empty pages within
each bucket chain.  No provision for reducing the number of buckets
if the index population shrinks (again, short of REINDEX).

* rtree, gist: no page recycling that I know of, but I've not looked
carefully.

regards, tom lane

---(end of broadcast)---
TIP 4: Don't 'kill -9' the postmaster


[HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Marty Scholes
I combed the archives but could not find a discussion on this and am 
amazed this hasn't been discussed.

My experience with Oracle (and now limited experience with Pg) is that 
the major choke point in performance is not the CPU or read I/O, it is 
the log performance of big update and select statements.

Essentially, the data is written twice: first to the log and then the 
data files.  This would be ok except the transaction is regularly frozen 
while the log files sync to disk with a bunch of tiny (8KB for Oracle 
and Pg) write requests.

I realize that the logs must be there to ensure crash recovery and that 
PITR is on the way to supplement this.

If a transaction will do large updates or inserts, why don't we just log 
the parsed statements in the WAL instead of the individual data blocks 
that have changed?  Then, the data files could be fsync()ed every 
checkpoint, but essentially no write I/O takes places in the interim.

Outside of checkpoints, large updates would only need to fsync() a very 
small addition to the log files.

Recovery could be similar to how I understand it currently is:
1. Roll back in-flight changes
2. Roll forward log entries in order, either direct changes to the data 
or re-execute the parsed command in the log.

Some informal testing suggests that we get a factor of 8 improvement in 
speed here if we completely disable fsync() in large updates under Pg.

I would suspect that a big portion of those gains would be preserved if 
fsync() calls were limited to checkpoints and saving the parsed SQL 
command in the log.

Why have I not seen this in any database?

There must be a reason.

Thanks in advance.

Sincerely,
Marty
---(end of broadcast)---
TIP 6: Have you searched our list archives?
  http://archives.postgresql.org


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Rod Taylor
 If a transaction will do large updates or inserts, why don't we just log 
 the parsed statements in the WAL instead of the individual data blocks 

UPDATE table SET col = random();



---(end of broadcast)---
TIP 2: you can get off all lists at once with the unregister command
(send unregister YourEmailAddressHere to [EMAIL PROTECTED])


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Sailesh Krishnamurthy
 Marty == Marty Scholes [EMAIL PROTECTED] writes:

Marty Why have I not seen this in any database?
Marty There must be a reason.

For ARIES-style systems, logging parsed statements (commonly called
logical logging) is not preferred compared to logging data items
(physical or physiological logging). 

A major reason for this is that logical logs make recovery contingent
on being able to execute the parsed statements. This execution
might, however, not be possible if the system is itself not in a
consistent state .. as is normally the case during recovery. 

What if, for instance, it's the catalog tables that were hosed when
the system went down ? It may be difficult to execute the parsed
statements without the catalogs. 

For this reason, a major goal of ARIES was to have each and every data
object (tables/indexes) individually recoverable. So ARIES follows
page-oriented redo logging.

Having said that, page-oriented undo logging can be a pain when B-tree
pages split. For higher concurrency, ARIES uses logical undo
logging. In this case, the logs are akin to your parsed statement
idea.

In any case, the only place that parsed statements are useful, imo are
with searched updates that cause a large number of records to change
and with insert into from select statements.

Then, there is also the case that this, the parsed statements
approach, is not a general solution. How would you handle the update
current of cursor scenarios ? In this case, there is some application
logic that determines the precise records that change and how they
change. 

Ergo, it is my claim that while logical redo logging does have some
benefits, it is not a viable general solution.

-- 
Pip-pip
Sailesh
http://www.cs.berkeley.edu/~sailesh



---(end of broadcast)---
TIP 9: the planner will ignore your desire to choose an index scan if your
  joining column's datatypes do not match


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Tom Lane
Marty Scholes [EMAIL PROTECTED] writes:
 My experience with Oracle (and now limited experience with Pg) is that 
 the major choke point in performance is not the CPU or read I/O, it is 
 the log performance of big update and select statements.

If your load is primarily big update statements, maybe so...

 Essentially, the data is written twice: first to the log and then the 
 data files.  This would be ok except the transaction is regularly frozen 
 while the log files sync to disk with a bunch of tiny (8KB for Oracle 
 and Pg) write requests.

I don't think I buy that claim.  We don't normally fsync the log file
except at transaction commit (and read-only transactions don't generate
any commit record, so they don't cause an fsync).  If a single
transaction is generating lots of log data, it doesn't have to wait for
that data to hit disk before it can do more stuff.

But having said that --- on some platforms our default WAL sync method
is open_datasync, which could result in the sort of behavior you are
talking about.  Try experimenting with the other possible values of
wal_sync_method to see if you like them better.

 If a transaction will do large updates or inserts, why don't we just log 
 the parsed statements in the WAL instead of the individual data blocks 
 that have changed?

As already pointed out, this would not give enough information to
reproduce the database state.

 Some informal testing suggests that we get a factor of 8 improvement in 
 speed here if we completely disable fsync() in large updates under Pg.

That probably gets you into a situation where no I/O is really happening
at all, it's just being absorbed by kernel disk buffers.  Unfortunately
that doesn't have a lot to do with the performance you can get if you
want to be sure you don't lose data ...

BTW, one thing you can do to reduce the WAL I/O volume in Postgres is
to increase the inter-checkpoint interval (there are two settings to
increase, one time-based and one volume-based).  The first write of a
given data page after a checkpoint dumps the whole page into WAL, as a
safety measure to deal with partial page writes during power failures.
So right after a checkpoint the WAL volume goes way up.  With a longer
interval between checkpoints you don't pay that price as often.

regards, tom lane

---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Marty Scholes
I can see that and considered it.

The seed state would need to be saved, or any particular command that is 
not reproducible would need to be exempted from this sort of logging.

Again, this would apply only to situations where a small SQL command 
created huge changes.

Marty

Rod Taylor wrote:
If a transaction will do large updates or inserts, why don't we just log 
the parsed statements in the WAL instead of the individual data blocks 


UPDATE table SET col = random();




---(end of broadcast)---
TIP 9: the planner will ignore your desire to choose an index scan if your
 joining column's datatypes do not match


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Rod Taylor
On Thu, 2004-03-11 at 21:04, Marty Scholes wrote:
 I can see that and considered it.
 
 The seed state would need to be saved, or any particular command that is 
 not reproducible would need to be exempted from this sort of logging.
 
 Again, this would apply only to situations where a small SQL command 
 created huge changes.

I would say a majority of SQL queries in most designed systems
(timestamp). Not to mention the fact the statement itself may use very
expensive functions -- perhaps even user functions that don't repeatably
do the same thing or depend on data from other tables.

Consider a successful write to table X for transaction 2, but an
unsuccessful write to table Y for transaction 1. Transaction 1 calls a
function that uses information from table X -- but it'll get different
information this time around.


Anyway, it really doesn't matter. You're trying to save a large amount
of time that simply isn't spent in this area in PostgreSQL. fsync()
happens once with commit -- and on a busy system, a single fsync call
may be sufficient for a number of parallel backends.



---(end of broadcast)---
TIP 2: you can get off all lists at once with the unregister command
(send unregister YourEmailAddressHere to [EMAIL PROTECTED])


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Marty Scholes
 A major reason for this is that logical logs make recovery contingent
 on being able to execute the parsed statements. This execution
 might, however, not be possible if the system is itself not in a
 consistent state .. as is normally the case during recovery.

I am not sure I follow you here.  The logs should (IMHO) save both types 
of data: physical pages (what happens now), or the SQL statement if it 
is small and generates a bunch of changes.

If the DB state cannot be put back to a consistent state prior to a SQL 
statement in the log, then NO amount of logging will help.  The idea is 
that the state can be put back to what it was prior to a particular log 
entry, be it raw datafile blocks or a SQL statement.

 What if, for instance, it's the catalog tables that were hosed when
 the system went down ? It may be difficult to execute the parsed
 statements without the catalogs.

See above.  If this cannot be resolved prior to re-executing a statement 
in the log, then the problem is beyond ANY subsequent logging.

 Having said that, page-oriented undo logging can be a pain when B-tree
 pages split. For higher concurrency, ARIES uses logical undo
 logging. In this case, the logs are akin to your parsed statement
 idea.

Yes, my experience exactly.  Maybe we are the only company on the planet 
that experiences this sort of thing.  Maybe not.

 In any case, the only place that parsed statements are useful, imo are
 with searched updates that cause a large number of records to change
 and with insert into from select statements.

Yes.  Correlated UPDATE, INSERT INTO with subselects AND mass DELETE on 
heavily indexed tables.  Index creation...  The list goes on and on.  I 
have experienced and live it all on a daily basis with Oracle.  And I 
despise it.

The difference is, of course, I can't even have this kind of discussion 
with Oracle, but I can here.  ;-)

 Then, there is also the case that this, the parsed statements
 approach, is not a general solution. How would you handle the update
 current of cursor scenarios ? In this case, there is some application
 logic that determines the precise records that change and how they
 change.

 Ergo, it is my claim that while logical redo logging does have some
 benefits, it is not a viable general solution.

Agreed, this is not a general solution.  What it is, however, is a 
tremendous improvement over the current situation for transactions that 
do massive changes to heavily indexed datasets.

I am working on an application right now that will require current 
postal information on EVERY address in the U.S. -- street name, street 
address, directional, subunit, 5 digit zip, 3 digit zip, city, state, 
delivery point barcode, carrier route, lattitude, longitude, etc.  Most 
of these fields will need to be indexed, because they will be searched 
in real time via a web application several thousand times per day.

To keep the address current, we will be updating them all (150+ million) 
 on a programmed basis, so we will go through and update several 
million addresses EVERY DAY, while needing to ensure that the address 
updates happen atomically so that they don't disrupt web activity.

Maybe this is not a traditional RDBMS app, but I am not in the mood to 
write my own storage infrastructure for it.

Then again, maybe I don't know what I am talking about...

Marty

Sailesh Krishnamurthy wrote:
Marty == Marty Scholes [EMAIL PROTECTED] writes:

Marty Why have I not seen this in any database?
Marty There must be a reason.
For ARIES-style systems, logging parsed statements (commonly called
logical logging) is not preferred compared to logging data items
(physical or physiological logging). 

A major reason for this is that logical logs make recovery contingent
on being able to execute the parsed statements. This execution
might, however, not be possible if the system is itself not in a
consistent state .. as is normally the case during recovery. 

What if, for instance, it's the catalog tables that were hosed when
the system went down ? It may be difficult to execute the parsed
statements without the catalogs. 

For this reason, a major goal of ARIES was to have each and every data
object (tables/indexes) individually recoverable. So ARIES follows
page-oriented redo logging.
Having said that, page-oriented undo logging can be a pain when B-tree
pages split. For higher concurrency, ARIES uses logical undo
logging. In this case, the logs are akin to your parsed statement
idea.
In any case, the only place that parsed statements are useful, imo are
with searched updates that cause a large number of records to change
and with insert into from select statements.
Then, there is also the case that this, the parsed statements
approach, is not a general solution. How would you handle the update
current of cursor scenarios ? In this case, there is some application
logic that determines the precise records that change and how they
change. 

Ergo, it is my claim that 

Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Marty Scholes
 If your load is primarily big update statements, maybe so...

It is.  Maybe we are anomalous here.

 I don't think I buy that claim.  We don't normally fsync the log file
 except at transaction commit (and read-only transactions
 don't generate
 any commit record, so they don't cause an fsync).  If a single
 transaction is generating lots of log data, it doesn't have
 to wait for
 that data to hit disk before it can do more stuff.
I have glanced at the code, and I agree that reads do not generate 
fsync() calls.  Since I watched my mirrored RAID 5 arrays hit 2,000 iops 
with an average request of 4 KB on a recent batch update with Pg, I 
still think that Pg may be fsync()-ing a bit too often.

Since I haven't digested all of the code, I am speaking a bit out of turn.

 But having said that --- on some platforms our default WAL sync method
 is open_datasync, which could result in the sort of behavior you are
 talking about.  Try experimenting with the other possible values of
 wal_sync_method to see if you like them better.
I will have to check that.  I am running Sparc Solaris 8.

 That probably gets you into a situation where no I/O
 is really happening
 at all, it's just being absorbed by kernel disk
 buffers.
Few things would please me more.

 Unfortunately
 that doesn't have a lot to do with the performance you can get if you
 want to be sure you don't lose data ...
I am not sure these are as mutually exclusive as it looks here.


 BTW, one thing you can do to reduce the WAL I/O volume in Postgres is
 to increase the inter-checkpoint interval (there are two settings to
 increase, one time-based and one volume-based).  The first write of a
 given data page after a checkpoint dumps the whole page into WAL, as a
 safety measure to deal with partial page writes during power failures.
 So right after a checkpoint the WAL volume goes way up.  With a longer
 interval between checkpoints you don't pay that price as often.
I did that and it helped tremendously.  Without proper tuning, I just 
made the numbers pretty large:

shared_buffers = 10
sort_mem = 131072
vacuum_mem = 65536
wal_buffers = 8192
checkpoint_segments = 32
Thanks for your feedback.

Sincerely,
Marty
Tom Lane wrote:
Marty Scholes [EMAIL PROTECTED] writes:

My experience with Oracle (and now limited experience with Pg) is that 
the major choke point in performance is not the CPU or read I/O, it is 
the log performance of big update and select statements.


If your load is primarily big update statements, maybe so...


Essentially, the data is written twice: first to the log and then the 
data files.  This would be ok except the transaction is regularly frozen 
while the log files sync to disk with a bunch of tiny (8KB for Oracle 
and Pg) write requests.


I don't think I buy that claim.  We don't normally fsync the log file
except at transaction commit (and read-only transactions don't generate
any commit record, so they don't cause an fsync).  If a single
transaction is generating lots of log data, it doesn't have to wait for
that data to hit disk before it can do more stuff.
But having said that --- on some platforms our default WAL sync method
is open_datasync, which could result in the sort of behavior you are
talking about.  Try experimenting with the other possible values of
wal_sync_method to see if you like them better.

If a transaction will do large updates or inserts, why don't we just log 
the parsed statements in the WAL instead of the individual data blocks 
that have changed?


As already pointed out, this would not give enough information to
reproduce the database state.

Some informal testing suggests that we get a factor of 8 improvement in 
speed here if we completely disable fsync() in large updates under Pg.


That probably gets you into a situation where no I/O is really happening
at all, it's just being absorbed by kernel disk buffers.  Unfortunately
that doesn't have a lot to do with the performance you can get if you
want to be sure you don't lose data ...
BTW, one thing you can do to reduce the WAL I/O volume in Postgres is
to increase the inter-checkpoint interval (there are two settings to
increase, one time-based and one volume-based).  The first write of a
given data page after a checkpoint dumps the whole page into WAL, as a
safety measure to deal with partial page writes during power failures.
So right after a checkpoint the WAL volume goes way up.  With a longer
interval between checkpoints you don't pay that price as often.
			regards, tom lane

---(end of broadcast)---
TIP 1: subscribe and unsubscribe commands go to [EMAIL PROTECTED]


---(end of broadcast)---
TIP 7: don't forget to increase your free space map settings


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Marty Scholes
 Anyway, it really doesn't matter. You're trying to save a large amount
 of time that simply isn't spent in this area in PostgreSQL. fsync()
 happens once with commit -- and on a busy system, a single fsync call
 may be sufficient for a number of parallel backends.
I think you may be right.  I suspect that most busy installations run 
a large number of light update/delete/insert statements.

In this scenario, the kind of logging I am talking about would make 
things worse, much worse.

Marty

Rod Taylor wrote:
On Thu, 2004-03-11 at 21:04, Marty Scholes wrote:

I can see that and considered it.

The seed state would need to be saved, or any particular command that is 
not reproducible would need to be exempted from this sort of logging.

Again, this would apply only to situations where a small SQL command 
created huge changes.


I would say a majority of SQL queries in most designed systems
(timestamp). Not to mention the fact the statement itself may use very
expensive functions -- perhaps even user functions that don't repeatably
do the same thing or depend on data from other tables.
Consider a successful write to table X for transaction 2, but an
unsuccessful write to table Y for transaction 1. Transaction 1 calls a
function that uses information from table X -- but it'll get different
information this time around.
Anyway, it really doesn't matter. You're trying to save a large amount
of time that simply isn't spent in this area in PostgreSQL. fsync()
happens once with commit -- and on a busy system, a single fsync call
may be sufficient for a number of parallel backends.


---(end of broadcast)---
TIP 2: you can get off all lists at once with the unregister command
(send unregister YourEmailAddressHere to [EMAIL PROTECTED])


---(end of broadcast)---
TIP 7: don't forget to increase your free space map settings


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Sailesh Krishnamurthy

(Just a note: my comments are not pg-specific .. indeed I don't know
much about pg recovery).

 Marty == Marty Scholes [EMAIL PROTECTED] writes:

Marty If the DB state cannot be put back to a consistent state
Marty prior to a SQL statement in the log, then NO amount of
Marty logging will help.  The idea is that the state can be put
Marty back to what it was prior to a particular log entry, be it
Marty raw datafile blocks or a SQL statement.

The point is that with redo logging, you can just blindly apply the
log to the data pages in question, without even really restarting the
database.

Note that in ARIES, recovery follows: (1) analysis, (2) redo
_everything_ since last checkpoint, (3) undo losers. 

So logging carefully will indeed help get the system to a consistent
state - actually after phase (2) above the system will be in precisely
the state during the crash .. and all that's left to do is undo all
the live transactions (losers). 

BTW, logging raw datafile blocks would be pretty gross (physical
logging) and so ARIES logs the changes to each tuple in logical
fashion .. so if only one column changes only that value (before and
after images) are logged. This is what's called physiological
logging.

Marty See above.  If this cannot be resolved prior to
Marty re-executing a statement in the log, then the problem is
Marty beyond ANY subsequent logging.

Not true ! By applying the log entries carefully you should be able to
restore the system to a consistent state. 

 Having said that, page-oriented undo logging can be a pain when
 B-tree pages split. For higher concurrency, ARIES uses logical
 undo logging. In this case, the logs are akin to your parsed
 statement idea.
 

Marty Yes, my experience exactly.  Maybe we are the only company
Marty on the planet that experiences this sort of thing.  Maybe

Well, logical undo is still at a much lower level than parsed
statements. Each logical undo log is something like delete key 5 from
index xyz. 

Marty Maybe this is not a traditional RDBMS app, but I am not
Marty in the mood to write my own storage infrastructure for it.

I agree that your app has a lot of updates .. it's just that I'm not
convinced that logical logging is a clean solution. 

I also don't have a solution for your problem :-)

-- 
Pip-pip
Sailesh
http://www.cs.berkeley.edu/~sailesh



---(end of broadcast)---
TIP 4: Don't 'kill -9' the postmaster


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Marty Scholes
 The point is that with redo logging, you can just blindly apply the
 log to the data pages in question, without even really restarting the
 database.
I also am not a recovery expert, but I have watched it happen more than 
once.

You bring up a good point.  My (perhaps false) understanding with 
recovery/redo was that the last checkpointed state was recreated, then 
log changes that finished with a commit were applied and the rest discarded.

Actually, this approach would not be ideal, since the last checkpointed 
state would be unavailable if any data file writes took place between 
the checkpoint and the crash.

Further, post-checkpoint log entries would surely contain multiple 
copies of the same data block, and there is no point in applying any but 
the last log entry for a particular block.

Ok.  To recap:

* Logging parsed statements don't apply to light updates and most 
installations live mostly on light updates
* Logging parsed statements would not work if the checkpoint state could 
not be recreated, which is likely the case.

So, this soluition won't work, and even if it did, would not apply to 
the vast majority of users.

Hmmm...  No wonder it hasn't been implemented yet.  ;-)

Thanks again,
Marty
Sailesh Krishnamurthy wrote:
(Just a note: my comments are not pg-specific .. indeed I don't know
much about pg recovery).

Marty == Marty Scholes [EMAIL PROTECTED] writes:

Marty If the DB state cannot be put back to a consistent state
Marty prior to a SQL statement in the log, then NO amount of
Marty logging will help.  The idea is that the state can be put
Marty back to what it was prior to a particular log entry, be it
Marty raw datafile blocks or a SQL statement.
The point is that with redo logging, you can just blindly apply the
log to the data pages in question, without even really restarting the
database.
Note that in ARIES, recovery follows: (1) analysis, (2) redo
_everything_ since last checkpoint, (3) undo losers. 

So logging carefully will indeed help get the system to a consistent
state - actually after phase (2) above the system will be in precisely
the state during the crash .. and all that's left to do is undo all
the live transactions (losers). 

BTW, logging raw datafile blocks would be pretty gross (physical
logging) and so ARIES logs the changes to each tuple in logical
fashion .. so if only one column changes only that value (before and
after images) are logged. This is what's called physiological
logging.
Marty See above.  If this cannot be resolved prior to
Marty re-executing a statement in the log, then the problem is
Marty beyond ANY subsequent logging.
Not true ! By applying the log entries carefully you should be able to
restore the system to a consistent state. 

 Having said that, page-oriented undo logging can be a pain when
 B-tree pages split. For higher concurrency, ARIES uses logical
 undo logging. In this case, the logs are akin to your parsed
 statement idea.
 

Marty Yes, my experience exactly.  Maybe we are the only company
Marty on the planet that experiences this sort of thing.  Maybe
Well, logical undo is still at a much lower level than parsed
statements. Each logical undo log is something like delete key 5 from
index xyz. 

Marty Maybe this is not a traditional RDBMS app, but I am not
Marty in the mood to write my own storage infrastructure for it.
I agree that your app has a lot of updates .. it's just that I'm not
convinced that logical logging is a clean solution. 

I also don't have a solution for your problem :-)



---(end of broadcast)---
TIP 3: if posting/reading through Usenet, please send an appropriate
 subscribe-nomail command to [EMAIL PROTECTED] so that your
 message can get through to the mailing list cleanly


Re: [HACKERS] Performance and WAL on big inserts/updates

2004-03-11 Thread Tom Lane
Sailesh Krishnamurthy [EMAIL PROTECTED] writes:
 (Just a note: my comments are not pg-specific .. indeed I don't know
 much about pg recovery).
 ...
 BTW, logging raw datafile blocks would be pretty gross (physical
 logging) and so ARIES logs the changes to each tuple in logical
 fashion .. so if only one column changes only that value (before and
 after images) are logged. This is what's called physiological
 logging.

What PG currently uses is sort of a hybrid approach.  The basic WAL
entry normally gives tuple-level detail: a tuple image and location
for an INSERT, a new tuple image and old and new locations for UPDATE,
a tuple location for DELETE, etc.  This might be a bit bulkier than
necessary for UPDATEs that change few columns, but it's consistent and
easy to replay.

However, as I mentioned to Marty, the very first change to any disk page
after a checkpoint will dump an entire (post-change) image of that page
into the log, in place of the tuple image or other detail that would
allow us to redo the change to that page.  The purpose of this is to
ensure that if a page is only partially written during a power failure,
we have the ability to recreate the entire correct page contents from
WAL by replaying everything since the last checkpoint.  Replay is thus
a write-only operation as far as the data files are concerned --- we
only write full pages or modify previously written pages.

(You may be thinking well, what about a partial write to WAL --- but
if that happens, that's where we stop replaying WAL.  The checksums on
WAL entries allow us to detect the invalid data before we use it.
So we will still have a consistent valid state on disk, showing the
effects of everything up through the last undamaged WAL record.)

BTW this is a one-directional log.  We do not care about UNDO, only
replay.  There is nothing that need be undone from a failed transaction;
it can only have littered the database with dead tuples, which will
eventually be reclaimed by VACUUM.

 Having said that, page-oriented undo logging can be a pain when
 B-tree pages split.

We don't bother to undo index page splits either ...

regards, tom lane

---(end of broadcast)---
TIP 5: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faqs/FAQ.html