Use crc32 for sqlite page checksums

This commit is contained in:
Trevor Clinkenbeard 2019-05-14 13:43:55 -07:00
parent a9b03ec505
commit 601c38ad82
1 changed files with 37 additions and 21 deletions

View File

@ -20,6 +20,7 @@
#define SQLITE_THREADSAFE 0 // also in sqlite3.amalgamation.c!
#include "fdbrpc/crc32c.h"
#include "fdbserver/IKeyValueStore.h"
#include "fdbserver/CoroFlow.h"
#include "fdbserver/Knobs.h"
@ -93,29 +94,44 @@ struct PageChecksumCodec {
SumType sum;
SumType *pSumInPage = (SumType *)(pData + dataLen);
// Write sum directly to page or to sum variable based on mode
SumType *sumOut = write ? pSumInPage : ∑
sumOut->part1 = pageNumber; //DO NOT CHANGE
sumOut->part2 = 0x5ca1ab1e;
hashlittle2(pData, dataLen, &sumOut->part1, &sumOut->part2);
// Verify if not in write mode
if(!write && sum != *pSumInPage) {
if(!silent)
TraceEvent (SevError, "SQLitePageChecksumFailure")
.error(checksum_failed())
.detail("CodecPageSize", pageSize)
.detail("CodecReserveSize", reserveSize)
.detail("Filename", filename)
.detail("PageNumber", pageNumber)
.detail("PageSize", pageLen)
.detail("ChecksumInPage", pSumInPage->toString())
.detail("ChecksumCalculated", sum.toString());
return false;
if (write) {
// Always write a CRC32 checksum for new pages
sum.part1 = 0; // Indicates CRC32 is being used
sum.part2 = crc32c_append(0xfdbeefdb, static_cast<uint8_t*>(data), dataLen);
memcpy(pSumInPage, &sum, sizeof(SumType));
return true;
}
return true;
if (pSumInPage->part1 == 0) {
// part1 being 0 indicates with high probability that a CRC32 checksum
// was used, so check that first. If this checksum fails, there is still
// some chance the page was written with hashlittle2, so fall back to checking
// hashlittle2
sum.part1 = 0;
sum.part2 = crc32c_append(0xfdbeefdb, static_cast<uint8_t*>(data), dataLen);
if (sum == *pSumInPage) return true;
SumType hashLittle2Sum;
hashLittle2Sum.part1 = pageNumber; // DO NOT CHANGE
hashLittle2Sum.part2 = 0x5ca1ab1e;
hashlittle2(pData, dataLen, &hashLittle2Sum.part1, &hashLittle2Sum.part2);
if (hashLittle2Sum == *pSumInPage) return true;
} else {
sum.part1 = pageNumber; // DO NOT CHANGE
sum.part2 = 0x5ca1ab1e;
hashlittle2(pData, dataLen, &sum.part1, &sum.part2);
if (sum == *pSumInPage) return true;
}
TraceEvent(SevError, "SQLitePageChecksumFailure")
.error(checksum_failed())
.detail("CodecPageSize", pageSize)
.detail("CodecReserveSize", reserveSize)
.detail("Filename", filename)
.detail("PageNumber", pageNumber)
.detail("PageSize", pageLen)
.detail("ChecksumInPage", pSumInPage->toString())
.detail("ChecksumCalculated", sum.toString());
return false;
}
static void * codec(void *vpSelf, void *data, Pgno pageNumber, int op) {