mariadb/mysql-test/suite/mariabackup/xb_history.result
Thirunarayanan Balathandayuthapani 2d1e019f4f MDEV-36871 mariadb-backup incremental segfault querying mariadb_backup_history
Problem:
=========
(1) Mariabackup tries to read the history data from
mysql.mariadb_backup_history and fails with segfault. Reason is that
mariabackup does force innodb_log_checkpoint_now from commit 652f33e0a44661d6093993d49d3e83d770904413(MDEV-30000).
Mariabackup sends the "innodb_log_checkpoint_now=1" query to server and
reads the result set for the query later in the code because the query
may trigger the page thread to flush the pages. But before reading the
query result for innodb_log_checkpoint_now=1, mariabackup does execute
the select query for the history table (mysql.mariadb_backup_history)
and wrongly reads the query result of innodb_log_checkpoint_now. This leads
to assertion in mariabackup.

(2) The recording of incremental backups has the format as "tar"
when mbstream was used. The xb_stream_fmt_t only had XB_STREAM_FMT_NONE
and XB_STREAM_FMT_XBSTREAM and hence in the mysql.mariadb_backup_history
table the format was recorded as "tar" for the "mbstream" due to the
offset in the xb_stream_name array within mariadb-backup.

(3) Also under Windows the full path of mariabackup was recorded in the the
history.

(4) select_incremental_lsn_from_history(): Name of the backup and UUID
of the history record variable could lead to buffer overflow while
copying the variable value from global variable.

Solution:
=========
(1) Move the reading of history data from mysql.mariadb_backup_history
after reading the result of innodb_log_checkpoint_now=1 query

(2) We've removed the "tar" element from the xb_stream_name. As the
"xbstream" was never used, the format name is changed to mbstream.
As the table needs alteration the "mbstream" appended instead of
the unused xbstream in the table. "tar" is left in the enum as
the previous recordings are still possible.

(3) The Windows path separator is used to store just the executable
name as the tool in the mariadb_backup_history table.

(4) select_incremental_lsn_from_history(): Check and validate
the length of incremental history name and incremental history uuid
before copying into temporary buffer

Thanks to Daniel black for contributing the code for solution (2) and (3)
2025-06-23 10:26:43 +10:00

37 lines
1.3 KiB
Text

DROP TABLE IF EXISTS mysql.mariadb_backup_history;
SHOW CREATE TABLE mysql.mariadb_backup_history;
Table Create Table
mariadb_backup_history CREATE TABLE `mariadb_backup_history` (
`uuid` varchar(40) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`tool_name` varchar(255) DEFAULT NULL,
`tool_command` text DEFAULT NULL,
`tool_version` varchar(255) DEFAULT NULL,
`ibbackup_version` varchar(255) DEFAULT NULL,
`server_version` varchar(255) DEFAULT NULL,
`start_time` timestamp NULL DEFAULT NULL,
`end_time` timestamp NULL DEFAULT NULL,
`lock_time` bigint(20) unsigned DEFAULT NULL,
`binlog_pos` varchar(128) DEFAULT NULL,
`innodb_from_lsn` bigint(20) unsigned DEFAULT NULL,
`innodb_to_lsn` bigint(20) unsigned DEFAULT NULL,
`partial` enum('Y','N') DEFAULT NULL,
`incremental` enum('Y','N') DEFAULT NULL,
`format` enum('file','tar','mbstream') DEFAULT NULL,
`compressed` enum('Y','N') DEFAULT NULL,
PRIMARY KEY (`uuid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci
SELECT COUNT(*) FROM mysql.mariadb_backup_history;
COUNT(*)
1
SELECT name FROM mysql.mariadb_backup_history;
name
foo
SELECT COUNT(*) FROM mysql.mariadb_backup_history;
COUNT(*)
2
SELECT name FROM mysql.mariadb_backup_history;
name
foo
DROP TABLE mysql.mariadb_backup_history;