确定Neo4j数据库版本 [英] Determine Neo4j database version

查看:283
本文介绍了确定Neo4j数据库版本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The Neo4j Java API automatically updates outdated databases to the current version when I call

new GraphDatabaseFactory()。newEmbeddedDatabase(File storeDir)

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

I would like to check what version the database is before doing that. Is there a way to do that with the Java API? Or alternatively: Where is the database version stored so I can read it out manually?

推荐答案

发布版本

我挖掘了Neo4j API源并找到答案。 Neo4j从 logs 目录中的 debug.log 文件中读出以前的版本。每当启动数据库时,版本都会以内核版本的形式打印到日志文件中:(这是您可以找到版本的地方)。例如,它可能如下所示:

I dug into the Neo4j API source and found an answer. Neo4j reads out the previous version from the debug.log file in the logs directory. Whenever the database is started the version is printed into the log file as Kernel version: (this is where you'll find the version). For instance it could look like this:

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

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

You could read out the debug.log the Neo4j way:

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;
        }
    }

}

以上方法为 debug.log 返回 V3_0_10 ,其最新的内核版本条目是上面的那个。

The above method returns V3_0_10 for a debug.log whose latest Kernel version entry is the one above.

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

Unfortunately the Neo4j way is not very precise. As you can see the Kernel version from the debug.log starts with 3.3.0 but the Neo method says it is V3_0_10. I'm assuming this has something to do with the way Neo handles versions internally.

但是既然我们现在知道Neo4j如何获得版本,我们可以做同样的事情一个更精确的方法:

But since we now know how Neo4j gets the version, we can do the same thing in a more exact way:

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 文件,您就可以读出商店版本,这不如阅读那么好发布版本,但至少它是一些东西。所以这是如何工作的:

Of course both of these methods only work if there is a debug.log file. Not all previous Neo4j versions have them. As long as the store directory contains the neostore file you can read out the store version which is not as nice as reading out the release version but at least it is something. So here's how that works:

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

There is a Neo4j class called StoreVersionCheck which contains a very handy method called getVersion(File neostoreFile). Unfortunately we need an instance of something called a PageCache to initialize an instance of StoreVersionCheck. We can make a PageCache, so that is what we'll do.

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) {}

    }

}

这篇关于确定Neo4j数据库版本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆