Note:
This topic has been translated from a Chinese forum by GPT and might contain errors.Original topic: tidb参数变量max_prepared_stmt_count不生效
[TiDB Usage Environment] Poc
[TiDB Version] 6.3.0
[Encountered Issue] max_prepared_stmt_count
not effective
[Reproduction Path] Operations that led to the issue:
set global max_prepared_stmt_count=2;
PREPARE mystmt1 FROM 'SELECT ? as num FROM DUAL';
PREPARE mystmt2 FROM 'SELECT ? as num FROM DUAL';
PREPARE mystmt3 FROM 'SELECT ? as num FROM DUAL';
Currently, only one session is open, and the tidb_server_prepared_stmts
metric in Prometheus is observed to be 3. After multiple executions, this metric far exceeds 3 without any errors.
[Issue Phenomenon and Impact]
max_prepared_stmt_count
- Scope: GLOBAL
- Persistent to cluster: Yes
- Type: Integer
- Default value:
-1
- Range:
[-1, 1048576]
- Specifies the maximum number of
PREPARE
statements in a session. - A value of
-1
means no limit on the number ofPREPARE
statements in a session. - If the variable value exceeds the upper limit
1048576
, the upper limit value1048576
is used:
To avoid memory OOM caused by prepare leaks, it is necessary to limit the session-level prepare. It is observed that there is a max_prepared_stmt_count
parameter that can limit the prepare in a session, but it is not effective in actual tests, as shown below:
From the figure, it can be seen that the current
tidb_prepared_statement_count
has exceeded 2, but there are no errors or warnings in the current session.There are two issues here:
Issue 1: The documentation states that the parameter value
max_prepared_stmt_count
is a session-level limit, but from the code below, it is seen that this parameter is limited by the size of PreparedStmtCount
. When PreparedStmtCount
exceeds max_prepared_stmt_count
, it will cause an error in the current session (potentially causing errors in all current sessions because if the session-level max_prepared_stmt_count
is not set, all sessions will encounter this issue). Therefore, is the documentation incorrect (or is the documentation correct and the code has a bug)?Issue 2: The current parameter is not effective. Looking at the AddPreparedStmt
method, when newPreparedStmtCount > maxPreparedStmtCount
, it should throw an error. However, in practice, newPreparedStmtCount
is greater than maxPreparedStmtCount
. Assuming the logic if maxPreparedStmtCount >= 0 && newPreparedStmtCount > maxPreparedStmtCount
is followed, then atomic.AddInt64(&PreparedStmtCount, -1)
should occur, and the tidb_prepared_statement_count
metric in Prometheus should not increase with each new statement compilation. Where is the misunderstanding here?