Подтвердить что ты не робот

Не удалось создать составной индекс, застрявший в INSTALLED

Я не могу создать индекс. Мой код Гремлина выглядит следующим образом:

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

Вскоре после получения двух ошибок:

18:04:57 ERROR com.thinkaurelius.titan.graphdb.database.management.ManagementLogger - Evicted [1 @0a00009d2537-ip-10-0-0-1572] из кеша, но слишком долго ждать завершения транзакций. Предупреждение о старом транзакции: [standardtitantx [0x6549ce71]] 18:04:57 ERROR com.thinkaurelius.titan.graphdb.database.management.ManagementLogger - Evicted [1 @0a00009d2537-ip-10-0-0-1572] из кеша, но слишком долго ждать завершения транзакций. Предупреждение о старом транзакции: [standardtitantx [0x2a2815cc], standardtitantx [0x025dc2c0]]

Состояние индекса застревает в INSTALLED:

usernameIndex.getIndexStatus(usernameProperty)
==>INSTALLED

Я прочитал, что неудавшийся экземпляр может вызвать проблему, но проверка запущенных экземпляров показывает только одно:

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

Я также попытался выпустить действие REGISTER_INDEX, которое также выдается из кэша транзакций с аналогичным сообщением об ошибке:

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

Я также пытался перезапустить сервер несколько раз.

Кажется, что процесс регистрации - это просто тайм-аут, вызывающий "выселение" из кэша транзакций. Я ждал 48 часов, чтобы убедиться, что это не медленный процесс. Нормальные чтения, записи и связанные с ними коммиты Titan действительно работают правильно, я просто не могу создать этот индекс. Я застрял, есть ли что-то еще, что я могу попробовать? Есть ли способ продлить время ожидания этой транзакции?

Я запускаю Titan 1.0.0 с использованием бэкэнда DynamoDB (настройка с использованием AWS Template Template).

EDIT: Вот полная команда, которую я вставляю в Гремлин с добавлением шага awaitGraphStatus, предложенного @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();

Это приводит к следующей ошибке:

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)     at 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 ERROR 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();
graph.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);

== > ВКЛЮЧЕНО

4b9b3361

Ответ 1

Если вы используете несколько экземпляров Titan, вы должны знать, что они должны координировать работу до того, как индекс станет доступным.

Кроме того, существуют различные тонкости управления транзакциями и при каких обстоятельствах транзакции будут оставлены открытыми; Я полагаю, что Titan 1.0.0 не имеет последней версии от TinkerPop в этом отношении. Вы пытались создать индекс сразу после загрузки?

Наконец, процесс создания индекса отличается в зависимости от того, были ли ранее использованы индексы свойств. Вы пытаетесь индексировать новые ключи или существующие?

Ответ 2

Вам нужно подождать, пока Titan и DynamoDB не смогут зарегистрировать индекс. Вы можете сделать это:

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

Тайм-аут по умолчанию обычно не достаточно длинный, поэтому вы можете увеличить его до 10 минут, обычно это трюк с поддержкой Dynamo.

Только когда индекс находится в состоянии REGISTERED, вы можете выполнить переопределение. Когда вы перевернете, вам нужно подождать, пока он не будет включен. повторным использованием примера кода выше и изменением состояния на ENABLED.

Для получения дополнительной информации см. docs.

Изменить

Позвольте мне разделить код, который работает со мной на Berkeley и Dynamo DB backends все время.

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

Из ошибки, которую я видел, похоже, что Titan не смог получить индекс, что означает, что вы ожидаете индекса, который даже не определен. Посмотрите на строку, которая вызывает ошибку здесь.

Убедитесь, что вы передаете правильное имя индекса в awaitGraphIndexStatus.