summaryrefslogtreecommitdiff
path: root/src/backend/replication
diff options
context:
space:
mode:
authorHeikki Linnakangas2014-11-04 09:35:15 +0000
committerHeikki Linnakangas2014-11-04 09:39:48 +0000
commit5028f22f6eb0579890689655285a4778b4ffc460 (patch)
treeed3a4cd635306b18cb0e2851281920db6770a826 /src/backend/replication
parent404bc51cde9dce1c674abe4695635612f08fe27e (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.c28
-rw-r--r--src/backend/replication/slot.c20
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)));