mirror of
https://github.com/postgres/postgres.git
synced 2025-07-02 09:02:37 +03:00
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.
This commit is contained in:
16
src/backend/utils/cache/relmapper.c
vendored
16
src/backend/utils/cache/relmapper.c
vendored
@ -84,7 +84,7 @@ typedef struct RelMapFile
|
||||
int32 magic; /* always RELMAPPER_FILEMAGIC */
|
||||
int32 num_mappings; /* number of valid RelMapping entries */
|
||||
RelMapping mappings[MAX_MAPPINGS];
|
||||
int32 crc; /* CRC of all above */
|
||||
pg_crc32 crc; /* CRC of all above */
|
||||
int32 pad; /* to make the struct size be 512 exactly */
|
||||
} RelMapFile;
|
||||
|
||||
@ -673,11 +673,11 @@ load_relmap_file(bool shared)
|
||||
mapfilename)));
|
||||
|
||||
/* verify the CRC */
|
||||
INIT_CRC32(crc);
|
||||
COMP_CRC32(crc, (char *) map, offsetof(RelMapFile, crc));
|
||||
FIN_CRC32(crc);
|
||||
INIT_CRC32C(crc);
|
||||
COMP_CRC32C(crc, (char *) map, offsetof(RelMapFile, crc));
|
||||
FIN_CRC32C(crc);
|
||||
|
||||
if (!EQ_CRC32(crc, map->crc))
|
||||
if (!EQ_CRC32C(crc, map->crc))
|
||||
ereport(FATAL,
|
||||
(errmsg("relation mapping file \"%s\" contains incorrect checksum",
|
||||
mapfilename)));
|
||||
@ -719,9 +719,9 @@ write_relmap_file(bool shared, RelMapFile *newmap,
|
||||
if (newmap->num_mappings < 0 || newmap->num_mappings > MAX_MAPPINGS)
|
||||
elog(ERROR, "attempt to write bogus relation mapping");
|
||||
|
||||
INIT_CRC32(newmap->crc);
|
||||
COMP_CRC32(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
|
||||
FIN_CRC32(newmap->crc);
|
||||
INIT_CRC32C(newmap->crc);
|
||||
COMP_CRC32C(newmap->crc, (char *) newmap, offsetof(RelMapFile, crc));
|
||||
FIN_CRC32C(newmap->crc);
|
||||
|
||||
/*
|
||||
* Open the target file. We prefer to do this before entering the
|
||||
|
Reference in New Issue
Block a user