HugeGraph之索引重建和刪除

linlin1989117發表於2020-10-14

索引重建和刪除

1. 索引重建

主要針對圖資料(vertices或edges)與其索引資訊不一致的場景,通過索引重建使索引資訊與原始資料同步。

1.1 重建場景

  • 場景1. 建立索引時,已經有vertices和edges存在,在index_label表中增加後設資料之後,需要對已存在的vertices或edges建立索引資訊
  • 場景2. bulkLoad之後,新增加的vertices或edges有對應的index需要建立(是否存在這種場景?
  • 場景3. 使用者手動重建某個索引
  • 場景4. 使用者重建某個vertex label或者edge label的全部索引

1.2 設計

索引重建的前兩種場景可以依賴場景3和場景4實現,因此實現rebuildIndex(SchemaElement schemaElement),作為索引重建場景的基本操作,功能為重建schemaElement(index label、vertex label或edge label)對應的所有索引,實現邏輯如下:

  • 若schema為index_label,重建該index_label代表的索引(單個);若schema為vertex_label,重建該vertex_label關聯的索引(0-n個);若schema為edge_label,重建該edge_label關聯的索引(0-n個)

  • 刪除對應索引資料(具體實現見下面)

  • 根據不同index_type重新建立索引

  • index_type = secondary

  • index_type = search

index_type = secondary

resultset = SELECT * FROM vertices where LABEL = 'person';// 獲取所有待重建索引的vertices或者edges
// 逐條建立索引
for(result :resultset)
    INSERT INTO secondary_indexes (PROPERTY_VALUES, INDEX_LABEL_NAME, ELEMENT_IDS) VALUE (x,y,z)

index_type = search

resultset = SELECT * FROM vertices where LABEL = 'person';// 獲取所有待重建索引的vertices或者edges
// 逐條建立索引
for(result :resultset)
    INSERT INTO search_indexes (INDEX_LABEL_NAME, PROPERTY_VALUES, ELEMENT_IDS) VALUE (x,y,z)

1.3 其他要點

1.3.1 鎖機制

  • 重建索引時,由於索引和資料會出現不一致,為保證正確性,應當加鎖,禁止重建過程中,對重建索引的資料進行讀取
  • 在程式架構中實現全域性鎖(單例模式實現),重建索引時禁止相應vertices或edges的查詢
  • 索引構建時,允許寫入vertices和edges。因為寫入時會先後更新原始資料和索引資訊,不會引起資料和索引的不一致

鎖的建立操作:

  • 鎖組(lockGroup)在hugegraph系統啟動時建立,用於邏輯上規定鎖的範圍。具體的鎖在使用時根據情況處理:如果key不存在,則建立並返回鎖;如果key存在則拋異常(developer負責控制命名規則)

鎖的lock操作:

  • 鎖空閒,則current thread成功上鎖,返回TRUE
  • 鎖被佔用,則current thread抓鎖失敗(即使鎖的當前所有者是自己),返回FALSE

鎖的unlock操作:

  • 鎖的擁有者是current thread,解鎖成功
  • 鎖的擁有者不是current thread,拋異常

加鎖場景:

參見加鎖場景分析

1.3.2 空值

  • 索引構建時,property為空怎麼處理?參考mysql資料庫實現,用0、特殊值或者空串代替空值

2. 索引刪除

刪除某個indexLabel對應的索引資訊和indexLabel本身,場景如下:

  1. 使用者刪除特定indexLabel
  2. 刪除vertex label或者edge label時,需要刪除建立在其上的index
  3. 刪除vertexLabel或者edgeLabel的某個建有索引的property,需要先刪除property相關的索引

先刪除index表中的具體索引資料,再從vertex label或者edge label的index_names中刪除對應的indexName,之後刪除indexLabel表中的後設資料

2.1 設計要點

  • 從功能上看,Cassandra不支援不包含第一列的where語句,對於secondary index需要先查詢出所有符合要求的index,再一條一條刪除;searchIndex第一列為index_label_name,則可以根據通過___delete from search_indexes where index_label_name = yyy___批量刪除
// delete index data from secondary index table
DELETE FROM secondary_indexes WHERE PROPERTY_VALUES='Beijing' AND INDEX_LABEL_NAME='personByCity';

// delete index data from search index table
DELETE FROM search_indexes WHERE INDEX_LABEL_NAME='personByAge';
  • 構造一個新的backendEntry,propValues和elementIDs都為空,表示___delete from table where indexLabelName = xxx___語句,傳遞到store,由store根據是secondary還是search選擇不同的處理方式

相關文章