无法创建复合索引,卡在 INSTALLED [英] Unable to create a composite index, stuck at INSTALLED

查看:13
本文介绍了无法创建复合索引,卡在 INSTALLED的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法创建索引.我的 Gremlin 代码如下:

usernameProperty = mgmt.getPropertyKey('username')usernameIndex = mgmt.buildIndex('byUsernameUnique', Vertex.class).addKey(usernameProperty).unique().buildCompositeIndex()mgmt.setConsistency(用户名索引,ConsistencyModifier.LOCK)mgmt.commit()

在我收到两个错误后不久:

<块引用>

18:04:57 错误 com.thinkaurelius.titan.graphdb.database.management.ManagementLogger - 从缓存中逐出 [1@0a00009d2537-ip-10-0-0-1572] 但等待交易关闭的时间过长.过时交易警报:[standardtitantx[0x6549ce71]]18:04:57 错误 com.thinkaurelius.titan.graphdb.database.management.ManagementLogger - 从缓存中驱逐 [1@0a00009d2537-ip-10-0-0-1572] 但等待交易关闭的时间过长.过时交易警报:[standardtitantx[0x2a2815cc],standardtitantx[0x025dc2c0]]

索引状态卡在INSTALLED:

usernameIndex.getIndexStatus(usernameProperty)==>已安装

我读到失败的实例可能会导致问题,但检查正在运行的实例只显示一个:

mgmt.getOpenInstances()==>0a00009d3011-ip-10-0-0-1572(当前)

我还尝试发出 REGISTER_INDEX 操作,该操作也会从事务缓存中逐出并显示类似的错误消息:

mgmt.updateIndex(usernameIndex, SchemaAction.REGISTER_INDEX).get()mgmt.commit()

我也试过多次重启服务器.

注册过程似乎只是超时,导致从事务缓存中驱逐".我已经等了 48 小时,以确保这不是一个缓慢的过程.对 Titan 的正常读取、写入和相关提交似乎工作正常,我只是无法创建此索引.我被卡住了,还有什么我可以尝试的吗?有没有办法延长该事务的超时时间?

我正在使用 DynamoDB 后端运行 Titan 1.0.0(使用 AWS 提供的设置 CloudFormation 模板).

这是我粘贴到 Gremlin 中的完整命令,并添加了 @M-T-A 建议的 awaitGraphStatus 步骤:

mgmt = graph.openManagement();usernameIndex = mgmt.getPropertyKey('usernameIndex');mgmt.buildIndex('byUsername',Vertex.class).addKey(usernameIndex).unique().buildCompositeIndex();//我在这里尝试过提交和不提交:mgmt.commit();mgmt.awaitGraphIndexStatus(graph, 'byUsername').status(SchemaStatus.REGISTERED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();

这会导致以下错误:

<块引用>

java.lang.NullPointerException在 com.thinkaurelius.titan.graphdb.database.management.GraphIndexStatusWatcher.call(GraphIndexStatusWatcher.java:52)在 com.thinkaurelius.titan.graphdb.database.management.GraphIndexStatusWatcher.call(GraphIndexStatusWatcher.java:18)在 java_util_concurrent_Callable$call.call(未知来源)在 org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)在 org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110)在 org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:114)在 groovysh_evaluate.run(groovysh_evaluate:3)在 org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:215)在 org.codehaus.groovy.tools.shell.Interpreter.evaluate(Interpreter.groovy:69)在 org.codehaus.groovy.tools.shell.Groovysh.execute(Groovysh.groovy:185)在 org.codehaus.groovy.tools.shell.Shell.leftShift(Shell.groovy:119)在 org.codehaus.groovy.tools.shell.ShellRunner.work(ShellRunner.groovy:94)

我还会注意到禁用和删除索引的例程也失败了.

mgmt = graph.openManagement()theIndex = mgmt.getGraphIndex('byUsername')mgmt.updateIndex(theIndex, SchemaAction.DISABLE_INDEX).get()mgmt.commit()mgmt.awaitGraphIndexStatus(graph, 'byUsername').status(SchemaStatus.DISABLED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();m = graph.openManagement()i = m.getGraphIndex('byUsername')m.updateIndex(i, SchemaAction.REMOVE_INDEX).get()m.commit()

<块引用>

19:26:26 错误 com.thinkaurelius.titan.graphdb.database.management.ManagementLogger - 从缓存中逐出 [1@ac1f3fa810472-ip-172-31-63-1681] 但等待交易关闭的时间过长.过时交易警报:[standardtitantx[0x2314cd97]、standardtitantx[0x39f8adc0]、standardtitantx[0x09de1b85]]

编辑 2:尝试在同一事务中创建新的属性键和索引确实有效!但这是否意味着我不能在现有的属性键上创建索引??

graph.tx().rollback();mgmt = graph.openManagement();indexName = 'byUsernameTest2';propertyKeyName = 'testPropertyName2';propertyKey = mgmt.makePropertyKey(propertyKeyName).dataType(String.class).cardinality(Cardinality.SINGLE).make();mgmt.buildIndex(indexName,Vertex.class).addKey(propertyKey).buildCompositeIndex();mgmt.commit();图.tx().commit();mgmt.awaitGraphIndexStatus(graph, indexName).status(SchemaStatus.REGISTERED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();mgmt.commit();

暂停后,结果是:

<块引用>

此管理系统实例已关闭

尝试获取新索引会导致:

mgmt = graph.openManagement();index = mgmt.getGraphIndex('byUsernameTest2');propkey = mgmt.getPropertyKey('testPropertyName2');index.getIndexStatus(propkey);

<块引用>

==>已启用

解决方案

需要等待 Titan 和 DynamoDB 注册索引.你可以这样做:

ManagementSystem.awaitGraphIndexStatus(graph, propertyKeyIndexName).status(SchemaStatus.REGISTERED).timeout(10, java.time.temporal.ChronoUnit.MINUTES)//将超时设置为 10 分钟.称呼();

默认超时时间通常不够长,因此您可以将其增加到 10 分钟,这通常在 Dynamo 支持的情况下可以解决问题.

只有当索引处于 REGISTERED 状态时,您才能执行重新索引.重新索引完成后,您需要等到它启用.通过重用上面的代码示例并将状态更改为 ENABLED.

有关详细信息,请参阅 文档.

编辑

让我一直分享在 Berkeley 和 Dynamo DB 后端上与我一起工作的代码.

 graph.tx().rollback();//当事务处于活动状态时,不要创建新索引TitanManagement mgmt=graph.openManagement();PropertyKey propertyKey=getOrCreatePropertyKeyIfNotExist(mgmt, propertyKeyName);String indexName = makePropertyKeyIndexName(propertyKey);if (mgmt.getGraphIndex(indexName)==null) {mgmt.buildIndex(indexName, Vertex.class).addKey(propertyKey).buildCompositeIndex();mgmt.commit();//你必须提交 mgmt图.tx().commit();//并提交事务ManagementSystem.awaitGraphIndexStatus(graph, indexName).status(SchemaStatus.REGISTERED).call();}else {//已经定义.mgmt.rollback();graph.tx().rollback();}私有静态 PropertyKey getOrCreatePropertyKeyIfNotExist(TitanManagement mgmt, String s) {PropertyKey key = mgmt.getPropertyKey(s);如果(键!= null)返回键;别的return mgmt.makePropertyKey(s).dataType(String.class).make();}私有静态字符串 makePropertyKeyIndexName(PropertyKey pk) {返回 pk.name() + Tokens.INDEX_SUFFIX;}

从我看到的错误来看,Titan 似乎无法获取索引,这意味着您正在等待甚至未定义的索引.查看导致错误的行 这里.

确保将正确的索引名称传递给 awaitGraphIndexStatus.

I'm unable to create an index. My Gremlin code is as follows:

usernameProperty = mgmt.getPropertyKey('username')
usernameIndex = mgmt.buildIndex('byUsernameUnique', Vertex.class).addKey(usernameProperty).unique().buildCompositeIndex()
mgmt.setConsistency(usernameIndex, ConsistencyModifier.LOCK)
mgmt.commit()

Shortly after I receive two errors:

18:04:57 ERROR com.thinkaurelius.titan.graphdb.database.management.ManagementLogger - Evicted [1@0a00009d2537-ip-10-0-0-1572] from cache but waiting too long for transactions to close. Stale transaction alert on: [standardtitantx[0x6549ce71]] 18:04:57 ERROR com.thinkaurelius.titan.graphdb.database.management.ManagementLogger - Evicted [1@0a00009d2537-ip-10-0-0-1572] from cache but waiting too long for transactions to close. Stale transaction alert on: [standardtitantx[0x2a2815cc], standardtitantx[0x025dc2c0]]

The status of the index is stuck at INSTALLED:

usernameIndex.getIndexStatus(usernameProperty)
==>INSTALLED

I read that a failed instance could cause the issue, but a check of running instances shows just one:

mgmt.getOpenInstances()
==>0a00009d3011-ip-10-0-0-1572(current)

I've also tried issuing a REGISTER_INDEX action, which also gets evicted from the transaction cache with a similar error message:

mgmt.updateIndex(usernameIndex, SchemaAction.REGISTER_INDEX).get()
mgmt.commit()

I've also tried restarting the server multiple times.

It seems like the registration process is simply timing out, causing an "eviction" from the transaction cache. I've waited 48 hours just to be sure it wasn't a slow process. Normal reads, writes, and associated commits to Titan do seem to be working correctly, I'm just not able to create this index. I'm stuck, is there something else I can try? Is there a way to extend the timeout on that transaction?

I'm running Titan 1.0.0 using a DynamoDB backend (setup with the AWS provided CloudFormation template).

EDIT: Here is the complete command I'm pasting into Gremlin with the addition of the awaitGraphStatus step suggested by @M-T-A:

mgmt = graph.openManagement();
usernameIndex = mgmt.getPropertyKey('usernameIndex');
mgmt.buildIndex('byUsername',Vertex.class).addKey(usernameIndex).unique().buildCompositeIndex();
// I have tried with and without a commit here: mgmt.commit();
mgmt.awaitGraphIndexStatus(graph, 'byUsername').status(SchemaStatus.REGISTERED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();

This results in the following error:

java.lang.NullPointerException at com.thinkaurelius.titan.graphdb.database.management.GraphIndexStatusWatcher.call(GraphIndexStatusWatcher.java:52) at com.thinkaurelius.titan.graphdb.database.management.GraphIndexStatusWatcher.call(GraphIndexStatusWatcher.java:18) at java_util_concurrent_Callable$call.call(Unknown Source) at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:110) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:114) at groovysh_evaluate.run(groovysh_evaluate:3) at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:215) at org.codehaus.groovy.tools.shell.Interpreter.evaluate(Interpreter.groovy:69) at org.codehaus.groovy.tools.shell.Groovysh.execute(Groovysh.groovy:185) at org.codehaus.groovy.tools.shell.Shell.leftShift(Shell.groovy:119) at org.codehaus.groovy.tools.shell.ShellRunner.work(ShellRunner.groovy:94)

I will also note that the routine to disable and delete an index is also failing.

mgmt = graph.openManagement()
theIndex = mgmt.getGraphIndex('byUsername')
mgmt.updateIndex(theIndex, SchemaAction.DISABLE_INDEX).get()
mgmt.commit()
mgmt.awaitGraphIndexStatus(graph, 'byUsername').status(SchemaStatus.DISABLED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();
m = graph.openManagement()
i = m.getGraphIndex('byUsername')
m.updateIndex(i, SchemaAction.REMOVE_INDEX).get()
m.commit()

19:26:26 ERROR com.thinkaurelius.titan.graphdb.database.management.ManagementLogger - Evicted [1@ac1f3fa810472-ip-172-31-63-1681] from cache but waiting too long for transactions to close. Stale transaction alert on: [standardtitantx[0x2314cd97], standardtitantx[0x39f8adc0], standardtitantx[0x09de1b85]]

EDIT 2: Attempting to create a new property key and index within the same transaction DOES WORK! But does this mean that I can't create indexes on existing property keys??

graph.tx().rollback();
mgmt = graph.openManagement();
indexName = 'byUsernameTest2';
propertyKeyName = 'testPropertyName2';
propertyKey = mgmt.makePropertyKey(propertyKeyName).dataType(String.class).cardinality(Cardinality.SINGLE).make();
mgmt.buildIndex(indexName,Vertex.class).addKey(propertyKey).buildCompositeIndex();
mgmt.commit();
graph.tx().commit();
mgmt.awaitGraphIndexStatus(graph, indexName).status(SchemaStatus.REGISTERED).timeout(10, java.time.temporal.ChronoUnit.MINUTES).call();
mgmt.commit();

After a pause, this results in:

This management system instance has been closed

Trying to fetch the new index results in:

mgmt = graph.openManagement();
index = mgmt.getGraphIndex('byUsernameTest2');
propkey = mgmt.getPropertyKey('testPropertyName2');
index.getIndexStatus(propkey);

==>ENABLED

解决方案

You need to wait for the Titan and DynamoDB to get the index registered. You could do so by:

ManagementSystem.awaitGraphIndexStatus(graph, propertyKeyIndexName)
                    .status(SchemaStatus.REGISTERED)
                    .timeout(10, java.time.temporal.ChronoUnit.MINUTES) // set timeout to 10 min
                    .call();

The default timeout is usually not long enough, so you could increase it to 10 minutes, it usually does the trick with Dynamo backened.

Only when the index is in REGISTERED state, you could perform a reindex. ONce the reindex is done, you need to wait until it's ENABLED. by reusing the code sample above and changing the state to ENABLED.

For more info, see the docs.

Edit

Let me share the code that works with me on Berkeley and Dynamo DB backends all the time.

    graph.tx().rollback(); //Never create new indexes while a transaction is active
    TitanManagement mgmt=graph.openManagement();
    PropertyKey propertyKey=getOrCreatePropertyKeyIfNotExist(mgmt, propertyKeyName);
    String indexName = makePropertyKeyIndexName(propertyKey);

    if (mgmt.getGraphIndex(indexName)==null) { 
        mgmt.buildIndex(indexName, Vertex.class).addKey(propertyKey).buildCompositeIndex();
        mgmt.commit(); // you MUST commit mgmt
        graph.tx().commit(); // and commit the transaction too
        ManagementSystem.awaitGraphIndexStatus(graph, indexName).status(SchemaStatus.REGISTERED).call();
    }else { // already defined.
        mgmt.rollback();
        graph.tx().rollback();
    }

private static PropertyKey getOrCreatePropertyKeyIfNotExist(TitanManagement mgmt, String s) {
    PropertyKey key = mgmt.getPropertyKey(s);
    if (key != null)
        return key;
    else
        return mgmt.makePropertyKey(s).dataType(String.class).make();
}

private static String makePropertyKeyIndexName(PropertyKey pk) {
    return pk.name() + Tokens.INDEX_SUFFIX;
}

From the error that I saw, it seems like Titan couldn't get the index which means you're waiting for the index that is not even defined. Have a look at the line that causes the error here.

Make sure you're passing the right index name to the awaitGraphIndexStatus.

这篇关于无法创建复合索引,卡在 INSTALLED的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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