mirror of
https://github.com/Qortal/qortal.git
synced 2025-07-22 20:26:50 +00:00
Added INDEX to speed up block orphaning.
NOTE: first startup after this commit can take a while due to building index! SQL statement "DELETE FROM HistoricAccountBalances WHERE height >= ?" required a full table scan and so was very slow on VMs/routers. This statement used by HSQLDBAccountRepository.deleteBalancesFromHeight(), itself called during Block.orphan(). Symptoms particularly evident during shutdown where above statement could take upwards of 15 minutes on single-CPU, small-memory VMs! Statement wasn't noticed before as slow-query checking wasn't involved. Slow-query checking now applies to HSQLDBRepository.delete() and HSQLDBRepository.exists() calls. Added test for correct HSQLDB interrupt handling. Fixed some typos.
This commit is contained in:
@@ -923,6 +923,11 @@ public class HSQLDBDatabaseUpdates {
|
||||
stmt.execute("ALTER TABLE Accounts DROP initial_level");
|
||||
break;
|
||||
|
||||
case 65:
|
||||
// Add INDEX to speed up very slow "DELETE FROM HistoricAccountBalances WHERE height >= ?"
|
||||
stmt.execute("CREATE INDEX IF NOT EXISTS HistoricAccountBalancesHeightIndex ON HistoricAccountBalances (height)");
|
||||
break;
|
||||
|
||||
default:
|
||||
// nothing to do
|
||||
return false;
|
||||
|
@@ -500,9 +500,18 @@ public class HSQLDBRepository implements Repository {
|
||||
try (PreparedStatement preparedStatement = this.prepareStatement(sql)) {
|
||||
prepareExecute(preparedStatement, objects);
|
||||
|
||||
long beforeQuery = System.currentTimeMillis();
|
||||
|
||||
if (preparedStatement.execute())
|
||||
throw new SQLException("Database produced results, not row count");
|
||||
|
||||
long queryTime = System.currentTimeMillis() - beforeQuery;
|
||||
if (this.slowQueryThreshold != null && queryTime > this.slowQueryThreshold) {
|
||||
LOGGER.info(String.format("HSQLDB query took %d ms: %s", queryTime, sql), new SQLException("slow query"));
|
||||
|
||||
logStatements();
|
||||
}
|
||||
|
||||
int rowCount = preparedStatement.getUpdateCount();
|
||||
if (rowCount == -1)
|
||||
throw new SQLException("Database returned invalid row count");
|
||||
@@ -516,7 +525,7 @@ public class HSQLDBRepository implements Repository {
|
||||
* <p>
|
||||
* Performs "CALL IDENTITY()" SQL statement to retrieve last value used when INSERTing into a table that has an IDENTITY column.
|
||||
* <p>
|
||||
* Typically used after INSERTing NULL as the IDENTIY column's value to fetch what value was actually stored by HSQLDB.
|
||||
* Typically used after INSERTing NULL as the IDENTITY column's value to fetch what value was actually stored by HSQLDB.
|
||||
*
|
||||
* @return Long
|
||||
* @throws SQLException
|
||||
@@ -557,12 +566,9 @@ public class HSQLDBRepository implements Repository {
|
||||
sql.append(whereClause);
|
||||
sql.append(" LIMIT 1");
|
||||
|
||||
try (PreparedStatement preparedStatement = this.prepareStatement(sql.toString());
|
||||
ResultSet resultSet = this.checkedExecuteResultSet(preparedStatement, objects)) {
|
||||
if (resultSet == null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
try (ResultSet resultSet = this.checkedExecute(sql.toString(), objects)) {
|
||||
// If matching row is found then resultSet will not be null
|
||||
return resultSet != null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,7 +31,7 @@ public class HSQLDBRepositoryFactory implements RepositoryFactory {
|
||||
*
|
||||
* @param connectionUrl
|
||||
* @throws DataException <i>without throwable</i> if repository in use by another process.
|
||||
* @throws DataException <i>with throwable</i> if repository cannot be opened for someother reason.
|
||||
* @throws DataException <i>with throwable</i> if repository cannot be opened for some other reason.
|
||||
*/
|
||||
public HSQLDBRepositoryFactory(String connectionUrl) throws DataException {
|
||||
// one-time initialization goes in here
|
||||
@@ -47,10 +47,10 @@ public class HSQLDBRepositoryFactory implements RepositoryFactory {
|
||||
|
||||
HsqlException he = (HsqlException) cause;
|
||||
if (he.getErrorCode() == -ErrorCode.LOCK_FILE_ACQUISITION_FAILURE)
|
||||
throw new DataException("Unable to open repository: " + e.getMessage());
|
||||
throw new DataException("Unable to lock repository: " + e.getMessage());
|
||||
|
||||
if (he.getErrorCode() != -ErrorCode.ERROR_IN_LOG_FILE && he.getErrorCode() != -ErrorCode.M_DatabaseScriptReader_read)
|
||||
throw new DataException("Unable to open repository: " + e.getMessage(), e);
|
||||
throw new DataException("Unable to read repository: " + e.getMessage(), e);
|
||||
|
||||
// Attempt recovery?
|
||||
HSQLDBRepository.attemptRecovery(connectionUrl);
|
||||
|
Reference in New Issue
Block a user