從 strfry 遷移

用一行指令將現有 strfry 中繼的事件遷移到 nostrfy — 準備、dry-run、遷移、驗證與復原。

一覽

nostrfy migrate-strfry 讀取 strfry 自己的匯出格式(JSONL,每行一個 NIP-01 事件),因此可跨 strfry 資料庫版本,且不依賴 strfry 內部的 LMDB schema。它從不寫入 strfry 資料庫。

已遷移未遷移
每個已儲存的事件(套用可替換/可定址語意)沒有 nostrfy 等效項的 strfry 設定(合併報告會列出每一項及原因)
NIP-40 過期 — 已過期的事件被跳過Blossom 媒體及其擁有者對應(strfry 沒有 Blossom 伺服器)
NIP-09 刪除,包括 strfry 已實際刪除的事件的重新發布阻擋存取清單(NIP-86 封鎖、中繼公鑰清單、Blossom 允許清單)
NIP-29 9005/9008 管理副作用NIP-43 邀請碼(用 createclaim 簽發新的)
首次出現時間戳(設定新公鑰門檻時)NIP-62 消除請求,除非給出 --apply-vanish
NIP-29 群組、NIP-43 角色及其中繼簽章中繼資料,在首次啟動時重建中繼本身的身分/金鑰(它們位於 nostrfy.toml)
等效的 strfry 設定,可選擇合併到 nostrfy.toml

摘要中的預期跳過:臨時事件(類型 20000-29999,nostrfy 從不儲存)與 已過期事件。

快速開始

sh
# 1. 停止 nostrfy 中繼(遷移需要資料庫目錄)
nostrfy --config /etc/nostrfy/nostrfy.toml stop

# 2. dry run — 解析並驗證每個事件,不寫入任何內容
nostrfy --config /etc/nostrfy/nostrfy.toml migrate-strfry \
    --strfry-db /var/lib/strfry-db --dry-run

# 3. 匯入
nostrfy --config /etc/nostrfy/nostrfy.toml migrate-strfry \
    --strfry-db /var/lib/strfry-db

# 4. 啟動 — NIP-29 群組與 NIP-43 角色從匯入的事件重建
nostrfy --config /etc/nostrfy/nostrfy.toml start
遷移是離線的
它直接寫入 database.path,當 nostrfy 常駐程式(或另一個遷移)佔用資料庫目錄時會拒絕執行。 請先停止中繼。strfry 本身可以繼續執行 — strfry export 讀取一致的快照。

環境需求

  • strfry 二進位檔(用於 --strfry-db),或你自己匯出的 JSONL 檔案。
  • nostrfy v0.1.15 或更高版本(migrate-strfry 子指令)。
  • 目標中繼的 nostrfy 設定,已設定 database.path、public_url 與 private_key。
  • 可用磁碟空間:大約為 strfry 匯出加上其索引的大小。NIP-50 詞索引會增加 一些;磁碟非常緊張時可先停用(database.search_index = false), 遷移後再啟用(索引在啟動時重建)。
  • 目標 database.path 上沒有執行中的 nostrfy 執行個體。

準備設定

toml
[relay]
name = "My Relay"
public_url = "wss://relay.example.com"   # NIP-42/62/98 與 NIP-29 中繼資料需要
private_key = "..."                       # NIP-29/43 中繼簽章中繼資料需要

[server]
host = "0.0.0.0"
port = 8080

[database]
path = "/var/lib/nostrfy"
map_size = 1073741824

如果沒有中繼金鑰,用 nostrfy genkey 產生,然後驗證:

sh
nostrfy --config /etc/nostrfy/nostrfy.toml check

合併 strfry 設定(選用)

在開啟資料庫之前,migrate-strfry 會尋找 strfry 的設定 (--strfry-config,然後 $STRFRY_CONFIG、/etc/strfry.conf、 ./strfry.conf),列印有 nostrfy 等效項且與你的 nostrfy.toml 不同的設定,並詢問是否合併。只重寫列出的鍵 — 註解 和所有其他行都保留,會使設定無效的值會被跳過並說明原因,其餘仍然合併。

  • --merge-config 不經詢問直接套用(用於腳本);--no-merge-config 跳過該步驟。
  • 沒有終端機時,會列印建議,除非給出 --merge-config,否則跳過合併。
  • --dry-run 列印建議但從不寫入。

Dry run

先看再跳 — dry run 解析並驗證整個匯出,而不觸碰資料庫:

sh
nostrfy migrate-strfry --strfry-db /var/lib/strfry-db --dry-run

非零的 bad signature 計數意味著匯出包含 strfry 未經 驗證就接受的事件;它們會被跳過。如果信任它們,傳 --no-verify 仍然匯入。

遷移

選擇三種輸入模式之一 — 結果完全相同:

sh
# 選項 A — nostrfy 自己執行 `strfry export`(strfry 在 PATH 中)
nostrfy migrate-strfry --strfry-db /var/lib/strfry-db

# 選項 B — 你自己匯出到檔案
strfry export > /tmp/strfry-export.jsonl
nostrfy migrate-strfry --input /tmp/strfry-export.jsonl

# 選項 C — 管線(stdin 是預設輸入)
strfry export | nostrfy migrate-strfry
旗標用途
--strfry-bin <PATH>strfry 不在 PATH 中
--since <UNIX>續傳/追趕:created_at 為該值或更新的事件(含邊界)
--apply-vanish處理匯出中發現的 NIP-62 消除請求(預設關閉)
--no-verify對可信傾印跳過簽章驗證(更快)
--batch <N>每個資料庫交易的事件數(預設 512)
--dry-run只解析和驗證

遷移可安全重複執行:重複項被跳過,刪除副作用會 重新套用,因此中斷的執行可以直接重跑(或用 --since 續傳)。

啟動與驗證

首次啟動會從匯入的事件重建 NIP-29 群組儲存與 NIP-43 角色儲存,並 重新發布中繼簽章的中繼資料(每個群組的 39000/39001/39002/39005, 以及 13534 成員清單)。大型資料庫可能需要一會兒;請觀察日誌。

sh
R=wss://relay.example.com      # 用於 nak(WebSocket)
H=https://relay.example.com    # 用於 curl(HTTP)

nak relay "$R"                              # 中繼回應並公佈其 NIP
curl -s "$H/api/v1/query?limit=1"           # 事件可被提供
nak req -i <deleted-event-id> "$R"          # 已刪除的事件保持消失
nak req -k 39000 "$R"                       # NIP-29 群組中繼資料(如已遷移)
nak req --auth --force-pre-auth --sec <nsec> -k 13534 "$R"   # NIP-43 成員清單(AUTH)

如需精確的數量對比,strfry scan '{}' | wc -l 減去遷移摘要中報告的臨時/過期事件 應等於用戶端能取回的數量。

恢復中斷的遷移

重新執行前不要啟動中繼
NIP-29 群組副作用(9005/9008)在匯入之後套用;中斷的執行 已儲存這些事件但尚未執行刪除,因此首次啟動可能會提供刪除本應移除的群組 歷史。請先重新執行遷移 — 它會完成副作用(清除是幂等的)— 然後再啟動中繼。
  • 匯出到檔案/管線:重新執行同一指令。重複項被跳過,刪除 阻擋會重新套用。
  • 使用了 --strfry-db:摘要會列印續傳提示;用那個 --since 重新執行(含邊界,邊界秒會重新匯入並去重)。
  • 如果執行失敗並顯示 database writer unavailable,檢查可用磁碟空間和 database.map_size,然後重跑。

復原

遷移只寫入 nostrfy 資料庫。要復原,停止中繼並還原遷移前的資料庫,或將其刪除:

sh
nostrfy --config /etc/nostrfy/nostrfy.toml stop
rm -rf /var/lib/nostrfy            # 或還原遷移前的備份

疑難排解

訊息原因 / 修正
cannot lock the database directory ...; stop the relay before migratingnostrfy 常駐程式(或另一個遷移)佔用了目錄:先 nostrfy stop
strfry database directory ... does not exist--strfry-db 必須指向包含 data.mdb 的目錄
cannot run 'strfry': ...安裝 strfry、設定 --strfry-bin,或使用 --input
database writer unavailable; the migration did not complete寫入執行緒停止或佇列過載:檢查磁碟/映射大小,重跑(安全)
group purge for <id> did not complete清除被中斷:重新執行遷移
高 bad signature 計數strfry 資料庫包含未驗證的事件:檢查它們;僅當信任來源時才用 --no-verify 匯入
啟動後缺少 NIP-29 中繼資料沒有 relay.private_key:執行 nostrfy genkey 並重新啟動
未提供設定合併未找到 strfry 的設定:傳 --strfry-config /etc/strfry.conf

檢查清單

  • nostrfy 中繼已停止
  • strfry 資料庫與 nostrfy 設定已備份
  • nostrfy check 通過
  • strfry 設定已合併(或報告已審閱)
  • dry run 已審閱(無意外的壞簽章)
  • 遷移無錯誤完成
  • 中繼啟動;群組/角色重建已記錄
  • 事件數量相符(減去臨時/過期)
  • 已刪除的事件保持消失(重新發布被拒絕)
  • 以匿名和成員身分檢查了私密群組可見性
  • 反向代理 / DNS / 用戶端中繼清單已更新
strfry 還在執行?
如果匯出期間 strfry 保持上線,在準備切換時做一次追趕執行:停止 nostrfy, 用 --since <last created_at> 重新執行遷移,然後再次啟動。