2016-03-09 19 views
0

我在32GB內存的服務器上運行Neo4J,社區版v2.3.2,配置爲使用8GB作爲pagecache,18GB作爲堆,另一個6GB作爲OS我對Neo4J的理解,這主要用於索引文件的頁面緩存)。刪除多個節點時,「RelationshipRecord not in use」

我的數據庫有250M左右的個人節點和1B的關係,我運行下面的查詢,刪除一些節點:

MATCH (p:Person) 
WHERE NOT HAS (p.fullname) 
OPTIONAL MATCH (prev:Person {fullname: p.fname +' '+p.lname}) 
WHERE prev IS NOT NULL 
WITH p LIMIT 100000 
DETACH DELETE p 

我已經打了很多與此得到它實際上沒有工作佔用所有內存並導致服務器崩潰。我必須說,我有點失望,我一次只能刪除100K節點。預計有幾百萬,但這可能是一個不同的問題。

我不斷收到以下錯誤:

ERROR (-v for expanded information): 
     TransactionFailureException: Transaction was marked as successful, but unable to commit transaction so rolled back. 
org.neo4j.graphdb.TransactionFailureException: Transaction was marked as successful, but unable to commit transaction so rolled back. 
    at org.neo4j.kernel.TopLevelTransaction.close(TopLevelTransaction.java:121) 
    at org.neo4j.shell.kernel.apps.TransactionProvidingApp.execute(TransactionProvidingApp.java:263) 
    at ... 

Caused by: org.neo4j.kernel.impl.store.InvalidRecordException: RelationshipRecord[250054319] not in use 
    at org.neo4j.kernel.impl.store.RelationshipStore.fillRecord(RelationshipStore.java:135) 
    at org.neo4j.kernel.impl.store.RelationshipStore.getRecord(RelationshipStore.java:93) 
    at org.neo4j.kernel.impl.store.RelationshipStore.getRecord(RelationshipStore.java:88) 
    at org.neo4j.kernel.impl.transaction.state.Loaders$3.load(Loaders.java:139) 
    at ... 

我找不到與250054319 ID任何關係。我可以找到具有該ID的節點,但我不確定它與我的查詢有什麼關係,因爲它不符合我的初始條件(NOT HAS p.fullname)。

我很困惑。有誰知道這個錯誤?這是什麼意思,我該怎麼做來解決它?

也許有用的說,我將這個刪除作爲一次性任務運行,因此可以開放創造性地使這個查詢運行。

另一件可能有用的事情是,即使在用LIMIT子句打破查詢之後,我仍然有很多內存問題。服務器掛起,崩潰或進入GC循環,直到找到允許它工作的配置,直到我開始遇到此問題。

謝謝!

+0

將是巨大的,如果你能包括的問題也完全堆棧跟蹤 –

回答

0

我有2個評論:

  1. 您的查詢是沒有做你的原意。它將刪除所有Person節點,該節點不具有fullname屬性,即使沒有匹配的prev節點。這是因爲OPTIONAL MATCH子句(和後續的WHERE)不必匹配以便查詢進入DELETE子句。

  2. 您可能會收到很多錯誤,因爲DETACH DELETE p將嘗試刪除每個p的所有關係,即使這些關係中的任何關係已被刪除。例如,如果兩個人之間有關係,那麼嘗試第二個人會導致錯誤。

這裏是一個查詢,可以解決這兩個問題:

MATCH (p:Person) 
WHERE NOT HAS (p.fullname) 
OPTIONAL MATCH (prev:Person { fullname: p.fname +' '+p.lname }) 
WITH CASE WHEN prev IS NOT NULL THEN p ELSE NULL END AS delP 
LIMIT 100000 
OPTIONAL MATCH (delP)-[r]-() 
WITH COLLECT(delP) AS ps, COLLECT(DISTINCT r) AS rels 
FOREACH (r IN rels | DELETE r) 
FOREACH (p IN ps | DELETE p)