Skip to content

Commit a20e364

Browse files
authored
Merge pull request #224 from lolepezy/fix/erase-all-maps
Erase every map from LMDB when cleaning cache
2 parents aab8ef2 + d1a0e36 commit a20e364

File tree

6 files changed

+49
-53
lines changed

6 files changed

+49
-53
lines changed

src/RPKI/Store/Base/LMDB.hs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
module RPKI.Store.Base.LMDB where
1111

12-
import Control.Monad (forM, forever)
12+
import Control.Monad
1313
import Control.Concurrent.STM
1414

1515
import qualified Data.ByteString as BS
@@ -35,7 +35,6 @@ import qualified Lmdb.Map as LMap
3535
import qualified Lmdb.Multimap as LMMap
3636
import qualified Lmdb.Types as Lmdb
3737

38-
3938
import Pipes
4039

4140
type Env = Lmdb.Environment 'Lmdb.ReadWrite
@@ -54,7 +53,7 @@ data LmdbStore (name :: Symbol) = LmdbStore {
5453
}
5554

5655
data LmdbMultiStore (name :: Symbol) = LmdbMultiStore {
57-
db :: Lmdb.MultiDatabase BS.ByteString BS.ByteString,
56+
db :: Lmdb.MultiDatabase BS.ByteString BS.ByteString,
5857
env :: LmdbEnv
5958
}
6059

@@ -314,5 +313,24 @@ getMapNames tx db =
314313
void $ runEffect $ LMap.firstForward c >-> do
315314
forever $ do
316315
Lmdb.KeyValue name _ <- await
317-
lift $ modifyIORef' maps ([name] <>)
318-
readIORef maps
316+
lift $ modifyIORef' maps (name :)
317+
readIORef maps
318+
319+
320+
eraseEnv :: Env -> Tx LmdbStorage 'RW -> IO [BS.ByteString]
321+
eraseEnv env (LmdbTx tx) = do
322+
db <- openDatabase tx Nothing defaultDbSettings
323+
mapNames <- getMapNames tx db
324+
forM_ mapNames $ \mapName -> do
325+
-- first open it as is
326+
m <- openDatabase tx (Just $ convert mapName) defaultDbSettings
327+
isMulti <- isMultiDatabase tx m
328+
if isMulti
329+
then do
330+
-- close and reopen as multi map
331+
closeDatabase env m
332+
m' <- openMultiDatabase tx (Just $ convert mapName) defaultMultiDbSettngs
333+
LMMap.clear tx m'
334+
else
335+
LMap.clear tx m
336+
pure mapNames

src/RPKI/Store/Base/Map.hs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ data SMap (name :: Symbol) s k v where
1818
instance Storage s => WithStorage s (SMap name s k v) where
1919
storage (SMap s _) = s
2020

21-
instance WithTx s => CanErase s (SMap name s k v) where
22-
erase tx (SMap _ s) = S.clear tx s
23-
2421
put :: (AsStorable k, AsStorable v) =>
2522
Tx s 'RW -> SMap name s k v -> k -> v -> IO ()
2623
put tx (SMap _ s) k v = S.put tx s (storableKey k) (storableValue v)

src/RPKI/Store/Base/MultiMap.hs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ data SMultiMap (name :: Symbol) s k v where
1414
instance Storage s => WithStorage s (SMultiMap name s k v) where
1515
storage (SMultiMap s _) = s
1616

17-
instance WithTx s => CanErase s (SMultiMap name s k v) where
18-
erase tx (SMultiMap _ s) = S.clearMu tx s
19-
2017
put :: (AsStorable k, AsStorable v) =>
2118
Tx s 'RW -> SMultiMap name s k v -> k -> v -> IO ()
2219
put tx (SMultiMap _ s) k v = S.putMu tx s (storableKey k) (storableValue v)

src/RPKI/Store/Base/Storage.hs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,3 @@ rwTxT :: (MonadIO m, WithStorage s ws)
6363
rwTxT tdb f = liftIO $ do
6464
db <- readTVarIO tdb
6565
rwTx db $ \tx -> f tx db
66-
67-
68-
class WithTx s => CanErase s a where
69-
erase :: Tx s 'RW -> a -> IO ()

src/RPKI/Store/Database.hs

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,14 @@ import RPKI.Time
6969
-- It is brittle and inconvenient, but so far seems to be
7070
-- the only realistic option.
7171
currentDatabaseVersion :: Integer
72-
currentDatabaseVersion = 35
72+
currentDatabaseVersion = 36
7373

7474
-- Some constant keys
7575
databaseVersionKey, forAsyncFetchKey, validatedByVersionKey :: Text
7676
databaseVersionKey = "database-version"
7777
forAsyncFetchKey = "for-async-fetch"
7878
validatedByVersionKey = "validated-by-version-map"
7979

80-
data EraseWrapper s where
81-
EraseWrapper :: forall t s . (Storage s, CanErase s t) => t -> EraseWrapper s
82-
8380
-- All of the stores of the application in one place
8481
data DB s = DB {
8582
taStore :: TAStore s,
@@ -96,8 +93,7 @@ data DB s = DB {
9693
slurmStore :: SlurmStore s,
9794
jobStore :: JobStore s,
9895
sequences :: SequenceMap s,
99-
metadataStore :: MetadataStore s,
100-
erasables :: [EraseWrapper s]
96+
metadataStore :: MetadataStore s
10197
} deriving stock (Generic)
10298

10399
instance Storage s => WithStorage s (DB s) where
@@ -964,10 +960,6 @@ getRtrPayloads tx db worldVersion =
964960
-- Get all SStats and `<>` them
965961
totalStats :: StorageStats -> SStats
966962
totalStats (StorageStats s) = mconcat $ Map.elems s
967-
968-
emptyDBMaps :: (MonadIO m, Storage s) => Tx s 'RW -> DB s -> m ()
969-
emptyDBMaps tx DB {..} = liftIO $
970-
forM_ erasables $ \(EraseWrapper t) -> erase tx t
971963

972964

973965
-- Utilities to have storage transaction in ValidatorT monad.

src/RPKI/Store/MakeLmdb.hs

Lines changed: 24 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ module RPKI.Store.MakeLmdb where
88
import Control.Lens
99
import Control.Concurrent.STM
1010

11-
import Data.IORef
1211
import Data.String.Interpolate.IsString
1312

1413
import GHC.TypeLits
@@ -35,9 +34,8 @@ data DbCheckResult = WasIncompatible | WasCompatible | DidntHaveVersion
3534

3635
createDatabase :: LmdbEnv -> AppLogger -> IncompatibleDbCheck -> IO (DB LmdbStorage, DbCheckResult)
3736
createDatabase env logger checkAction = do
38-
39-
erasables <- newIORef []
40-
db <- doCreateDb erasables
37+
38+
db <- doCreateDb
4139

4240
case checkAction of
4341
CheckVersion ->
@@ -51,24 +49,31 @@ createDatabase env logger checkAction = do
5149
dbVersion <- getDatabaseVersion tx db
5250
case dbVersion of
5351
Nothing -> do
54-
logInfo logger [i|Cache version is not set, setting it to #{currentDatabaseVersion}, cleaning up the cache.|]
55-
(_, ms) <- timedMS $ emptyDBMaps tx db
56-
logDebug logger [i|Erasing cache took #{ms}ms.|]
52+
logInfo logger [i|Cache version is not set, will set the version to #{currentDatabaseVersion} and clean up the cache.|]
53+
ms <- eraseCache tx
54+
logDebug logger [i|Erased cache in #{ms}ms.|]
5755
saveCurrentDatabaseVersion tx db
5856
pure DidntHaveVersion
59-
Just version ->
60-
if version /= currentDatabaseVersion then do
57+
Just version
58+
| version == currentDatabaseVersion ->
59+
pure WasCompatible
60+
| otherwise -> do
6161
-- We are seeing incompatible storage. The only option
6262
-- now is to erase all the maps and start from scratch.
63-
logInfo logger [i|Persisted cache version is #{version} and expected version is #{currentDatabaseVersion}, dropping the cache.|]
64-
(_, ms) <- timedMS $ emptyDBMaps tx db
65-
logDebug logger [i|Erasing cache took #{ms}ms.|]
63+
logInfo logger [i|Persisted cache version is #{version} and expected version is #{currentDatabaseVersion}, will drop the cache.|]
64+
-- NOTE: We erase every map in the cache, including metadata, but that's not an problem,
65+
-- since we'll set new DB version here
66+
ms <- eraseCache tx
67+
logDebug logger [i|Erased cache in #{ms}ms.|]
6668
saveCurrentDatabaseVersion tx db
67-
pure WasIncompatible
68-
else
69-
pure WasCompatible
69+
pure WasIncompatible
7070

71-
doCreateDb erasablesRef = do
71+
eraseCache tx = do
72+
nativeEnv <- atomically $ getNativeEnv env
73+
(_, ms) <- timedMS $ eraseEnv nativeEnv tx
74+
pure ms
75+
76+
doCreateDb = do
7277
sequences <- createMap
7378
taStore <- TAStore <$> createMap
7479
validationsStore <- ValidationsStore <$> createMap
@@ -83,10 +88,7 @@ createDatabase env logger checkAction = do
8388
jobStore <- JobStore <$> createMap
8489
metadataStore <- MetadataStore <$> createMap
8590
repositoryStore <- createRepositoryStore
86-
objectStore <- createObjectStore sequences
87-
88-
erasables <- readIORef erasablesRef
89-
91+
objectStore <- createObjectStore sequences
9092
pure DB {..}
9193
where
9294

@@ -112,16 +114,10 @@ createDatabase env logger checkAction = do
112114
lmdb = LmdbStorage env
113115

114116
createMap :: forall k v name . (KnownSymbol name) => IO (SMap name LmdbStorage k v)
115-
createMap = do
116-
sm <- SMap lmdb <$> createLmdbStore env
117-
modifyIORef' erasablesRef (EraseWrapper sm :)
118-
pure sm
117+
createMap = SMap lmdb <$> createLmdbStore env
119118

120119
createMultiMap :: forall k v name . (KnownSymbol name) => IO (SMultiMap name LmdbStorage k v)
121-
createMultiMap = do
122-
sm <- SMultiMap lmdb <$> createLmdbMultiStore env
123-
modifyIORef' erasablesRef (EraseWrapper sm :)
124-
pure sm
120+
createMultiMap = SMultiMap lmdb <$> createLmdbMultiStore env
125121

126122

127123
mkLmdb :: FilePath -> Config -> IO LmdbEnv

0 commit comments

Comments
 (0)