diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2014-11-04 11:35:15 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2014-11-04 11:39:48 +0200 |
commit | 5028f22f6eb0579890689655285a4778b4ffc460 (patch) | |
tree | ed3a4cd635306b18cb0e2851281920db6770a826 /src/backend/access/transam/xlog.c | |
parent | 404bc51cde9dce1c674abe4695635612f08fe27e (diff) | |
download | postgresql-5028f22f6eb0579890689655285a4778b4ffc460.tar.gz postgresql-5028f22f6eb0579890689655285a4778b4ffc460.zip |
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/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 50 |
1 files changed, 25 insertions, 25 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 3c9aeaec1e7..3160db72458 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -1059,9 +1059,9 @@ begin:; * the whole record in the order: rdata, then backup blocks, then record * header. */ - INIT_CRC32(rdata_crc); + INIT_CRC32C(rdata_crc); for (rdt = rdata; rdt != NULL; rdt = rdt->next) - COMP_CRC32(rdata_crc, rdt->data, rdt->len); + COMP_CRC32C(rdata_crc, rdt->data, rdt->len); /* * Construct record header (prev-link is filled in later, after reserving @@ -1076,7 +1076,7 @@ begin:; rechdr->xl_info = info; rechdr->xl_rmid = rmid; rechdr->xl_prev = InvalidXLogRecPtr; - COMP_CRC32(rdata_crc, ((char *) rechdr), offsetof(XLogRecord, xl_prev)); + COMP_CRC32C(rdata_crc, ((char *) rechdr), offsetof(XLogRecord, xl_prev)); hdr_rdt.next = rdata; hdr_rdt.data = (char *) rechdr; @@ -1193,8 +1193,8 @@ begin:; * Now that xl_prev has been filled in, finish CRC calculation of the * record header. */ - COMP_CRC32(rdata_crc, ((char *) &rechdr->xl_prev), sizeof(XLogRecPtr)); - FIN_CRC32(rdata_crc); + COMP_CRC32C(rdata_crc, ((char *) &rechdr->xl_prev), sizeof(XLogRecPtr)); + FIN_CRC32C(rdata_crc); rechdr->xl_crc = rdata_crc; /* @@ -4344,11 +4344,11 @@ WriteControlFile(void) ControlFile->float8ByVal = FLOAT8PASSBYVAL; /* Contents are protected with a CRC */ - INIT_CRC32(ControlFile->crc); - COMP_CRC32(ControlFile->crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32(ControlFile->crc); + INIT_CRC32C(ControlFile->crc); + COMP_CRC32C(ControlFile->crc, + (char *) ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(ControlFile->crc); /* * We write out PG_CONTROL_SIZE bytes into pg_control, zero-padding the @@ -4444,13 +4444,13 @@ ReadControlFile(void) errhint("It looks like you need to initdb."))); /* Now check the CRC. */ - INIT_CRC32(crc); - COMP_CRC32(crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32(crc); + INIT_CRC32C(crc); + COMP_CRC32C(crc, + (char *) ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(crc); - if (!EQ_CRC32(crc, ControlFile->crc)) + if (!EQ_CRC32C(crc, ControlFile->crc)) ereport(FATAL, (errmsg("incorrect checksum in control file"))); @@ -4593,11 +4593,11 @@ UpdateControlFile(void) { int fd; - INIT_CRC32(ControlFile->crc); - COMP_CRC32(ControlFile->crc, - (char *) ControlFile, - offsetof(ControlFileData, crc)); - FIN_CRC32(ControlFile->crc); + INIT_CRC32C(ControlFile->crc); + COMP_CRC32C(ControlFile->crc, + (char *) ControlFile, + offsetof(ControlFileData, crc)); + FIN_CRC32C(ControlFile->crc); fd = BasicOpenFile(XLOG_CONTROL_FILE, O_RDWR | PG_BINARY, @@ -4975,10 +4975,10 @@ BootStrapXLOG(void) record->xl_rmid = RM_XLOG_ID; memcpy(XLogRecGetData(record), &checkPoint, sizeof(checkPoint)); - INIT_CRC32(crc); - COMP_CRC32(crc, &checkPoint, sizeof(checkPoint)); - COMP_CRC32(crc, (char *) record, offsetof(XLogRecord, xl_crc)); - FIN_CRC32(crc); + INIT_CRC32C(crc); + COMP_CRC32C(crc, &checkPoint, sizeof(checkPoint)); + COMP_CRC32C(crc, (char *) record, offsetof(XLogRecord, xl_crc)); + FIN_CRC32C(crc); record->xl_crc = crc; /* Create first XLOG segment file */ |