diff --git a/cardano-db-sync/src/Cardano/DbSync/Ledger/State.hs b/cardano-db-sync/src/Cardano/DbSync/Ledger/State.hs index 9690d2c73..11d4e84dc 100644 --- a/cardano-db-sync/src/Cardano/DbSync/Ledger/State.hs +++ b/cardano-db-sync/src/Cardano/DbSync/Ledger/State.hs @@ -118,7 +118,7 @@ import Ouroboros.Network.Block (HeaderHash, pointSlot) import System.FS.API (SomeHasFS (..), mkFsPath) import System.FS.API.Types (MountPoint (..)) import System.FS.IO (ioHasFS) -import System.FilePath (splitDirectories, ()) +import System.FilePath (()) import System.Mem (performMajorGC) import System.Random (genWord64, newStdGen) @@ -227,7 +227,13 @@ mkHasLedgerEnv trce protoInfo dir nw maxLovelaceSupply systemStart syncOptions b LedgerBackendLSM mPath -> do let lsmPath = fromMaybe (unLedgerStateDir dir "lsm") mPath salt <- fst . genWord64 <$> newStdGen - let args = LSM.LSMArgs (mkFsPath $ splitDirectories lsmPath) salt (LSM.stdMkBlockIOFS lsmPath) + -- The HasBlockIO is rooted at lsmPath, so the session's FsPath inside it + -- must be the empty path. Passing the full lsmPath here causes the LSM + -- session to be created at /, which breaks snapshot + -- bundling in scripts/postgresql-setup.sh (it falls back to the InMemory + -- branch and ships an incomplete tarball; on restore db-sync then can't + -- find the snapshot and replays from genesis). + let args = LSM.LSMArgs (mkFsPath []) salt (LSM.stdMkBlockIOFS lsmPath) res <- runWithTempRegistry $ (,()) diff --git a/scripts/postgresql-setup.sh b/scripts/postgresql-setup.sh index fd381b957..f20a80b75 100755 --- a/scripts/postgresql-setup.sh +++ b/scripts/postgresql-setup.sh @@ -176,6 +176,15 @@ function create_snapshot { # The active/ directory is not needed — it gets cleared on session restore. tar czf "${tmp_dir}/${ledger_dir_name}.tar.gz" \ -C "${state_dir}" "${ledger_dir_name}" "lsm/snapshots/${ledger_dir_name}" "lsm/metadata" + elif [ -d "${state_dir}/lsm" ]; then + # State directory contains an lsm/ subtree but the expected snapshot path is missing. + # Refuse to silently fall back to the InMemory branch — the resulting tarball would + # exclude the LSM tree files and restoration would replay from genesis. + echo "ERROR: ${state_dir}/lsm exists but no LSM snapshot found at ${lsm_snap_dir}." >&2 + echo " The LSM session may be using a non-standard layout. Aborting to avoid" >&2 + echo " producing an incomplete snapshot." >&2 + rm "${recursive}" "${force}" "${tmp_dir}" + exit 1 else echo "Detected InMemory backend snapshot at slot ${ledger_dir_name}" # InMemory backend: just the ledger snapshot directory