feat(files): avoid initial unnecessary rechunking

This commit is contained in:
Gregor Kleen 2020-09-07 15:03:40 +02:00
parent d624a951c5
commit e80f7d7a89
4 changed files with 27 additions and 11 deletions

View File

@ -227,13 +227,15 @@ makeFoundation appSettings'@AppSettings{..} = do
forM_ ldapPool $ registerFailoverMetrics "ldap" forM_ ldapPool $ registerFailoverMetrics "ldap"
-- Perform database migration using our application's logging settings. -- Perform database migration using our application's logging settings.
if flip runReaderT tempFoundation $
| appAutoDbMigrate -> do if
$logDebugS "setup" "Migration" | appAutoDbMigrate -> do
migrateAll `runSqlPool` sqlPool $logDebugS "setup" "Migration"
| otherwise -> whenM (requiresMigration `runSqlPool` sqlPool) $ do migrateAll `runSqlPool` sqlPool
$logErrorS "setup" "Migration required" | otherwise -> whenM (requiresMigration `runSqlPool` sqlPool) $ do
liftIO . exitWith $ ExitFailure 2 $logErrorS "setup" "Migration required"
liftIO . exitWith $ ExitFailure 2
$logDebugS "setup" "Cluster-Config" $logDebugS "setup" "Cluster-Config"
appCryptoIDKey <- clusterSetting (Proxy :: Proxy 'ClusterCryptoIDKey) `runSqlPool` sqlPool appCryptoIDKey <- clusterSetting (Proxy :: Proxy 'ClusterCryptoIDKey) `runSqlPool` sqlPool
appSecretBoxKey <- clusterSetting (Proxy :: Proxy 'ClusterSecretBoxKey) `runSqlPool` sqlPool appSecretBoxKey <- clusterSetting (Proxy :: Proxy 'ClusterSecretBoxKey) `runSqlPool` sqlPool

View File

@ -4,6 +4,7 @@ module Import
import Foundation as Import import Foundation as Import
import Import.NoFoundation as Import import Import.NoFoundation as Import
import Model.Migration as Import
import Utils.SystemMessage as Import import Utils.SystemMessage as Import
import Utils.Metrics as Import import Utils.Metrics as Import

View File

@ -4,7 +4,6 @@ module Import.NoFoundation
import Import.NoModel as Import import Import.NoModel as Import
import Model as Import import Model as Import
import Model.Migration as Import
import Model.Rating as Import import Model.Rating as Import
import Model.Submission as Import import Model.Submission as Import
import Model.Tokens as Import import Model.Tokens as Import

View File

@ -7,6 +7,8 @@ module Model.Migration
import Import.NoModel hiding (Max(..), Last(..)) import Import.NoModel hiding (Max(..), Last(..))
import Model import Model
import Settings
import Foundation.Type
import Jobs.Types import Jobs.Types
import Audit.Types import Audit.Types
import Model.Migration.Version import Model.Migration.Version
@ -40,6 +42,8 @@ import qualified Data.CaseInsensitive as CI
import qualified Data.Aeson as Aeson import qualified Data.Aeson as Aeson
import Web.ServerSession.Backend.Persistent.Memcached (migrateMemcachedSqlStorage) import Web.ServerSession.Backend.Persistent.Memcached (migrateMemcachedSqlStorage)
import Data.Conduit.Algorithms.FastCDC (FastCDCParameters(fastCDCMinBlockSize))
-- Database versions must follow https://pvp.haskell.org: -- Database versions must follow https://pvp.haskell.org:
-- - Breaking changes are instances where manual migration is necessary (via customMigrations; i.e. changing a columns format) -- - Breaking changes are instances where manual migration is necessary (via customMigrations; i.e. changing a columns format)
@ -80,6 +84,7 @@ migrateAll' = sequence_
migrateAll :: ( MonadLogger m migrateAll :: ( MonadLogger m
, MonadResource m , MonadResource m
, MonadUnliftIO m , MonadUnliftIO m
, MonadReader UniWorX m
) )
=> ReaderT SqlBackend m () => ReaderT SqlBackend m ()
migrateAll = do migrateAll = do
@ -112,7 +117,7 @@ requiresMigration = mapReaderT (exceptT return return) $ do
$logInfoS "Migration" $ intercalate "; " initial $logInfoS "Migration" $ intercalate "; " initial
throwError True throwError True
customs <- mapReaderT lift $ getMissingMigrations @_ @m customs <- mapReaderT lift $ getMissingMigrations @_ @(ReaderT UniWorX m)
unless (Map.null customs) $ do unless (Map.null customs) $ do
$logInfoS "Migration" . intercalate ", " . map tshow $ Map.keys customs $logInfoS "Migration" . intercalate ", " . map tshow $ Map.keys customs
throwError True throwError True
@ -134,6 +139,7 @@ getMissingMigrations :: forall m m'.
( MonadLogger m ( MonadLogger m
, MonadIO m , MonadIO m
, MonadResource m' , MonadResource m'
, MonadReader UniWorX m'
) )
=> ReaderT SqlBackend m (Map (Key AppliedMigration) (ReaderT SqlBackend m' ())) => ReaderT SqlBackend m (Map (Key AppliedMigration) (ReaderT SqlBackend m' ()))
getMissingMigrations = do getMissingMigrations = do
@ -180,7 +186,9 @@ migrateManual = do
-} -}
customMigrations :: forall m. customMigrations :: forall m.
MonadResource m ( MonadResource m
, MonadReader UniWorX m
)
=> Map (Key AppliedMigration) (ReaderT SqlBackend m ()) => Map (Key AppliedMigration) (ReaderT SqlBackend m ())
customMigrations = Map.fromListWith (>>) customMigrations = Map.fromListWith (>>)
[ ( AppliedMigrationKey [migrationVersion|initial|] [version|0.0.0|] [ ( AppliedMigrationKey [migrationVersion|initial|] [version|0.0.0|]
@ -923,14 +931,20 @@ customMigrations = Map.fromListWith (>>)
|] |]
) )
, ( AppliedMigrationKey [migrationVersion|40.0.0|] [version|41.0.0|] , ( AppliedMigrationKey [migrationVersion|40.0.0|] [version|41.0.0|]
, whenM (tableExists "file_content") $ , whenM (tableExists "file_content") $ do
chunkingParams <- lift $ view _appFileChunkingParams
[executeQQ| [executeQQ|
ALTER TABLE file_content RENAME TO file_content_chunk; ALTER TABLE file_content RENAME TO file_content_chunk;
ALTER INDEX file_content_pkey RENAME TO file_content_chunk_pkey;
CREATE TABLE file_content_chunk_unreferenced (id bigserial, hash bytea NOT NULL, since timestamp with time zone NOT NULL); CREATE TABLE file_content_chunk_unreferenced (id bigserial, hash bytea NOT NULL, since timestamp with time zone NOT NULL);
INSERT INTO file_content_chunk_unreferenced (since, hash) (SELECT unreferenced_since as since, hash FROM file_content_chunk WHERE NOT (unreferenced_since IS NULL)); INSERT INTO file_content_chunk_unreferenced (since, hash) (SELECT unreferenced_since as since, hash FROM file_content_chunk WHERE NOT (unreferenced_since IS NULL));
ALTER TABLE file_content_chunk DROP COLUMN unreferenced_since; ALTER TABLE file_content_chunk DROP COLUMN unreferenced_since;
ALTER TABLE file_content_chunk ADD COLUMN content_based boolean NOT NULL DEFAULT false;
UPDATE file_content_chunk SET content_based = true WHERE length(content) <= #{fastCDCMinBlockSize chunkingParams};
CREATE TABLE file_content_entry (hash bytea NOT NULL, ix bigint NOT NULL, chunk_hash bytea NOT NULL); CREATE TABLE file_content_entry (hash bytea NOT NULL, ix bigint NOT NULL, chunk_hash bytea NOT NULL);
INSERT INTO file_content_entry (hash, chunk_hash, ix) (SELECT hash, hash as chunk_hash, 0 as ix FROM file_content_chunk); INSERT INTO file_content_entry (hash, chunk_hash, ix) (SELECT hash, hash as chunk_hash, 0 as ix FROM file_content_chunk);
|] |]