知识库

查询以终止耗时超过 X 秒且不包含特定关键字的事务

在 Neo4j 中,我们目前有一个称为 execution guard 的配置属性

dbms.transaction.timeout=30s

它可以自动设置,以终止运行时间超过 “x” 秒的事务(x 等于 dbms.transaction.timeout 的设置值,本例为 30 秒)。然而,这仅在全局层面生效,无法针对特定用户或查询类型进行控制。

因此,为了实现此功能,可以编写一个小脚本并安排其运行,以终止运行时间超过 30 秒的查询。该脚本可以通过 cypher-shell 触发。用于终止不属于 LOAD CSV 且运行时间超过 30 秒的事务的查询可以写成如下:

call dbms.listQueries() yield query, elapsedTimeMillis, queryId, username
where  NOT query contains toLower(“LOAD")
and elapsedTimeMillis >30000
with query, collect(queryId) as q
call dbms.killQueries(q) yield queryId
return query, queryId

用于终止执行查询的用户不是 “neo4j” 且运行时间超过 30 秒的事务的查询

call dbms.listQueries() yield query, elapsedTimeMillis, queryId, username
where  NOT username contains toLower("neo4j")
and elapsedTimeMillis >30000
with query, collect(queryId) as q
call dbms.killQueries(q) yield queryId
return query, queryId

您可以根据特定查询参数或不应被终止的特定用户来修改上述查询。

注意:此仅适用于 Neo4j 3.1 及以上版本!

到目前为止,一切正常。如果我们只执行一次上述查询,它只会检查一次长期运行的查询。至今没有任何重复。为了实现自动化,我们可以使用 apoc。

CALL apoc.periodic.repeat("kill long-running queries", "
    call dbms.listQueries() yield query, elapsedTimeMillis, queryId, username
    where NOT username contains toLower("neo4j")
    and elapsedTimeMillis >30000
    with query, collect(queryId) as q
    call dbms.killQueries(q) yield queryId
    return query, queryId
", 10)

在这种情况下,用于检查长期运行查询的查询将在我们执行 apoc 命令的实例和数据库上每十秒执行一次。请根据需要调整时间参数。

如果您想手动取消作业,可以使用

CALL apoc.periodic.cancel("kill long-running queries")

请注意,通过 apoc.periodic.repeat 添加的这些作业在数据库重启后不会保留。因此,如果我们想永久安装它,可以使用 apoc 的初始化器(/labs/apoc/4.4/operational/init-script/

在您的 conf/apoc.conf 文件中添加以下行(另见 /labs/apoc/4.4/config/

apoc.initializer.cypher.1=CALL apoc.periodic.repeat("kill long-running queries", "CALL dbms.listQueries() yield query, elapsedTimeMillis, queryId, username WHERE username contains toLower('neo4j') AND elapsedTimeMillis > 10000 WITH query, collect(queryId) as q CALL dbms.killQueries(q) yield queryId return query, queryId", 10)

请注意,这是在实例级别设置的,适用于所有数据库。

您可能想在磁盘上使用专用的 cypher 文件来存储查询,这样就不会在配置文件中出现复杂的查询。以下是一个示例:/labs/apoc/4.4/operational/init-script/

© . This site is unofficial and not affiliated with Neo4j, Inc.