@@ -930,20 +930,26 @@ func (db *DB) initDatabaseFile() error {
930930 // Build per-page checksum map for existing pages. The database could be
931931 // short compared to the page count in the header so just checksum what we
932932 // can. The database may recover in applyLTX() so we'll do validation then.
933- buf := make ([]byte , db .pageSize )
934933 db .chksums .pages = make ([]ltx.Checksum , db .PageN ())
935934 db .chksums .blocks = make ([]ltx.Checksum , pageChksumBlock (db .PageN ()))
936- for pgno := uint32 (1 ); pgno <= db .PageN (); pgno ++ {
937- offset := int64 (pgno - 1 ) * int64 (db .pageSize )
938- if _ , err := internal .ReadFullAt (f , buf , offset ); err == io .EOF || err == io .ErrUnexpectedEOF {
939- log .Printf ("database checksum ending early at page %d of %d " , pgno - 1 , db .PageN ())
940- break
941- } else if err != nil {
942- return fmt .Errorf ("read database page %d: %w" , pgno , err )
943- }
944935
945- chksum := ltx .ChecksumPage (pgno , buf )
946- db .setDatabasePageChecksum (pgno , chksum )
936+ lastGoodPage , err := ltx .ChecksumPages (db .DatabasePath (), db .pageSize , db .PageN (), 0 , db .chksums .pages )
937+
938+ // lastGoodPage tells us how far we got before the first error. Most likely
939+ // is that we got an EOF because the db was short, in which case no
940+ // subsequent checksums would have been written. To be cautious though,
941+ // zero out any checksums after the last good page.
942+ clear (db .chksums .pages [lastGoodPage :])
943+
944+ // Always overwrite the lock page as a zero checksum.
945+ if lockPage := ltx .LockPgno (db .pageSize ); len (db .chksums .pages ) >= int (lockPage ) {
946+ db .chksums .pages [lockPage - 1 ] = 0
947+ }
948+
949+ if err == io .EOF || err == io .ErrUnexpectedEOF {
950+ log .Printf ("database checksum ending early at page %d of %d " , lastGoodPage , db .PageN ())
951+ } else if err != nil {
952+ return fmt .Errorf ("read database page %d: %w" , lastGoodPage + 1 , err )
947953 }
948954
949955 return nil
0 commit comments