Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MV background thread -- Causing system overload #2206

Open
goranschwarz opened this issue Oct 25, 2019 · 1 comment
Open

MV background thread -- Causing system overload #2206

goranschwarz opened this issue Oct 25, 2019 · 1 comment

Comments

@goranschwarz
Copy link

goranschwarz commented Oct 25, 2019

After I installed 1.4.200 I got the following issues:

  • MV background thread -- uses to much resources in housekeeping mode
    • a lot of reads... (the Linux device is at almost 100% bussy, depending if it's a local SSD or a slower SAN attached disk number of reads per sec is approx: SSD=5000-10000, slowSAN=500-1000)
    • since it reads so much... the 'OS Load Average' (uptime) is getting to high, which causes the machine to go slow...
  • shutdown -- takes a long time (too long since I abort the shutdown sequence after 1 minute)
    • startup/recovery -- If the shutdown isn't clean, then the startup phase will have to alot more work... and it takes a long time hour(s) to start/open the DB
  • shutdown defrag -- takes longer time than in prev versions(s)... from 20-30 minutes up to 3 hours

Note: I closed the case #1820 (which was a bit to fragmented and continued here)

I think that everything is connected to MV background thread
And this is how I draw that conclution!

  • most stacktraces (using jstack) I grabbed: was located at
    MVStore$BackgroundWriterThread -> writeInBackground -> doMaintenance -> rewriteChunks -> compactRewrite -> ...
  • So I added some small probes in method compactRewrite to write out (see code snippet later)
    • milliseconds it took to execute this method
    • how many FileSystem read/writes was done during the method call
    • rewrittenPageCount, map.size(), set.size()

And here are some of the results

>>> DEBUG >>> 2019-10-24 12:57:22.03 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=2809770, fsReads=4085788, fsWrites=744, rewrittenPageCount=35043, map.size()=2404, set.size()=617
>>> DEBUG >>> 2019-10-24 14:03:51.503 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=3978161, fsReads=4164416, fsWrites=869, rewrittenPageCount=34545, map.size()=2400, set.size()=534
>>> DEBUG >>> 2019-10-24 15:20:42.259 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=4599842, fsReads=4482713, fsWrites=1018, rewrittenPageCount=35620, map.size()=2400, set.size()=665
>>> DEBUG >>> 2019-10-24 17:33:28.351 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=7954549, fsReads=5346535, fsWrites=1569, rewrittenPageCount=36151, map.size()=2400, set.size()=643
>>> DEBUG >>> 2019-10-24 20:25:51.587 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=10320480, fsReads=3945544, fsWrites=381, rewrittenPageCount=39177, map.size()=2400, set.size()=950
>>> DEBUG >>> 2019-10-24 23:37:45.186 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=11506096, fsReads=3586797, fsWrites=42, rewrittenPageCount=37396, map.size()=2400, set.size()=533
>>> DEBUG >>> 2019-10-25 00:59:19.05 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=1260305, fsReads=3903046, fsWrites=261, rewrittenPageCount=39568, map.size()=2401, set.size()=2065
>>> DEBUG >>> 2019-10-25 01:19:19.064 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=1193738, fsReads=3849653, fsWrites=247, rewrittenPageCount=37127, map.size()=2401, set.size()=823
>>> DEBUG >>> 2019-10-25 05:25:07.955 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=1144385, fsReads=3877481, fsWrites=236, rewrittenPageCount=38629, map.size()=2401, set.size()=1485
>>> DEBUG >>> 2019-10-25 05:50:05.616 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=1491005, fsReads=3955934, fsWrites=370, rewrittenPageCount=38148, map.size()=2401, set.size()=820
>>> DEBUG >>> 2019-10-25 07:16:49.699 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=5197338, fsReads=3734068, fsWrites=213, rewrittenPageCount=34368, map.size()=2401, set.size()=251
>>> DEBUG >>> 2019-10-25 11:52:48.749 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=3770372, fsReads=4405477, fsWrites=671, rewrittenPageCount=38782, map.size()=2400, set.size()=2021
>>> DEBUG >>> 2019-10-25 13:00:09.162 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=4028562, fsReads=4482262, fsWrites=750, rewrittenPageCount=36194, map.size()=2400, set.size()=717
>>> DEBUG >>> 2019-10-25 14:11:17.087 - MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db - MVStore.compactRewrite(); execTimeMs=4261741, fsReads=4402916, fsWrites=651, rewrittenPageCount=34267, map.size()=2400, set.size()=497

Execution Time varies from: 20 minutes up to above 3 hours
Number of reads averaging around 4M reads (yes 4_000_000)

I guess this is not how things was intended to work!
This will cause:

  • Everything to go slow on the machine (due to overloading the IO Subsystem)
    • OS will be in wa - iowait if the pages are not in H2 cache or OS FileSystemCache
    • OS will be in us - user time if the pages are in cache... but it still eats alot of CPU
  • makes it hard to run more than one H2 database on the same machine (and since H2 usually is embedded in an application, it makes it harder to run more than one instance of the application on the same machine)
  • normal shutdown of H2, takes a long time, which probably means that it violates most shutdown sequences... and will cause unclean/dirty shutdown(s).
  • next startup of H2 needs to do alot more, since the shutdown was dirty

This problem is mainly on larger databases.
my 'DBXTUNE_CENTRAL_DB' database is around 30-35 GB

NOTE On smaller databases 2-4 GB
On smaller databases (which I have a couple of, for the moment 9 collector databases, where a new database is created after 24 hour, as an archive mechanism) the "Execution time" for method compactRewrite is typically around 2-10 seconds.
But it still does alot of IO's. between 50K and 200K on every invocation.
The file system cache might hold many of those IO requests (because I don't see that many IO reads from isostat, but the MVStore: FileStore fileStore.readCount is still incremented.
Meaning: it's not idle... it's using alot of CPU cyckles.

URL

typically:
jdbc:h2:file:/home/sybase/.dbxtune/dbxc/data/DBXTUNE_CENTRAL_DB;DATABASE_TO_UPPER=f alse;RETENTION_TIME=1000;MAX_COMPACT_TIME=2000;COMPRESS=TRUE;WRITE_DELAY=30000;DB_CLOSE_ON_EXIT=FALSE

Short snippet from the startup phase (where the above URL was grabbed from)

Includes all settings from the information_schema

2019-10-24 11:58:05,001 - INFO  - main                           - CentralPersistWriterJdbc       - Initializing the Central PersistentCounterHandler.WriterClass component named 'com.asetune.central.pcs.CentralPersistWriterJdbc'.
2019-10-24 11:58:05,002 - INFO  - main                           - CentralPersistWriterJdbc       - Open initial connection to Checking/creating common DbxCentral tables.
2019-10-24 11:58:05,010 - INFO  - main                           - CentralPersistWriterJdbc       - Open a new connection to the Persistent Counter Storage. 'keep conn open=true'
2019-10-24 11:58:05,011 - INFO  - main                           - CentralPersistWriterJdbc       - H2 URL add option: DATABASE_TO_UPPER=false
2019-10-24 11:58:05,011 - INFO  - main                           - CentralPersistWriterJdbc       - H2 URL add option: RETENTION_TIME=1000
2019-10-24 11:58:05,012 - INFO  - main                           - CentralPersistWriterJdbc       - H2 URL add option: MAX_COMPACT_TIME=2000
2019-10-24 11:58:05,012 - INFO  - main                           - CentralPersistWriterJdbc       - H2 URL add option: COMPRESS=TRUE
2019-10-24 11:58:05,012 - INFO  - main                           - CentralPersistWriterJdbc       - H2 URL add option: WRITE_DELAY=30000
2019-10-24 11:58:05,012 - INFO  - main                           - CentralPersistWriterJdbc       - H2 URL add option: DB_CLOSE_ON_EXIT=false  (due to isShutdownHookInstalled=true)
2019-10-24 11:58:05,012 - INFO  - main                           - CentralPersistWriterJdbc       - Added some options to the H2 URL. New URL is 'jdbc:h2:file:/home/sybase/.dbxtune/dbxc/data/DBXTUNE_CENTRAL_DB;DATABASE_TO_UPPER=false;RETENTION_TIME=1000;MAX_
COMPACT_TIME=2000;COMPRESS=TRUE;WRITE_DELAY=30000;DB_CLOSE_ON_EXIT=FALSE'.
2019-10-24 12:10:24,720 - INFO  - main                           - CentralPersistWriterJdbc       - A Database connection has been opened. connectTime='00:12:19.705', to URL 'jdbc:h2:file:/home/sybase/.dbxtune/dbxc/data/DBXTUNE_CENTRAL_DB;DATABASE_TO_UPPER=f
alse;RETENTION_TIME=1000;MAX_COMPACT_TIME=2000;COMPRESS=TRUE;WRITE_DELAY=30000;DB_CLOSE_ON_EXIT=FALSE', using driver 'org.h2.Driver'.
2019-10-24 12:10:24,733 - INFO  - main                           - CentralPersistWriterJdbc       - Connected using JDBC driver Name='H2 JDBC Driver', Version='1.4.200 (2019-10-14)', MajorVersion='1', MinorVersion='4', JdbcMajorVersion='4', JdbcMinorVersion=
'2'.
2019-10-24 12:10:24,734 - INFO  - main                           - CentralPersistWriterJdbc       - Connected to Database Product Name='H2', Version='1.4.200 (2019-10-14)', MajorVersion='1', MinorVersion='4'.
2019-10-24 12:10:24,734 - INFO  - main                           - CentralPersistWriterJdbc       - Do H2 Specific settings for the database.
2019-10-24 12:10:24,734 - INFO  - main                           - CentralPersistWriterJdbc       - H2: SET COMPRESS_LOB DEFLATE
2019-10-24 12:10:24,737 - INFO  - main                           - CentralPersistWriterJdbc       - H2: SET DEFAULT_LOCK_TIMEOUT 30000
2019-10-24 12:10:24,737 - INFO  - main                           - CentralPersistWriterJdbc       - H2: SET QUERY_TIMEOUT 30000
2019-10-24 12:10:24,881 - INFO  - main                           - CentralPersistWriterJdbc       - H2 Configuration/Settings: {ALIAS_COLUMN_NAME=false, ANALYZE_AUTO=2000, ANALYZE_SAMPLE=10000, CASE_INSENSITIVE_IDENTIFIERS=false, COMPRESS=TRUE, COMPRESS_LOB=
DEFLATE, CREATE_BUILD=200, DATABASE_TO_LOWER=false, DATABASE_TO_UPPER=false, DB_CLOSE_ON_EXIT=FALSE, DEFAULT_CONNECTION=false, DEFAULT_ESCAPE=\, DEFAULT_LOCK_TIMEOUT=30000, DEFAULT_TABLE_ENGINE=NULL, DEFRAG_ALWAYS=false, DROP_RESTRICT=true, EARLY_FILTER=fals
e, ESTIMATED_FUNCTION_TABLE_ROWS=1000, EXCLUSIVE=FALSE, FUNCTIONS_IN_SCHEMA=true, IGNORE_CATALOGS=false, LOB_TIMEOUT=300000, LOG=2, MAX_COMPACT_COUNT=2147483647, MAX_COMPACT_TIME=2000, MAX_QUERY_TIMEOUT=0, MODE=REGULAR, MV_STORE=true, OPTIMIZE_DISTINCT=true,
 OPTIMIZE_EVALUATABLE_SUBQUERIES=true, OPTIMIZE_INSERT_FROM_SELECT=true, OPTIMIZE_IN_LIST=true, OPTIMIZE_IN_SELECT=true, OPTIMIZE_OR=true, OPTIMIZE_TWO_EQUALS=true, OPTIMIZE_UPDATE=true, QUERY_CACHE_SIZE=8, QUERY_TIMEOUT=30000, RECOMPILE_ALWAYS=false, RETENT
ION_TIME=1000, REUSE_SPACE=true, SHARE_LINKED_CONNECTIONS=true, WRITE_DELAY=30000, info.BUILD_ID=200, info.CACHE_MAX_SIZE=16, info.CACHE_SIZE=15, info.FILE_READ=71674, info.FILE_WRITE=0, info.PAGE_COUNT=9507737, info.PAGE_SIZE=65536, info.UPDATE_FAILURE_PERC
ENT=0.00%, info.VERSION=1.4.200 (2019-10-14), info.VERSION_MAJOR=1, info.VERSION_MINOR=4, property.file.encoding=UTF-8, property.file.separator=/, property.java.runtime.version=1.8.0_222-b10, property.java.vendor=Oracle Corporation, property.java.vm.name=Ope
nJDK 64-Bit Server VM, property.line.separator=, property.os.arch=amd64, property.os.name=Linux, property.os.version=3.10.0-1062.1.1.el7.x86_64, property.path.separator=:, property.sun.os.patch.level=unknown, property.user.country=US, property.user.language=
en, property.user.variant=}
2019-10-24 12:10:24,903 - INFO  - main                           - ConnectionDialog               - Setting 'DBXTUNE_SAVE_DIR' in the System Properties to value '/home/sybase/.dbxtune/dbxc/data'.
2019-10-24 12:10:24,966 - INFO  - main                           - CentralPersistWriterJdbc       - Checking/creating common DbxCentral tables.
2019-10-24 12:10:25,367 - INFO  - main                           - CentralPersistWriterJdbc       - Internal Dbx Central database version number is 10, which is the latest version.
2019-10-24 12:10:25,856 - INFO  - main                           - CentralPersistReader           - PCS Reader initialized using: jdbcDriver='org.h2.Driver', jdbcUrl='jdbc:h2:file:/home/sybase/.dbxtune/dbxc/data/DBXTUNE_CENTRAL_DB', jdbcUsername='sa', jdbcPa
ssword='*secret*'.
2019-10-24 12:10:25,859 - INFO  - CentralPcsWriterHandler        - CentralPcsWriterHandler        - Starting a thread for the module 'CentralPcsWriterHandler'.
2019-10-24 12:10:25,864 - INFO  - main                           - DbxTuneCentral                 - Starting a H2 TCP server. Switches: [-tcpDaemon, -tcpAllowOthers, -tcpPort, 9092, -ifExists, -baseDir, /home/sybase/.dbxtune/dbxc/data]
2019-10-24 12:10:25,904 - INFO  - main                           - DbxTuneCentral                 - H2 TCP server, url='tcp://172.25.1.247:9092', Status='TCP server running at tcp://172.25.1.247:9092 (others can connect)'.
2019-10-24 12:10:25,905 - INFO  - main                           - DbxTuneCentral                 - Starting a H2 WEB server. Switches: [-webDaemon, -webAllowOthers, -webPort, 8082, -ifExists, -baseDir, /home/sybase/.dbxtune/dbxc/data]
2019-10-24 12:10:25,934 - INFO  - main                           - DbxTuneCentral                 - H2 WEB server, url='http://172.25.1.247:8082', Status='Web Console server running at http://172.25.1.247:8082 (others can connect)'.
2019-10-24 12:10:25,935 - INFO  - main                           - DbxTuneCentral                 - Starting a H2 Postgres server. Switches: [-pgDaemon, -pgAllowOthers, -pgPort, 5435, -ifExists, -baseDir, /home/sybase/.dbxtune/dbxc/data]
2019-10-24 12:10:25,943 - INFO  - main                           - DbxTuneCentral                 - H2 Postgres server, url='pg://172.25.1.247:5435', Status='PG server running at pg://172.25.1.247:5435 (others can connect)'.
2019-10-24 12:10:25,946 - INFO  - main                           - AlarmHandler                   - Initializing the AlarmHandler functionality.

Possible Solution

Not sure what the best solution is, but some part of it might be:

  • break down the algorithm into smaller peices...
    for example in a shutdown scenario, we should honnor MAX_COMPACT_TIME or similar, so we do not spend ages in shutdown... causing apps to do unclean shutdowns
  • maybe an option BG_MAINT_INTERVALL=### where we can set that the background thread
    cleanup part, is only executed after ### seconds (so some kind of mechanism to not run it as often as it is today)

Normall stacktrace

"MVStore background writer nio:/sybdev/asetune/data/DBXTUNE_CENTRAL_DB.mv.db" #13 daemon prio=5 os_prio=0 tid=0x00007f5ae0234800 nid=0x8ec runnable [0x00007f5a98167000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.FileDispatcherImpl.pread0(Native Method)
        at sun.nio.ch.FileDispatcherImpl.pread(FileDispatcherImpl.java:52)
        at sun.nio.ch.IOUtil.readIntoNativeBuffer(IOUtil.java:220)
        at sun.nio.ch.IOUtil.read(IOUtil.java:197)
        at sun.nio.ch.FileChannelImpl.readInternal(FileChannelImpl.java:735)
        at sun.nio.ch.FileChannelImpl.read(FileChannelImpl.java:721)
        at org.h2.store.fs.FileNio.read(FilePathNio.java:74)
        at org.h2.mvstore.DataUtils.readFully(DataUtils.java:442)
        at org.h2.mvstore.FileStore.readFully(FileStore.java:98)
        at org.h2.mvstore.Chunk.readBufferForPage(Chunk.java:361)
        at org.h2.mvstore.MVStore.readBufferForPage(MVStore.java:1212)
        at org.h2.mvstore.MVStore.readPage(MVStore.java:2212)
        at org.h2.mvstore.MVMap.readPage(MVMap.java:672)
        at org.h2.mvstore.Page$NonLeaf.getChildPage(Page.java:1043)
        at org.h2.mvstore.MVMap.rewrite(MVMap.java:748)
        at org.h2.mvstore.MVMap.rewrite(MVMap.java:748)
        at org.h2.mvstore.MVMap.rewrite(MVMap.java:748)
        at org.h2.mvstore.MVMap.rewrite(MVMap.java:710)
        at org.h2.mvstore.MVStore.compactRewrite(MVStore.java:2132)
        at org.h2.mvstore.MVStore.rewriteChunks(MVStore.java:2023)
        at org.h2.mvstore.MVStore.doMaintenance(MVStore.java:2847)
        at org.h2.mvstore.MVStore.writeInBackground(MVStore.java:2791)
        at org.h2.mvstore.MVStore$BackgroundWriterThread.run(MVStore.java:3293)

Code changes to probe compactRewrite

The code that is not indentation is the added code

    private int compactRewrite(Set<Integer> set) {
        assert storeLock.isHeldByCurrentThread();
long startTime = System.currentTimeMillis();
long fsReadsAtStart  = getFileStore().getReadCount();
long fsWritesAtStart = getFileStore().getWriteCount();

        // this will ensure better recognition of the last chunk
        // in case of power failure, since we are going to move older chunks
        // to the end of the file
        writeStoreHeader();
        sync();

        int rewrittenPageCount = 0;
        storeLock.unlock();
        try {
            for (MVMap<?, ?> map : maps.values()) {
                if (!map.isClosed() && !map.isSingleWriter()) {
                    try {
                        rewrittenPageCount += map.rewrite(set);
                    } catch(IllegalStateException ex) {
                        if (!map.isClosed()) {
                            throw ex;
                        }
                    }
                }
            }
            int rewriteMetaCount = meta.rewrite(set);
            if (rewriteMetaCount > 0) {
                markMetaChanged();
                rewrittenPageCount += rewriteMetaCount;
            }
        } finally {
            storeLock.lock();
        }
        commit();
        assert validateRewrite(set);

if (_debug)
{
    long execTimeMs = System.currentTimeMillis() - startTime;
    long fsReads   = getFileStore().getReadCount()  - fsReadsAtStart;
    long fsWrites  = getFileStore().getWriteCount() - fsWritesAtStart;
    System.out.println(">>> DEBUG >>> " + new Timestamp(System.currentTimeMillis()) + " - " + Thread.currentThread().getName() + " - MVStore.compactRewrite(); execTimeMs=" + execTimeMs + ", fsReads=" + fsReads + ", fsWrites=" + fsWrites + ", rewrittenPageCount=" + rewrittenPageCount + ", map.size()=" + maps.size() + ", set.size()=" + set.size());
}
        return rewrittenPageCount;
    }

private boolean _debug = System.getProperty("MVStore.writeInBackground.debug", "true").equalsIgnoreCase("true");

I also added a small probe to method rewriteChunks to probe the writeLimit parameter, and also to see when the method was called.
But I removed that output from the output "a bit up", because it was to messy...

    private boolean rewriteChunks(int writeLimit) {
        TxCounter txCounter = registerVersionUsage();
        try {
if (_debug)
    System.out.println(">>> DEBUG >>> " + new Timestamp(System.currentTimeMillis()) + " - " + Thread.currentThread().getName() + " - MVStore.rewriteChunks(writeLimit="+writeLimit+"); txCounter=" + txCounter);
            Iterable<Chunk> old = findOldChunks(writeLimit);
            if (old != null) {
                HashSet<Integer> idSet = createIdSet(old);
                return !idSet.isEmpty() && compactRewrite(idSet) > 0;
            }
        } finally {
            deregisterVersionUsage(txCounter);
        }
        return false;
    }
@andreitokar
Copy link
Contributor

@goranschwarz, Sorry to hear about all those problems, but please understand that 30-35GB database with 2400 tables/indexes is not a typical application for H2. I am sure we are going to fix those inefficiencies, but please understand that you are raising the bar here.

But it still does alot of IO's. between 50K and 200K on every invocation.
The file system cache might hold many of those IO requests (because I don't see that many IO reads from isostat, but the MVStore: FileStore fileStore.readCount is still incremented.
Meaning: it's not idle... it's using alot of CPU cyckles.

Database file maintenance is necessary evil and it never comes for free. Two basic actions are there: chunks movements (defragmentation) and chunks re-writing (compaction). Chunk is a collection of pages (up to 1-2 mb in size), which was written at once and that serves as a unit of "garbage collection". In order to make continuous free file space to write a new chunk, existing chunks has to be moved around (as a whole units). Chunk movement is a single read and single write. Chunk rewriting, on the other hand is a process of elimination of a sparsely populated (due to page attrition) chunk. Here individual sill alive pages are read, collected and written as a one new chunk, so it's multiple (possibly hundreds) reads and one write. But the worst part is that in order to figure out dead pages all maps has to be scanned to find live pages (somewhat similar to the "mark" stage of java GC), and that involves tons of page reads blowing away any page caches. That's why number of read requests is so high, but majority of them are very small (4-10Kb), so iostat is not that terrible. Please understand that H2 was designed with SSD in mind, under assumption that random small reads are cheap.

That dead/live page determination definitely does not scale well, has to be re-worked, and I have some ideas/plans in that area. For now, to disable chunk re-writing, you can use undocumented way: add ";MAX_COMPACT_COUNT=100" to the url. You should definitely see reduction in read request count (but not necessary amount of data read).

What surprises me a lot and what I was not able to reproduce in my experiments (I've been playing with 3-10GB databases, containing just a few tables) is the fact that plain "SHUTDOWN" (without defrag) takes so long.
As far as defrag goes - my speed was ~30sec per GB of de-fragmented file (SSD) and growing slightly above linear, but four times that on a spinning local drive. I guess, on a remote disk (even it it's SAN) it may become really slow. At the moment, I have no Idea how to speed this up, but ideally it should not be a part of a production procedure, database should keep pace with the updates and do maintenance in the background.

What is also surprising is your complain about high CPU usage. Single background thread can't take more than one core, so where this

makes it hard to run more than one H2 database on the same machine

coming from?

BTW, what is you heap size? MVStore's autoCommitBufferSize is calculated based on this, and it seems to be very high, judging by the output you provided, like "set.size()=2021", which means it tries to re-write 2021 chunks at once.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants