首批通过分布式安全可靠测评,为关键业务系统打造
多条 SQL 执行使用相同的 trace_id 的原因
更新时间:2026-05-15 09:06
通常,trace_id 可以标识一条 SQL 的唯一一次执行,但当应用侧设置 allowmultiqueries=true 并将多条 SQL 拼接在一起发送到 OceanBase 数据库时,多条 SQL 会使用相同的 trace_id。
当应用侧开启了批处理时(allowmultiqueries=true),可以主动将多条 SQL 使用逗号分隔的方式拼接在一起,或者使用 addBatch 方式将多条 INSERT 语句使用逗号分隔的方式拼接在一起,拼接后的 SQL 一次性发送到 OceanBase 数据库。当 OceanBase 数据库收到拼接的 SQL 时,会拆分开 SQL 逐一执行,在 SQL_AUDIT 中,这些 SQL 的执行会有以下特征。
- 这些 SQL 的 request_time 和 trace_id 相同,因为它们同时到达 OceanBase 数据库。
- 如果拼接在一起的 SQL 是对同一个表执行的批量 UPDATE 或 INSERT,下一条 SQL 执行的时间会包含前面 SQL 的执行时间,即批量执行的 SQL 的 elapsed_time 会逐个增加。
SELECT 语句拼接执行的示例:
程序代码:String sql = "select * from a;select * from shoubiantest;"
Connection con;
String driver="com.mysql.jdbc.Driver";
String url="jdbc:mysql://xxxx/test?&useSSL=false&serverTimezone=UTC&socketTimeout=50000&allowMultiQueries=true";
String user="root@sys";
String password="";
try {
Class.forName(driver);
con = DriverManager.getConnection(url, user, password);
if (!con.isClosed()) {
Statement statement = con.createStatement();
String sql = "select * from a;select * from shoubiantest;";
con.setAutoCommit(false);
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println(resultSet.getDate("a"));
}
con.commit();
resultSet.close();
statement.close();
con.close();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
SQL_AUDIT 记录:
- request_time 和 trace_id 相同。
- elapsed_time 不叠加。
obclient [test]> select TRACE_ID,QUERY_SQL,REQUEST_TIME, ELAPSED_TIME from oceanbase.gv$sql_audit where trace_id='YB42AC17D798-0005E7BCEE19D648' \G
*************************** 1. row ***************************
TRACE_ID: YB42AC17D798-0005E7BCEE19D648
QUERY_SQL: select * from a;
REQUEST_TIME: 1662174355777732
ELAPSED_TIME: 1080
*************************** 2. row ***************************
TRACE_ID: YB42AC17D798-0005E7BCEE19D648
QUERY_SQL: select * from shoubiantest;
REQUEST_TIME: 1662174355777732
ELAPSED_TIME: 1009
2 rows in set (0.09 sec)
批量 UPDATE 语句的 SQL_Audit 示例:
- request_time 和 trace_id 相同。
- elapsed_time 叠加。
obclient [test]> select TRACE_ID,QUERY_SQL,REQUEST_TIME, ELAPSED_TIME from oceanbase.gv$sql_audit where trace_id='YB42AC1A3D2F-0005DDF3D59F35C2' \G
*************************** 1. row ***************************
TRACE_ID: YB42AC1A3D2F-0005DDF3D59F35C2
QUERY_SQL: UPDATE tb1 set c1='xx' where c2 = 'xxx';
REQUEST_TIME: 1662351465070562
ELAPSED_TIME: 133483
*************************** 2. row ***************************
TRACE_ID: YB42AC1A3D2F-0005DDF3D59F35C2
QUERY_SQL: UPDATE tb2 SET c1='xxx',c2='xxxx' where c3='xxx';
REQUEST_TIME: 1662351465070562
ELAPSED_TIME: 3161171
2 rows in set (0.09 sec)
适用版本
OceanBase 数据库 V2.x、V3.x 版本。