压测的时候报错
执行./runBenchmark.sh mysql_1000w.properties报错
报错内容如下:
08:58:52,889 [Thread-3] ERROR jTPCCTData : Unexpected SQLException in STOCK_LEVEL 08:58:52,889 [Thread-3] ERROR jTPCCTData : Every derived table must have its own alias java.sql.SQLSyntaxErrorException: Every derived table must have its own alias at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1009) at jTPCCTData.executeStockLevel(jTPCCTData.java:2110) at jTPCCTData.execute(jTPCCTData.java:205) at jTPCCTerminal.executeTransactions(jTPCCTerminal.java:194) at jTPCCTerminal.run(jTPCCTerminal.java:96) at java.lang.Thread.run(Thread.java:748) 08:58:52,929 [Thread-2] ERROR jTPCCTData : Unexpected SQLException in STOCK_LEVEL 08:58:52,929 [Thread-2] ERROR jTPCCTData : Every derived table must have its own alias java.sql.SQLSyntaxErrorException: Every derived table must have its own alias at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122) at com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:953) at com.mysql.cj.jdbc.ClientPreparedStatement.executeQuery(ClientPreparedStatement.java:1009) at jTPCCTData.executeStockLevel(jTPCCTData.java:2110) at jTPCCTData.execute(jTPCCTData.java:205) at jTPCCTerminal.executeTransactions(jTPCCTerminal.java:194) at jTPCCTerminal.run(jTPCCTerminal.java:96) at java.lang.Thread.run(Thread.java:748)
错误分析
可以看到jTPCCTData.executeStockLevel方法报错,查看此方法内容
该错误与SQL查询有关,这里提示的是"Every derived table must have its own alias",也就是说每个派生表必须有自己的别名。这种错误通常在我们在SQL查询中使用子查询或者join操作,但没有给子查询或者join的表提供别名时出现。
private void executeStockLevel(Logger log, jTPCCConnection db)
throws Exception
{
PreparedStatement stmt;
ResultSet rs;
try
{
stmt = db.stmtStockLevelSelectLow;
stmt.setInt(1, stockLevel.w_id);
stmt.setInt(2, stockLevel.threshold);
stmt.setInt(3, stockLevel.w_id);
stmt.setInt(4, stockLevel.d_id);
rs = stmt.executeQuery();
if (!rs.next())
{
throw new Exception("Failed to get low-stock for" +
" W_ID=" + stockLevel.w_id +
" D_ID=" + stockLevel.d_id);
}
stockLevel.low_stock = rs.getInt("low_stock");
rs.close();
db.commit();
}
catch (SQLException se)
{
log.error("Unexpected SQLException in STOCK_LEVEL");
for (SQLException x = se; x != null; x = x.getNextException())
log.error(x.getMessage());
se.printStackTrace();
try
{
db.rollback();
}
catch (SQLException se2)
{
throw new Exception("Unexpected SQLException on rollback: " +
se2.getMessage());
}
}
catch (Exception e)
{
try
{
db.rollback();
}
catch (SQLException se2)
{
throw new Exception("Unexpected SQLException on rollback: " +
se2.getMessage());
}
throw e;
}
}
我们需要找到db.stmtStockLevelSelectLow这个PreparedStatement的定义部分,也就是对应的SQL语句是什么,才能对其进行修改。
找到那个SQL查询语句后,你需要检查这个查询中的每个子查询或者JOIN的表是否都有别名。如果没有,需要为其添加别名。
可以看到PG和Oracle的SQL定义都带了 AS L,将MySQL部分加上即可
default:
stmtStockLevelSelectLow = dbConn.prepareStatement(
"SELECT count(*) AS low_stock FROM (" +
" SELECT s_w_id, s_i_id, s_quantity " +
" FROM bmsql_stock " +
" WHERE s_w_id = ? AND s_quantity < ? AND s_i_id IN (" +
" SELECT ol_i_id " +
" FROM bmsql_district " +
" JOIN bmsql_order_line ON ol_w_id = d_w_id " +
" AND ol_d_id = d_id " +
" AND ol_o_id >= d_next_o_id - 20 " +
" AND ol_o_id < d_next_o_id " +
" WHERE d_w_id = ? AND d_id = ? " +
" ) " +
" ) AS L");
break;
}
重新编译
编译后,可以正常进行压测
11:21:28,205 [main] INFO jTPCC : Term-00,
progress: 0.0, tpmTOTAL: 7500.0, tpmC: 0.0
progress: 1.0, tpmTOTAL: 16303.7, tpmC: 7732.3
progress: 2.0, tpmTOTAL: 18422.4, tpmC: 8806.8
progress: 3.0, tpmTOTAL: 18573.8, tpmC: 8957.0
progress: 4.0, tpmTOTAL: 18800.6, tpmC: 8650.7
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




