首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何触发垃圾回收器来减小数据库大小?

如何触发垃圾回收器来减小数据库大小?
EN

Stack Overflow用户
提问于 2019-06-19 16:12:39
回答 1查看 138关注 0票数 2

我们为一个远程探测项目使用Xodus,以便在将临时数据发送到集中式数据库之前存储这些数据。因此,我们有几个商店,可以根据环境(流量、网络连接等)而增加或减少。多亏了垃圾回收器,我们希望看到数据库文件大小的减少,但就目前而言,它只是增加了。

我们尝试了几种垃圾收集器配置,以尽可能频繁地触发它。例如,我们有:

代码语言:javascript
运行
复制
    conf.setGcFileMinAge(1);
    conf.setGcFilesInterval(1);
    conf.setGcMinUtilization(1);

没有可见的效果。

存储清空后,我们预计会看到.xd文件的减少或删除,但数据库却在不断增长。

编辑:我尝试使用更简单的代码来查看GC效果,如下所示:

代码语言:javascript
运行
复制
        Environment exodus = Environments.newInstance(dbPath);

        final Transaction xtxn = exodus.beginExclusiveTransaction();
        Store store = exodus.openStore("testStore", StoreConfig.WITHOUT_DUPLICATES, xtxn);
        xtxn.commit();

        Thread.sleep(10 * 1000); // Wait to do actions after first  background cleaning cycle

        // Fill store, then clear it
        exodus.executeInExclusiveTransaction(tx -> {
            for(int i = 1; i <= 1000000; i++) {
                store.putRight(tx, LongBinding.longToEntry(i), StringBinding.stringToEntry(dbPath));
            }
        });
        clearStore(exodus, store);

        exodus.gc();
        Thread.sleep(5 * 60 * 1000); // Wait to see GC doing the work

    boolean clearStore(final Environment exodus, final Store store) {
        Transaction tx = exodus.beginExclusiveTransaction();
        try(Cursor cursor = store.openCursor(tx)) {
            boolean success = true;
            while(cursor.getNext() && success) {
                success &= cursor.deleteCurrent();
            }
            if(success) {
                tx.commit();
                return true;
            } else {
                log.warn("failed to delete entry {}", cursor.getKey());
                tx.abort();
                return false;
            }


        } catch(Exception e) {
            tx.abort();
            return false;
        }
    }

如果我删除第一个“睡眠”,垃圾收集器正在做这项工作,数据库文件大小如预期的那样减小,一切正常。但是如果我保持第一个“睡眠”,垃圾收集器似乎永远不会被调用。好像第一个背景清理周期没问题,但后面的就不行了……在本例中,我保留了默认配置。

EN

回答 1

Stack Overflow用户

发布于 2019-06-20 00:24:08

有一种是Environment.gc()方法。该方法的javadoc如下:

说,环境可以加快后台数据库垃圾收集器的活动。调用此方法不会立即产生释放磁盘空间、删除特定文件等后果。

我不建议修改默认GC设置。EnvironmentConfig.setGcMinUtilization()可以用来使数据库比默认情况下更紧凑,或者减少GC负载(例如,与批量更新并行)。基本上,更高的所需最小利用率(允许的空闲空间更少)会导致更高的GC负载。

GC逐个清理数据库文件,首先选择利用率最低的文件。清理文件时,不会立即删除该文件,应满足两个条件:

EnvironmentConfig.getGcFilesDeletionDelay()配置的

  1. 延迟应该会过去。默认为5秒。
  2. 在清理文件之前创建的任何事务(即使是只读的)都应完成(提交或中止)。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56662998

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档