H2 is written in Java, in-memory HSQL databases, can be embedded in Java applications or run in the client-server mode.
H2 supports a simple clustering / high availability mechanism. The architecture is: two database servers run on two different computers, and on both computers is a copy of the same database. If both servers run, each database operation is executed on both computers. If one server fails (power, hardware or network failure), the other server can still continue to work. From this point on, the operations will be executed only on one server until the other server is back up.
Clustering can only be used in the server mode (the embedded mode does not support clustering, but maybe oneday in the future, the 'mixed clustering mode' will add this to the feature request list; it should be quite easy to implement.). It is possible to restore the cluster without stopping the server, however it is critical that no other application is changing the data in the first database while the second database is restored, so restoring the cluster is currently a manual process.
Suppose two server:
server1: java -cp "h2.jar;%H2DRIVERS%;%CLASSPATH%" org.h2.tools.Server -tcp -tcpPort 9101 -baseDir server1
server2: java -cp "h2.jar;%H2DRIVERS%;%CLASSPATH%" org.h2.tools.Server -tcp -tcpPort 9102 -baseDir server2
Createcluster1:
java -cp "h2.jar;%H2DRIVERS%;%CLASSPATH%" org.h2.tools.CreateCluster -urlSource jdbc:h2:tcp://localhost:9101/./test -urlTarget jdbc:h2:tcp://localhost:9102/./test -user sa -serverlist localhost:9101,localhost:9102
Createcluster2:
java -cp "h2.jar;%H2DRIVERS%;%CLASSPATH%" org.h2.tools.CreateCluster -urlSource jdbc:h2:tcp://localhost:9102/./test -urlTarget jdbc:h2:tcp://localhost:9101/./test -user sa -serverlist localhost:9101,localhost:9102
In this mode, Read-only queries(such as select) are only executed against the first cluster node - server1(9101), but all other statements are executed against all nodes. There is currently no load balancing made to avoid problems with transactions. The following functions may yield different results on different cluster nodes and must be executed with care: RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), MEMORY_FREE(), MEMORY_USED(), CSVREAD(), CSVWRITE(), RAND() [when not using a seed]. Those functions should not be used directly in modifying statements (for example INSERT, UPDATE, or MERGE). However, they can be used in read-only statements and the result can then be used for modifying statements.
Data restore:
If server2 crash, insert/update/delete statements are only submitted to server1 without exception. we should delete server2's db file first, and then restart server2 mannually, and then redo Createcluster1 command, H2 will do data synchronization automatically (from server1 to server2), and after that, insert/update/delete statements will be executed against server1 and server2.
If server1 crash, we should delete server1's db file first, and then restart server1, then do another Createcluster2 command instead of Createcluster1 , otherwise the exception(target db's file should be empty) will be thrown, that's to say, H2's culstering data synchronization is baed on -urlSource and -urlTarget, and the target db file must be empty. But in this way, the select queries will be executed against server2, not server1.