Details
-
Bug
-
Status: Open (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11.19
-
None
-
None
-
Debian 12, kernel 6.1.0-53-amd64, x86_64. wsrep/Galera enabled (not implicated).
-
Can result in unexpected behaviour
Description
ha_maria::drop_table dereferences file unconditionally on the line immediately following an assertion that explicitly permits it to be NULL:
void ha_maria::drop_table(const char *name) // storage/maria/ha_maria.cc:2858
{ DBUG_ASSERT(!file || file->s->temporary); // 2860 - allows file == NULL file->s->deleting= 1; // 2861 - SIGSEGV (void) ha_close(); (void) maria_delete_table_files(name, 1, MY_WME); }That state is reachable through normal error handling. For an internal temp table requiring Aria:
1. create_internal_tmp_table converts the distinct index to a unique constraint — sql/sql_select.cc:21912-21913, share->keys= 0; share->uniques= 1.
2. maria_create succeeds, and sql/sql_select.cc:22035 calls table->set_created().
3. open_tmp_table fails in ha_open. sql/sql_select.cc:21826 sets db_stat= 0 and returns 1. ha_maria::file remains NULL, and created from step 2 is never reset.
4. create_tmp_table:21622 calls cleanup_on_failure → free_tmp_table.
5. sql/sql_select.cc:22351 tests entry->file && entry->is_created() — both true. 22353 tests entry->db_stat, correctly skipping the statistics calls. 22361 then calls entry->file->drop_table(...) unconditionally.
6. Crash at ha_maria.cc:2861.
Note that free_tmp_table already anticipates created-but-not-opened at line 22353 ("The table was properly opened in open_tmp_table()"). ha_maria::drop_table does not. MyISAM does not override drop_table, so this is Aria-specific. Values from an intact core (mariadb-server-core-dbgsym 1:10.11.19+maria~deb12):
#3 ha_maria::drop_table (this=0x563c4595f508,
name=0x563c4595f018 "/database/tmp/#sql-temptable-112e0-20f9a62a-7700a")
at ./storage/maria/ha_maria.cc:2861
entry->db_stat = 0
entry->file = (ha_maria *) 0x563c4595f508
((ha_maria*)entry->file)>file = (MARIA_HA *) 0x0 <- dereferenced
entry->s->keys / uniques = 0 / 1
entry->s->fields / blob_fields = 5 / 1
entry->s->reclength = 198
entry->field[3] = (Field_blob *) ..., field_length 16777215
thd->m_stmt_da->m_sql_errno = 1032 (ER_KEY_NOT_FOUND)
thd->m_stmt_da->m_message = "Can't find record in '(temporary)'"
How to reproduce: The crash is independent of why open_tmp_table fails — any failure of ha_open on an Aria internal temp table reaches it. I do not have a reproducer for the failure we hit (filed separately as <link>), but the defect is visible by inspection, and forcing ha_open to fail by any means should demonstrate it. Exhausting file descriptors via a low --open-files-limit while a query materialises an Aria temp table looks like the cheapest deterministic route; I have not tested it. The query shape that produces the relevant temp table (on-disk Aria, one mediumtext, keys=0/uniques=1) is:
CREATE TABLE t (
id int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
value1 char(10) DEFAULT NULL, identifier char(32) DEFAULT NULL,
user_id int unsigned DEFAULT NULL,
created timestamp(6) NOT NULL DEFAULT '0000-00-00 00:00:00.000000',
received timestamp(6) NOT NULL DEFAULT current_timestamp(6),
need_reply tinyint(1) DEFAULT 0) ENGINE=InnoDB;
WITH cte AS
(SELECT created, received, value1, NULL AS user_id, NULL AS identifier
FROM t WHERE need_reply = TRUE AND value1 IS NOT NULL
UNION
SELECT MIN(created), MAX(received), NULL, GROUP_CONCAT(DISTINCT user_id), identifier
FROM t WHERE need_reply = TRUE AND identifier IS NOT NULL GROUP BY identifier)
SELECT value1, user_id, identifier FROM cte ORDER BY created;
This does not crash on its own — it only establishes the structure. Suggested fix In ha_maria::drop_table, honour what the assertion already states. Note the file deletion must still happen, or the temp files leak into tmpdir:
void ha_maria::drop_table(const char *name)
{
DBUG_ASSERT(!file || file->s->temporary);
if (file)
(void) maria_delete_table_files(name, 1, MY_WME);
}
Guarding the call site at sql_select.cc:22361 with db_stat instead would avoid the crash but leak the created files. Impact A recoverable query error becomes a server crash. On a Galera cluster this evicts the node; in our case it was one of two coincident faults that cost the cluster its primary component.
Attachments
Issue Links
- relates to
-
MDEV-41295 maria_open() fails with error 126 on a freshly created internal temporary table with keys=0, uniques=1
-
- Open
-