aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/transam/xlog.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-11-04 11:35:15 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2014-11-04 11:39:48 +0200
commit5028f22f6eb0579890689655285a4778b4ffc460 (patch)
treeed3a4cd635306b18cb0e2851281920db6770a826 /src/backend/access/transam/xlog.c
parent404bc51cde9dce1c674abe4695635612f08fe27e (diff)
downloadpostgresql-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.c50
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 */