Bug #2345 Deadlock or hang after inserting large number of records
Submitted: 11 Jan 2004 0:14 Modified: 13 Jan 2004 12:55
Reporter: [ name withheld ] Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:4.0.17 (max-nt) OS:Windows (Windows 2000 Professional)
Assigned to: Dean Ellis CPU Architecture:Any

[11 Jan 2004 0:14] [ name withheld ]
Description:
One of the features of my Java application is importing records from files into the database. If I use files with large number of records MySQL eventually hangs. At first I thought I had some deadlocks inside my application, but then I managed to reproduce the hang in the standalone program (see attached code).

The hang happens after arbitrary amount of records have been inserted - 300000, 400000 or 600000. I could never insert more than 900000 records. After the hang MySQL enters funny "deadlocked" state - mysqladmin reports that the server is alive, but any queries from mysql tool hang. Also mysqladmin fails to shutdown the server so I use TaskManager.

Error log reports nothing. Binary log appears to be corrupt (not sure) - at least mysqlbinlog starts displaying funny characters in the middle of valid queries. Also when I restart mysql without deleting logs, more weird things start happening - valid tables are not recognized etc. When I restart mysql after deleting logs, everything is OK.

It seems also that the problem is somehow related to the type of records being inserted. I could not reproduce the problem with text fields only, but I can reproduce it when I use text, integer and datetime fields.

The JDBC driver I am using is MySQLConnector 2.0.14. Theoretically it could be driver's problem, but I doubt it.

How to repeat:
See the snippet of the code below, which reproduces the problem after some 400000-500000 records have been inserted.

/** Initialise everything */

Class.forName("com.mysql.jdbc.Driver");
Connection connection  = DriverManager.getConnection("jdbc:mysql://localhost/BASDB");
connection.setAutoCommit (false);

Statement stmt = connection.createStatement ();
stmt.execute ("CREATE TABLE TEST1 (ID INT PRIMARY KEY, BASVERSION int, BASTIMESTAMP datetime, TEXT VARCHAR(20), NMB int, ATTRDATE datetime) TYPE = BDB");
stmt.execute ("CREATE TABLE BAS_IDGEN (MAX_ID int)");

Connection c1  = DriverManager.getConnection("jdbc:mysql://localhost/BASDB");
c1.setAutoCommit (true);
PreparedStatement readStmt = c1.prepareStatement ("SELECT * FROM BAS_IDGEN");
PreparedStatement updateStmt = c1.prepareStatement ("UPDATE BAS_IDGEN  SET " +
					           "MAX_ID=?");
Statement insertStmt = c1.createStatement ();
insertStmt.execute ("INSERT INTO BAS_IDGEN (MAX_ID) Values (0)");

String stmtStr = "INSERT INTO TEST1 (ID,BASVERSION,BASTIMESTAMP,TEXT,NMB,ATTRDATE) VALUES(?,?,?,?,?,?)";
PreparedStatement pstmt = connection.prepareStatement (stmtStr);

/** Start the test */
for (int i = 0; i < 1500000; ++i)
{
  /* generate new id in a separate table */
  ResultSet rs = readStmt.executeQuery ();
  rs.next ();
  int maxUsedId = rs.getInt (1);
				
  updateStmt.clearParameters ();
  updateStmt.setInt (1, ++maxUsedId);
	
  updateStmt.executeUpdate ();

  /** Insert new record */				
  pstmt.clearParameters ();
  pstmt.setInt (1, i);
  pstmt.setInt (2, 1);
  SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-MM-dd");
  pstmt.setString (3, sdf.format (new Date ()));
  pstmt.setString (4, "Test");
  pstmt.setInt    (5, 10);
  pstmt.setString (6, "1963-06-19");
				
  pstmt.execute ();

  /* Commit every 1000 records */				
  if ((i % 1000) == 0)
  {
     System.out.println ("Committing " + i + " records");
     connection.commit ();
					
     connection.close ();
     pstmt.close ();
					
     connection  = DriverManager.getConnection("jdbc:mysql://localhost/BASDB");
     connection.setAutoCommit (false);
     connection.setTransactionIsolation (Connection.TRANSACTION_SERIALIZABLE);
			
     pstmt = connection.prepareStatement (stmtStr);
  }
}
[13 Jan 2004 12:55] Dean Ellis
I cannot repeat this using a current version of Connector/J.  As you note you are using 2.0.14, could you try this with a current release?
[22 Jan 2004 18:32] [ name withheld ]
I have downloaded latest production version of MySQL Connector (3.0.10) and tried the standalone test described in the bug report.

On a first try I could not reproduce the problem - I managed to insert 1500000 records successfully. However on a second attempt I did reproduce the hang again after 770000 records. 

The similar hang happens every now and then in my application as well and it is starting to concern me more and more.
[4 Feb 2004 9:53] Dean Ellis
When you repeat the test, are you dropping the tables, truncating them, or leaving them as they were at the end of the last run?

Is any other process touching the tables during the test?
[5 Feb 2004 0:08] [ name withheld ]
When I run the test for the second time I leave the tables as they were after the first test. I am not touching them in any way.

There is no other process that is accessing the tables at the same time. I run the test on my standalone machine and my test program is the only process that is accessing MySQL.