TitanDB Index not changing state
Asked Answered
C

2

5

I wanted to drop an existing index and followed the steps in the documentation so far. I have no separate indexing backend configured for now. However, when I get to the step where you have to wait for the index status to change using m.awaitGraphIndexStatus it waits forever for the change and times out with the following error:

GraphIndexStatusReport[success=false, indexName='usernameComposite', targetStatus=DISABLED, notConverged={username=INSTALLED}, converged={}, elapsed=PT1M0.092S]

The very same happens when I try to create a new one. Any ideas what could cause this?

I'm creating indizes using the following code snippet:

graph.tx().rollback()
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('username')
mgmt.buildIndex('username-composite', Vertex.class).addKey(name).unique().buildCompositeIndex()
mgmt.commit()
mgmt.awaitGraphIndexStatus(graph, 'username-composite').call()
Cerebrovascular answered 6/1, 2016 at 21:44 Comment(2)
Could you post the steps/code you use to change the Index ?Vogel
I edited my post above.Cerebrovascular
T
4

As Dan describes in this gremlin-users post, you need to make sure that there are no open transactions against the graph. Keep in mind this includes transactions from other connections, in case you have multiple clients or threads open against the graph.

You can check for open transactions with graph.getOpenTransactions() defined in StandardTitanGraph which returns null if there are none. If there are open transactions, you would need to either commit() or rollback() them all.

Here's a snippet that I have used successfully in the Gremlin Console.

// Disable the index. Once the able is DISABLED, it cannot be re-enabled again!
// Instead, you could build a new index with the same properties.
future = null
if (graph.getOpenTransactions()) graph.tx().rollback()
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
nameIndex = mgmt.getGraphIndex('nameIndex')
nameIndexStatus = nameIndex.getIndexStatus(name) // must be ENABLED, INSTALLED, or REGISTERED
if (nameIndexStatus == SchemaStatus.INSTALLED || nameIndexStatus == SchemaStatus.ENABLED) future = mgmt.updateIndex(nameIndex, SchemaAction.DISABLE_INDEX)
nameIndexStatus = nameIndex.getIndexStatus(name) // should be INSTALLED here
mgmt.commit()

// Block until disabling index is complete (ENABLED -> INSTALLED -> DISABLED), no metrics are reported (null)
if (graph.getOpenTransactions()) graph.tx().rollback()
t = System.currentTimeMillis(); metrics = future.get(); 'disabled in '+(System.currentTimeMillis()-t)+' ms'
if (nameIndexStatus == SchemaStatus.ENABLED) mgmt.awaitGraphIndexStatus(graph, 'nameIndex').status(SchemaStatus.INSTALLED).call()
if (nameIndexStatus == SchemaStatus.INSTALLED) mgmt.awaitGraphIndexStatus(graph, 'nameIndex').status(SchemaStatus.DISABLED).call()
Tristram answered 10/1, 2016 at 14:13 Comment(3)
So in other words, if I'm running multiple gremlin servers to support a lot of concurrent transactions I need to take them down all together before doing maintenance on any indizes, correct?Cerebrovascular
One more follow up question: Would I also need to stop all the machines if I would create the property in the same management transaction I'm using to create the index?Cerebrovascular
If you create a new property key and an index on it in the same management transaction, I think the index should be enabled immediately after the commit.Tristram
P
6

It also happens when I try to create a new one. I use script to create a new index under a property with some data. The script comes from Titan 1.0.0 Document

graph.tx().rollback() //Never create new indexes while a transaction is active
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
age = mgmt.getPropertyKey('age')
mgmt.buildIndex('byNameComposite', Vertex.class).addKey(name).buildCompositeIndex()
mgmt.buildIndex('byNameAndAgeComposite', Vertex.class).addKey(name).addKey(age).buildCompositeIndex()
mgmt.commit()
//Wait for the index to become available
mgmt.awaitGraphIndexStatus(graph, 'byNameComposite').call()
mgmt.awaitGraphIndexStatus(graph, 'byNameAndAgeComposite').call()
//Reindex the existing data
mgmt = graph.openManagement()
mgmt.updateIndex(mgmt.getGraphIndex("byNameComposite"), SchemaAction.REINDEX).get()
mgmt.updateIndex(mgmt.getGraphIndex("byNameAndAgeComposite"), SchemaAction.REINDEX).get()
mgmt.commit()

After several experiments, I found it's graph.tx().rollback() not work properly.

gremlin> :> graph.getOpenTransactions()
==>standardtitantx[0x1e14c346]
==>standardtitantx[0x7a0067f2]
==>standardtitantx[0x0de3ee40]
==>standardtitantx[0x47e19812]
==>standardtitantx[0x27b20549]
==>standardtitantx[0x0ee46d99]
gremlin> :> graph.tx().rollback()
==>null
gremlin> :> graph.getOpenTransactions()
==>standardtitantx[0x1e14c346]
==>standardtitantx[0x7a0067f2]
==>standardtitantx[0x0de3ee40]
==>standardtitantx[0x47e19812]
==>standardtitantx[0x093ac20f]
==>standardtitantx[0x27b20549]
==>standardtitantx[0x0ee46d99]

This is why I fail to create a new index. So I replace graph.tx().rollback() with

// rollback all exist transactions
int size = graph.getOpenTransactions().size();
for(i=0;i<size;i++) {graph.getOpenTransactions().getAt(0).rollback()}

It works fine now. If you use the cluster, then you need to ensure that only a instances to survive. Or you must make sure all instances's transactions in the cluster are rollback or commit. I hope this is helpful for others.

Parceling answered 9/9, 2016 at 7:12 Comment(0)
T
4

As Dan describes in this gremlin-users post, you need to make sure that there are no open transactions against the graph. Keep in mind this includes transactions from other connections, in case you have multiple clients or threads open against the graph.

You can check for open transactions with graph.getOpenTransactions() defined in StandardTitanGraph which returns null if there are none. If there are open transactions, you would need to either commit() or rollback() them all.

Here's a snippet that I have used successfully in the Gremlin Console.

// Disable the index. Once the able is DISABLED, it cannot be re-enabled again!
// Instead, you could build a new index with the same properties.
future = null
if (graph.getOpenTransactions()) graph.tx().rollback()
mgmt = graph.openManagement()
name = mgmt.getPropertyKey('name')
nameIndex = mgmt.getGraphIndex('nameIndex')
nameIndexStatus = nameIndex.getIndexStatus(name) // must be ENABLED, INSTALLED, or REGISTERED
if (nameIndexStatus == SchemaStatus.INSTALLED || nameIndexStatus == SchemaStatus.ENABLED) future = mgmt.updateIndex(nameIndex, SchemaAction.DISABLE_INDEX)
nameIndexStatus = nameIndex.getIndexStatus(name) // should be INSTALLED here
mgmt.commit()

// Block until disabling index is complete (ENABLED -> INSTALLED -> DISABLED), no metrics are reported (null)
if (graph.getOpenTransactions()) graph.tx().rollback()
t = System.currentTimeMillis(); metrics = future.get(); 'disabled in '+(System.currentTimeMillis()-t)+' ms'
if (nameIndexStatus == SchemaStatus.ENABLED) mgmt.awaitGraphIndexStatus(graph, 'nameIndex').status(SchemaStatus.INSTALLED).call()
if (nameIndexStatus == SchemaStatus.INSTALLED) mgmt.awaitGraphIndexStatus(graph, 'nameIndex').status(SchemaStatus.DISABLED).call()
Tristram answered 10/1, 2016 at 14:13 Comment(3)
So in other words, if I'm running multiple gremlin servers to support a lot of concurrent transactions I need to take them down all together before doing maintenance on any indizes, correct?Cerebrovascular
One more follow up question: Would I also need to stop all the machines if I would create the property in the same management transaction I'm using to create the index?Cerebrovascular
If you create a new property key and an index on it in the same management transaction, I think the index should be enabled immediately after the commit.Tristram

© 2022 - 2024 — McMap. All rights reserved.