Truncating takes too much time hsqldb

2019-08-06 16:22发布

问题:

I use HSQLDB 2.3.2 and I've got the following issues:

  1. My database has cached table with 10 000 000 records without any constraints and indexes. Its size is about ~900mb. I turn off autocommit mode and when I try to execute "Truncate table tableName", execution hangs but only dbName.backup is growing. And here's why:

TRACE ENGINE:? - copyShadow [size, time] 2246252 9721
TRACE ENGINE:? - setFileModified flag set
TRACE ENGINE:? - cache save rows [count,time] totals 24801,9921 operation 24801,9921 txts 96
TRACE ENGINE:? - copyShadow [size, time] 4426920 7732
TRACE ENGINE:? - cache save rows [count,time] totals 49609,17775 operation 24808,7854 txts 96
TRACE ENGINE:? - copyShadow [size, time] 6574796 9024

It takes about 1500-2000 seconds and finally I can get either empty table or exception that is something like this:

Tests run: 0, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1,525.509 sec
org.apache.maven.surefire.util.SurefireReflectionException: java.lang.reflect.InvocationTargetException; nested exception is java.lang.reflect.InvocationTargetException: null
java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:164)
    at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:110)
    at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:175)
    at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcessWhenForked(SurefireStarter.java:107)
    at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:68)
Caused by: java.lang.OutOfMemoryError: Java heap space

After the truncating dbName.backup is removed. I don't have to use any backups in my application, how can I avoid the copying?

  1. dbName.properties doesn't work. It contains the following text:

    #HSQL Database Engine 2.3.2

    #Thu Mar 19 08:42:10 EAT 2015

    version=2.3.2
    modified=no

I tried to append hsqldb.applog=1 but nothing happened.
dbName.app.log appears in case you change the line SET DATABASE EVENT LOG LEVEL 1 in dbName.script
After working with the database from my application dbName.properties is overwrited: 'modified' changes on 'yes' and any lines below are deleted. What do I do wrong?

回答1:

My database has cached table with 10 000 000 records without any constraints and indexes.

It is simply wrong to have a large table without any constraints and indexes. Any SELECT, UPDATE or DELETE on this table that affects a few rows has to search all the rows in the table.

I try to execute "Truncate table tableName"

The above statement allows you to roll back the action before you commit. The information for rolling back is stored in memory and memory will run out when the table is very large. As you do want to commit the change, use this statement instead:

TRUNCATE TABLE tableName AND COMMIT

This is mentioned in the Guide: http://hsqldb.org/doc/2.0/guide/dataaccess-chapt.html#dac_truncate_statement

The only addition that you can make to the .properties file is to set the database files readonly. Any other change will be ignored and deleted.

The .backup file is for internal use of the database engine and you cannot stop its use.