SET STATEMENT <var=val> FOR <query> causes crash when plugin reallocates dynamic string thread variable memory

Bug #1532042 reported by George Ormond Lorch III
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Percona Server moved to https://jira.percona.com/projects/PS
Status tracked in 5.7
5.6
Triaged
Low
Unassigned
5.7
Triaged
Low
Unassigned

Bug Description

- Both TokuDB and TokuBackupPlugin define and use a MYSQL_THDVAR_STR to report/hold some status information. In TokuDB it is tokudb_last_lock_timeout, TokuBackup it is tokudb_backup_last_error_string.
- These variable manage their own memory, meaning that when modified by either a user executing a 'SET <variable>=' or from some internal action, they free and reallocate their buffer that is holding their content.

Consider this sequence:
1. DROP DATABASE test;CREATE DATABASE test;USE test;
2. CREATE TABLE t(a INT,b INT,c BINARY(1),d BINARY (1),e VARBINARY(1),f VARBINARY(1),g BLOB,h BLOB,id INT,KEY(b),CLUSTERING KEY(e)) ENGINE=TokuDB;
3. CREATE TABLE t1(a INT KEY,b CHAR (1),c VARCHAR(1)) ENGINE=TokuDB;
4. XA START 'xid1','br_1';
5. SET @a :=(SELECT COUNT(*)FROM t1);
6. SET GLOBAL table_open_cache=3;
7. select concat('From JSON subselect ',c,' as DATE'),cast((select a from t where c='opaque_mysql_typebn') as DATE) from t where c='opaque_mysql_typebn';
8. SELECT * FROM t1;
9. SET STATEMENT sort_buffer_size=150000 FOR SELECT * FROM t1;
10. select count(*)from t1 where MBRIntersects(t1.c2,@g1);

If the statement on line 9 above encounters a lock timeout, it frees the old tokudb_last_lock_timeout buffer, allocates a new buffer and sets the tokudb_last_lock_timeout to some the new buffer, it is then lost as a result of the SET STATEMENT resetting all of the thread vars to their (pointer) values from before the statement (and perhaps exhibits a memory leak).

The crash occurs on line 10 because now the tokudb_last_lock_timeout pointer pointing to a buffer that was allocated in one of the statements prior to line 9, then freed on line 9, then attempted to free again on line 10 as a result of a lock timeout.

Related upstream issue: https://bugs.mysql.com/bug.php?id=71759
Original TokuDB report: https://tokutek.atlassian.net/browse/DB-920

From a private email discussion with Laurynas:
"Yes, I think this is a bug in SET STATEMENT. It should either update the variable properly (maybe something like
plugin_var_memalloc_session_update?), failing that, it shouldn't touch variables like this and and should be documented as such. "

Workarounds for those encountering this crash:
- For tokudb_backup_last_error_string: do not use SET STATEMENT in the same session as invoking the backup plugin via setting tokudb_backup_dir
- For tokudb_last_lock_timeout: disable tokudb_lock_timeout_debug by setting it to 0 (it defaults to 1).

tags: added: set-statement
Revision history for this message
Shahriyar Rzayev (rzayev-sehriyar) wrote :

Percona now uses JIRA for bug reports so this bug report is migrated to: https://jira.percona.com/browse/PS-2136

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.