Skip to content

Commit 412fb07

Browse files
authored
Merge pull request JanusGraph#445 from smcquillan/titanIdStoreIssue418
Failure to correctly set ids.store-name=titan_ids can corrupt a Titan Cassandra Issue JanusGraph#418
2 parents 7d5779a + f450292 commit 412fb07

File tree

6 files changed

+90
-16
lines changed

6 files changed

+90
-16
lines changed

docs/advanced.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,5 @@ include::serializer.txt[]
2020
include::hadoop.txt[]
2121

2222
include::monitoring.txt[]
23+
24+
include::migrating.txt[]

docs/migrating.txt

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
[[migrating-titan]]
2+
== Migrating from Titan
3+
4+
This page describes some of the Configuration options that JanusGraph provides to allow migration of data from a data store which had previously been created by Titan.
5+
6+
=== Configuration
7+
8+
When connecting to an existing Titan data store the `graph.titan-version` property should be set to the Titan version used to create that store.
9+
10+
[source, properties]
11+
----
12+
graph.titan-version=1.0.0
13+
----
14+
15+
The ID store name in JanusGraph is configurable via the `ids.store-name` property whereas in Titan it was a constant. If the `graph.titan-version` has been set, as in the example above, then you do **not** need to explicitly set this value as it will default to `titan_ids`.
16+
17+
=== Cassandra
18+
19+
The default keyspace used by Titan was `titan` and in order to reuse that existing keyspace the `storage.cassandra.keyspace` property needs to be set accordingly.
20+
21+
[source, properties]
22+
----
23+
graph.titan-version=1.0.0
24+
storage.cassandra.keyspace=titan
25+
----
26+
27+
These configuration options allow JanusGraph to read data from a Cassandra database which had previously been created by Titan. However, once JanusGraph writes back to that database it will register additional serializers which mean that it will no longer be compatible with Titan. Users are therefore encouraged to backup the data in Casssandra before attempting to use it with the JanusGraph release.
28+
29+
=== HBase
30+
31+
The name of the table used by Titan was `titan` and in order to reuse that existing table the `storage.hbase.table` property needs to be set accordingly.
32+
33+
[source, properties]
34+
----
35+
graph.titan-version=1.0.0
36+
storage.hbase.table=titan
37+
----
38+
39+
These configuration options allow JanusGraph to read data from an HBase database which had previously been created by Titan. However, once JanusGraph writes back to that database it will register additional serializers which mean that it will no longer be compatible with Titan. Users are therefore encouraged to backup the data in HBase before attempting to use it with the JanusGraph release.
40+
41+
=== BerkeleyDB
42+
43+
The BerkeleyDB version has been updated, and it contains changes to the file format stored on disk. This file format change is forward compatible with previous versions of BerkeleyDB, so existing graph data stored with Titan can be read in. However, once the data has been read in with the newer version of BerkeleyDB, those files can no longer be read by the older version. Users are encouraged to backup the BerkeleyDB storage directory before attempting to use it with the JanusGraph release.

docs/upgrade.txt

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,7 @@ your code and configuration accordingly:
1919
duplicate a word, e.g., `TitanGraph` is simply `JanusGraph` rather than
2020
`JanusGraphGraph`
2121

22-
*IMPORTANT* If you are pointing JanusGraph at an existing Titan database you will need to
23-
set the `ids.store-name` property to `titan_ids` in your JanusGraph properties file.
24-
Failure to do this could result in id allocation issues.
25-
See https://github.com/JanusGraph/janusgraph/issues/228[228] for more details.
26-
27-
The BerkeleyDB version has been updated, and it contains changes to the file
28-
format stored on disk. This file format change is forward compatible with
29-
previous versions of BerkeleyDB, so existing graph data stored with Titan
30-
can be read in. However, once the data has been read in with the newer version
31-
of BerkeleyDB, those files can no longer be read by the older version. Users
32-
are encouraged to backup the BerkeleyDB storage directory before attempting to
33-
use it with the JanusGraph release.
22+
*IMPORTANT* If you are pointing JanusGraph at an existing Titan database you will
23+
need to set the `graph.titan-version` property. For more information on how to
24+
configure JanusGraph to read data which had previously been written by Titan
25+
refer to <<migrating-titan>>.

janusgraph-cassandra/src/test/java/org/janusgraph/graphdb/CassandraGraphTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,12 @@ public void testTitanGraphBackwardCompatibility() {
128128
wc.get(ConfigElement.getPath(GraphDatabaseConfiguration.TITAN_COMPATIBLE_VERSIONS),
129129
GraphDatabaseConfiguration.TITAN_COMPATIBLE_VERSIONS.getDatatype())
130130
));
131-
131+
132+
wc.set(ConfigElement.getPath(GraphDatabaseConfiguration.IDS_STORE_NAME), JanusGraphConstants.TITAN_ID_STORE_NAME);
133+
assertTrue(JanusGraphConstants.TITAN_ID_STORE_NAME.equals(
134+
wc.get(ConfigElement.getPath(GraphDatabaseConfiguration.IDS_STORE_NAME),
135+
GraphDatabaseConfiguration.IDS_STORE_NAME.getDatatype())
136+
));
132137
graph = (StandardJanusGraph) JanusGraphFactory.open(wc);
133138
}
134139
}

janusgraph-core/src/main/java/org/janusgraph/graphdb/configuration/GraphDatabaseConfiguration.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ public boolean apply(@Nullable Integer integer) {
724724
public static final ConfigOption<String> IDS_STORE_NAME = new ConfigOption<>(IDS_NS, "store-name",
725725
"The name of the ID KCVStore. IDS_STORE_NAME is meant to be used only for backward compatibility with Titan, " +
726726
"and should not be used explicitly in normal operations or in new graphs.",
727-
ConfigOption.Type.GLOBAL_OFFLINE, "janusgraph_ids");
727+
ConfigOption.Type.GLOBAL_OFFLINE, JanusGraphConstants.JANUSGRAPH_ID_STORE_NAME);
728728

729729

730730
/**
@@ -1402,7 +1402,7 @@ public GraphDatabaseConfiguration(ReadConfiguration localConfig) {
14021402
throw new JanusGraphException(String.format(INCOMPATIBLE_VERSION_EXCEPTION, version, JanusGraphConstants.VERSION));
14031403
}
14041404
} catch (IllegalStateException ise) {
1405-
checkBackwardCompatibilityWithTitan(globalWrite);
1405+
checkBackwardCompatibilityWithTitan(globalWrite, localbc, kcvsConfig, overwrite);
14061406
}
14071407

14081408
final boolean managedOverridesAllowed;
@@ -1426,6 +1426,12 @@ else if (globalWrite.has(ALLOW_STALE_CONFIG))
14261426
// Get the storage backend's setting and compare with localValue
14271427
Object storeValue = globalWrite.get(opt, pid.umbrellaElements);
14281428

1429+
// Check if the value is to be overwritten
1430+
if (overwrite.has(opt, pid.umbrellaElements))
1431+
{
1432+
storeValue = overwrite.get(opt, pid.umbrellaElements);
1433+
}
1434+
14291435
// Most validation predicate impls disallow null, but we can't assume that here
14301436
final boolean match;
14311437
if (null != localValue && null != storeValue) {
@@ -1493,12 +1499,28 @@ else if (globalWrite.has(ALLOW_STALE_CONFIG))
14931499
preLoadConfiguration();
14941500
}
14951501

1496-
private void checkBackwardCompatibilityWithTitan(ModifiableConfiguration globalWrite) {
1502+
private void checkBackwardCompatibilityWithTitan(ModifiableConfiguration globalWrite, BasicConfiguration localbc, KCVSConfiguration kcvsConfig, ModifiableConfiguration overwrite) {
14971503
String version = globalWrite.get(TITAN_COMPATIBLE_VERSIONS);
14981504
Preconditions.checkArgument(version!=null,"JanusGraph version nor Titan compatibility have not been initialized");
14991505
if (!JanusGraphConstants.TITAN_COMPATIBLE_VERSIONS.contains(version)) {
15001506
throw new JanusGraphException(String.format(INCOMPATIBLE_VERSION_EXCEPTION, version, JanusGraphConstants.VERSION));
15011507
}
1508+
1509+
// When connecting to a store created by Titan the ID store name will not be in the
1510+
// global configuration. To ensure compatibility override the default to titan_ids.
1511+
boolean localTitanConfigured = localbc.get(TITAN_COMPATIBLE_VERSIONS) != null;
1512+
boolean localIdStoreIsDefault = JanusGraphConstants.JANUSGRAPH_ID_STORE_NAME.equals(localbc.get(IDS_STORE_NAME));
1513+
1514+
if (localTitanConfigured == true) {
1515+
boolean usingTitanIdStore = localIdStoreIsDefault == true || JanusGraphConstants.TITAN_ID_STORE_NAME.equals(localbc.get(IDS_STORE_NAME));
1516+
boolean existingKeyStore = kcvsConfig.get(IDS_STORE_NAME.getName(), IDS_STORE_NAME.getDatatype()) != null;
1517+
1518+
Preconditions.checkArgument(usingTitanIdStore,"ID store for Titan compatibility has not been initialized to: " + JanusGraphConstants.TITAN_ID_STORE_NAME);
1519+
if (existingKeyStore == false) {
1520+
log.info("Setting {} to {} for Titan compatibility", IDS_STORE_NAME.getName(), JanusGraphConstants.TITAN_ID_STORE_NAME);
1521+
overwrite.set(IDS_STORE_NAME, JanusGraphConstants.TITAN_ID_STORE_NAME);
1522+
}
1523+
}
15021524
}
15031525

15041526
private static Map<ConfigElement.PathIdentifier, Object> getGlobalSubset(Map<ConfigElement.PathIdentifier, Object> m) {

janusgraph-core/src/main/java/org/janusgraph/graphdb/configuration/JanusGraphConstants.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ public class JanusGraphConstants {
5050
*/
5151
public static final List<String> TITAN_COMPATIBLE_VERSIONS;
5252

53+
/**
54+
* Name of the ids.store-name used by JanusGraph which is configurable
55+
*/
56+
public static final String JANUSGRAPH_ID_STORE_NAME = "janusgraph_ids";
57+
58+
/**
59+
* Past name of the ids.store-name used by Titan Graph but which was not configurable
60+
*/
61+
public static final String TITAN_ID_STORE_NAME = "titan_ids";
62+
5363
static {
5464

5565
/*

0 commit comments

Comments
 (0)