Browse Source

Trimming old block online accounts signatures

There's still an existing issue where log entries like this appear:

  Unable to trim old online accounts signatures in repository

which is actually caused by:

  integrity constraint violation: unique constraint or index violation; SYS_PK_10092 table: BLOCKS

which seems to be a bug in the version of HSQLDB we use.
(Tested using synced-from-scratch DB).
It's not clear what the actual problem is at this point.

It might be possible to switch to v2.5.1 if our recent HSQLDB-related
commits have fixed/worked-around the OOM issues.

Move the inner method from BlockChain to Controller.
Remove blockchain lock as it's not needed because it's not an
HSQLDB "serialization failure" but constraint violation.

Trimming old online accounts signatures limited to batches of 1440
rows to reduce CPU and memory load.
split-DB
catbref 4 years ago
parent
commit
d93e9d570f
  1. 30
      src/main/java/org/qortal/block/BlockChain.java
  2. 19
      src/main/java/org/qortal/controller/Controller.java
  3. 5
      src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java

30
src/main/java/org/qortal/block/BlockChain.java

@ -32,7 +32,6 @@ import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager;
import org.qortal.settings.Settings;
import org.qortal.utils.NTP;
import org.qortal.utils.StringLongMapXmlAdapter;
/**
@ -578,33 +577,4 @@ public class BlockChain {
}
}
public static void trimOldOnlineAccountsSignatures() {
final Long now = NTP.getTime();
if (now == null)
return;
ReentrantLock blockchainLock = Controller.getInstance().getBlockchainLock();
if (!blockchainLock.tryLock())
// Too busy to trim right now, try again later
return;
try {
try (final Repository repository = RepositoryManager.tryRepository()) {
if (repository == null)
return;
int numBlocksTrimmed = repository.getBlockRepository().trimOldOnlineAccountsSignatures(now - BlockChain.getInstance().getOnlineAccountSignaturesMaxLifetime());
if (numBlocksTrimmed > 0)
LOGGER.debug(String.format("Trimmed old online accounts signatures from %d block%s", numBlocksTrimmed, (numBlocksTrimmed != 1 ? "s" : "")));
repository.saveChanges();
} catch (DataException e) {
LOGGER.warn(String.format("Repository issue trying to trim old online accounts signatures: %s", e.getMessage()));
}
} finally {
blockchainLock.unlock();
}
}
}

19
src/main/java/org/qortal/controller/Controller.java

@ -1407,7 +1407,24 @@ public class Controller extends Thread {
sendOurOnlineAccountsInfo();
// Trim blockchain by removing 'old' online accounts signatures
BlockChain.trimOldOnlineAccountsSignatures();
long upperMintedTimestamp = now - BlockChain.getInstance().getOnlineAccountSignaturesMaxLifetime();
trimOldOnlineAccountsSignatures(upperMintedTimestamp);
}
private void trimOldOnlineAccountsSignatures(long upperMintedTimestamp) {
try (final Repository repository = RepositoryManager.tryRepository()) {
if (repository == null)
return;
int numBlocksTrimmed = repository.getBlockRepository().trimOldOnlineAccountsSignatures(upperMintedTimestamp);
if (numBlocksTrimmed > 0)
LOGGER.debug(() -> String.format("Trimmed old online accounts signatures from %d block%s", numBlocksTrimmed, (numBlocksTrimmed != 1 ? "s" : "")));
repository.saveChanges();
} catch (DataException e) {
LOGGER.warn(String.format("Repository issue trying to trim old online accounts signatures: %s", e.getMessage()));
}
}
private void sendOurOnlineAccountsInfo() {

5
src/main/java/org/qortal/repository/hsqldb/HSQLDBBlockRepository.java

@ -465,11 +465,14 @@ public class HSQLDBBlockRepository implements BlockRepository {
@Override
public int trimOldOnlineAccountsSignatures(long timestamp) throws DataException {
String sql = "UPDATE Blocks set online_accounts_signatures = NULL WHERE minted_when < ? AND online_accounts_signatures IS NOT NULL";
// We're often called so no need to trim all blocks in one go.
// Limit updates to reduce CPU and memory load.
String sql = "UPDATE Blocks set online_accounts_signatures = NULL WHERE minted_when < ? AND online_accounts_signatures IS NOT NULL LIMIT 1440";
try {
return this.repository.executeCheckedUpdate(sql, timestamp);
} catch (SQLException e) {
repository.examineException(e);
throw new DataException("Unable to trim old online accounts signatures in repository", e);
}
}

Loading…
Cancel
Save