Allow DB.MetaPath to be configured (#485)

This commit is contained in:
Ben Toews
2023-06-09 10:26:51 -06:00
committed by GitHub
parent 2045363cd1
commit 749bc0d95a
2 changed files with 22 additions and 10 deletions

View File

@@ -247,6 +247,7 @@ func ReadConfigFile(filename string, expandEnv bool) (_ Config, err error) {
// DBConfig represents the configuration for a single database. // DBConfig represents the configuration for a single database.
type DBConfig struct { type DBConfig struct {
Path string `yaml:"path"` Path string `yaml:"path"`
MetaPath *string `yaml:"meta-path"`
MonitorInterval *time.Duration `yaml:"monitor-interval"` MonitorInterval *time.Duration `yaml:"monitor-interval"`
CheckpointInterval *time.Duration `yaml:"checkpoint-interval"` CheckpointInterval *time.Duration `yaml:"checkpoint-interval"`
MinCheckpointPageN *int `yaml:"min-checkpoint-page-count"` MinCheckpointPageN *int `yaml:"min-checkpoint-page-count"`
@@ -266,6 +267,9 @@ func NewDBFromConfig(dbc *DBConfig) (*litestream.DB, error) {
db := litestream.NewDB(path) db := litestream.NewDB(path)
// Override default database settings if specified in configuration. // Override default database settings if specified in configuration.
if dbc.MetaPath != nil {
db.SetMetaPath(*dbc.MetaPath)
}
if dbc.MonitorInterval != nil { if dbc.MonitorInterval != nil {
db.MonitorInterval = *dbc.MonitorInterval db.MonitorInterval = *dbc.MonitorInterval
} }

28
db.go
View File

@@ -44,6 +44,7 @@ const BusyTimeout = 1 * time.Second
type DB struct { type DB struct {
mu sync.RWMutex mu sync.RWMutex
path string // part to database path string // part to database
metaPath string // Path to the database metadata.
db *sql.DB // target database db *sql.DB // target database
f *os.File // long-running db file descriptor f *os.File // long-running db file descriptor
rtx *sql.Tx // long running read transaction rtx *sql.Tx // long running read transaction
@@ -101,9 +102,12 @@ type DB struct {
// NewDB returns a new instance of DB for a given path. // NewDB returns a new instance of DB for a given path.
func NewDB(path string) *DB { func NewDB(path string) *DB {
dir, file := filepath.Split(path)
db := &DB{ db := &DB{
path: path, path: path,
notify: make(chan struct{}), metaPath: filepath.Join(dir, "."+file+MetaDirSuffix),
notify: make(chan struct{}),
MinCheckpointPageN: DefaultMinCheckpointPageN, MinCheckpointPageN: DefaultMinCheckpointPageN,
MaxCheckpointPageN: DefaultMaxCheckpointPageN, MaxCheckpointPageN: DefaultMaxCheckpointPageN,
@@ -147,20 +151,24 @@ func (db *DB) WALPath() string {
// MetaPath returns the path to the database metadata. // MetaPath returns the path to the database metadata.
func (db *DB) MetaPath() string { func (db *DB) MetaPath() string {
dir, file := filepath.Split(db.path) return db.metaPath
return filepath.Join(dir, "."+file+MetaDirSuffix) }
// SetMetaPath sets the path to database metadata.
func (db *DB) SetMetaPath(mp string) {
db.metaPath = mp
} }
// GenerationNamePath returns the path of the name of the current generation. // GenerationNamePath returns the path of the name of the current generation.
func (db *DB) GenerationNamePath() string { func (db *DB) GenerationNamePath() string {
return filepath.Join(db.MetaPath(), "generation") return filepath.Join(db.metaPath, "generation")
} }
// GenerationPath returns the path of a single generation. // GenerationPath returns the path of a single generation.
// Panics if generation is blank. // Panics if generation is blank.
func (db *DB) GenerationPath(generation string) string { func (db *DB) GenerationPath(generation string) string {
assert(generation != "", "generation name required") assert(generation != "", "generation name required")
return filepath.Join(db.MetaPath(), "generations", generation) return filepath.Join(db.metaPath, "generations", generation)
} }
// ShadowWALDir returns the path of the shadow wal directory. // ShadowWALDir returns the path of the shadow wal directory.
@@ -283,7 +291,7 @@ func (db *DB) Open() (err error) {
} }
// Clear old temporary files that my have been left from a crash. // Clear old temporary files that my have been left from a crash.
if err := removeTmpFiles(db.MetaPath()); err != nil { if err := removeTmpFiles(db.metaPath); err != nil {
return fmt.Errorf("cannot remove tmp files: %w", err) return fmt.Errorf("cannot remove tmp files: %w", err)
} }
@@ -446,7 +454,7 @@ func (db *DB) init() (err error) {
} }
// Ensure meta directory structure exists. // Ensure meta directory structure exists.
if err := internal.MkdirAll(db.MetaPath(), db.dirInfo); err != nil { if err := internal.MkdirAll(db.metaPath, db.dirInfo); err != nil {
return err return err
} }
@@ -522,7 +530,7 @@ func (db *DB) cleanGenerations() error {
return err return err
} }
dir := filepath.Join(db.MetaPath(), "generations") dir := filepath.Join(db.metaPath, "generations")
fis, err := ioutil.ReadDir(dir) fis, err := ioutil.ReadDir(dir)
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil return nil
@@ -652,7 +660,7 @@ func (db *DB) createGeneration() (string, error) {
generation := hex.EncodeToString(buf) generation := hex.EncodeToString(buf)
// Generate new directory. // Generate new directory.
dir := filepath.Join(db.MetaPath(), "generations", generation) dir := filepath.Join(db.metaPath, "generations", generation)
if err := internal.MkdirAll(dir, db.dirInfo); err != nil { if err := internal.MkdirAll(dir, db.dirInfo); err != nil {
return "", err return "", err
} }