-
Nisha Gopalakrishnan authored
EXCEPTION HANDLERS Analysis -------- Excessive memory consumption is observed when executing a stored procedure multiple times when: a) The stored procedure has an SQL statement which fails during validation. b) The stored procedure has an an SQL statement which requires to be re-prepared. Under the above scenarios, the query within the stored procedure is invalidated during the execution. The invalidation calls for the re-parse of the query. During the re-parse, the lex tree is allocated on the persistent mem_root of the stored procedure. When the stored procedure is executed multiple times, the repeated allocation of the new lex tree on the persistent mem_root is observed. The previous allocations for the lex tree in the mem_root are never freed. In addition to the lex tree, the Ref_ptr_array(array of pointers to the field items) was also allocated on the persistent mem_root and never freed during re-parse. Hence the memory growth was observed. Also the patch solves the memory growth due to the cases listed below: a) Allocation of Sql_condition and its memory on persistent mem-root every time a condition is raised. b) Allocation of Handler-structure on the persistent mem-root every time an SQL-handler is pushed. Observed when the execution flow goes to DECLARE HANDLER statement. c) Allocation of Cursor-structure on the persistent mem-root every time a cursor is pushed. Observed when the DECLARE CURSOR statement is executed. Fix: ---- 1) Patch for the allocation of the lex tree and 'Ref_ptr_array' on the persistent mem_root: A new mem_root 'm_lex_mem_root' is introduced which holds the lex tree and the Ref_ptr_array. When a query is invalidated, before the reparse we free this mem_root, init the root and use it to allocate the newly parsed lex tree. The 'ref_pointer_array' part of the lex tree object points the Ref_ptr_array. Since 'Ref_ptr_array' should not be allocated on the persistent mem_root, we switch the stmt_arena's mem_root to that of the new 'm_lex_mem_root'. This mem_root is persistent until reparse or the stored routine is dropped, hence the 'Ref_ptr_array' is allocated on the new mem_root as well. Since this mem_root is freed and re-initialised during re-parse we will not observe a memory growth. Also ensures that the prepared statement execution is unaffected. 2) Patch for the next set of issues listed above: a) The Sql_condition is a temporary instance hence initialised in the execution mem_root which is freed at the end of the execution. b) The handler is now stored on the heap instead of the caller's mem_root thus avoiding the memory growth. c) The cursor is now stored on the heap instead of the caller's mem_root thus avoiding the memory growth. Note: I have not added an mtr test case: A test case which executes for a longer period is needed to observe the increasing memory consumption and is not suitable for mtr. Also the existing test suite has tests which uses the new mem_root.
Nisha Gopalakrishnan authoredEXCEPTION HANDLERS Analysis -------- Excessive memory consumption is observed when executing a stored procedure multiple times when: a) The stored procedure has an SQL statement which fails during validation. b) The stored procedure has an an SQL statement which requires to be re-prepared. Under the above scenarios, the query within the stored procedure is invalidated during the execution. The invalidation calls for the re-parse of the query. During the re-parse, the lex tree is allocated on the persistent mem_root of the stored procedure. When the stored procedure is executed multiple times, the repeated allocation of the new lex tree on the persistent mem_root is observed. The previous allocations for the lex tree in the mem_root are never freed. In addition to the lex tree, the Ref_ptr_array(array of pointers to the field items) was also allocated on the persistent mem_root and never freed during re-parse. Hence the memory growth was observed. Also the patch solves the memory growth due to the cases listed below: a) Allocation of Sql_condition and its memory on persistent mem-root every time a condition is raised. b) Allocation of Handler-structure on the persistent mem-root every time an SQL-handler is pushed. Observed when the execution flow goes to DECLARE HANDLER statement. c) Allocation of Cursor-structure on the persistent mem-root every time a cursor is pushed. Observed when the DECLARE CURSOR statement is executed. Fix: ---- 1) Patch for the allocation of the lex tree and 'Ref_ptr_array' on the persistent mem_root: A new mem_root 'm_lex_mem_root' is introduced which holds the lex tree and the Ref_ptr_array. When a query is invalidated, before the reparse we free this mem_root, init the root and use it to allocate the newly parsed lex tree. The 'ref_pointer_array' part of the lex tree object points the Ref_ptr_array. Since 'Ref_ptr_array' should not be allocated on the persistent mem_root, we switch the stmt_arena's mem_root to that of the new 'm_lex_mem_root'. This mem_root is persistent until reparse or the stored routine is dropped, hence the 'Ref_ptr_array' is allocated on the new mem_root as well. Since this mem_root is freed and re-initialised during re-parse we will not observe a memory growth. Also ensures that the prepared statement execution is unaffected. 2) Patch for the next set of issues listed above: a) The Sql_condition is a temporary instance hence initialised in the execution mem_root which is freed at the end of the execution. b) The handler is now stored on the heap instead of the caller's mem_root thus avoiding the memory growth. c) The cursor is now stored on the heap instead of the caller's mem_root thus avoiding the memory growth. Note: I have not added an mtr test case: A test case which executes for a longer period is needed to observe the increasing memory consumption and is not suitable for mtr. Also the existing test suite has tests which uses the new mem_root.
Loading