【问题标题】:Determine Neo4j database version确定 Neo4j 数据库版本
【发布时间】:2018-05-02 21:11:02
【问题描述】:

Neo4j Java API 在我调用时自动将过时的数据库更新到当前版本

new GraphDatabaseFactory().newEmbeddedDatabase(File storeDir)

我想在此之前检查数据库的版本。有没有办法用 Java API 做到这一点?或者:数据库版本存储在哪里,以便我可以手动读取?

【问题讨论】:

    标签: java neo4j neo4j-java-api


    【解决方案1】:

    发布版本

    我深入研究了 Neo4j API 源并找到了答案。 Neo4j 从logs 目录下的debug.log 文件中读取之前的版本。每当启动数据库时,版本都会作为Kernel version: (this is where you'll find the version) 打印到日志文件中。例如,它可能看起来像这样:

    2017-11-21 06:21:43.460+0000 INFO [o.n.k.i.DiagnosticsManager] Kernel version: 3.3.0,5b700972242a5ec3e0140261120f2845fb3520ad
    

    你可以用 Neo4j 的方式读出 debug.log:

    import java.io.File;
    
    import org.neo4j.io.fs.DefaultFileSystemAbstraction;
    import org.neo4j.io.fs.FileSystemAbstraction;
    import org.neo4j.kernel.impl.transaction.log.LogTailScanner;
    import org.neo4j.kernel.impl.transaction.log.PhysicalLogFile;
    import org.neo4j.kernel.impl.transaction.log.PhysicalLogFiles;
    import org.neo4j.kernel.impl.transaction.log.ReadableClosablePositionAwareChannel;
    import org.neo4j.kernel.impl.transaction.log.entry.LogEntryReader;
    import org.neo4j.kernel.impl.transaction.log.entry.LogEntryVersion;
    import org.neo4j.kernel.impl.transaction.log.entry.VersionAwareLogEntryReader;
    
    public class Neo4jVersionChecker {
    
        //Note that this method needs the store directory NOT the debug.log file
        public static String getNeo4jVersion(File storeDir) {   
            FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction();
            final PhysicalLogFiles logFiles = new PhysicalLogFiles( storeDir, PhysicalLogFile.DEFAULT_NAME, fileSystem );
            final LogEntryReader<ReadableClosablePositionAwareChannel> logEntryReader = new VersionAwareLogEntryReader<>();
            LogTailScanner tailScanner = new LogTailScanner( logFiles, fileSystem, logEntryReader );
    
            LogEntryVersion version = tailScanner.getTailInformation().latestLogEntryVersion;
    
            if(version!=null) {
                    return version.toString();
            } else {
                    return null;
            }
        }
    
    }
    

    上述方法返回V3_0_10debug.log,其最新的Kernel version 条目是上述条目。

    不幸的是,Neo4j 的方式不是很精确。如您所见,debug.log 中的 Kernel version3.3.0 开头,但 Neo 方法说它是 V3_0_10。我假设这与 Neo 在内部处理版本的方式有关。

    但既然我们现在知道 Neo4j 是如何获取版本的,我们可以用更准确的方式做同样的事情:

    import java.io.File;
    import java.io.IOException;
    import java.nio.charset.StandardCharsets;
    
    import org.apache.commons.io.input.ReversedLinesFileReader;
    
    public class VersionChecker {
    
        public static String getVersion(File storeDir) {
            File debugLog = new File(storeDir, "logs" + File.separator + "debug.log");
            if(debugLog.exists()) {
                try {
                    //The ReversedLinesFileReader reads the last line of a file first and so on
                    ReversedLinesFileReader reader = new ReversedLinesFileReader(debugLog, StandardCharsets.UTF_8);
                    //Read last line
                    String line = reader.readLine();
                    while(line!=null) {
                        //Line can't be null at this point
    
                        if(line.contains("Kernel version: ")) {
                            //This line contains the version
                            line = line.substring(line.indexOf("Kernel version: ")).substring(16);  //get rid of everything except the version
                            line = line.split(",")[0];  //get rid of the second part of the Kernel version that we don't want
                            return line;
                        }
    
                        //Next line
                        line = reader.readLine();
                    }
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
    }
    

    上面的方法会返回3.3.0

    商店版本

    当然,这两种方法只有在有 debug.log 文件时才有效。并非所有以前的 Neo4j 版本都有它们。只要存储目录包含neostore 文件,您就可以读出store version,这不如读出发布版本好,但至少它是一些东西。下面是它的工作原理:

    有一个名为 StoreVersionCheck 的 Neo4j 类,其中包含一个非常方便的方法,名为 getVersion(File neostoreFile)。不幸的是,我们需要一个名为PageCache 的实例来初始化StoreVersionCheck 的实例。我们可以创建一个PageCache,这就是我们要做的。

    import java.io.File;
    import java.io.IOException;
    import java.util.Optional;
    import java.util.function.Consumer;
    
    import org.neo4j.graphdb.factory.GraphDatabaseSettings;
    import org.neo4j.io.fs.DefaultFileSystemAbstraction;
    import org.neo4j.io.fs.FileSystemAbstraction;
    import org.neo4j.io.pagecache.PageCache;
    import org.neo4j.kernel.configuration.Config;
    import org.neo4j.kernel.impl.factory.GraphDatabaseFacadeFactory;
    import org.neo4j.kernel.impl.pagecache.ConfiguringPageCacheFactory;
    import org.neo4j.kernel.impl.storemigration.StoreVersionCheck;
    import org.neo4j.kernel.impl.util.Neo4jJobScheduler;
    import org.neo4j.kernel.monitoring.Monitors;
    import org.neo4j.kernel.monitoring.tracing.Tracers;
    import org.neo4j.logging.Log;
    import org.neo4j.logging.Logger;
    import org.neo4j.scheduler.JobScheduler;
    
    public class StoreVersionChecker {
    
        public static String getStoreVersion(File storeDir) {
            File storeFile = new File(storeDir, "neostore");
            if(!storeFile.exists()) {
                return null;
            }
            StoreVersionCheck check = new StoreVersionCheck(buildPageCache());
            try {
                Optional<String> version = check.getVersion(storeFile);
                if(version.isPresent()) {
                    return version.get();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        private static PageCache buildPageCache() {
            FileSystemAbstraction fileSystem = new DefaultFileSystemAbstraction();
            Config config = Config.defaults();
            Log pageCacheLog = new DummyLog();
            String desiredImplementationName = config.get( GraphDatabaseFacadeFactory.Configuration.tracer );
            Monitors monitors = new Monitors();
            JobScheduler jobScheduler = new Neo4jJobScheduler();
            Tracers tracers = new Tracers( desiredImplementationName, new DummyLog(), monitors, jobScheduler );
            ConfiguringPageCacheFactory pageCacheFactory = new ConfiguringPageCacheFactory(fileSystem, config, tracers.pageCacheTracer, tracers.pageCursorTracerSupplier, pageCacheLog );
            PageCache pageCache = pageCacheFactory.getOrCreatePageCache();
    
            if ( config.get( GraphDatabaseSettings.dump_configuration ) )
            {
                pageCacheFactory.dumpConfiguration();
            }
            return pageCache;
        }
    
        //We need this so we can give the Tracers a Log
        private static class DummyLog implements Log {
    
            @Override
            public boolean isDebugEnabled() {return false;}
    
            @Override
            public Logger debugLogger() {return null;}
    
            @Override
            public void debug(String message) {}
    
            @Override
            public void debug(String message, Throwable throwable) {}
    
            @Override
            public void debug(String format, Object... arguments) {}
    
            @Override
            public Logger infoLogger() {return null;}
    
            @Override
            public void info(String message) {}
    
            @Override
            public void info(String message, Throwable throwable) {}
    
            @Override
            public void info(String format, Object... arguments) {}
    
            @Override
            public Logger warnLogger() {return null;}
    
            @Override
            public void warn(String message) {}
    
            @Override
            public void warn(String message, Throwable throwable) {}
    
            @Override
            public void warn(String format, Object... arguments) {}
    
            @Override
            public Logger errorLogger() {return null;}
    
            @Override
            public void error(String message) {}
    
            @Override
            public void error(String message, Throwable throwable) {}
    
            @Override
            public void error(String format, Object... arguments) {}
    
            @Override
            public void bulk(Consumer<Log> consumer) {}
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-03-18
      • 2011-11-21
      • 2013-06-12
      • 2014-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多