MDEV-37520 Failure to detect corruption during backups of Aria table

Fixed the following issues:
- aria_read_index() and aria_read_data(), used by mariabackup, checked
  the wrong status from maria_page_crc_check().
- Both functions did infinite retries if crc did not match.
- Wrong usage of ma_check_if_zero() in maria_page_crc_check()

Author: Thirunarayanan Balathandayuthapani <thiru@mariadb.com>
This commit is contained in:
Monty 2025-09-03 14:03:24 +03:00
parent 5a35fff422
commit fd39c63b41
4 changed files with 25 additions and 23 deletions

View File

@ -399,21 +399,19 @@ bool Table::copy(ds_ctxt_t *ds, bool is_index, unsigned thread_num) {
for (ulonglong block= 0 ; ; block++) {
size_t length = m_cap.block_size;
if (is_index) {
if ((error= aria_read_index(
partition.m_index_file, &m_cap, block, copy_buffer) ==
HA_ERR_END_OF_FILE))
break;
} else {
if ((error= aria_read_data(
partition.m_data_file, &m_cap, block, copy_buffer, &length) ==
HA_ERR_END_OF_FILE))
break;
}
if (error) {
msg(thread_num, "error: aria_read %s failed: %d",
is_index ? "index" : "data", error);
goto err;
if (is_index)
error= aria_read_index(partition.m_index_file, &m_cap,
block, copy_buffer);
else
error= aria_read_data(partition.m_data_file, &m_cap,
block, copy_buffer, &length);
if (error)
{
if (error == HA_ERR_END_OF_FILE)
break;
msg(thread_num, "error: aria_read %s failed: %d",
is_index ? "index" : "data", error);
goto err;
}
xtrabackup_io_throttling();
if ((error = ds_write(dst_file, copy_buffer, length))) {

View File

@ -34,11 +34,11 @@ CREATE TABLE test.t1(id INT, txt LONGTEXT) ENGINE=Aria;
--source include/aria_log_control_load.inc
CALL display_aria_log_control(@aria_log_control);
let $backuplog= $MYSQLTEST_VARDIR/tmp/backup.log;
--echo # Running --backup
--let after_scanning_log_files=CALL test.populate_t1
--disable_result_log
--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --parallel=10 --target-dir=$targetdir --dbug=+d,mariabackup_events 2>&1
--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events > $backuplog
--let after_scanning_log_files=
--enable_result_log
@ -77,6 +77,7 @@ CALL display_aria_log_control(@aria_log_control);
SELECT id, LENGTH(txt) FROM t1 ORDER BY id;
DROP TABLE t1;
rmdir $targetdir;
remove_file $backuplog;
DROP PROCEDURE populate_t1;
DROP PROCEDURE display_aria_log_control;

View File

@ -202,11 +202,11 @@ int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block,
error= maria_page_crc_check(buffer, block, &share,
MARIA_NO_CRC_NORMAL_PAGE,
(int) length);
if (error != HA_ERR_WRONG_CRC)
if (error == 0 || my_errno != HA_ERR_WRONG_CRC)
DBUG_RETURN(error);
}
my_sleep(100000); /* Sleep 0.1 seconds */
} while (retry < MAX_RETRY);
} while (retry++ < MAX_RETRY);
DBUG_RETURN(HA_ERR_WRONG_CRC);
}
@ -264,15 +264,18 @@ int aria_read_data(File dfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block,
if (length == cap->block_size)
{
error= maria_page_crc_check(buffer, block, &share,
if (!_ma_check_if_zero(buffer, share.block_size - CRC_SIZE))
error= 0;
else
error= maria_page_crc_check(buffer, block, &share,
((block % cap->bitmap_pages_covered) == 0 ?
MARIA_NO_CRC_BITMAP_PAGE :
MARIA_NO_CRC_NORMAL_PAGE),
share.block_size - CRC_SIZE);
if (error != HA_ERR_WRONG_CRC)
if (error == 0 || my_errno != HA_ERR_WRONG_CRC)
DBUG_RETURN(error);
}
my_sleep(100000); /* Sleep 0.1 seconds */
} while (retry < MAX_RETRY);
} while (retry++ < MAX_RETRY);
DBUG_RETURN(HA_ERR_WRONG_CRC);
}

View File

@ -103,7 +103,7 @@ my_bool maria_page_crc_check(uchar *page,
the CRC will be corrected at next write)
*/
if (no_crc_val == MARIA_NO_CRC_BITMAP_PAGE &&
crc == 0 && _ma_check_if_zero(page, data_length))
crc == 0 && !_ma_check_if_zero(page, data_length))
{
DBUG_PRINT("warning", ("Found bitmap page that was not initialized"));
DBUG_RETURN(0);