Skip to content

Commit 5fd1136

Browse files
committed
go/oasis-node/cmd/storage: Add command that flattens db instances
As from the benchmarks using 8 workers for the flatten command gave around 3x speed-up. Further parallelizing by running each db compaction in the separate goroutine made things slower.
1 parent 2969de8 commit 5fd1136

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

.changelog/6309.feature.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
go/oasis-node/cmd/storage: Add new compact command
2+
3+
A new command `oasis-node storage compact` has been added.
4+
5+
The command finds all the node databases and triggers compaction
6+
of the underyling database tables.
7+
8+
It should be called everytime before exporting the node data, e.g.
9+
copying state to a remote node, backups, snapshots etc.

go/oasis-node/cmd/storage/storage.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ import (
55
"context"
66
"errors"
77
"fmt"
8+
"io/fs"
89
"os"
910
"path/filepath"
11+
"strings"
1012
"time"
1113

14+
badgerDB "github.com/dgraph-io/badger/v4"
1215
"github.com/spf13/cobra"
1316

1417
"github.com/oasisprotocol/oasis-core/go/common"
18+
cmnBadger "github.com/oasisprotocol/oasis-core/go/common/badger"
1519
"github.com/oasisprotocol/oasis-core/go/common/crypto/hash"
1620
"github.com/oasisprotocol/oasis-core/go/common/logging"
1721
"github.com/oasisprotocol/oasis-core/go/config"
@@ -53,6 +57,16 @@ var (
5357
RunE: doRenameNs,
5458
}
5559

60+
storageCompactCmd = &cobra.Command{
61+
Use: "compact",
62+
Args: cobra.NoArgs,
63+
Short: "trigger compaction across all the databases",
64+
Long: `Optimize the storage for all the databases by doing the compaction.
65+
66+
It is recommended to call this before doing storage snapshots or copying the data to a remote node.`,
67+
RunE: doDbCompactions,
68+
}
69+
5670
logger = logging.GetLogger("cmd/storage")
5771

5872
pretty = cmdCommon.Isatty(1)
@@ -283,12 +297,87 @@ func doRenameNs(_ *cobra.Command, args []string) error {
283297
return nil
284298
}
285299

300+
func doDbCompactions(_ *cobra.Command, args []string) error {
301+
dataDir := cmdCommon.DataDir()
302+
303+
dbDirs, err := findDBInstances(dataDir)
304+
if err != nil {
305+
return fmt.Errorf("failed to find database instances: %w", err)
306+
}
307+
308+
if len(dbDirs) == 0 {
309+
return fmt.Errorf("no database instances found (dataDir: %s)", dataDir)
310+
}
311+
312+
if pretty {
313+
fmt.Println("Starting database compactions. This may take a while...")
314+
}
315+
316+
for _, path := range dbDirs {
317+
if err := compactDB(path); err != nil {
318+
logger.Error("failed to compact", "path", path, "err", err)
319+
if pretty {
320+
fmt.Printf("Failed to compact %s: %v\n", path, err)
321+
}
322+
}
323+
}
324+
325+
return nil
326+
}
327+
328+
func findDBInstances(dataDir string) ([]string, error) {
329+
var dbDirs []string
330+
err := filepath.WalkDir(dataDir, func(path string, d fs.DirEntry, err error) error {
331+
if err != nil {
332+
return err
333+
}
334+
if d.IsDir() && strings.HasSuffix(d.Name(), ".db") {
335+
dbDirs = append(dbDirs, path)
336+
}
337+
return nil
338+
})
339+
if err != nil {
340+
return nil, fmt.Errorf("failed to walk dir %s: %w", dataDir, err)
341+
}
342+
343+
return dbDirs, nil
344+
}
345+
346+
func compactDB(path string) error {
347+
logger = logger.With("path", path)
348+
349+
logger.Info("compacting")
350+
if pretty {
351+
fmt.Printf("Compacting %s\n", path)
352+
}
353+
354+
opts := badgerDB.DefaultOptions(path).WithLogger(cmnBadger.NewLogAdapter(logger))
355+
db, err := badgerDB.Open(opts)
356+
if err != nil {
357+
return fmt.Errorf("failed to open db: %w", err)
358+
}
359+
defer db.Close()
360+
361+
if err := db.Flatten(8); err != nil {
362+
return fmt.Errorf("failed to flatten db: %w", err)
363+
364+
}
365+
366+
logger.Info("compaction completed")
367+
if pretty {
368+
fmt.Printf("Compaction completed: %s\n", path)
369+
}
370+
371+
return nil
372+
}
373+
286374
// Register registers the client sub-command and all of its children.
287375
func Register(parentCmd *cobra.Command) {
288376
storageMigrateCmd.Flags().AddFlagSet(bundle.Flags)
289377
storageCheckCmd.Flags().AddFlagSet(bundle.Flags)
290378
storageCmd.AddCommand(storageMigrateCmd)
291379
storageCmd.AddCommand(storageCheckCmd)
292380
storageCmd.AddCommand(storageRenameNsCmd)
381+
storageCmd.AddCommand(storageCompactCmd)
293382
parentCmd.AddCommand(storageCmd)
294383
}

0 commit comments

Comments
 (0)