refactor: optimize graph lock scope in document deletion

- Move dependency analysis outside graph database lock
- Add persistence call before lock release to prevent dirty reads
This commit is contained in:
yangdx 2025-08-25 17:46:32 +08:00
parent cac8e189e7
commit 0b1b264a5d

View file

@ -2272,9 +2272,6 @@ class LightRAG:
relationships_to_delete = set() relationships_to_delete = set()
relationships_to_rebuild = {} # (src, tgt) -> remaining_chunk_ids relationships_to_rebuild = {} # (src, tgt) -> remaining_chunk_ids
# Use graph database lock to ensure atomic merges and updates
graph_db_lock = get_graph_db_lock(enable_logging=False)
async with graph_db_lock:
try: try:
# Get affected entities and relations from full_entities and full_relations storage # Get affected entities and relations from full_entities and full_relations storage
doc_entities_data = await self.full_entities.get_by_id(doc_id) doc_entities_data = await self.full_entities.get_by_id(doc_id)
@ -2287,11 +2284,9 @@ class LightRAG:
if doc_entities_data and "entity_names" in doc_entities_data: if doc_entities_data and "entity_names" in doc_entities_data:
entity_names = doc_entities_data["entity_names"] entity_names = doc_entities_data["entity_names"]
# get_nodes_batch returns dict[str, dict], need to convert to list[dict] # get_nodes_batch returns dict[str, dict], need to convert to list[dict]
nodes_dict = ( nodes_dict = await self.chunk_entity_relation_graph.get_nodes_batch(
await self.chunk_entity_relation_graph.get_nodes_batch(
entity_names entity_names
) )
)
for entity_name in entity_names: for entity_name in entity_names:
node_data = nodes_dict.get(entity_name) node_data = nodes_dict.get(entity_name)
if node_data: if node_data:
@ -2307,11 +2302,9 @@ class LightRAG:
{"src": pair[0], "tgt": pair[1]} for pair in relation_pairs {"src": pair[0], "tgt": pair[1]} for pair in relation_pairs
] ]
# get_edges_batch returns dict[tuple[str, str], dict], need to convert to list[dict] # get_edges_batch returns dict[tuple[str, str], dict], need to convert to list[dict]
edges_dict = ( edges_dict = await self.chunk_entity_relation_graph.get_edges_batch(
await self.chunk_entity_relation_graph.get_edges_batch(
edge_pairs_dicts edge_pairs_dicts
) )
)
for pair in relation_pairs: for pair in relation_pairs:
src, tgt = pair[0], pair[1] src, tgt = pair[0], pair[1]
@ -2343,9 +2336,7 @@ class LightRAG:
entities_to_rebuild[node_label] = remaining_sources entities_to_rebuild[node_label] = remaining_sources
async with pipeline_status_lock: async with pipeline_status_lock:
log_message = ( log_message = f"Found {len(entities_to_rebuild)} affected entities"
f"Found {len(entities_to_rebuild)} affected entities"
)
logger.info(log_message) logger.info(log_message)
pipeline_status["latest_message"] = log_message pipeline_status["latest_message"] = log_message
pipeline_status["history_messages"].append(log_message) pipeline_status["history_messages"].append(log_message)
@ -2383,6 +2374,9 @@ class LightRAG:
logger.error(f"Failed to process graph analysis results: {e}") logger.error(f"Failed to process graph analysis results: {e}")
raise Exception(f"Failed to process graph dependencies: {e}") from e raise Exception(f"Failed to process graph dependencies: {e}") from e
# Use graph database lock to prevent dirty read
graph_db_lock = get_graph_db_lock(enable_logging=False)
async with graph_db_lock:
# 5. Delete chunks from storage # 5. Delete chunks from storage
if chunk_ids: if chunk_ids:
try: try:
@ -2453,6 +2447,9 @@ class LightRAG:
logger.error(f"Failed to delete relationships: {e}") logger.error(f"Failed to delete relationships: {e}")
raise Exception(f"Failed to delete relationships: {e}") from e raise Exception(f"Failed to delete relationships: {e}") from e
# Persist changes to graph database before releasing graph database lock
await self._insert_done()
# 8. Rebuild entities and relationships from remaining chunks # 8. Rebuild entities and relationships from remaining chunks
if entities_to_rebuild or relationships_to_rebuild: if entities_to_rebuild or relationships_to_rebuild:
try: try:
@ -2471,9 +2468,7 @@ class LightRAG:
except Exception as e: except Exception as e:
logger.error(f"Failed to rebuild knowledge from chunks: {e}") logger.error(f"Failed to rebuild knowledge from chunks: {e}")
raise Exception( raise Exception(f"Failed to rebuild knowledge graph: {e}") from e
f"Failed to rebuild knowledge graph: {e}"
) from e
# 9. Delete from full_entities and full_relations storage # 9. Delete from full_entities and full_relations storage
try: try: