3
votes

Spring batch uses a few sequence tables, which in the case of MySQL use the MyISAM storage engine. The issue I'm facing is that I'm using an Amazon Web Services RDS database, and their "Point in Time" database restore feature does not play nicely with databases containing MyISAM tables.

I'm looking for a solution that will let me switch out these Spring Batch MyISAM sequence tables and replacing them with InnoDB tables instead, with the goal of enabling the AWS RDS "Point in Time" database restoration feature.

Edit:

Per @Michael's response, here's a comment from the Java class MySQLMaxValueIncrementerthat reads the sequence:

The sequence is kept in a table; there should be one sequence table per
table that needs an auto-generated key. The table type of the sequence table
should be MyISAM so the sequences are allocated without regard to any
transactions that might be in progress.

So my specific question is "what is the simplest possible way to remove the MyISAM sequence table" and keep Spring Batch humming along?

1
What is your actual question? You can change the scripts...Michael Minella
Michael, thanks for checking out my question. If it's as simple as changing the table definition, that's great. This comment in the MySQLMaxValueIncrementer led me to believe that it's not that simple. "The sequence is kept in a table; there should be one sequence table per table that needs an auto-generated key. The table type of the sequence table should be MyISAM so the sequences are allocated without regard to any transactions that might be in progress."Alex

1 Answers

2
votes

I confirmed that merely changing the MyISAM sequence tables to InnoDB causes update locks to be created on the sequence tables after the update...set...=last_insert_id() statement but before the transaction has been committed. These locks are not created when using the MyISAM sequences. So the "easy" approach could have a negative impact on performance.

Here's what I came up with. Not sure that this is the easiest way, but it is working.

  1. Per this answer, drop the existing sequence tables and redefine them with a single column uid BIGINT(20) UNSIGNED NOT NULL PRIMARY KEY auto_increment
  2. Create a stored procedure that: a) takes the sequence name as an argument, b) does the insert into the sequence, and c) returns LAST_INSERT_ID()
  3. Write a java class that extends MySQLMaxValueIncrementer and calls the stored procedure in the getNextKey() method. I'm using a SimpleJdbcCall instance to do this.
  4. Write a java class that implements DataFieldMaxValueIncrementerFactory and returns an instance from step #3 from the getIncrementer() method
  5. In the batch configuration, update the org.springframework.batch.core.repository.support.JobRepositoryFactoryBean configuration to use the incrementer factory from step #4