@@ -274,30 +274,27 @@ void print_leaf_stats(
274
274
}
275
275
}
276
276
277
- /* * Get the ROW_FORMAT=COMPRESSED size from the filespace header.
278
- @param[in] buf buffer used to read the page.
279
- @return ROW_FORMAT_COMPRESSED page size
280
- @retval 0 if not ROW_FORMAT=COMPRESSED */
281
- static ulint get_zip_size (const byte* buf)
277
+ /* * Init the page size for the tablespace.
278
+ @param[in] buf buffer used to read the page */
279
+ static void init_page_size (const byte* buf)
282
280
{
283
281
const unsigned flags = mach_read_from_4 (buf + FIL_PAGE_DATA
284
282
+ FSP_SPACE_FLAGS);
285
283
284
+ if (FSP_FLAGS_FCRC32_HAS_MARKER (flags)) {
285
+ srv_page_size = fil_space_t::logical_size (flags);
286
+ physical_page_size = srv_page_size;
287
+ return ;
288
+ }
289
+
286
290
const ulong ssize = FSP_FLAGS_GET_PAGE_SSIZE (flags);
287
291
288
292
srv_page_size_shift = ssize
289
293
? UNIV_ZIP_SIZE_SHIFT_MIN - 1 + ssize
290
294
: UNIV_PAGE_SIZE_SHIFT_ORIG;
291
295
292
- srv_page_size = 1U << srv_page_size_shift;
293
- ulint zip_size = FSP_FLAGS_GET_ZIP_SSIZE (flags);
294
- if (zip_size) {
295
- zip_size = (UNIV_ZIP_SIZE_MIN >> 1 ) << zip_size;
296
- physical_page_size = zip_size;
297
- } else {
298
- physical_page_size = srv_page_size;
299
- }
300
- return zip_size;
296
+ srv_page_size = fil_space_t::logical_size (flags);
297
+ physical_page_size = fil_space_t::physical_size (flags);
301
298
}
302
299
303
300
#ifdef _WIN32
@@ -429,19 +426,16 @@ ulint read_file(
429
426
430
427
/* * Check if page is corrupted or not.
431
428
@param[in] buf page frame
432
- @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
433
429
@param[in] is_encrypted true if page0 contained cryp_data
434
430
with crypt_scheme encrypted
435
- @param[in] is_compressed true if page0 fsp_flags contained
436
- page compression flag
431
+ @param[in] flags tablespace flags
437
432
@retval true if page is corrupted otherwise false. */
438
433
static
439
434
bool
440
435
is_page_corrupted (
441
436
byte* buf,
442
- ulint zip_size,
443
437
bool is_encrypted,
444
- bool is_compressed )
438
+ ulint flags )
445
439
{
446
440
447
441
/* enable if page is corrupted. */
@@ -450,9 +444,12 @@ is_page_corrupted(
450
444
ulint logseq;
451
445
ulint logseqfield;
452
446
ulint page_type = mach_read_from_2 (buf+FIL_PAGE_TYPE);
453
- uint key_version = mach_read_from_4 (buf+FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION );
447
+ uint key_version = buf_page_get_key_version (buf, flags );
454
448
ulint space_id = mach_read_from_4 (
455
449
buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
450
+ ulint zip_size = fil_space_t::zip_size (flags);
451
+ ulint is_compressed = fil_space_t::is_compressed (flags);
452
+ const bool use_full_crc32 = fil_space_t::full_crc32 (flags);
456
453
457
454
/* We can't trust only a page type, thus we take account
458
455
also fsp_flags or crypt_data on page 0 */
@@ -468,9 +465,11 @@ is_page_corrupted(
468
465
/* check the stored log sequence numbers
469
466
for uncompressed tablespace. */
470
467
logseq = mach_read_from_4 (buf + FIL_PAGE_LSN + 4 );
471
- logseqfield = mach_read_from_4 (
472
- buf + srv_page_size -
473
- FIL_PAGE_END_LSN_OLD_CHKSUM + 4 );
468
+ logseqfield = use_full_crc32
469
+ ? mach_read_from_4 (buf + srv_page_size
470
+ - FIL_PAGE_FCRC32_END_LSN)
471
+ : mach_read_from_4 (buf + srv_page_size
472
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4 );
474
473
475
474
if (is_log_enabled) {
476
475
fprintf (log_file,
@@ -498,23 +497,22 @@ is_page_corrupted(
498
497
so if crypt checksum does not match we verify checksum using
499
498
normal method. */
500
499
if (is_encrypted && key_version != 0 ) {
501
- is_corrupted = !fil_space_verify_crypt_checksum (buf, zip_size);
500
+ is_corrupted = use_full_crc32
501
+ ? buf_page_is_corrupted (true , buf, flags)
502
+ : !fil_space_verify_crypt_checksum (buf, zip_size);
503
+
502
504
if (is_corrupted && log_file) {
503
505
fprintf (log_file,
504
506
" Page " ULINTPF " :%llu may be corrupted;"
505
507
" key_version=%u\n " ,
506
- space_id, cur_page_num,
507
- mach_read_from_4 (
508
- FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
509
- + buf));
508
+ space_id, cur_page_num, key_version);
510
509
}
511
510
} else {
512
511
is_corrupted = true ;
513
512
}
514
513
515
514
if (is_corrupted) {
516
- is_corrupted = buf_page_is_corrupted (
517
- true , buf, zip_size, NULL );
515
+ is_corrupted = buf_page_is_corrupted (true , buf, flags);
518
516
}
519
517
520
518
return (is_corrupted);
@@ -566,17 +564,13 @@ is_page_empty(
566
564
/* *******************************************************************/ /* *
567
565
Rewrite the checksum for the page.
568
566
@param [in/out] page page buffer
569
- @param [in] iscompressed Is compressed/Uncompressed Page.
567
+ @param [in] flags tablespace flags
570
568
571
569
@retval true : do rewrite
572
570
@retval false : skip the rewrite as checksum stored match with
573
571
calculated or page is doublwrite buffer.
574
572
*/
575
-
576
- bool
577
- update_checksum (
578
- byte* page,
579
- bool iscompressed)
573
+ static bool update_checksum (byte* page, ulint flags)
580
574
{
581
575
ib_uint32_t checksum = 0 ;
582
576
byte stored1[4 ]; /* get FIL_PAGE_SPACE_OR_CHKSUM field checksum */
@@ -588,6 +582,9 @@ update_checksum(
588
582
return (false );
589
583
}
590
584
585
+ const bool use_full_crc32 = fil_space_t::full_crc32 (flags);
586
+ const bool iscompressed = fil_space_t::zip_size (flags);
587
+
591
588
memcpy (stored1, page + FIL_PAGE_SPACE_OR_CHKSUM, 4 );
592
589
memcpy (stored2, page + physical_page_size -
593
590
FIL_PAGE_END_LSN_OLD_CHKSUM, 4 );
@@ -615,12 +612,24 @@ update_checksum(
615
612
" %u\n " , cur_page_num, checksum);
616
613
}
617
614
615
+ } else if (use_full_crc32) {
616
+ checksum = buf_calc_page_full_crc32 (page);
617
+ byte* c = page + physical_page_size - FIL_PAGE_FCRC32_CHECKSUM;
618
+ if (mach_read_from_4 (c) == checksum) return false ;
619
+ mach_write_to_4 (c, checksum);
620
+ if (is_log_enabled) {
621
+ fprintf (log_file, " page::%llu; Updated checksum"
622
+ " = %u\n " , cur_page_num, checksum);
623
+ }
624
+ return true ;
618
625
} else {
619
626
/* page is uncompressed. */
620
627
621
628
/* Store the new formula checksum */
622
629
switch ((srv_checksum_algorithm_t ) write_check) {
623
630
631
+ case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
632
+ case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
624
633
case SRV_CHECKSUM_ALGORITHM_CRC32:
625
634
case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
626
635
checksum = buf_calc_page_crc32 (page);
@@ -636,6 +645,7 @@ update_checksum(
636
645
case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
637
646
checksum = BUF_NO_CHECKSUM_MAGIC;
638
647
break ;
648
+
639
649
/* no default so the compiler will emit a warning if new
640
650
enum is added and not handled here */
641
651
}
@@ -689,8 +699,7 @@ update_checksum(
689
699
@param[in,out] file file pointer where content
690
700
have to be written
691
701
@param[in] buf file buffer read
692
- @param[in] compressed Enabled if tablespace is
693
- compressed.
702
+ @param[in] flags tablespace flags
694
703
@param[in,out] pos current file position.
695
704
696
705
@retval true if successfully written
@@ -702,12 +711,12 @@ write_file(
702
711
const char * filename,
703
712
FILE* file,
704
713
byte* buf,
705
- bool compressed ,
714
+ ulint flags ,
706
715
fpos_t * pos)
707
716
{
708
717
bool do_update;
709
718
710
- do_update = update_checksum (buf, compressed );
719
+ do_update = update_checksum (buf, flags );
711
720
712
721
if (file != stdin) {
713
722
if (do_update) {
@@ -1322,6 +1331,13 @@ innochecksum_get_one_option(
1322
1331
srv_checksum_algorithm =
1323
1332
SRV_CHECKSUM_ALGORITHM_STRICT_NONE;
1324
1333
break ;
1334
+
1335
+ case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
1336
+ case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
1337
+ srv_checksum_algorithm =
1338
+ SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32;
1339
+ break ;
1340
+
1325
1341
default :
1326
1342
return (true );
1327
1343
}
@@ -1415,30 +1431,21 @@ static bool check_encryption(const char* filename, const byte* page)
1415
1431
return (type == CRYPT_SCHEME_1);
1416
1432
}
1417
1433
1418
- /* *
1419
- Verify page checksum.
1434
+ /* * Verify page checksum.
1420
1435
@param[in] buf page to verify
1421
1436
@param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
1422
1437
@param[in] is_encrypted true if tablespace is encrypted
1423
- @param[in] is_compressed true if tablespace is page compressed
1424
1438
@param[in,out] mismatch_count Number of pages failed in checksum verify
1425
- @retval 0 if page checksum matches or 1 if it does not match
1426
- */
1427
- static
1428
- int verify_checksum (
1429
- byte* buf,
1430
- ulint zip_size,
1431
- bool is_encrypted,
1432
- bool is_compressed,
1433
- unsigned long long * mismatch_count)
1439
+ @param[in] flags tablespace flags
1440
+ @retval 0 if page checksum matches or 1 if it does not match */
1441
+ static int verify_checksum (
1442
+ byte* buf,
1443
+ bool is_encrypted,
1444
+ unsigned long long * mismatch_count,
1445
+ ulint flags)
1434
1446
{
1435
1447
int exit_status = 0 ;
1436
- bool is_corrupted = false ;
1437
-
1438
- is_corrupted = is_page_corrupted (
1439
- buf, zip_size, is_encrypted, is_compressed);
1440
-
1441
- if (is_corrupted) {
1448
+ if (is_page_corrupted (buf, is_encrypted, flags)) {
1442
1449
fprintf (stderr, " Fail: page::%llu invalid\n " ,
1443
1450
cur_page_num);
1444
1451
@@ -1464,35 +1471,26 @@ int verify_checksum(
1464
1471
@param[in] filename File name
1465
1472
@param[in] fil_in File pointer
1466
1473
@param[in] buf page
1467
- @param[in] zip_size ROW_FORMAT=COMPRESSED page size, or 0
1468
1474
@param[in] pos File position
1469
1475
@param[in] is_encrypted true if tablespace is encrypted
1470
- @param[in] is_compressed true if tablespace is page compressed
1476
+ @param[in] flags tablespace flags
1471
1477
@retval 0 if checksum rewrite was successful, 1 if error was detected */
1472
1478
static
1473
1479
int
1474
1480
rewrite_checksum (
1475
1481
const char * filename,
1476
1482
FILE* fil_in,
1477
1483
byte* buf,
1478
- ulint zip_size,
1479
1484
fpos_t * pos,
1480
- bool is_encrypted,
1481
- bool is_compressed )
1485
+ bool is_encrypted,
1486
+ ulint flags )
1482
1487
{
1483
- int exit_status = 0 ;
1488
+ bool is_compressed = fil_space_t::is_compressed (flags);
1489
+
1484
1490
/* Rewrite checksum. Note that for encrypted and
1485
1491
page compressed tables this is not currently supported. */
1486
- if (do_write &&
1487
- !is_encrypted &&
1488
- !is_compressed
1489
- && !write_file (filename, fil_in, buf,
1490
- zip_size, pos)) {
1491
-
1492
- exit_status = 1 ;
1493
- }
1494
-
1495
- return (exit_status);
1492
+ return do_write && !is_encrypted && !is_compressed
1493
+ && !write_file (filename, fil_in, buf, flags, pos);
1496
1494
}
1497
1495
1498
1496
int main (
@@ -1668,10 +1666,9 @@ int main(
1668
1666
1669
1667
/* Determine page size, zip_size and page compression
1670
1668
from fsp_flags and encryption metadata from page 0 */
1671
- ulint zip_size = get_zip_size (buf);
1669
+ init_page_size (buf);
1672
1670
1673
1671
ulint flags = mach_read_from_4 (FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf);
1674
- bool is_compressed = FSP_FLAGS_HAS_PAGE_COMPRESSION (flags);
1675
1672
1676
1673
if (physical_page_size > UNIV_ZIP_SIZE_MIN) {
1677
1674
/* Read rest of the page 0 to determine crypt_data */
@@ -1698,7 +1695,8 @@ int main(
1698
1695
unsigned long long tmp_allow_mismatches = allow_mismatches;
1699
1696
allow_mismatches = 0 ;
1700
1697
1701
- exit_status = verify_checksum (buf, zip_size, is_encrypted, is_compressed, &mismatch_count);
1698
+ exit_status = verify_checksum (buf, is_encrypted,
1699
+ &mismatch_count, flags);
1702
1700
1703
1701
if (exit_status) {
1704
1702
fprintf (stderr, " Error: Page 0 checksum mismatch, can't continue. \n " );
@@ -1707,8 +1705,9 @@ int main(
1707
1705
allow_mismatches = tmp_allow_mismatches;
1708
1706
}
1709
1707
1710
- if ((exit_status = rewrite_checksum (filename, fil_in, buf,
1711
- zip_size, &pos, is_encrypted, is_compressed))) {
1708
+ if ((exit_status = rewrite_checksum (
1709
+ filename, fil_in, buf,
1710
+ &pos, is_encrypted, flags))) {
1712
1711
goto my_exit;
1713
1712
}
1714
1713
@@ -1874,13 +1873,15 @@ int main(
1874
1873
checksum verification.*/
1875
1874
if (!no_check
1876
1875
&& !skip_page
1877
- && (exit_status = verify_checksum (buf, zip_size,
1878
- is_encrypted, is_compressed, &mismatch_count))) {
1876
+ && (exit_status = verify_checksum (
1877
+ buf, is_encrypted,
1878
+ &mismatch_count, flags))) {
1879
1879
goto my_exit;
1880
1880
}
1881
1881
1882
- if ((exit_status = rewrite_checksum (filename, fil_in, buf,
1883
- zip_size, &pos, is_encrypted, is_compressed))) {
1882
+ if ((exit_status = rewrite_checksum (
1883
+ filename, fil_in, buf,
1884
+ &pos, is_encrypted, flags))) {
1884
1885
goto my_exit;
1885
1886
}
1886
1887
0 commit comments