package org.neo4j.onlinebackup; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.neo4j.kernel.EmbeddedGraphDatabase; import org.neo4j.kernel.impl.nioneo.store.UnderlyingStorageException; import org.neo4j.kernel.impl.transaction.LockManager; import org.neo4j.kernel.impl.transaction.TxModule; import org.neo4j.kernel.impl.transaction.XaDataSourceManager; import org.neo4j.kernel.impl.transaction.xaframework.XaDataSource; public class ApplyNewLogs { public static void main( String args[] ) { if ( args.length != 1 ) { System.err.println( "Usage: ApplyNewLogs <db path>" ); System.exit( -1 ); } String destDir = args[0]; if ( !new File( destDir ).exists() ) { throw new RuntimeException( "Unable to locate store in[" + destDir + "]" ); } Map<String,String> params = new HashMap<String, String>(); params.put( "backup_slave", "true" ); EmbeddedGraphDatabase graphDb = new EmbeddedGraphDatabase( destDir ); setupLuceneIfOnClasspath( destDir, graphDb ); XaDataSourceManager xaDsMgr = graphDb.getConfig().getTxModule().getXaDataSourceManager(); System.out.println( "Starting apply of new logs..." ); for ( XaDataSource xaDs : xaDsMgr.getAllRegisteredDataSources() ) { xaDs.makeBackupSlave(); System.out.println( "Checking " + xaDs.getName() + " ..." ); long nextVersion = xaDs.getCurrentLogVersion(); boolean logApplied = false; while ( xaDs.hasLogicalLog( nextVersion ) ) { try { xaDs.applyLog( xaDs.getLogicalLog( nextVersion ) ); logApplied = true; } catch ( IOException e ) { throw new UnderlyingStorageException( "Unable to recover slave to consistent state", e ); } nextVersion++; } if ( !logApplied ) { System.out.println( "No new logs for " + xaDs.getName() ); } } graphDb.shutdown(); System.out.println( "Apply of new logs completed." ); } private static final String LUCENE_DS_CLASS = "org.neo4j.index.lucene.LuceneDataSource"; private static final String LUCENE_FULLTEXT_DS_CLASS = "org.neo4j.index.lucene.LuceneFulltextDataSource"; private static void setupLuceneIfOnClasspath( String dstDir, EmbeddedGraphDatabase graphDb ) { TxModule txModule = graphDb.getConfig().getTxModule(); XaDataSourceManager xaDsMgr = txModule.getXaDataSourceManager(); LockManager lockManager = graphDb.getConfig().getLockManager(); try { // hack since kernel 1.0 unregisters datasources after recovery Class clazz = Class.forName( LUCENE_FULLTEXT_DS_CLASS ); if ( xaDsMgr.getXaDataSource( "lucene-fulltext" ) == null ) { Map<Object, Object> params = new HashMap<Object, Object>(); params.put( "dir", dstDir + "/lucene-fulltext" ); txModule.registerDataSource( "lucene-fulltext", clazz.getName(), "162373".getBytes(), params ); } clazz = Class.forName( LUCENE_DS_CLASS ); if ( xaDsMgr.getXaDataSource( "lucene" ) == null ) { Map<Object, Object> params = new HashMap<Object, Object>(); params.put( "dir", dstDir + "/lucene" ); txModule.registerDataSource( "lucene", clazz.getName(), "262374".getBytes(), params ); } } catch ( ClassNotFoundException e ) { // ok not on classpath } } }