Commit 8f04ec28 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED

Also fixes MDEV-24467 Memory not freed after failed INSERT DELAYED

Description:

In case of an error (e.g. data truncation) during mysql_insert()
handling an INSERT DELAYED, the data type specific data in
fields (e.g. Field_blob::value) is not taken over by the delayed
writer thread.

All fields in table_list->table are freed by free_root()
immediately after mysql_insert(). To avoid a memory leak,
we need to free the specific data before exiting mysql_insert()
on error.
parent eadd8788
#
# MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED
#
SET sql_mode='TRADITIONAL';
CREATE TABLE t1 (c BLOB) ENGINE=MyISAM;
INSERT DELAYED INTO t1 VALUES (''||'');
ERROR 22007: Truncated incorrect DOUBLE value: ''
DROP TABLE t1;
SET sql_mode=DEFAULT;
#
# MDEV-24467 Memory not freed after failed INSERT DELAYED
#
CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM;
ALTER TABLE t1 ADD b BLOB DEFAULT 'x';
INSERT DELAYED INTO t1 (a) VALUES ('foo');
ERROR 22001: Data too long for column 'a' at row 1
DROP TABLE t1;
--init_connect="set @a='something unique to have MTR start a dedicated mariadbd for this test and shutdown it after the test'"
--echo #
--echo # MDEV-25925 Warning: Memory not freed: 32 on INSERT DELAYED
--echo #
SET sql_mode='TRADITIONAL';
CREATE TABLE t1 (c BLOB) ENGINE=MyISAM;
--error ER_TRUNCATED_WRONG_VALUE
INSERT DELAYED INTO t1 VALUES (''||'');
DROP TABLE t1;
SET sql_mode=DEFAULT;
--echo #
--echo # MDEV-24467 Memory not freed after failed INSERT DELAYED
--echo #
CREATE TABLE t1 (a VARCHAR(1)) ENGINE=MyISAM;
ALTER TABLE t1 ADD b BLOB DEFAULT 'x';
--error ER_DATA_TOO_LONG
INSERT DELAYED INTO t1 (a) VALUES ('foo');
DROP TABLE t1;
......@@ -1257,7 +1257,18 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
abort:
#ifndef EMBEDDED_LIBRARY
if (lock_type == TL_WRITE_DELAYED)
{
end_delayed_insert(thd);
/*
In case of an error (e.g. data truncation), the data type specific data
in fields (e.g. Field_blob::value) was not taken over
by the delayed writer thread. All fields in table_list->table
will be freed by free_root() soon. We need to free the specific
data before free_root() to avoid a memory leak.
*/
for (Field **ptr= table_list->table->field ; *ptr ; ptr++)
(*ptr)->free();
}
#endif
if (table != NULL)
table->file->ha_release_auto_increment();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment