Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 73 additions & 3 deletions cmd/juno/dbcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
"errors"
"fmt"
"os"
"runtime"
"strconv"
"time"

"github.com/NethermindEth/juno/blockchain"
"github.com/NethermindEth/juno/blockchain/networks"
Expand All @@ -22,6 +25,7 @@

const (
dbRevertToBlockF = "to-block"
dbCompactForceF = "force"
)

type DBInfo struct {
Expand All @@ -44,7 +48,7 @@

dbCmd.PersistentFlags().String(dbPathF, defaultDBPath, dbPathUsage)
dbCmd.PersistentFlags().Bool(newStateF, defaultNewState, newStateUsage)
dbCmd.AddCommand(DBInfoCmd(), DBSizeCmd(), DBRevertCmd())
dbCmd.AddCommand(DBInfoCmd(), DBSizeCmd(), DBRevertCmd(), DBCompactCmd())
return dbCmd
}

Expand Down Expand Up @@ -78,6 +82,72 @@
return cmd
}

func DBCompactCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "compact",
Short: "Compact the database so current table options apply to existing data",
Long: `This subcommand compacts the full key range with the current table options ` +
`(bloom filters, compression). Without --force, data already settled in the ` +
`bottom level — most of an aged database — is not rewritten; pass --force to ` +
`rewrite every sstable. It may take a long time and needs enough free disk ` +
`space to hold rewritten tables while old ones are dropped.`,
RunE: dbCompact,
}
cmd.Flags().String(dbCompressionF, "",
dbCompressionUsage+" Required: rewritten data is stored with it.")
cmd.Flags().Bool(dbCompactForceF, false,
"Rewrite every sstable even if the database is already fully compacted")
cmd.Flags().String(dbCompactionConcurrencyF, strconv.Itoa(runtime.GOMAXPROCS(0)),
"Number of concurrent compactions; the database is held exclusively, so default to all cores")

return cmd
}

func dbCompact(cmd *cobra.Command, args []string) error {
dbPath, err := cmd.Flags().GetString(dbPathF)
if err != nil {
return err

Check warning on line 109 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L106-L109

Added lines #L106 - L109 were not covered by tests
}

compression, err := cmd.Flags().GetString(dbCompressionF)
if err != nil {
return err

Check warning on line 114 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L112-L114

Added lines #L112 - L114 were not covered by tests
}
if compression == "" {
return fmt.Errorf("--%s is required: compaction stores rewritten data with it", dbCompressionF)

Check warning on line 117 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L116-L117

Added lines #L116 - L117 were not covered by tests
}

force, err := cmd.Flags().GetBool(dbCompactForceF)
if err != nil {
return err

Check warning on line 122 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L120-L122

Added lines #L120 - L122 were not covered by tests
}

concurrency, err := cmd.Flags().GetString(dbCompactionConcurrencyF)
if err != nil {
return err

Check warning on line 127 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L125-L127

Added lines #L125 - L127 were not covered by tests
}

database, err := openDB(
dbPath,
pebblev2.WithCompression(compression),
pebblev2.WithCompactionConcurrency(concurrency),
pebblev2.WithOfflineCompaction(),
)
if err != nil {
return err

Check warning on line 137 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L130-L137

Added lines #L130 - L137 were not covered by tests
}
defer database.Close()

Check warning on line 139 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L139

Added line #L139 was not covered by tests

fmt.Fprintln(cmd.OutOrStdout(), "Compacting the whole database, this may take a while")
start := time.Now()
if err := database.(*pebblev2.DB).CompactAll(cmd.Context(), force); err != nil {
return fmt.Errorf("compacting database: %w", err)

Check warning on line 144 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L141-L144

Added lines #L141 - L144 were not covered by tests
}
fmt.Fprintf(cmd.OutOrStdout(), "Compaction finished in %s\n", time.Since(start).Round(time.Second))

Check warning on line 146 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L146

Added line #L146 was not covered by tests

return nil

Check warning on line 148 in cmd/juno/dbcmd.go

View check run for this annotation

Codecov / codecov/patch

cmd/juno/dbcmd.go#L148

Added line #L148 was not covered by tests
}

func dbInfo(cmd *cobra.Command, args []string) error {
dbPath, err := cmd.Flags().GetString(dbPathF)
if err != nil {
Expand Down Expand Up @@ -355,13 +425,13 @@
return "unknown"
}

func openDB(path string) (db.KeyValueStore, error) {
func openDB(path string, options ...pebblev2.Option) (db.KeyValueStore, error) {
_, err := os.Stat(path)
if os.IsNotExist(err) {
return nil, errors.New("database path does not exist")
}

database, err := pebblev2.New(path)
database, err := pebblev2.New(path, append(options, pebblev2.WithBloomFilter())...)
if err != nil {
return nil, fmt.Errorf("failed to open db: %w", err)
}
Expand Down
Loading
Loading