Code review comment: >   How about only print out the id of the db? There should be some simpler and safer way to identify db. As an open source project that can be privatized deployed, I think our log on exception should be as detailed as possible because those logs are all we can get from the users.

Code under review:
public boolean close() {
        boolean closeSuccess = true;
        lock.writeLock().lock();
        try {
            closing = true;

            LOG.info("start to close log databases");
            for (CloseSafeDatabase db : openedDatabases) {
                try {
                    db.close();
                } catch (DatabaseException exception) {
                    LOG.error("Error closing db", exception);
                    closeSuccess = false;
                }
            }
            LOG.info("close log databases end");
            openedDatabases.clear();

            LOG.info("start to close epoch database");
            if (epochDB != null) {
                try {
                    epochDB.close();
                } catch (DatabaseException exception) {
                    LOG.error("Error closing db ", exception);
                    closeSuccess = false;
                }
            }
            LOG.info("close epoch database end");

            LOG.info("start to close replicated environment");
            if (replicatedEnvironment != null) {
                try {
                    
                    replicatedEnvironment.close();
                } catch (DatabaseException exception) {
                    LOG.error("Error closing replicatedEnvironment", exception);
                    closeSuccess = false;
                }
            }
            LOG.info("close replicated environment end");
        } finally {
            closing = false;
            lock.writeLock().unlock();
        }
        return closeSuccess;
    }

Line commented on: LOG.error("Error closing db", exception);

Revised code:
public boolean close() {
        boolean closeSuccess = true;
        lock.writeLock().lock();
        try {
            closing = true;

            LOG.info("start to close log databases");
            for (CloseSafeDatabase db : openedDatabases) {
                try {
                    db.close();
                } catch (DatabaseException exception) {
                    LOG.error("Error closing db {}", db.getDatabaseName(), exception);
                    closeSuccess = false;
                }
            }
            LOG.info("close log databases end");
            openedDatabases.clear();

            LOG.info("start to close epoch database");
            if (epochDB != null) {
                try {
                    epochDB.close();
                } catch (DatabaseException exception) {
                    LOG.error("Error closing db {}", epochDB.getDatabaseName(), exception);
                    closeSuccess = false;
                }
            }
            LOG.info("close epoch database end");

            LOG.info("start to close replicated environment");
            if (replicatedEnvironment != null) {
                try {
                    
                    replicatedEnvironment.close();
                } catch (DatabaseException exception) {
                    LOG.error("Error closing replicatedEnvironment", exception);
                    closeSuccess = false;
                }
            }
            LOG.info("close replicated environment end");
        } finally {
            closing = false;
            lock.writeLock().unlock();
        }
        return closeSuccess;
    }