Enabling Checksums

Started by Jeff Davisover 13 years ago365 messageshackers
Jump to latest
#1Jeff Davis
pgsql@j-davis.com

As I understand it, the main part of the remaining work to be done for
the checksums patch (at least the first commit) is to have a better way
to enable/disable them.

For the sake of simplicity (implementation as well as usability), it
seems like there is agreement that checksums should be enabled or
disabled for the entire instance, not per-table.

I don't think a GUC entirely makes sense (in its current form, anyway).
We basically care about 3 states:
1. Off: checksums are not written, nor are they verified. Pages that
are newly dirtied have the checksum information in the header cleared.
2. Enabling: checksums are written for every dirty page, but only
verified for pages where the checksum is present (as determined by
information in the page header).
3. On: checksums are written for every dirty page, and verified for
every page that's read. If a page does not have a checksum, it's
corrupt.

Does it make sense to store this information in pg_control? That doesn't
require adding any new file, and it has the benefit that it's already
checksummed. It's available during recovery and can be made available
pretty easily in the places where we write data.

And the next question is what commands to add to change state. Ideas:

CHECKSUMS ENABLE; -- set state to "Enabling"
CHECKSUMS DISABLE; -- set state to "Off"

And then to get to the "On" state, you have to run a system-wide VACUUM
while in the "Enabling" state. Or, if the above syntax causes problems,
we can make all of these into VACUUM options.

Thoughts?

Regards,
Jeff Davis

#2Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Jeff Davis (#1)
Re: Enabling Checksums

Jeff Davis wrote:

And the next question is what commands to add to change state. Ideas:

CHECKSUMS ENABLE; -- set state to "Enabling"
CHECKSUMS DISABLE; -- set state to "Off"

And then to get to the "On" state, you have to run a system-wide VACUUM
while in the "Enabling" state. Or, if the above syntax causes problems,
we can make all of these into VACUUM options.

There's no such thing as a system-wide VACUUM. The most you can get is
a database-wide VACUUM, which means you'd have to store the state
per-database somewhere (presumably the pg_database catalog), and perhaps
pg_control could have it as a system-wide value that's computed as the
minimum of all database states (so it stays "enabling" until all
databases have upgraded to "on").

--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

#3Amit Kapila
amit.kapila16@gmail.com
In reply to: Jeff Davis (#1)
Re: Enabling Checksums

On Friday, November 09, 2012 6:32 AM Jeff Davis wrote:

As I understand it, the main part of the remaining work to be done for
the checksums patch (at least the first commit) is to have a better way
to enable/disable them.

For the sake of simplicity (implementation as well as usability), it
seems like there is agreement that checksums should be enabled or
disabled for the entire instance, not per-table.

I don't think a GUC entirely makes sense (in its current form, anyway).
We basically care about 3 states:
1. Off: checksums are not written, nor are they verified. Pages that
are newly dirtied have the checksum information in the header cleared.
2. Enabling: checksums are written for every dirty page, but only
verified for pages where the checksum is present (as determined by
information in the page header).
3. On: checksums are written for every dirty page, and verified for
every page that's read. If a page does not have a checksum, it's
corrupt.

Does it make sense to store this information in pg_control? That doesn't
require adding any new file, and it has the benefit that it's already
checksummed. It's available during recovery and can be made available
pretty easily in the places where we write data.

And the next question is what commands to add to change state. Ideas:

CHECKSUMS ENABLE; -- set state to "Enabling"
CHECKSUMS DISABLE; -- set state to "Off"

And then to get to the "On" state, you have to run a system-wide VACUUM
while in the "Enabling" state. Or, if the above syntax causes problems,
we can make all of these into VACUUM options.

I think one thing may needs to be taken care during such a VACUUM operation
is not to allow user to say
CHECKSUM DISABLE.

Also how about following ways :
1. Allow CHECKSUM Enable only during initdb as mentioned by Robert.
Allow user to only do CHECKSUM DISABLE after initdb.
2. Do the Checksum only for particular pages (SRLU) or to do for System
tables only.

With Regards,
Amit Kapila.

#4Jesper Krogh
jesper@krogh.cc
In reply to: Jeff Davis (#1)
Re: Enabling Checksums

On 09/11/12 02:01, Jeff Davis wrote:

As I understand it, the main part of the remaining work to be done for
the checksums patch (at least the first commit) is to have a better way
to enable/disable them.

For the sake of simplicity (implementation as well as usability), it
seems like there is agreement that checksums should be enabled or
disabled for the entire instance, not per-table.

I can definately see that simplicity is an argument here, but
I can easily imagine that some performance hungry users
would prefer to be able to disable the functionality on a
per table level. UNCHECKSUMMED TABLES (similar to UNLOGGED TABLES).

I would definately stuff our system in state = 2 in your
description if it was available.

--
Jesper

#5Markus Wanner
markus@bluegap.ch
In reply to: Jeff Davis (#1)
Re: Enabling Checksums

Jeff,

On 11/09/2012 02:01 AM, Jeff Davis wrote:

For the sake of simplicity (implementation as well as usability), it
seems like there is agreement that checksums should be enabled or
disabled for the entire instance, not per-table.

Agreed. I've quickly thought about making it a per-database setting, but
how about shared system catalogs... Let's keep it simple and have a
single per-cluster instance switch for now.

I don't think a GUC entirely makes sense (in its current form, anyway).
We basically care about 3 states:
1. Off: checksums are not written, nor are they verified. Pages that
are newly dirtied have the checksum information in the header cleared.
2. Enabling: checksums are written for every dirty page, but only
verified for pages where the checksum is present (as determined by
information in the page header).
3. On: checksums are written for every dirty page, and verified for
every page that's read. If a page does not have a checksum, it's
corrupt.

Sounds sane, yes.

And the next question is what commands to add to change state. Ideas:

CHECKSUMS ENABLE; -- set state to "Enabling"
CHECKSUMS DISABLE; -- set state to "Off"

Yet another SQL command doesn't feel like the right thing for such a
switch. Quick googling revealed that CHECKSUM is a system function in MS
SQL and MySQL knows a CHECKSUM TABLE command. And you never know what
the committee is coming up with next.

Apart from that, I'd like something more descriptive that just
"checksums". Block checksums? Heap checksums? Data checksums?

Regards

Markus Wanner

#6Markus Wanner
markus@bluegap.ch
In reply to: Jesper Krogh (#4)
Re: Enabling Checksums

On 11/09/2012 06:18 AM, Jesper Krogh wrote:

I would definately stuff our system in state = 2 in your
description if it was available.

Hm.. that's an interesting statement.

What's probably worst when switching from OFF to ON is the VACUUM run
that needs to touch every page (provided you haven't ever turned
checksumming on before). Maybe you want to save that step and still get
the additional safety for newly dirtied pages, right?

A use case worth supporting?

Regards

Markus Wanner

#7Josh Berkus
josh@agliodbs.com
In reply to: Jeff Davis (#1)
Re: Enabling Checksums

Jeff,

I don't think a GUC entirely makes sense (in its current form, anyway).
We basically care about 3 states:

Huh? Why would a GUC not make sense? How else would you make sure that
checksums where on when you started the system?

1. Off: checksums are not written, nor are they verified. Pages that
are newly dirtied have the checksum information in the header cleared.
2. Enabling: checksums are written for every dirty page, but only
verified for pages where the checksum is present (as determined by
information in the page header).
3. On: checksums are written for every dirty page, and verified for
every page that's read. If a page does not have a checksum, it's
corrupt.

Well, large databases would tend to be stuck permanently in "Enabling",
becuase the user would never vacuum old cold partitions in order to
checksum them. So we need to be prepared for this to be the end state
for a lot of databases.

In fact, we'd need three settings for the checksum GUC:

OFF -- don't checksum anything, equal to state (1) above

WRITES -- checksum pages which are being written anyway, but ignore
tables which aren't touched. Permanent "Enabling" state.

ALL -- checksum everything you can. particularly, autovacuum would
checksum any table which was not already checksummed at the next vacuum
of that table. Goal is to get to state 3 above.

Does it make sense to store this information in pg_control? That doesn't
require adding any new file, and it has the benefit that it's already
checksummed. It's available during recovery and can be made available
pretty easily in the places where we write data.

And the next question is what commands to add to change state. Ideas:

CHECKSUMS ENABLE; -- set state to "Enabling"
CHECKSUMS DISABLE; -- set state to "Off"

Don't like this, please make it a GUC.

And then to get to the "On" state, you have to run a system-wide VACUUM
while in the "Enabling" state. Or, if the above syntax causes problems,
we can make all of these into VACUUM options.

As there's no such thing as system-wide vacuum, we're going to have to
track whether a table is "fully checksummed" in the system catalogs.
We'll also need:

VACUUM ( CHECKSUM ON )

... which would vacuum an entire table, skipping no pages and writing
checksums for every page, unless the table were marked fully checksummed
already, in which case it would do a regular vacuum.

Once a table was flagged as "all checksummed", then the system could
start producing errors (or warnings?) whenever a page with a missing
checksum was found.

Hmmm, better to have a 2nd GUC:

checksum_fail_action = WARNING | ERROR

... since some people want the write or read to fail, and others just
want to see it in the logs.

So, thinking about it, state (3) is never the state of an entire
installation; it's always the state of individual tables.

--
Josh Berkus
PostgreSQL Experts Inc.
http://pgexperts.com

#8Jeff Davis
pgsql@j-davis.com
In reply to: Markus Wanner (#6)
Re: Enabling Checksums

On Fri, 2012-11-09 at 15:42 +0100, Markus Wanner wrote:

On 11/09/2012 06:18 AM, Jesper Krogh wrote:

I would definately stuff our system in state = 2 in your
description if it was available.

Hm.. that's an interesting statement.

What's probably worst when switching from OFF to ON is the VACUUM run
that needs to touch every page (provided you haven't ever turned
checksumming on before). Maybe you want to save that step and still get
the additional safety for newly dirtied pages, right?

A use case worth supporting?

One problem is telling which pages are protected and which aren't. We
can have a couple bits in the header indicating that a checksum is
present, but it's a little disappointing to have only a few bits
protecting a 16-bit checksum.

Also, I think that people will want to have a way to protect their old
data somehow.

Regards,
Jeff Davis

#9Jeff Davis
pgsql@j-davis.com
In reply to: Alvaro Herrera (#2)
Re: Enabling Checksums

On Thu, 2012-11-08 at 23:33 -0300, Alvaro Herrera wrote:

There's no such thing as a system-wide VACUUM. The most you can get is
a database-wide VACUUM, which means you'd have to store the state
per-database somewhere (presumably the pg_database catalog), and perhaps
pg_control could have it as a system-wide value that's computed as the
minimum of all database states (so it stays "enabling" until all
databases have upgraded to "on").

That's a good point. Maybe this should be done as an offline operation
using a command-line utility?

Regards,
Jeff Davis

#10Markus Wanner
markus@bluegap.ch
In reply to: Jeff Davis (#8)
Re: Enabling Checksums

On 11/09/2012 07:53 PM, Jeff Davis wrote:

One problem is telling which pages are protected and which aren't. We
can have a couple bits in the header indicating that a checksum is
present, but it's a little disappointing to have only a few bits
protecting a 16-bit checksum.

Given your description of option 2 I was under the impression that each
page already has a bit indicating whether or not the page is protected
by a checksum. Why do you need more bits than that?

Also, I think that people will want to have a way to protect their old
data somehow.

Well, given that specific set of users is not willing to go through a
rewrite of each and every page of its database, it's hard to see how we
can protect their old data better.

However, we certainly need to provide the option to go through the
rewrite for other users, who are well willing to bite that bullet.

From a users perspective, the trade-off seems to be: if you want your
old data to be covered by checksums, you need to go through such an
expensive VACUUM run that touches every page in your database.

If you don't want to or cannot do that, you can still turn on
checksumming for newly written pages. You won't get full protection and
it's hard to tell what data is protected and what not, but it's still
better than no checksumming at all. Especially for huge databases, that
might be a reasonable compromise.

One could even argue, that this just leads to a prolonged migration and
with time, the remaining VACUUM step becomes less and less frightening.

Do you see any real foot-guns or other show-stoppers for permanently
allowing that in-between-state?

Or do we have other viable options that prolong the migration and thus
spread the load better over time?

Regards

Markus Wanner

#11Jeff Davis
pgsql@j-davis.com
In reply to: Markus Wanner (#10)
Re: Enabling Checksums

On Fri, 2012-11-09 at 20:48 +0100, Markus Wanner wrote:

Given your description of option 2 I was under the impression that each
page already has a bit indicating whether or not the page is protected
by a checksum. Why do you need more bits than that?

The bit indicating that a checksum is present may be lost due to
corruption.

However, we certainly need to provide the option to go through the
rewrite for other users, who are well willing to bite that bullet.

That's the use case that I've been focusing on, but perhaps you are
right that it's not the only important one.

Do you see any real foot-guns or other show-stoppers for permanently
allowing that in-between-state?

The biggest problem that I see is a few bits indicating the presence of
a checksum may be vulnerable to more kinds of corruption.

Regards,
Jeff Davis

#12Florian Pflug
fgp@phlo.org
In reply to: Jeff Davis (#11)
Re: Enabling Checksums

On Nov10, 2012, at 00:08 , Jeff Davis <pgsql@j-davis.com> wrote:

On Fri, 2012-11-09 at 20:48 +0100, Markus Wanner wrote:

Given your description of option 2 I was under the impression that each
page already has a bit indicating whether or not the page is protected
by a checksum. Why do you need more bits than that?

The bit indicating that a checksum is present may be lost due to
corruption.

Though that concern mostly goes away if instead of a separate bit we use a
special checksum value, say 0xDEAD, to indicate that the page isn't
checksummed, no?

If checksums were always enabled, the probability of a random corruption
going undetected is N/N^2 = 1/N where N is the number of distinct checksum
values, since out of the N^2 equally likely pairs of computed and stored
checksums values, N show two identical values.

With the 0xDEAD-scheme, the probability of a random corruption going
undetected is (N-1 + N)/N^2 = 2/N - 1/N^2, since there are (N-1) pairs
with identical values != 0xDEAD, and N pairs where the stored checksum
value is 0xDEAD.

So instead of a 1 in 65536 chance of a corruption going undetected, the
0xDEAD-schema gives (approximately) a chance of 1 in 32768, i.e the
strength of the checksum is reduced by one bit. That's still acceptable,
I'd say.

In practice, 0xDEAD may be a bad choice because of it's widespread use
as an uninitialized marker for blocks of memory. A randomly picked value
would probably be a better choice.

best regards,
Florian Pflug

#13Jeff Davis
pgsql@j-davis.com
In reply to: Florian Pflug (#12)
Re: Enabling Checksums

On Sat, 2012-11-10 at 14:46 +0100, Florian Pflug wrote:

The bit indicating that a checksum is present may be lost due to
corruption.

Though that concern mostly goes away if instead of a separate bit we use a
special checksum value, say 0xDEAD, to indicate that the page isn't
checksummed, no?

Right. But then we have an upgrade impact to set the checksum to 0xDEAD
on all existing pages, which seems to eliminate most of the possible
reason for it.

Also, we'd need to tweak the algorithm to make sure that it never landed
on that magic value. So if we think we might want this in the future, we
should reserve that magic value now.

But I can't think of many reasons for it, unless we expect people to be
turning checksums on and off repeatedly.

Regards,
Jeff Davis

#14Jeff Davis
pgsql@j-davis.com
In reply to: Josh Berkus (#7)
Re: Enabling Checksums

On Fri, 2012-11-09 at 09:57 -0800, Josh Berkus wrote:

Huh? Why would a GUC not make sense? How else would you make sure that
checksums where on when you started the system?

If we stored the information in pg_control, you could check with
pg_controldata. We could have a separate utility, pg_checksums, that can
alter the state and/or do an offline verification. And initdb would take
an option that would start everything out fully protected with
checksums.

The problem with a GUC is that checksums aren't really something you can
change by just changing the variable and restarting, unless you are only
using checksums opportunistically (only write checksums when a page is
dirtied and only verify a checksum if the header indicates that it's
present).

There are also usability issues. If someone has a fully-protected
instance, and turns the GUC off, and starts the server, they'll lose the
"fully-protected" status on the first write, and have to re-read all the
data to get back to fully protected. That just doesn't seem right to me.

Well, large databases would tend to be stuck permanently in "Enabling",
becuase the user would never vacuum old cold partitions in order to
checksum them. So we need to be prepared for this to be the end state
for a lot of databases.

That may be true, but if that's the case, it's more like a 3-bit
checksum than a 16-bit checksum, because of the page-header corruption
problem. I don't know of any way to give those users more than that,
which won't be good enough for the set-at-initdb time users.

In fact, we'd need three settings for the checksum GUC:

OFF -- don't checksum anything, equal to state (1) above

WRITES -- checksum pages which are being written anyway, but ignore
tables which aren't touched. Permanent "Enabling" state.

ALL -- checksum everything you can. particularly, autovacuum would
checksum any table which was not already checksummed at the next vacuum
of that table. Goal is to get to state 3 above.

That's slightly more eager, but it's basically the same as the WRITES
state. In order to get to the fully-protected state, you still need to
somehow make sure that all of the old data is checksummed.

And the "fully protected" state is important in my opinion, because
otherwise we aren't protected against corrupt page headers that say they
have no checksum (even when it really should have a checksum).

Does it make sense to store this information in pg_control? That doesn't
require adding any new file, and it has the benefit that it's already
checksummed. It's available during recovery and can be made available
pretty easily in the places where we write data.

And the next question is what commands to add to change state. Ideas:

CHECKSUMS ENABLE; -- set state to "Enabling"
CHECKSUMS DISABLE; -- set state to "Off"

Don't like this, please make it a GUC.

I'll see if you have ideas about how to resolve the problems with a GUC
that I mentioned above. But if not, then what about using a utility,
perhaps called pg_checksums? That way we wouldn't need new syntax.

As there's no such thing as system-wide vacuum, we're going to have to
track whether a table is "fully checksummed" in the system catalogs.

It seems like this is going down the road of per-table checksums. I'm
not opposed to that, but that has a low chance of making 9.3.

Let's try to do something simpler now that leaves open the possibility
of more flexibility later. I'm inclined to agree with Robert that the
first patch should probably be an initdb-time option. Then, we can allow
a lazy mode (like your WRITES state) and an eager offline check with a
pg_checksums utility. Then we can work towards per-table checksums,
control via VACUUM, protecting the SLRU, treating zero pages as invalid,
protecting temp files (which can be a GUC), replication integration,
etc.

Hmmm, better to have a 2nd GUC:

checksum_fail_action = WARNING | ERROR

... since some people want the write or read to fail, and others just
want to see it in the logs.

Checksums don't introduce new failure modes on writes, only on reads.

And for reads, I think we have a problem doing anything less than an
ERROR. If we allow the read to succeed, we either risk a crash (or
silently corrupting other buffers in shared memory), or we have to put a
zero page in its place. But we already have the zero_damaged_pages
option, which I think is better because reading corrupt data is only
useful for data recovery efforts.

So, thinking about it, state (3) is never the state of an entire
installation; it's always the state of individual tables.

That contradicts the idea of using a GUC then. It would make more sense
to have extra syntax or extra VACUUM modes to accomplish that per-table.

Unfortunately, I'm worried that the per-table approach will not be
completed by 9.3. Do you see something about my proposal that makes it
harder to get where we want to go in the future?

If we do ultimately get per-table checksums, then I agree that a flag in
pg_control may be a bit of a wart, but it's easy enough to remove later.

Regards,
Jeff Davis

#15Pavel Stehule
pavel.stehule@gmail.com
In reply to: Jeff Davis (#14)
Re: Enabling Checksums

Hello

Does it make sense to store this information in pg_control? That doesn't
require adding any new file, and it has the benefit that it's already
checksummed. It's available during recovery and can be made available
pretty easily in the places where we write data.

And the next question is what commands to add to change state. Ideas:

CHECKSUMS ENABLE; -- set state to "Enabling"
CHECKSUMS DISABLE; -- set state to "Off"

Don't like this, please make it a GUC.

I'll see if you have ideas about how to resolve the problems with a GUC
that I mentioned above. But if not, then what about using a utility,
perhaps called pg_checksums? That way we wouldn't need new syntax.

I don't think so GUC are good for this purpouse, but I don't like
single purpouse statements too.

what do you think about enhancing ALTER DATABASE statement

some like

ALTER DATABASE name ENABLE CHECKSUMS and ALTER DATABASE name DISABLE CHECKSUMS

Regards

Pavel

#16Jeff Davis
pgsql@j-davis.com
In reply to: Pavel Stehule (#15)
Re: Enabling Checksums

On Sun, 2012-11-11 at 21:20 +0100, Pavel Stehule wrote:

I don't think so GUC are good for this purpouse, but I don't like
single purpouse statements too.

what do you think about enhancing ALTER DATABASE statement

some like

ALTER DATABASE name ENABLE CHECKSUMS and ALTER DATABASE name DISABLE CHECKSUMS

Per-database does sound easier than per-table. I'd have to think about
how that would affect shared catalogs though.

For now, I'm leaning toward an offline utility to turn checksums on or
off, called pg_checksums. It could do so lazily (just flip a switch to
"enabling" in pg_control), or it could do so eagerly and turn it into a
fully-protected instance.

For the first patch, it might just be an initdb-time option for
simplicity.

Regards,
Jeff Davis

#17Andrew Dunstan
andrew@dunslane.net
In reply to: Jeff Davis (#16)
Re: Enabling Checksums

On 11/11/2012 05:52 PM, Jeff Davis wrote:

On Sun, 2012-11-11 at 21:20 +0100, Pavel Stehule wrote:

I don't think so GUC are good for this purpouse, but I don't like
single purpouse statements too.

what do you think about enhancing ALTER DATABASE statement

some like

ALTER DATABASE name ENABLE CHECKSUMS and ALTER DATABASE name DISABLE CHECKSUMS

Per-database does sound easier than per-table. I'd have to think about
how that would affect shared catalogs though.

For now, I'm leaning toward an offline utility to turn checksums on or
off, called pg_checksums. It could do so lazily (just flip a switch to
"enabling" in pg_control), or it could do so eagerly and turn it into a
fully-protected instance.

For the first patch, it might just be an initdb-time option for
simplicity.

+1

I haven't followed this too closely, but I did wonder several days ago
why this wasn't being made an initdb-time decision.

cheers

andrew

#18Greg Smith
gsmith@gregsmith.com
In reply to: Jeff Davis (#14)
Re: Enabling Checksums

On 11/11/12 2:56 PM, Jeff Davis wrote:

We could have a separate utility, pg_checksums, that can
alter the state and/or do an offline verification. And initdb would take
an option that would start everything out fully protected with
checksums.

Adding an initdb option to start out with everything checksummed seems
an uncontroversial good first thing to have available. It seems like a
proper 9.3 target to aim at even if per-table upgrading gets bogged down
in details. I have an argument below that the area between initdb and
per-table upgrades is fundamentally uncertain and therefore not worth
chasing after, based on reasons you already started to outline. There's
not much useful middle ground there.

Won't a pg_checksums program just grow until it looks like a limited
version of vacuum though? It's going to iterate over most of the table;
it needs the same cost controls as autovacuum (and to respect the load
of concurrent autovacuum work) to keep I/O under control; and those cost
control values might change if there's a SIGHUP to reload parameters.
It looks so much like vacuum that I think there needs to be a really
compelling reason to split it into something new. Why can't this be yet
another autovacuum worker that does its thing?

In order to get to the fully-protected state, you still need to
somehow make sure that all of the old data is checksummed.

And the "fully protected" state is important in my opinion, because
otherwise we aren't protected against corrupt page headers that say
they have no checksum (even when it really should have a checksum).

I think it's useful to step back for a minute and consider the larger
uncertainty an existing relation has, which amplifies just how ugly this
situation is. The best guarantee I think online checksumming can offer
is to tell the user "after transaction id X, all new data in relation R
is known to be checksummed". Unless you do this at initdb time, any
conversion case is going to have the possibility that a page is
corrupted before you get to it--whether you're adding the checksum as
part of a "let's add them while we're writing anyway" page update or the
conversion tool is hitting it.

That's why I don't think anyone will find online conversion really
useful until they've done a full sweep updating the old pages. And if
you accept that, a flexible checksum upgrade utility, one that co-exists
with autovacuum activity costs, becomes a must.

One of the really common cases I was expecting here is that conversions
are done by kicking off a slow background VACUUM CHECKSUM job that might
run in pieces. I was thinking of an approach like this:

-Initialize a last_checked_block value for each table
-Loop:
--Grab the next block after the last checked one
--When on the last block of the relation, grab an exclusive lock to
protect against race conditions with extension
--If it's marked as checksummed and the checksum matches, skip it
---Otherwise, add a checksum and write it out
--When that succeeds, update last_checked_block
--If that was the last block, save some state saying the whole table is
checkedsummed

With that logic, there is at least a forward moving pointer that removes
the uncertainty around whether pages have been updated or not. It will
keep going usefully if interrupted too. One obvious this way this can
fail is if:

1) A late page in the relation is updated and a checksummed page written
2) The page is corrupted such that the "is this checksummed?" bits are
not consistent anymore, along with other damage to it
3) The conversion process gets to this page eventually
4) The corruption of (2) isn't detected

But I think that this possibility--that a page might get quietly
corrupted after checked once, but still in the middle of checking a
relation--is both impossible to remove and a red herring. How do we
know that this page of the relation wasn't corrupted on disk before we
even started? We don't, and we can't.

The only guarantee I see that we can give for online upgrades is that
after a VACUUM CHECKSUM sweep is done, and every page is known to both
have a valid checksum on it and have its checksum bits set, *then* any
page that doesn't have both set bits and a matching checksum is garbage.
Until reaching that point, any old data is suspect. The idea of
operating in an "we'll convert on write but never convert old pages"
can't come up with any useful guarantees about data integrity that I can
see. As you say, you don't ever gain the ability to tell pages that
were checksummed but have since been corrupted from ones that were
corrupt all along in that path.

--
Greg Smith 2ndQuadrant US greg@2ndQuadrant.com Baltimore, MD
PostgreSQL Training, Services, and 24x7 Support www.2ndQuadrant.com

#19Jesper Krogh
jesper@krogh.cc
In reply to: Greg Smith (#18)
Re: Enabling Checksums

On 12/11/12 05:55, Greg Smith wrote:

The only guarantee I see that we can give for online upgrades is that
after a VACUUM CHECKSUM sweep is done, and every page is known to both
have a valid checksum on it and have its checksum bits set, *then* any
page that doesn't have both set bits and a matching checksum is
garbage. Until reaching that point, any old data is suspect. The
idea of operating in an "we'll convert on write but never convert old
pages" can't come up with any useful guarantees about data integrity
that I can see. As you say, you don't ever gain the ability to tell
pages that were checksummed but have since been corrupted from ones
that were corrupt all along in that path.

You're right about that, but I'd just like some rough guard against
hardware/OS related data corruption.
and that is more likely to hit data-blocks constantly flying in and out
of the system.
I'm currently running a +2TB database and the capabillity to just see
some kind of corruption earlier
rather than later is a major benefit by itself. Currently corruption can
go undetected if it just
happens to hit data-only parts of the database.

But I totally agree that the scheme described with integrating it into a
autovacuum process would
be very close to ideal, even on a database as the one I'l running.

--
Jesper

#20Greg Smith
gsmith@gregsmith.com
In reply to: Jesper Krogh (#19)
Re: Enabling Checksums

On 11/12/12 12:55 AM, Jesper Krogh wrote:

I'd just like some rough guard against
hardware/OS related data corruption.
and that is more likely to hit data-blocks constantly flying in and out
of the system.

I get that. I think that some of the design ideas floating around since
this feature was first proposed have been innovating in the hope of
finding a clever halfway point here. Ideally we'd be able to get online
checksum conversion and up running easily, reliably, and without adding
a lot of code. I have given up on that now though.

The approach of doing a heavy per-table conversion with more state
information than we'd like seems unavoidable, if you want to do it right
and allow people to (slowly but surely) reach a trustworthy state. I
think we should stop searching for a clever way around and just do slog
through doing it. I've resigned myself to that now, and recently set
aside a good block of time to beat my head against that particular wall
over the next couple of months.

But I totally agree that the scheme described with integrating it into a
autovacuum process would
be very close to ideal, even on a database as the one I'm running.

I am sadly all too familiar with how challenging it is to keep a 2TB
PostgreSQL database running reliably. One of my recent catch phrases
for talks is "if you have a big Postgres database, you also have a
vacuum problem". I think it's unreasonable to consider online
conversion solutions that don't recognize that, and allow coordinating
the work with the challenges of vacuuming larger systems too.

--
Greg Smith 2ndQuadrant US greg@2ndQuadrant.com Baltimore, MD
PostgreSQL Training, Services, and 24x7 Support www.2ndQuadrant.com

#21Markus Wanner
markus@bluegap.ch
In reply to: Jeff Davis (#11)
#22Markus Wanner
markus@bluegap.ch
In reply to: Greg Smith (#18)
#23Craig Ringer
craig@2ndquadrant.com
In reply to: Markus Wanner (#21)
#24Markus Wanner
markus@bluegap.ch
In reply to: Craig Ringer (#23)
#25Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Greg Smith (#18)
#26Jeff Davis
pgsql@j-davis.com
In reply to: Markus Wanner (#21)
#27Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#18)
#28Markus Wanner
markus@bluegap.ch
In reply to: Jeff Davis (#27)
#29Greg Smith
gsmith@gregsmith.com
In reply to: Craig Ringer (#23)
#30Jeff Davis
pgsql@j-davis.com
In reply to: Markus Wanner (#28)
#31Greg Smith
gsmith@gregsmith.com
In reply to: Markus Wanner (#21)
#32Josh Berkus
josh@agliodbs.com
In reply to: Jeff Davis (#27)
#33Markus Wanner
markus@bluegap.ch
In reply to: Greg Smith (#31)
#34Robert Haas
robertmhaas@gmail.com
In reply to: Jeff Davis (#16)
#35Robert Haas
robertmhaas@gmail.com
In reply to: Craig Ringer (#23)
#36Tom Lane
tgl@sss.pgh.pa.us
In reply to: Robert Haas (#35)
#37Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#36)
#38Bruce Momjian
bruce@momjian.us
In reply to: Josh Berkus (#32)
#39Peter Eisentraut
peter_e@gmx.net
In reply to: Andrew Dunstan (#17)
#40Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Peter Eisentraut (#39)
#41Andrew Dunstan
andrew@dunslane.net
In reply to: Alvaro Herrera (#40)
#42Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andrew Dunstan (#41)
#43Andrew Dunstan
andrew@dunslane.net
In reply to: Tom Lane (#42)
#44Jeff Davis
pgsql@j-davis.com
In reply to: Robert Haas (#35)
#45Jeff Davis
pgsql@j-davis.com
In reply to: Robert Haas (#34)
#46Robert Haas
robertmhaas@gmail.com
In reply to: Jeff Davis (#44)
#47Jeff Davis
pgsql@j-davis.com
In reply to: Robert Haas (#46)
#48Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#45)
#49Robert Haas
robertmhaas@gmail.com
In reply to: Jeff Davis (#47)
#50Jeff Davis
pgsql@j-davis.com
In reply to: Robert Haas (#49)
#51Andres Freund
andres@anarazel.de
In reply to: Jeff Davis (#50)
#52Jeff Davis
pgsql@j-davis.com
In reply to: Andres Freund (#51)
#53Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#52)
#54Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#48)
#55Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#54)
#56Simon Riggs
simon@2ndQuadrant.com
In reply to: Simon Riggs (#55)
#57Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#54)
#58Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#56)
#59Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#55)
#60Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#59)
#61Robert Haas
robertmhaas@gmail.com
In reply to: Jeff Davis (#60)
#62Simon Riggs
simon@2ndQuadrant.com
In reply to: Robert Haas (#61)
#63Kevin Grittner
Kevin.Grittner@wicourts.gov
In reply to: Simon Riggs (#62)
#64Greg Smith
gsmith@gregsmith.com
In reply to: Simon Riggs (#62)
#65Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#64)
#66Greg Smith
gsmith@gregsmith.com
In reply to: Jeff Davis (#65)
#67Dimitri Fontaine
dimitri@2ndQuadrant.fr
In reply to: Jeff Davis (#65)
#68Simon Riggs
simon@2ndQuadrant.com
In reply to: Greg Smith (#66)
#69Tom Lane
tgl@sss.pgh.pa.us
In reply to: Simon Riggs (#68)
#70Simon Riggs
simon@2ndQuadrant.com
In reply to: Tom Lane (#69)
#71Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#68)
#72Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#71)
#73Greg Smith
gsmith@gregsmith.com
In reply to: Simon Riggs (#72)
#74Kevin Grittner
Kevin.Grittner@wicourts.gov
In reply to: Greg Smith (#73)
#75Bruce Momjian
bruce@momjian.us
In reply to: Kevin Grittner (#74)
#76Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#72)
#77Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#73)
#78Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#59)
#79Martijn van Oosterhout
kleptog@svana.org
In reply to: Greg Smith (#73)
#80Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#59)
#81Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#80)
#82Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#81)
#83Greg Smith
gsmith@gregsmith.com
In reply to: Jeff Davis (#78)
#84Greg Smith
gsmith@gregsmith.com
In reply to: Greg Smith (#66)
#85Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#59)
#86Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#84)
#87Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#85)
#88Robert Haas
robertmhaas@gmail.com
In reply to: Jeff Davis (#80)
#89Jeff Davis
pgsql@j-davis.com
In reply to: Robert Haas (#88)
#90Robert Haas
robertmhaas@gmail.com
In reply to: Jeff Davis (#89)
#91Simon Riggs
simon@2ndQuadrant.com
In reply to: Robert Haas (#88)
#92Robert Haas
robertmhaas@gmail.com
In reply to: Simon Riggs (#91)
#93Jeff Davis
pgsql@j-davis.com
In reply to: Robert Haas (#90)
#94Robert Haas
robertmhaas@gmail.com
In reply to: Jeff Davis (#93)
#95Greg Smith
gsmith@gregsmith.com
In reply to: Jeff Davis (#87)
#96Daniel Farina
daniel@heroku.com
In reply to: Greg Smith (#95)
#97Craig Ringer
craig@2ndquadrant.com
In reply to: Daniel Farina (#96)
#98Greg Smith
gsmith@gregsmith.com
In reply to: Greg Smith (#95)
#99Greg Smith
gsmith@gregsmith.com
In reply to: Greg Smith (#98)
#100Greg Smith
gsmith@gregsmith.com
In reply to: Jeff Davis (#78)
#101Greg Smith
gsmith@gregsmith.com
In reply to: Craig Ringer (#97)
#102Craig Ringer
craig@2ndquadrant.com
In reply to: Greg Smith (#101)
#103Greg Smith
gsmith@gregsmith.com
In reply to: Craig Ringer (#102)
#104Craig Ringer
craig@2ndquadrant.com
In reply to: Greg Smith (#103)
#105Simon Riggs
simon@2ndQuadrant.com
In reply to: Greg Smith (#98)
#106Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Simon Riggs (#105)
#107Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#106)
#108Greg Smith
gsmith@gregsmith.com
In reply to: Simon Riggs (#105)
#109Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#95)
#110Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Greg Smith (#108)
#111Jeff Davis
pgsql@j-davis.com
In reply to: Craig Ringer (#102)
#112Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Jeff Davis (#107)
#113Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#110)
#114Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#101)
#115Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#108)
#116Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Jeff Davis (#107)
#117Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Jeff Davis (#115)
#118Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#112)
#119Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Jim Nasby (#116)
#120Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Jeff Davis (#113)
#121Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Heikki Linnakangas (#119)
In reply to: Jeff Davis (#118)
#123Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Jeff Davis (#118)
#124Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Jim Nasby (#116)
#125Stephen Frost
sfrost@snowman.net
In reply to: Heikki Linnakangas (#123)
#126Jeff Davis
pgsql@j-davis.com
In reply to: Jim Nasby (#117)
#127Craig Ringer
craig@2ndquadrant.com
In reply to: Jeff Davis (#114)
#128Greg Smith
gsmith@gregsmith.com
In reply to: Heikki Linnakangas (#110)
#129Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Craig Ringer (#127)
#130Craig Ringer
craig@2ndquadrant.com
In reply to: Jim Nasby (#129)
#131Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Craig Ringer (#130)
#132Josh Berkus
josh@agliodbs.com
In reply to: Heikki Linnakangas (#123)
#133Daniel Farina
daniel@heroku.com
In reply to: Heikki Linnakangas (#123)
#134Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#123)
#135Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#120)
#136Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#100)
#137Simon Riggs
simon@2ndQuadrant.com
In reply to: Daniel Farina (#133)
#138Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Simon Riggs (#105)
#139Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#138)
#140Simon Riggs
simon@2ndQuadrant.com
In reply to: Heikki Linnakangas (#138)
#141Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#139)
#142Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Simon Riggs (#141)
#143Andres Freund
andres@anarazel.de
In reply to: Heikki Linnakangas (#142)
#144Garick Hamlin
ghamlin@isc.upenn.edu
In reply to: Heikki Linnakangas (#142)
#145Andres Freund
andres@anarazel.de
In reply to: Garick Hamlin (#144)
#146Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#145)
#147Robert Haas
robertmhaas@gmail.com
In reply to: Heikki Linnakangas (#110)
#148Josh Berkus
josh@agliodbs.com
In reply to: Robert Haas (#147)
#149Josh Berkus
josh@agliodbs.com
In reply to: Robert Haas (#147)
#150Robert Haas
robertmhaas@gmail.com
In reply to: Josh Berkus (#148)
#151Robert Haas
robertmhaas@gmail.com
In reply to: Josh Berkus (#149)
#152Joshua D. Drake
jd@commandprompt.com
In reply to: Robert Haas (#151)
#153Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Daniel Farina (#133)
#154Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Josh Berkus (#148)
#155Craig Ringer
craig@2ndquadrant.com
In reply to: Heikki Linnakangas (#142)
#156Andres Freund
andres@anarazel.de
In reply to: Craig Ringer (#155)
#157Greg Smith
gsmith@gregsmith.com
In reply to: Robert Haas (#147)
#158Craig Ringer
craig@2ndquadrant.com
In reply to: Andres Freund (#156)
#159Greg Smith
gsmith@gregsmith.com
In reply to: Heikki Linnakangas (#142)
#160Greg Smith
gsmith@gregsmith.com
In reply to: Tom Lane (#146)
#161Bruce Momjian
bruce@momjian.us
In reply to: Robert Haas (#150)
#162Greg Smith
gsmith@gregsmith.com
In reply to: Jeff Davis (#136)
#163Daniel Farina
daniel@heroku.com
In reply to: Greg Smith (#162)
#164Greg Smith
gsmith@gregsmith.com
In reply to: Daniel Farina (#163)
#165Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#138)
#166Bruce Momjian
bruce@momjian.us
In reply to: Daniel Farina (#133)
#167Pavel Stehule
pavel.stehule@gmail.com
In reply to: Bruce Momjian (#166)
#168Daniel Farina
daniel@heroku.com
In reply to: Bruce Momjian (#166)
#169Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Bruce Momjian (#166)
#170Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Jeff Davis (#165)
#171Josh Berkus
josh@agliodbs.com
In reply to: Bruce Momjian (#166)
#172Bruce Momjian
bruce@momjian.us
In reply to: Josh Berkus (#171)
#173Greg Smith
gsmith@gregsmith.com
In reply to: Heikki Linnakangas (#169)
#174Simon Riggs
simon@2ndQuadrant.com
In reply to: Bruce Momjian (#166)
#175Jeff Davis
pgsql@j-davis.com
In reply to: Jeff Davis (#165)
#176Josh Berkus
josh@agliodbs.com
In reply to: Jeff Davis (#175)
#177Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Bruce Momjian (#166)
#178Ants Aasma
ants.aasma@cybertec.at
In reply to: Heikki Linnakangas (#142)
#179Ants Aasma
ants.aasma@cybertec.at
In reply to: Ants Aasma (#178)
#180Andres Freund
andres@anarazel.de
In reply to: Ants Aasma (#178)
#181Simon Riggs
simon@2ndQuadrant.com
In reply to: Andres Freund (#180)
#182Tom Lane
tgl@sss.pgh.pa.us
In reply to: Simon Riggs (#181)
#183Simon Riggs
simon@2ndQuadrant.com
In reply to: Tom Lane (#182)
#184Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#175)
#185Greg Smith
gsmith@gregsmith.com
In reply to: Ants Aasma (#178)
#186Greg Smith
gsmith@gregsmith.com
In reply to: Simon Riggs (#183)
#187Daniel Farina
daniel@heroku.com
In reply to: Greg Smith (#186)
#188Simon Riggs
simon@2ndQuadrant.com
In reply to: Greg Smith (#186)
#189Bruce Momjian
bruce@momjian.us
In reply to: Greg Smith (#186)
#190Pavel Stehule
pavel.stehule@gmail.com
In reply to: Bruce Momjian (#189)
#191Simon Riggs
simon@2ndQuadrant.com
In reply to: Bruce Momjian (#189)
#192Stephen Frost
sfrost@snowman.net
In reply to: Bruce Momjian (#189)
#193Josh Berkus
josh@agliodbs.com
In reply to: Bruce Momjian (#189)
#194Jeff Davis
pgsql@j-davis.com
In reply to: Bruce Momjian (#189)
#195Jeff Davis
pgsql@j-davis.com
In reply to: Daniel Farina (#187)
#196Bruce Momjian
bruce@momjian.us
In reply to: Jeff Davis (#194)
#197Bruce Momjian
bruce@momjian.us
In reply to: Simon Riggs (#191)
#198Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#195)
#199Greg Smith
gsmith@gregsmith.com
In reply to: Bruce Momjian (#189)
#200Greg Smith
gsmith@gregsmith.com
In reply to: Bruce Momjian (#189)
#201Greg Smith
gsmith@gregsmith.com
In reply to: Bruce Momjian (#189)
#202Ants Aasma
ants.aasma@cybertec.at
In reply to: Greg Smith (#185)
#203Daniel Farina
daniel@heroku.com
In reply to: Greg Smith (#201)
#204Greg Smith
gsmith@gregsmith.com
In reply to: Daniel Farina (#203)
#205Daniel Farina
daniel@heroku.com
In reply to: Greg Smith (#204)
#206Jeff Davis
pgsql@j-davis.com
In reply to: Tom Lane (#182)
#207Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#178)
#208Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#206)
#209Simon Riggs
simon@2ndQuadrant.com
In reply to: Ants Aasma (#202)
#210Tom Lane
tgl@sss.pgh.pa.us
In reply to: Jeff Davis (#206)
#211Greg Smith
gsmith@gregsmith.com
In reply to: Bruce Momjian (#172)
#212Greg Smith
gsmith@gregsmith.com
In reply to: Ants Aasma (#202)
#213Ants Aasma
ants.aasma@cybertec.at
In reply to: Greg Smith (#212)
#214Greg Smith
gsmith@gregsmith.com
In reply to: Ants Aasma (#213)
#215Daniel Farina
daniel@heroku.com
In reply to: Greg Smith (#214)
#216Andrew Dunstan
andrew@dunslane.net
In reply to: Greg Smith (#214)
#217Greg Smith
gsmith@gregsmith.com
In reply to: Daniel Farina (#215)
#218Ants Aasma
ants.aasma@cybertec.at
In reply to: Greg Smith (#214)
#219Simon Riggs
simon@2ndQuadrant.com
In reply to: Greg Smith (#217)
#220Greg Smith
gsmith@gregsmith.com
In reply to: Simon Riggs (#219)
#221Tom Lane
tgl@sss.pgh.pa.us
In reply to: Greg Smith (#214)
#222Greg Smith
gsmith@gregsmith.com
In reply to: Tom Lane (#221)
#223Ants Aasma
ants.aasma@cybertec.at
In reply to: Greg Smith (#222)
#224Ants Aasma
ants.aasma@cybertec.at
In reply to: Ants Aasma (#223)
#225Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#189)
#226Bruce Momjian
bruce@momjian.us
In reply to: Bruce Momjian (#189)
#227Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#218)
#228Ants Aasma
ants.aasma@cybertec.at
In reply to: Jeff Davis (#227)
#229Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#228)
#230Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#228)
#231Ants Aasma
ants.aasma@cybertec.at
In reply to: Jeff Davis (#229)
#232Craig Ringer
craig@2ndquadrant.com
In reply to: Jeff Davis (#230)
#233Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Simon Riggs (#181)
#234Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Simon Riggs (#198)
#235Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Bruce Momjian (#226)
#236Ants Aasma
ants.aasma@cybertec.at
In reply to: Craig Ringer (#232)
#237Andres Freund
andres@anarazel.de
In reply to: Ants Aasma (#231)
#238Ants Aasma
ants.aasma@cybertec.at
In reply to: Andres Freund (#237)
#239Andres Freund
andres@anarazel.de
In reply to: Ants Aasma (#238)
#240Bruce Momjian
bruce@momjian.us
In reply to: Jim Nasby (#235)
#241Bruce Momjian
bruce@momjian.us
In reply to: Ants Aasma (#228)
#242Ants Aasma
ants.aasma@cybertec.at
In reply to: Bruce Momjian (#241)
#243Robert Haas
robertmhaas@gmail.com
In reply to: Greg Smith (#201)
#244Andres Freund
andres@anarazel.de
In reply to: Robert Haas (#243)
#245Robert Haas
robertmhaas@gmail.com
In reply to: Andres Freund (#244)
#246Andres Freund
andres@anarazel.de
In reply to: Robert Haas (#245)
#247Jim Nasby
Jim.Nasby@BlueTreble.com
In reply to: Bruce Momjian (#240)
#248Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#242)
#249Ants Aasma
ants.aasma@cybertec.at
In reply to: Jeff Davis (#248)
#250Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#249)
#251Greg Smith
gsmith@gregsmith.com
In reply to: Jeff Davis (#248)
#252Kevin Grittner
Kevin.Grittner@wicourts.gov
In reply to: Jeff Davis (#250)
#253Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Kevin Grittner (#252)
#254Simon Riggs
simon@2ndQuadrant.com
In reply to: Heikki Linnakangas (#253)
#255Ants Aasma
ants.aasma@cybertec.at
In reply to: Ants Aasma (#249)
#256Simon Riggs
simon@2ndQuadrant.com
In reply to: Ants Aasma (#255)
#257Ants Aasma
ants.aasma@cybertec.at
In reply to: Simon Riggs (#256)
#258Ants Aasma
ants.aasma@cybertec.at
In reply to: Ants Aasma (#255)
#259Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#255)
#260Ants Aasma
ants.aasma@cybertec.at
In reply to: Jeff Davis (#259)
#261Simon Riggs
simon@2ndQuadrant.com
In reply to: Ants Aasma (#260)
#262Ants Aasma
ants.aasma@cybertec.at
In reply to: Simon Riggs (#261)
#263Bruce Momjian
bruce@momjian.us
In reply to: Ants Aasma (#262)
#264Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#260)
#265Simon Riggs
simon@2ndQuadrant.com
In reply to: Ants Aasma (#262)
#266Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#265)
#267Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#266)
#268Bruce Momjian
bruce@momjian.us
In reply to: Jeff Davis (#264)
#269Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#267)
#270Bruce Momjian
bruce@momjian.us
In reply to: Jeff Davis (#269)
#271Andres Freund
andres@anarazel.de
In reply to: Simon Riggs (#267)
#272Bruce Momjian
bruce@momjian.us
In reply to: Andres Freund (#271)
#273Andres Freund
andres@anarazel.de
In reply to: Bruce Momjian (#272)
#274Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Bruce Momjian (#272)
#275Simon Riggs
simon@2ndQuadrant.com
In reply to: Heikki Linnakangas (#274)
#276Jeff Davis
pgsql@j-davis.com
In reply to: Bruce Momjian (#270)
#277Jeff Davis
pgsql@j-davis.com
In reply to: Andres Freund (#271)
#278Jeff Davis
pgsql@j-davis.com
In reply to: Heikki Linnakangas (#274)
#279Ants Aasma
ants.aasma@cybertec.at
In reply to: Jeff Davis (#278)
#280Simon Riggs
simon@2ndQuadrant.com
In reply to: Ants Aasma (#279)
#281Bruce Momjian
bruce@momjian.us
In reply to: Jeff Davis (#278)
#282Andres Freund
andres@anarazel.de
In reply to: Bruce Momjian (#281)
#283Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#282)
#284Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#283)
#285Ants Aasma
ants.aasma@cybertec.at
In reply to: Tom Lane (#283)
#286Andres Freund
andres@anarazel.de
In reply to: Ants Aasma (#285)
#287Ants Aasma
ants.aasma@cybertec.at
In reply to: Andres Freund (#286)
#288Bruce Momjian
bruce@momjian.us
In reply to: Ants Aasma (#285)
#289Simon Riggs
simon@2ndQuadrant.com
In reply to: Ants Aasma (#255)
#290Bruce Momjian
bruce@momjian.us
In reply to: Simon Riggs (#275)
#291Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#290)
#292Simon Riggs
simon@2ndQuadrant.com
In reply to: Tom Lane (#291)
#293Florian Pflug
fgp@phlo.org
In reply to: Ants Aasma (#285)
#294Ants Aasma
ants.aasma@cybertec.at
In reply to: Simon Riggs (#289)
#295Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ants Aasma (#294)
#296Ants Aasma
ants.aasma@cybertec.at
In reply to: Florian Pflug (#293)
#297Florian Pflug
fgp@phlo.org
In reply to: Ants Aasma (#296)
#298Ants Aasma
ants.aasma@cybertec.at
In reply to: Florian Pflug (#297)
#299Bruce Momjian
bruce@momjian.us
In reply to: Ants Aasma (#298)
#300Florian Pflug
fgp@phlo.org
In reply to: Bruce Momjian (#299)
#301Florian Pflug
fgp@phlo.org
In reply to: Ants Aasma (#298)
#302Bruce Momjian
bruce@momjian.us
In reply to: Florian Pflug (#300)
#303Bruce Momjian
bruce@momjian.us
In reply to: Florian Pflug (#300)
#304Florian Pflug
fgp@phlo.org
In reply to: Bruce Momjian (#303)
#305Bruce Momjian
bruce@momjian.us
In reply to: Florian Pflug (#304)
#306Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#302)
#307Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#306)
#308Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#307)
#309Bruce Momjian
bruce@momjian.us
In reply to: Tom Lane (#308)
#310Tom Lane
tgl@sss.pgh.pa.us
In reply to: Bruce Momjian (#309)
#311Jeff Davis
pgsql@j-davis.com
In reply to: Bruce Momjian (#305)
#312Jeff Davis
pgsql@j-davis.com
In reply to: Bruce Momjian (#302)
#313Bruce Momjian
bruce@momjian.us
In reply to: Jeff Davis (#311)
#314Ants Aasma
ants.aasma@cybertec.at
In reply to: Florian Pflug (#301)
#315Tom Lane
tgl@sss.pgh.pa.us
In reply to: Ants Aasma (#314)
#316Florian Pflug
fgp@phlo.org
In reply to: Tom Lane (#315)
#317Florian Pflug
fgp@phlo.org
In reply to: Ants Aasma (#314)
#318Ants Aasma
ants.aasma@cybertec.at
In reply to: Tom Lane (#315)
#319Ants Aasma
ants.aasma@cybertec.at
In reply to: Florian Pflug (#317)
#320Greg Smith
gsmith@gregsmith.com
In reply to: Tom Lane (#315)
#321Ants Aasma
ants.aasma@cybertec.at
In reply to: Greg Smith (#320)
#322Daniel Farina
daniel@heroku.com
In reply to: Greg Smith (#320)
#323Greg Smith
gsmith@gregsmith.com
In reply to: Ants Aasma (#321)
#324Andres Freund
andres@anarazel.de
In reply to: Daniel Farina (#322)
#325Andres Freund
andres@anarazel.de
In reply to: Ants Aasma (#314)
#326Simon Riggs
simon@2ndQuadrant.com
In reply to: Bruce Momjian (#313)
#327Daniel Farina
daniel@heroku.com
In reply to: Andres Freund (#324)
#328Ants Aasma
ants.aasma@cybertec.at
In reply to: Greg Smith (#323)
#329Ants Aasma
ants.aasma@cybertec.at
In reply to: Andres Freund (#325)
#330Bruce Momjian
bruce@momjian.us
In reply to: Simon Riggs (#326)
#331Ants Aasma
ants.aasma@cybertec.at
In reply to: Ants Aasma (#329)
#332Jeff Davis
pgsql@j-davis.com
In reply to: Greg Smith (#320)
#333Florian Weimer
fw@deneb.enyo.de
In reply to: Greg Smith (#173)
#334Florian Pflug
fgp@phlo.org
In reply to: Jeff Davis (#332)
#335Ants Aasma
ants.aasma@cybertec.at
In reply to: Florian Pflug (#334)
#336Florian Pflug
fgp@phlo.org
In reply to: Ants Aasma (#331)
#337Ants Aasma
ants.aasma@cybertec.at
In reply to: Florian Pflug (#336)
#338Jeff Davis
pgsql@j-davis.com
In reply to: Florian Pflug (#334)
#339Ants Aasma
ants.aasma@cybertec.at
In reply to: Ants Aasma (#337)
#340Florian Pflug
fgp@phlo.org
In reply to: Ants Aasma (#339)
#341Ants Aasma
ants.aasma@cybertec.at
In reply to: Florian Pflug (#340)
#342Bruce Momjian
bruce@momjian.us
In reply to: Florian Weimer (#333)
#343Robert Haas
robertmhaas@gmail.com
In reply to: Greg Smith (#320)
#344Andres Freund
andres@anarazel.de
In reply to: Robert Haas (#343)
#345Ants Aasma
ants.aasma@cybertec.at
In reply to: Robert Haas (#343)
#346Ants Aasma
ants.aasma@cybertec.at
In reply to: Andres Freund (#344)
#347Josh Berkus
josh@agliodbs.com
In reply to: Ants Aasma (#345)
#348Florian Pflug
fgp@phlo.org
In reply to: Ants Aasma (#345)
#349Ants Aasma
ants.aasma@cybertec.at
In reply to: Florian Pflug (#348)
#350Jeff Davis
pgsql@j-davis.com
In reply to: Florian Pflug (#348)
#351Robert Haas
robertmhaas@gmail.com
In reply to: Jeff Davis (#350)
#352Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#345)
#353Florian Pflug
fgp@phlo.org
In reply to: Jeff Davis (#350)
#354Simon Riggs
simon@2ndQuadrant.com
In reply to: Florian Pflug (#353)
#355Ants Aasma
ants.aasma@cybertec.at
In reply to: Simon Riggs (#354)
#356Ants Aasma
ants.aasma@cybertec.at
In reply to: Ants Aasma (#355)
#357Jeff Davis
pgsql@j-davis.com
In reply to: Ants Aasma (#356)
#358Alvaro Herrera
alvherre@2ndquadrant.com
In reply to: Jeff Davis (#357)
#359Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#357)
#360Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#359)
#361Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#360)
#362Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#361)
#363Simon Riggs
simon@2ndQuadrant.com
In reply to: Jeff Davis (#362)
#364Jeff Davis
pgsql@j-davis.com
In reply to: Simon Riggs (#363)
#365Tom Lane
tgl@sss.pgh.pa.us
In reply to: Simon Riggs (#363)