From a4100b6ac250071c50c7ce5e0067a6016c283d05 Mon Sep 17 00:00:00 2001 From: halibobo1205 <82020050+halibobo1205@users.noreply.github.com> Date: Wed, 23 Aug 2023 11:07:29 +0800 Subject: [PATCH] feat(db):tune the databases closure (#5429) --- .../java/org/tron/core/ChainBaseManager.java | 58 +--------- .../java/org/tron/core/db/TronDatabase.java | 9 +- .../tron/core/db/TronStoreWithRevoking.java | 9 +- .../org/tron/core/db2/common/TxCacheDB.java | 12 +++ .../tron/core/db2/core/SnapshotManager.java | 4 - .../common/application/ApplicationImpl.java | 7 +- .../main/java/org/tron/core/db/Manager.java | 23 +--- .../org/tron/core/db/TronDatabaseTest.java | 101 ++++++++++++++++++ .../org/tron/core/db/TxCacheDBInitTest.java | 1 + 9 files changed, 140 insertions(+), 84 deletions(-) create mode 100644 framework/src/test/java/org/tron/core/db/TronDatabaseTest.java diff --git a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java index 939d95dc584..e43d442534a 100644 --- a/chainbase/src/main/java/org/tron/core/ChainBaseManager.java +++ b/chainbase/src/main/java/org/tron/core/ChainBaseManager.java @@ -28,9 +28,7 @@ import org.tron.core.db.PbftSignDataStore; import org.tron.core.db.RecentBlockStore; import org.tron.core.db.RecentTransactionStore; -import org.tron.core.db.TransactionCache; import org.tron.core.db.TransactionStore; -import org.tron.core.db2.core.ITronChainBase; import org.tron.core.exception.BadItemException; import org.tron.core.exception.HeaderNotFound; import org.tron.core.exception.ItemNotFoundException; @@ -238,9 +236,6 @@ public class ChainBaseManager { @Autowired private DbStatService dbStatService; - @Autowired - private TransactionCache transactionCache; - @Getter @Setter private NodeType nodeType; @@ -249,55 +244,6 @@ public class ChainBaseManager { @Setter private long lowestBlockNum = -1; // except num = 0. - public void closeOneStore(ITronChainBase database) { - logger.info("******** Begin to close {}. ********", database.getName()); - try { - database.close(); - } catch (Exception e) { - logger.info("Failed to close {}.", database.getName(), e); - } finally { - logger.info("******** End to close {}. ********", database.getName()); - } - } - - public void closeAllStore() { - dbStatService.shutdown(); - closeOneStore(transactionRetStore); - closeOneStore(recentBlockStore); - closeOneStore(transactionHistoryStore); - closeOneStore(transactionStore); - closeOneStore(accountStore); - closeOneStore(blockStore); - closeOneStore(blockIndexStore); - closeOneStore(accountIdIndexStore); - closeOneStore(accountIndexStore); - closeOneStore(witnessScheduleStore); - closeOneStore(assetIssueStore); - closeOneStore(dynamicPropertiesStore); - closeOneStore(abiStore); - closeOneStore(codeStore); - closeOneStore(contractStore); - closeOneStore(contractStateStore); - closeOneStore(storageRowStore); - closeOneStore(exchangeStore); - closeOneStore(proposalStore); - closeOneStore(votesStore); - closeOneStore(delegatedResourceStore); - closeOneStore(delegatedResourceAccountIndexStore); - closeOneStore(assetIssueV2Store); - closeOneStore(exchangeV2Store); - closeOneStore(nullifierStore); - closeOneStore(merkleTreeStore); - closeOneStore(delegationStore); - closeOneStore(proofStore); - closeOneStore(commonStore); - closeOneStore(commonDataBase); - closeOneStore(pbftSignDataStore); - closeOneStore(sectionBloomStore); - closeOneStore(accountAssetStore); - closeOneStore(transactionCache); - } - // for test only public List getWitnesses() { return witnessScheduleStore.getActiveWitnesses(); @@ -437,6 +383,10 @@ private void init() { this.nodeType = getLowestBlockNum() > 1 ? NodeType.LITE : NodeType.FULL; } + public void shutdown() { + dbStatService.shutdown(); + } + public boolean isLiteNode() { return getNodeType() == NodeType.LITE; } diff --git a/chainbase/src/main/java/org/tron/core/db/TronDatabase.java b/chainbase/src/main/java/org/tron/core/db/TronDatabase.java index b96d7543302..d791e189eb4 100644 --- a/chainbase/src/main/java/org/tron/core/db/TronDatabase.java +++ b/chainbase/src/main/java/org/tron/core/db/TronDatabase.java @@ -94,7 +94,14 @@ public void reset() { */ @Override public void close() { - dbSource.closeDB(); + logger.info("******** Begin to close {}. ********", getName()); + try { + dbSource.closeDB(); + } catch (Exception e) { + logger.warn("Failed to close {}.", getName(), e); + } finally { + logger.info("******** End to close {}. ********", getName()); + } } public abstract void put(byte[] key, T item); diff --git a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java index c1da54d84f4..4b75ddee3a4 100644 --- a/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java +++ b/chainbase/src/main/java/org/tron/core/db/TronStoreWithRevoking.java @@ -182,7 +182,14 @@ public String getName() { @Override public void close() { - revokingDB.close(); + logger.info("******** Begin to close {}. ********", getName()); + try { + revokingDB.close(); + } catch (Exception e) { + logger.warn("Failed to close {}.", getName(), e); + } finally { + logger.info("******** End to close {}. ********", getName()); + } } @Override diff --git a/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java b/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java index 9923a876cad..34f6720a3a1 100644 --- a/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java +++ b/chainbase/src/main/java/org/tron/core/db2/common/TxCacheDB.java @@ -21,6 +21,8 @@ import java.util.Properties; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicBoolean; +import lombok.Getter; +import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.ArrayUtils; import org.bouncycastle.util.encoders.Hex; @@ -79,6 +81,10 @@ public class TxCacheDB implements DB, Flusher { private final Path cacheDir; private AtomicBoolean isValid = new AtomicBoolean(false); + @Getter + @Setter + private volatile boolean alive; + public TxCacheDB(String name, RecentTransactionStore recentTransactionStore) { this.name = name; this.TRANSACTION_COUNT = @@ -138,6 +144,7 @@ private void initCache() { public void init() { if (recovery()) { isValid.set(true); + setAlive(true); return; } long size = recentTransactionStore.size(); @@ -160,6 +167,7 @@ public void init() { bloomFilters[1].approximateElementCount(), bloomFilters[1].expectedFpp(), System.currentTimeMillis() - start); isValid.set(true); + setAlive(true); } @Override @@ -247,10 +255,14 @@ public synchronized void flush(Map batch) { @Override public void close() { + if (!isAlive()) { + return; + } dump(); bloomFilters[0] = null; bloomFilters[1] = null; persistentStore.close(); + setAlive(false); } @Override diff --git a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java index 4eed2c06733..96796b3c460 100644 --- a/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java +++ b/chainbase/src/main/java/org/tron/core/db2/core/SnapshotManager.java @@ -284,10 +284,6 @@ public synchronized void disable() { @Override public void shutdown() { - logger.info("******** Begin to pop revokingDb. ********"); - logger.info("******** Before revokingDb size: {}.", size); - checkTmpStore.close(); - logger.info("******** End to pop revokingDb. ********"); if (pruneCheckpointThread != null) { pruneCheckpointThread.shutdown(); } diff --git a/framework/src/main/java/org/tron/common/application/ApplicationImpl.java b/framework/src/main/java/org/tron/common/application/ApplicationImpl.java index 26200abec2d..b6bcd670a03 100644 --- a/framework/src/main/java/org/tron/common/application/ApplicationImpl.java +++ b/framework/src/main/java/org/tron/common/application/ApplicationImpl.java @@ -77,12 +77,13 @@ public void shutdown() { synchronized (dbManager.getRevokingStore()) { dbManager.getSession().reset(); closeRevokingStore(); - closeAllStore(); } dbManager.stopRePushThread(); dbManager.stopRePushTriggerThread(); EventPluginLoader.getInstance().stopPlugin(); dbManager.stopFilterProcessThread(); + dbManager.stopValidateSignThread(); + getChainBaseManager().shutdown(); dynamicArgs.close(); logger.info("******** end to shutdown ********"); } @@ -112,8 +113,4 @@ private void closeRevokingStore() { dbManager.getRevokingStore().shutdown(); } - private void closeAllStore() { - dbManager.closeAllStore(); - } - } diff --git a/framework/src/main/java/org/tron/core/db/Manager.java b/framework/src/main/java/org/tron/core/db/Manager.java index 3a18dce32a9..c50e8c900a1 100644 --- a/framework/src/main/java/org/tron/core/db/Manager.java +++ b/framework/src/main/java/org/tron/core/db/Manager.java @@ -105,7 +105,6 @@ import org.tron.core.db.api.MoveAbiHelper; import org.tron.core.db2.ISession; import org.tron.core.db2.core.Chainbase; -import org.tron.core.db2.core.ITronChainBase; import org.tron.core.db2.core.SnapshotManager; import org.tron.core.exception.AccountResourceInsufficientException; import org.tron.core.exception.BadBlockException; @@ -450,6 +449,10 @@ public void stopFilterProcessThread() { ExecutorServiceManager.shutdownAndAwaitTermination(filterEs, filterEsName); } + public void stopValidateSignThread() { + ExecutorServiceManager.shutdownAndAwaitTermination(validateSignService, "validate-sign"); + } + @PostConstruct public void init() { ChainBaseManager.init(chainBaseManager); @@ -1926,24 +1929,6 @@ public NullifierStore getNullifierStore() { return chainBaseManager.getNullifierStore(); } - public void closeAllStore() { - logger.info("******** Begin to close db. ********"); - chainBaseManager.closeAllStore(); - validateSignService.shutdown(); - logger.info("******** End to close db. ********"); - } - - public void closeOneStore(ITronChainBase database) { - logger.info("******** Begin to close {}. ********", database.getName()); - try { - database.close(); - } catch (Exception e) { - logger.info("Failed to close {}.", database.getName(), e); - } finally { - logger.info("******** End to close {}. ********", database.getName()); - } - } - public boolean isTooManyPending() { return getPendingTransactions().size() + getRePushTransactions().size() > maxTransactionPendingSize; diff --git a/framework/src/test/java/org/tron/core/db/TronDatabaseTest.java b/framework/src/test/java/org/tron/core/db/TronDatabaseTest.java new file mode 100644 index 00000000000..f38f55df64d --- /dev/null +++ b/framework/src/test/java/org/tron/core/db/TronDatabaseTest.java @@ -0,0 +1,101 @@ +package org.tron.core.db; + +import com.google.protobuf.InvalidProtocolBufferException; +import java.io.IOException; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.rules.TemporaryFolder; +import org.rocksdb.RocksDB; +import org.tron.core.Constant; +import org.tron.core.config.args.Args; +import org.tron.core.exception.BadItemException; +import org.tron.core.exception.ItemNotFoundException; + +public class TronDatabaseTest extends TronDatabase { + + @ClassRule + public static final TemporaryFolder temporaryFolder = new TemporaryFolder(); + + static { + RocksDB.loadLibrary(); + } + + @BeforeClass + public static void initArgs() throws IOException { + Args.setParam(new String[]{"-d", temporaryFolder.newFolder().toString()}, Constant.TEST_CONF); + } + + @AfterClass + public static void destroy() { + Args.clearParam(); + } + + @Override + public void put(byte[] key, String item) { + + } + + @Override + public void delete(byte[] key) { + + } + + @Override + public String get(byte[] key) { + return "test"; + } + + @Override + public boolean has(byte[] key) { + return false; + } + + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void TestInit() { + TronDatabaseTest db = new TronDatabaseTest(); + Assert.assertNull(db.getDbSource()); + Assert.assertNull(db.getDbName()); + } + + @Test + public void TestIterator() { + TronDatabaseTest db = new TronDatabaseTest(); + thrown.expect(UnsupportedOperationException.class); + db.iterator(); + } + + @Test + public void TestIsNotEmpty() { + TronDatabaseTest db = new TronDatabaseTest(); + thrown.expect(UnsupportedOperationException.class); + db.isNotEmpty(); + } + + @Test + public void TestGetUnchecked() { + TronDatabaseTest db = new TronDatabaseTest(); + Assert.assertNull(db.getUnchecked("test".getBytes())); + } + + @Test + public void TestClose() { + TronDatabaseTest db = new TronDatabaseTest(); + db.close(); + } + + @Test + public void TestGetFromRoot() throws + InvalidProtocolBufferException, BadItemException, ItemNotFoundException { + TronDatabaseTest db = new TronDatabaseTest(); + Assert.assertEquals(db.getFromRoot("test".getBytes()), + "test"); + } +} diff --git a/framework/src/test/java/org/tron/core/db/TxCacheDBInitTest.java b/framework/src/test/java/org/tron/core/db/TxCacheDBInitTest.java index c3cb7cb2eb6..e415476d739 100644 --- a/framework/src/test/java/org/tron/core/db/TxCacheDBInitTest.java +++ b/framework/src/test/java/org/tron/core/db/TxCacheDBInitTest.java @@ -51,6 +51,7 @@ public void reload() { DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory(); queryTransaction(); + db.close(); defaultListableBeanFactory.destroySingleton("transactionCache"); TransactionCache transactionCache = new TransactionCache("transactionCache", context.getBean(RecentTransactionStore.class));