← Back to team overview

maria-developers team mailing list archive

How correctly allocate memory to avoid problems with 2nd execution (instruction)

 

Hi!

It is for all who decide to write or already is writing something for server.


There is 2 ways to execute query/statement:
 1) conventional (one time)
2) with storing the statement and executing it many times (Prepared statements (PS)/ Stored Procedures(SP))

Also there is so called Query_arena, which is a MEM_ROOT and list of allocated Item-s in it. (we need list of items because they could require not trivial destruction/cleanup procedure before freeing memory, see cleanup() methods of Item-s)

For conventional execution there is only one (run-time) query arena (part of THD in this case) where all memory allocated, and all Item-s linked. After execution Item-s cleaned up and memory freed.

For case with stored statements (PS/SP) there is one Query_arena where Parsing result allocated (statement arena), and the other one so called run-time arena (which freed after execution as for conventional execution).

During parsing statement arena is active (default), during all execution steps the run-time arena is active (if nothing changed it specially).

So if some one decided allocate some memory during execution one should think if it is:
I) only for execution
II) should live with the statement

All references on the memory allocated as case I) should be returned in the state as it was before execution or taken other measures to prevent using them during the next execution.

All object which allocated as persistent (for statement of course) should be
a) allocated only once (can be first execution or prepare phase, it does not matter, what does matter: do not make memory leak by allocating on each execution) b) reference on them should not be lost (because it supposed to be reused during next execution)
c) procedure of allocation during run-time should looks like this:

Query_arena *arena, backup;
// backup run-time arena and set as default statement arena if needed
// (if it is not conventional execution)
arena= thd->activate_stmt_arena_if_needed(&backup);\

<MAKE ALLOOCATION HERE USING thd->mem_root>

// return old default arena if it was changed before
if (arena)
  thd->restore_active_arena(arena, &backup);