Patutin Mikhail - 2016-12-24

Hi. I created cluster over 3 same hsqldb databases.

<ha-jdbc xmlns="urn:ha-jdbc:cluster:3.0">
    <sync id="full">
       <property name="fetchSize">100</property>
        <property name="maxBatchSize">100</property>
    </sync>
    <state id="simple"/>
    <cluster default-sync="full" dialect="hsqldb" balancer="simple" durability="fine" meta-data-cache="shared-eager" detect-sequences="true"
             failure-detect-schedule="0,15,30,45 * * ? * *" auto-activate-schedule="0,15,30,45 * * ? * *">
       <database id="db1" location="jdbc:hsqldb:hsql://10.34.10.57:9001/node1" weight="100">
         <property name="ifexists">true</property>
       </database>
       <database id="db2" location="jdbc:hsqldb:hsql://10.34.10.57:9002/node2" weight="70">
         <property name="ifexists">true</property>
       </database>
        <database id="db3" location="jdbc:hsqldb:hsql://10.34.10.57:9003/node3" weight="30">
            <property name="ifexists">true</property>
        </database>
    </cluster>
</ha-jdbc>

Got two problems:
1. In db present table with name "USER". For this table incorrectly received metadata about primary keys, unique constraints and foreing keys.
I fix it with creating my own dialect hsqldb234 with
class HSQLDB234Dialect extends HSQLDBDialect with internal
private class hsqldb234IdentifierNormalizer extends StandardIdentifierNormalizer
HSQLDB234DialectFactory implements DialectFactory
Question: Is it bug in ha-jdbc or I don't know something?

  1. In addition in ~10% of hard reset of any database in cluster i got error
[Server@fce56f8]: [Thread[HSQLDB Server @fce56f8,5,main]]: Opening database: [file:node3/ConsoleDb]
2016-12-24T21:32:06.181+0300  SEVERE  statement error processing log - open continuednode3/ConsoleDb.log line: 9
org.hsqldb.HsqlException: user lacks privilege or object not found: SYS_FK_10364
        at org.hsqldb.error.Error.error(Unknown Source)
        at org.hsqldb.error.Error.error(Unknown Source)

After that ALL foreign key in database are changing it names and cluster stop normally syncronize (i'm using full syncronization strategy)
Probles it that in sync process is used metadata that parsed on cluster startup. But after db restoration I have database with changed metadata.
I fix it by dirty hack SynchronizationSupportImpl with modification dropForeignKeys()

    public void dropForeignKeys() throws SQLException
    {
        Dialect dialect = this.context.getDialect();

        Connection connection = this.context.getConnection(this.context.getTargetDatabase());
        boolean autoCommit = connection.getAutoCommit();

---     DatabaseMetaData metaData = connection.getMetaData();
---     DatabaseProperties properties = new EagerDatabaseProperties(metaData, dialect);

        try
        {
            connection.setAutoCommit(true);

            Statement statement = connection.createStatement();
            try
            {
---             for (TableProperties table: properties.getTables())
                {
                    for (ForeignKeyConstraint constraint: table.getForeignKeyConstraints())
                    {
                        String sql = dialect.getDropForeignKeyConstraintSQL(constraint);

                        this.logger.log(Level.DEBUG, sql);

                        statement.addBatch(sql);
                    }
                    statement.executeBatch();
                }
            }
            finally
            {
                Resources.close(statement);
            }
        }
        finally
        {
            connection.setAutoCommit(autoCommit);
        }
    }

I'm sure that this way is incorrect.
How I must work with this problem? Create my own sycronization strategy?