Description:
I use the following JDBC testcase to see what happens if a client continues to open cursors, and the server dies when reaching approximately 40,000 open cursors (interesting enough, if just server-side prepared statements are used, the server dies at 41,000 open statements with no stack trace, so that might be an OOM kill, I unfortunately do not have immediate access to a box that will allow mysqld to grow big enough to test any further):
public void testResourceExhaustion() throws Exception {
if (versionMeetsMinimum(5, 0, 3)) {
int i = 0;
try {
this.stmt.executeUpdate("DROP TABLE IF EXISTS testResourceExhaustion");
this.stmt.executeUpdate("CREATE TABLE testResourceExhaustion (field1 INT)");
this.stmt.executeUpdate("INSERT INTO testResourceExhaustion VALUES (1)");
List openStatements = new ArrayList();
List openResultSets = new ArrayList();
while (true) {
i++;
PreparedStatement pStmt = this.conn.prepareStatement("SELECT field1 FROM testResourceExhaustion");
pStmt.setFetchSize(100); // causes JDBC driver to use cursor
// for this statement
ResultSet cursorRs = pStmt.executeQuery();
openStatements.add(pStmt);
openResultSets.add(cursorRs);
}
} catch (Exception ex) {
System.out.println("Number of open cursors: " + i);
throw ex;
} finally {
this.stmt.executeUpdate("DROP TABLE IF EXISTS testResourceExhaustion");
}
}
}
The backtrace when the server crashes is the following:
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
Cannot determine thread, fp=0x295e7c, backtrace may not be correct.
Stack range sanity check OK, backtrace follows:
0x818877c handle_segfault + 668
0x19b8d8 (?)
0x8d23414 _end + 7276356
0x81f1e90 _ZN18Prepared_statementD0Ev + 80
0x844e983 hash_free + 99
0x817467a _ZN3THDD0Ev + 506
0x818831c _Z10end_threadP3THDb + 60
0x81aa459 handle_one_connection + 937
0x1953ae (?)
0xc93b6e (?)
How to repeat:
Open as many cursors as you can, the server eventually dies with either an OOM kill or just in general.