-
Praveenkumar Hulakund authored
For the SQL statements in the stored routine, while resolving the statement (on first execution or on re-parse trigger) memory is allocated on the permanent mem-root. After executing the statement for the first time a state of the statement query arena is changed to STMT_EXECUTED. Subsequent execution uses execution mem-root which is freed at the end of the execution. But for CREATE TABLE ... SELECT(CTS), state of the statement query arena is never changed to the STMT_EXECUTED. Allocation in the subsequent execution goes to the permanent mem-root. Hence the memory growth or leak is observed. Why query arena state is not switched for CTS? ============================================== For the CTS, existence of the table being created is checked while executing the statement. If table already exists then error (or warning with IF TABLE EXISTS clause) is reported. In the subsequent execution allocation(when table does not exists) for items being created goes to permanent mem-root(as statement query arena state is set STMT_INITIALIZED_FOR_SP always). So the next execution will have valid pointers to refer. If state of query arena is set to the STMT_EXECUTED after first execution then state is changed even when table exists error or warning is reported. In this case subsequent execution uses execution mem-root to allocate items. This memory is freed at the end of the execution. So the next execution of routine refers to invalid pointers. To avoid any issues related to invalid pointer reference(e.g. bug19897405) the state of the statement query arena is set to STMT_INITIALIZED_FOR_SP always for CTS by patch for bug25053286. Fix: ============================================== For the CTS in the stored routine, special handling is required for the case of table exists error or warning. In case of table exists error or warning, the statement arena is set to STMT_INITIALIZED_FOR_SP. With this change, next execution uses permanent mem-root while resolving the statement (this change fixes invalid pointer reference issues e.g. bug19897405). If the execution is successful then statement query arena is changed to the STMT_EXECUTED. So on the subsequent execution of the CTS, memory is allocated in the execution mem-root (this change fixes memory growth or leak issue). Additional changes for mysql-8.0 and mysql-trunk: -------------------------------------------------- As part of this patch, code is modified to check the SP statement execution state instead of error codes or flags while setting the statement query arena state. Modification is made so that, SP statement query arena state is not changed when error occurs in the statement parsing, table opening and preparation phase. Query arena state is changed to STMT_EXECUTED when error occurs in the execution phase (or when execution succeeds). If "table exists" error during execution phase of CTS then the state of the statement query arena is set to STMT_INITIALIZED_FOR_SP, as if statement must be reprepared.
Praveenkumar Hulakund authoredFor the SQL statements in the stored routine, while resolving the statement (on first execution or on re-parse trigger) memory is allocated on the permanent mem-root. After executing the statement for the first time a state of the statement query arena is changed to STMT_EXECUTED. Subsequent execution uses execution mem-root which is freed at the end of the execution. But for CREATE TABLE ... SELECT(CTS), state of the statement query arena is never changed to the STMT_EXECUTED. Allocation in the subsequent execution goes to the permanent mem-root. Hence the memory growth or leak is observed. Why query arena state is not switched for CTS? ============================================== For the CTS, existence of the table being created is checked while executing the statement. If table already exists then error (or warning with IF TABLE EXISTS clause) is reported. In the subsequent execution allocation(when table does not exists) for items being created goes to permanent mem-root(as statement query arena state is set STMT_INITIALIZED_FOR_SP always). So the next execution will have valid pointers to refer. If state of query arena is set to the STMT_EXECUTED after first execution then state is changed even when table exists error or warning is reported. In this case subsequent execution uses execution mem-root to allocate items. This memory is freed at the end of the execution. So the next execution of routine refers to invalid pointers. To avoid any issues related to invalid pointer reference(e.g. bug19897405) the state of the statement query arena is set to STMT_INITIALIZED_FOR_SP always for CTS by patch for bug25053286. Fix: ============================================== For the CTS in the stored routine, special handling is required for the case of table exists error or warning. In case of table exists error or warning, the statement arena is set to STMT_INITIALIZED_FOR_SP. With this change, next execution uses permanent mem-root while resolving the statement (this change fixes invalid pointer reference issues e.g. bug19897405). If the execution is successful then statement query arena is changed to the STMT_EXECUTED. So on the subsequent execution of the CTS, memory is allocated in the execution mem-root (this change fixes memory growth or leak issue). Additional changes for mysql-8.0 and mysql-trunk: -------------------------------------------------- As part of this patch, code is modified to check the SP statement execution state instead of error codes or flags while setting the statement query arena state. Modification is made so that, SP statement query arena state is not changed when error occurs in the statement parsing, table opening and preparation phase. Query arena state is changed to STMT_EXECUTED when error occurs in the execution phase (or when execution succeeds). If "table exists" error during execution phase of CTS then the state of the statement query arena is set to STMT_INITIALIZED_FOR_SP, as if statement must be reprepared.
Loading