diff options
| author | Heikki Linnakangas | 2014-11-04 09:35:15 +0000 |
|---|---|---|
| committer | Heikki Linnakangas | 2014-11-04 09:39:48 +0000 |
| commit | 5028f22f6eb0579890689655285a4778b4ffc460 (patch) | |
| tree | ed3a4cd635306b18cb0e2851281920db6770a826 /src/backend/replication | |
| parent | 404bc51cde9dce1c674abe4695635612f08fe27e (diff) | |
Switch to CRC-32C in WAL and other places.
The old algorithm was found to not be the usual CRC-32 algorithm, used by
Ethernet et al. We were using a non-reflected lookup table with code meant
for a reflected lookup table. That's a strange combination that AFAICS does
not correspond to any bit-wise CRC calculation, which makes it difficult to
reason about its properties. Although it has worked well in practice, seems
safer to use a well-known algorithm.
Since we're changing the algorithm anyway, we might as well choose a
different polynomial. The Castagnoli polynomial has better error-correcting
properties than the traditional CRC-32 polynomial, even if we had
implemented it correctly. Another reason for picking that is that some new
CPUs have hardware support for calculating CRC-32C, but not CRC-32, let
alone our strange variant of it. This patch doesn't add any support for such
hardware, but a future patch could now do that.
The old algorithm is kept around for tsquery and pg_trgm, which use the
values in indexes that need to remain compatible so that pg_upgrade works.
While we're at it, share the old lookup table for CRC-32 calculation
between hstore, ltree and core. They all use the same table, so might as
well.
Diffstat (limited to 'src/backend/replication')
| -rw-r--r-- | src/backend/replication/logical/snapbuild.c | 28 | ||||
| -rw-r--r-- | src/backend/replication/slot.c | 20 |
2 files changed, 24 insertions, 24 deletions
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index 5e59c6b819b..71c5fe2490a 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -1517,9 +1517,9 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) ondisk->magic = SNAPBUILD_MAGIC; ondisk->version = SNAPBUILD_VERSION; ondisk->length = needed_length; - INIT_CRC32(ondisk->checksum); - COMP_CRC32(ondisk->checksum, - ((char *) ondisk) + SnapBuildOnDiskNotChecksummedSize, + INIT_CRC32C(ondisk->checksum); + COMP_CRC32C(ondisk->checksum, + ((char *) ondisk) + SnapBuildOnDiskNotChecksummedSize, SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize); ondisk_c += sizeof(SnapBuildOnDisk); @@ -1531,20 +1531,20 @@ SnapBuildSerialize(SnapBuild *builder, XLogRecPtr lsn) ondisk->builder.running.xip = NULL; ondisk->builder.committed.xip = NULL; - COMP_CRC32(ondisk->checksum, - &ondisk->builder, - sizeof(SnapBuild)); + COMP_CRC32C(ondisk->checksum, + &ondisk->builder, + sizeof(SnapBuild)); /* copy running xacts */ sz = sizeof(TransactionId) * builder->running.xcnt_space; memcpy(ondisk_c, builder->running.xip, sz); - COMP_CRC32(ondisk->checksum, ondisk_c, sz); + COMP_CRC32C(ondisk->checksum, ondisk_c, sz); ondisk_c += sz; /* copy committed xacts */ sz = sizeof(TransactionId) * builder->committed.xcnt; memcpy(ondisk_c, builder->committed.xip, sz); - COMP_CRC32(ondisk->checksum, ondisk_c, sz); + COMP_CRC32C(ondisk->checksum, ondisk_c, sz); ondisk_c += sz; /* we have valid data now, open tempfile and write it there */ @@ -1672,8 +1672,8 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) (errmsg("snapbuild state file \"%s\" has unsupported version %u instead of %u", path, ondisk.version, SNAPBUILD_VERSION))); - INIT_CRC32(checksum); - COMP_CRC32(checksum, + INIT_CRC32C(checksum); + COMP_CRC32C(checksum, ((char *) &ondisk) + SnapBuildOnDiskNotChecksummedSize, SnapBuildOnDiskConstantSize - SnapBuildOnDiskNotChecksummedSize); @@ -1687,7 +1687,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) errmsg("could not read file \"%s\", read %d of %d: %m", path, readBytes, (int) sizeof(SnapBuild)))); } - COMP_CRC32(checksum, &ondisk.builder, sizeof(SnapBuild)); + COMP_CRC32C(checksum, &ondisk.builder, sizeof(SnapBuild)); /* restore running xacts information */ sz = sizeof(TransactionId) * ondisk.builder.running.xcnt_space; @@ -1701,7 +1701,7 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) errmsg("could not read file \"%s\", read %d of %d: %m", path, readBytes, (int) sz))); } - COMP_CRC32(checksum, ondisk.builder.running.xip, sz); + COMP_CRC32C(checksum, ondisk.builder.running.xip, sz); /* restore committed xacts information */ sz = sizeof(TransactionId) * ondisk.builder.committed.xcnt; @@ -1715,12 +1715,12 @@ SnapBuildRestore(SnapBuild *builder, XLogRecPtr lsn) errmsg("could not read file \"%s\", read %d of %d: %m", path, readBytes, (int) sz))); } - COMP_CRC32(checksum, ondisk.builder.committed.xip, sz); + COMP_CRC32C(checksum, ondisk.builder.committed.xip, sz); CloseTransientFile(fd); /* verify checksum of what we've read */ - if (!EQ_CRC32(checksum, ondisk.checksum)) + if (!EQ_CRC32C(checksum, ondisk.checksum)) ereport(ERROR, (errcode_for_file_access(), errmsg("snapbuild state file %s: checksum mismatch, is %u, should be %u", diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c index f355f13d293..2c3ea555d09 100644 --- a/src/backend/replication/slot.c +++ b/src/backend/replication/slot.c @@ -993,7 +993,7 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel) } cp.magic = SLOT_MAGIC; - INIT_CRC32(cp.checksum); + INIT_CRC32C(cp.checksum); cp.version = 1; cp.length = ReplicationSlotOnDiskDynamicSize; @@ -1003,9 +1003,9 @@ SaveSlotToPath(ReplicationSlot *slot, const char *dir, int elevel) SpinLockRelease(&slot->mutex); - COMP_CRC32(cp.checksum, - (char *) (&cp) + ReplicationSlotOnDiskConstantSize, - ReplicationSlotOnDiskDynamicSize); + COMP_CRC32C(cp.checksum, + (char *) (&cp) + ReplicationSlotOnDiskConstantSize, + ReplicationSlotOnDiskDynamicSize); if ((write(fd, &cp, sizeof(cp))) != sizeof(cp)) { @@ -1181,13 +1181,13 @@ RestoreSlotFromDisk(const char *name) CloseTransientFile(fd); - /* now verify the CRC32 */ - INIT_CRC32(checksum); - COMP_CRC32(checksum, - (char *) &cp + ReplicationSlotOnDiskConstantSize, - ReplicationSlotOnDiskDynamicSize); + /* now verify the CRC */ + INIT_CRC32C(checksum); + COMP_CRC32C(checksum, + (char *) &cp + ReplicationSlotOnDiskConstantSize, + ReplicationSlotOnDiskDynamicSize); - if (!EQ_CRC32(checksum, cp.checksum)) + if (!EQ_CRC32C(checksum, cp.checksum)) ereport(PANIC, (errmsg("replication slot file %s: checksum mismatch, is %u, should be %u", path, checksum, cp.checksum))); |
