OrientDB 无限期地锁定记录
OrientDB keeps locking records indefinitely
我运行在多节点分布式模式下使用 OrientDB(社区版 2.2.9)。
几分钟后,我的查询开始出现以下错误:
com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException: Timeout (1500ms) on acquiring lock on record #1010:2651. It is locked by request 3.1000 DB name="MyDatabase"
此实例中的查询如下所示:
UPDATE #1010:2651 SET name='foo';
记录保持锁定状态,在重新启动数据库之前我无法运行查询。
如果我不 运行 服务器处于分布式模式,我不会收到此错误,所以它一定与 运行 在分布式模式下运行有关。
这是我的默认分布式数据库-config.json
{
"autoDeploy": true,
"readQuorum": 1,
"writeQuorum": 1,
"executionMode": "asynchronous",
"readYourWrites": true,
"servers": {
"*": "master"
},
"clusters": {
"internal": {
},
"*": {
"servers": ["<NEW_NODE>"]
}
}
}
我在我的 orientdb-server-config.xml 中使用了以下配置:
....
<handler class="com.orientechnologies.orient.server.hazelcast.OHazelcastPlugin">
<parameters>
....
<parameter value="com.orientechnologies.orient.server.distributed.conflict.ODefaultReplicationConflictResolver" name="conflict.resolver.impl"/>
....
</parameters>
</handler>
...
通过从配置中删除“ODefaultReplicationConflictResolver”参数,锁定问题发生的频率降低了。
为什么记录会这样锁定,我该如何避免?
使用asynchronous
执行方式可能会出现这个问题。参见:Asynchronous replication mode.
您可以尝试更改执行模式或尝试在查询中添加重试。使用Java:可以在异步复制期间捕获命令事件,这要归功于OCommandSQL的以下方法:
onAsyncReplicationOk()
, 异步复制成功时捕获事件
onAsyncReplicationError()
,捕捉异步复制returns错误时的事件
创建边时出现并发修改异常时最多重试 3 次的示例:
g.command( new OCommandSQL("create edge Own from (select from User) to (select from Post)")
.onAsyncReplicationError(new OAsyncReplicationError() {
@Override
public ACTION onAsyncReplicationError(Throwable iException, int iRetry) {
System.err.println("Error, retrying...");
return iException instanceof ONeedRetryException && iRetry<=3 ? ACTION.RETRY : ACTION.IGNORE;
}
})
.onAsyncReplicationOk(new OAsyncReplicationOk() {
System.out.println("OK");
}
).execute();
或将重试添加到 SQL Batch:
begin
let upd = UPDATE #1010:2651 SET name='foo'
commit retry 100
return $upd
希望对您有所帮助。
我运行在多节点分布式模式下使用 OrientDB(社区版 2.2.9)。
几分钟后,我的查询开始出现以下错误:
com.orientechnologies.orient.server.distributed.task.ODistributedRecordLockedException: Timeout (1500ms) on acquiring lock on record #1010:2651. It is locked by request 3.1000 DB name="MyDatabase"
此实例中的查询如下所示:
UPDATE #1010:2651 SET name='foo';
记录保持锁定状态,在重新启动数据库之前我无法运行查询。
如果我不 运行 服务器处于分布式模式,我不会收到此错误,所以它一定与 运行 在分布式模式下运行有关。
这是我的默认分布式数据库-config.json
{
"autoDeploy": true,
"readQuorum": 1,
"writeQuorum": 1,
"executionMode": "asynchronous",
"readYourWrites": true,
"servers": {
"*": "master"
},
"clusters": {
"internal": {
},
"*": {
"servers": ["<NEW_NODE>"]
}
}
}
我在我的 orientdb-server-config.xml 中使用了以下配置:
....
<handler class="com.orientechnologies.orient.server.hazelcast.OHazelcastPlugin">
<parameters>
....
<parameter value="com.orientechnologies.orient.server.distributed.conflict.ODefaultReplicationConflictResolver" name="conflict.resolver.impl"/>
....
</parameters>
</handler>
...
通过从配置中删除“ODefaultReplicationConflictResolver”参数,锁定问题发生的频率降低了。
为什么记录会这样锁定,我该如何避免?
使用asynchronous
执行方式可能会出现这个问题。参见:Asynchronous replication mode.
您可以尝试更改执行模式或尝试在查询中添加重试。使用Java:可以在异步复制期间捕获命令事件,这要归功于OCommandSQL的以下方法:
onAsyncReplicationOk()
, 异步复制成功时捕获事件onAsyncReplicationError()
,捕捉异步复制returns错误时的事件
创建边时出现并发修改异常时最多重试 3 次的示例:
g.command( new OCommandSQL("create edge Own from (select from User) to (select from Post)")
.onAsyncReplicationError(new OAsyncReplicationError() {
@Override
public ACTION onAsyncReplicationError(Throwable iException, int iRetry) {
System.err.println("Error, retrying...");
return iException instanceof ONeedRetryException && iRetry<=3 ? ACTION.RETRY : ACTION.IGNORE;
}
})
.onAsyncReplicationOk(new OAsyncReplicationOk() {
System.out.println("OK");
}
).execute();
或将重试添加到 SQL Batch:
begin
let upd = UPDATE #1010:2651 SET name='foo'
commit retry 100
return $upd
希望对您有所帮助。