Rename replicator to replica
This commit is contained in:
@@ -70,15 +70,15 @@ func (c *GenerationsCommand) Run(ctx context.Context, args []string) (err error)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over each replicator in the database.
|
// Iterate over each replica in the database.
|
||||||
for _, r := range db.Replicators {
|
for _, r := range db.Replicas {
|
||||||
generations, err := r.Generations(ctx)
|
generations, err := r.Generations(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("%s: cannot list generations", r.Name(), err)
|
log.Printf("%s: cannot list generations", r.Name(), err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Iterate over each generation for the replicator.
|
// Iterate over each generation for the replica.
|
||||||
for _, generation := range generations {
|
for _, generation := range generations {
|
||||||
stats, err := r.GenerationStats(ctx, generation)
|
stats, err := r.GenerationStats(ctx, generation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -134,8 +134,8 @@ type DBConfig struct {
|
|||||||
|
|
||||||
type ReplicaConfig struct {
|
type ReplicaConfig struct {
|
||||||
Type string `yaml:"type"` // "file", "s3"
|
Type string `yaml:"type"` // "file", "s3"
|
||||||
Name string `yaml:"name"` // name of replicator, optional.
|
Name string `yaml:"name"` // name of replica, optional.
|
||||||
Path string `yaml:"path"` // used for file replicators
|
Path string `yaml:"path"` // used for file replicas
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerConfigFlag(fs *flag.FlagSet, p *string) {
|
func registerConfigFlag(fs *flag.FlagSet, p *string) {
|
||||||
@@ -147,32 +147,32 @@ func newDBFromConfig(config *DBConfig) (*litestream.DB, error) {
|
|||||||
// Initialize database with given path.
|
// Initialize database with given path.
|
||||||
db := litestream.NewDB(config.Path)
|
db := litestream.NewDB(config.Path)
|
||||||
|
|
||||||
// Instantiate and attach replicators.
|
// Instantiate and attach replicas.
|
||||||
for _, rconfig := range config.Replicas {
|
for _, rconfig := range config.Replicas {
|
||||||
r, err := newReplicatorFromConfig(db, rconfig)
|
r, err := newReplicaFromConfig(db, rconfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
db.Replicators = append(db.Replicators, r)
|
db.Replicas = append(db.Replicas, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// newReplicatorFromConfig instantiates a replicator for a DB based on a config.
|
// newReplicaFromConfig instantiates a replica for a DB based on a config.
|
||||||
func newReplicatorFromConfig(db *litestream.DB, config *ReplicaConfig) (litestream.Replicator, error) {
|
func newReplicaFromConfig(db *litestream.DB, config *ReplicaConfig) (litestream.Replica, error) {
|
||||||
switch config.Type {
|
switch config.Type {
|
||||||
case "", "file":
|
case "", "file":
|
||||||
return newFileReplicatorFromConfig(db, config)
|
return newFileReplicaFromConfig(db, config)
|
||||||
default:
|
default:
|
||||||
return nil, fmt.Errorf("unknown replicator type in config: %q", config.Type)
|
return nil, fmt.Errorf("unknown replica type in config: %q", config.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// newFileReplicatorFromConfig returns a new instance of FileReplicator build from config.
|
// newFileReplicaFromConfig returns a new instance of FileReplica build from config.
|
||||||
func newFileReplicatorFromConfig(db *litestream.DB, config *ReplicaConfig) (*litestream.FileReplicator, error) {
|
func newFileReplicaFromConfig(db *litestream.DB, config *ReplicaConfig) (*litestream.FileReplica, error) {
|
||||||
if config.Path == "" {
|
if config.Path == "" {
|
||||||
return nil, fmt.Errorf("file replicator path require for db %q", db.Path())
|
return nil, fmt.Errorf("file replica path require for db %q", db.Path())
|
||||||
}
|
}
|
||||||
return litestream.NewFileReplicator(db, config.Name, config.Path), nil
|
return litestream.NewFileReplica(db, config.Name, config.Path), nil
|
||||||
}
|
}
|
||||||
|
|||||||
34
db.go
34
db.go
@@ -52,9 +52,9 @@ type DB struct {
|
|||||||
// unbounded if there are always read transactions occurring.
|
// unbounded if there are always read transactions occurring.
|
||||||
MaxCheckpointPageN int
|
MaxCheckpointPageN int
|
||||||
|
|
||||||
// List of replicators for the database.
|
// List of replicas for the database.
|
||||||
// Must be set before calling Open().
|
// Must be set before calling Open().
|
||||||
Replicators []Replicator
|
Replicas []Replica
|
||||||
|
|
||||||
// Frequency at which to perform db sync.
|
// Frequency at which to perform db sync.
|
||||||
MonitorInterval time.Duration
|
MonitorInterval time.Duration
|
||||||
@@ -154,11 +154,11 @@ func (db *DB) PageSize() int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) Open() (err error) {
|
func (db *DB) Open() (err error) {
|
||||||
// Validate that all replicator names are unique.
|
// Validate that all replica names are unique.
|
||||||
m := make(map[string]struct{})
|
m := make(map[string]struct{})
|
||||||
for _, r := range db.Replicators {
|
for _, r := range db.Replicas {
|
||||||
if _, ok := m[r.Name()]; ok {
|
if _, ok := m[r.Name()]; ok {
|
||||||
return fmt.Errorf("duplicate replicator name: %q", r.Name())
|
return fmt.Errorf("duplicate replica name: %q", r.Name())
|
||||||
}
|
}
|
||||||
m[r.Name()] = struct{}{}
|
m[r.Name()] = struct{}{}
|
||||||
}
|
}
|
||||||
@@ -276,7 +276,7 @@ func (db *DB) Init() (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start replication.
|
// Start replication.
|
||||||
for _, r := range db.Replicators {
|
for _, r := range db.Replicas {
|
||||||
r.Start(db.ctx)
|
r.Start(db.ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,8 +318,8 @@ func (db *DB) SoftClose() (err error) {
|
|||||||
db.cancel()
|
db.cancel()
|
||||||
db.wg.Wait()
|
db.wg.Wait()
|
||||||
|
|
||||||
// Ensure replicators all stop replicating.
|
// Ensure replicas all stop replicating.
|
||||||
for _, r := range db.Replicators {
|
for _, r := range db.Replicas {
|
||||||
r.Stop()
|
r.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ func (db *DB) CurrentGeneration() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// createGeneration starts a new generation by creating the generation
|
// createGeneration starts a new generation by creating the generation
|
||||||
// directory, snapshotting to each replicator, and updating the current
|
// directory, snapshotting to each replica, and updating the current
|
||||||
// generation name.
|
// generation name.
|
||||||
func (db *DB) createGeneration() (string, error) {
|
func (db *DB) createGeneration() (string, error) {
|
||||||
// Generate random generation hex name.
|
// Generate random generation hex name.
|
||||||
@@ -516,7 +516,7 @@ func (db *DB) Sync() (err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify replicators of WAL changes.
|
// Notify replicas of WAL changes.
|
||||||
if changed {
|
if changed {
|
||||||
close(db.notify)
|
close(db.notify)
|
||||||
db.notify = make(chan struct{})
|
db.notify = make(chan struct{})
|
||||||
@@ -1084,14 +1084,14 @@ func (db *DB) Restore(ctx context.Context, opt RestoreOptions) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) restoreTarget(ctx context.Context, opt RestoreOptions, logger *log.Logger) (Replicator, string, error) {
|
func (db *DB) restoreTarget(ctx context.Context, opt RestoreOptions, logger *log.Logger) (Replica, string, error) {
|
||||||
var target struct {
|
var target struct {
|
||||||
replicator Replicator
|
replica Replica
|
||||||
generation string
|
generation string
|
||||||
stats GenerationStats
|
stats GenerationStats
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, r := range db.Replicators {
|
for _, r := range db.Replicas {
|
||||||
// Skip replica if it does not match filter.
|
// Skip replica if it does not match filter.
|
||||||
if opt.ReplicaName != "" && r.Name() != opt.ReplicaName {
|
if opt.ReplicaName != "" && r.Name() != opt.ReplicaName {
|
||||||
continue
|
continue
|
||||||
@@ -1127,7 +1127,7 @@ func (db *DB) restoreTarget(ctx context.Context, opt RestoreOptions, logger *log
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
target.replicator = r
|
target.replica = r
|
||||||
target.generation = generation
|
target.generation = generation
|
||||||
target.stats = stats
|
target.stats = stats
|
||||||
}
|
}
|
||||||
@@ -1138,11 +1138,11 @@ func (db *DB) restoreTarget(ctx context.Context, opt RestoreOptions, logger *log
|
|||||||
return nil, "", fmt.Errorf("no matching backups found")
|
return nil, "", fmt.Errorf("no matching backups found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return target.replicator, target.generation, nil
|
return target.replica, target.generation, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// restoreSnapshot copies a snapshot from the replica to a file.
|
// restoreSnapshot copies a snapshot from the replica to a file.
|
||||||
func (db *DB) restoreSnapshot(ctx context.Context, r Replicator, generation string, index int, filename string) error {
|
func (db *DB) restoreSnapshot(ctx context.Context, r Replica, generation string, index int, filename string) error {
|
||||||
if err := os.MkdirAll(filepath.Dir(filename), 0700); err != nil {
|
if err := os.MkdirAll(filepath.Dir(filename), 0700); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -1170,7 +1170,7 @@ func (db *DB) restoreSnapshot(ctx context.Context, r Replicator, generation stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
// restoreWAL copies a WAL file from the replica to the local WAL and forces checkpoint.
|
// restoreWAL copies a WAL file from the replica to the local WAL and forces checkpoint.
|
||||||
func (db *DB) restoreWAL(ctx context.Context, r Replicator, generation string, index int, dbPath string) error {
|
func (db *DB) restoreWAL(ctx context.Context, r Replica, generation string, index int, dbPath string) error {
|
||||||
// Open handle to destination WAL path.
|
// Open handle to destination WAL path.
|
||||||
f, err := os.Create(dbPath + "-wal")
|
f, err := os.Create(dbPath + "-wal")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -15,13 +15,12 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Replicator represents a method for replicating the snapshot & WAL data to
|
// Replica represents a remote destination to replicate the database & WAL.
|
||||||
// a remote destination.
|
type Replica interface {
|
||||||
type Replicator interface {
|
// The name of the replica. Defaults to type if no name specified.
|
||||||
// The name of the replicator. Defaults to type if no name specified.
|
|
||||||
Name() string
|
Name() string
|
||||||
|
|
||||||
// String identifier for the type of replicator ("file", "s3", etc).
|
// String identifier for the type of replica ("file", "s3", etc).
|
||||||
Type() string
|
Type() string
|
||||||
|
|
||||||
// Starts replicating in a background goroutine.
|
// Starts replicating in a background goroutine.
|
||||||
@@ -30,7 +29,7 @@ type Replicator interface {
|
|||||||
// Stops all replication processing. Blocks until processing stopped.
|
// Stops all replication processing. Blocks until processing stopped.
|
||||||
Stop()
|
Stop()
|
||||||
|
|
||||||
// Returns a list of generation names for the replicator.
|
// Returns a list of generation names for the replica.
|
||||||
Generations(ctx context.Context) ([]string, error)
|
Generations(ctx context.Context) ([]string, error)
|
||||||
|
|
||||||
// Returns basic information about a generation including the number of
|
// Returns basic information about a generation including the number of
|
||||||
@@ -52,12 +51,12 @@ type Replicator interface {
|
|||||||
WALReader(ctx context.Context, generation string, index int) (io.ReadCloser, error)
|
WALReader(ctx context.Context, generation string, index int) (io.ReadCloser, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Replicator = (*FileReplicator)(nil)
|
var _ Replica = (*FileReplica)(nil)
|
||||||
|
|
||||||
// FileReplicator is a replicator that replicates a DB to a local file path.
|
// FileReplica is a replica that replicates a DB to a local file path.
|
||||||
type FileReplicator struct {
|
type FileReplica struct {
|
||||||
db *DB // source database
|
db *DB // source database
|
||||||
name string // replicator name, optional
|
name string // replica name, optional
|
||||||
dst string // destination path
|
dst string // destination path
|
||||||
|
|
||||||
// mu sync.RWMutex
|
// mu sync.RWMutex
|
||||||
@@ -67,9 +66,9 @@ type FileReplicator struct {
|
|||||||
cancel func()
|
cancel func()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFileReplicator returns a new instance of FileReplicator.
|
// NewFileReplica returns a new instance of FileReplica.
|
||||||
func NewFileReplicator(db *DB, name, dst string) *FileReplicator {
|
func NewFileReplica(db *DB, name, dst string) *FileReplica {
|
||||||
return &FileReplicator{
|
return &FileReplica{
|
||||||
db: db,
|
db: db,
|
||||||
name: name,
|
name: name,
|
||||||
dst: dst,
|
dst: dst,
|
||||||
@@ -77,41 +76,41 @@ func NewFileReplicator(db *DB, name, dst string) *FileReplicator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Name returns the name of the replicator. Returns the type if no name set.
|
// Name returns the name of the replica. Returns the type if no name set.
|
||||||
func (r *FileReplicator) Name() string {
|
func (r *FileReplica) Name() string {
|
||||||
if r.name != "" {
|
if r.name != "" {
|
||||||
return r.name
|
return r.name
|
||||||
}
|
}
|
||||||
return r.Type()
|
return r.Type()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Type returns the type of replicator.
|
// Type returns the type of replica.
|
||||||
func (r *FileReplicator) Type() string {
|
func (r *FileReplica) Type() string {
|
||||||
return "file"
|
return "file"
|
||||||
}
|
}
|
||||||
|
|
||||||
// SnapshotDir returns the path to a generation's snapshot directory.
|
// SnapshotDir returns the path to a generation's snapshot directory.
|
||||||
func (r *FileReplicator) SnapshotDir(generation string) string {
|
func (r *FileReplica) SnapshotDir(generation string) string {
|
||||||
return filepath.Join(r.dst, "generations", generation, "snapshots")
|
return filepath.Join(r.dst, "generations", generation, "snapshots")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SnapshotPath returns the path to a snapshot file.
|
// SnapshotPath returns the path to a snapshot file.
|
||||||
func (r *FileReplicator) SnapshotPath(generation string, index int) string {
|
func (r *FileReplica) SnapshotPath(generation string, index int) string {
|
||||||
return filepath.Join(r.SnapshotDir(generation), fmt.Sprintf("%016x.snapshot.gz", index))
|
return filepath.Join(r.SnapshotDir(generation), fmt.Sprintf("%016x.snapshot.gz", index))
|
||||||
}
|
}
|
||||||
|
|
||||||
// WALDir returns the path to a generation's WAL directory
|
// WALDir returns the path to a generation's WAL directory
|
||||||
func (r *FileReplicator) WALDir(generation string) string {
|
func (r *FileReplica) WALDir(generation string) string {
|
||||||
return filepath.Join(r.dst, "generations", generation, "wal")
|
return filepath.Join(r.dst, "generations", generation, "wal")
|
||||||
}
|
}
|
||||||
|
|
||||||
// WALPath returns the path to a WAL file.
|
// WALPath returns the path to a WAL file.
|
||||||
func (r *FileReplicator) WALPath(generation string, index int) string {
|
func (r *FileReplica) WALPath(generation string, index int) string {
|
||||||
return filepath.Join(r.WALDir(generation), fmt.Sprintf("%016x.wal", index))
|
return filepath.Join(r.WALDir(generation), fmt.Sprintf("%016x.wal", index))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generations returns a list of available generation names.
|
// Generations returns a list of available generation names.
|
||||||
func (r *FileReplicator) Generations(ctx context.Context) ([]string, error) {
|
func (r *FileReplica) Generations(ctx context.Context) ([]string, error) {
|
||||||
fis, err := ioutil.ReadDir(filepath.Join(r.dst, "generations"))
|
fis, err := ioutil.ReadDir(filepath.Join(r.dst, "generations"))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@@ -132,7 +131,7 @@ func (r *FileReplicator) Generations(ctx context.Context) ([]string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GenerationStats returns stats for a generation.
|
// GenerationStats returns stats for a generation.
|
||||||
func (r *FileReplicator) GenerationStats(ctx context.Context, generation string) (stats GenerationStats, err error) {
|
func (r *FileReplica) GenerationStats(ctx context.Context, generation string) (stats GenerationStats, err error) {
|
||||||
// Determine stats for all snapshots.
|
// Determine stats for all snapshots.
|
||||||
n, min, max, err := r.snapshotStats(generation)
|
n, min, max, err := r.snapshotStats(generation)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -159,7 +158,7 @@ func (r *FileReplicator) GenerationStats(ctx context.Context, generation string)
|
|||||||
return stats, nil
|
return stats, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FileReplicator) snapshotStats(generation string) (n int, min, max time.Time, err error) {
|
func (r *FileReplica) snapshotStats(generation string) (n int, min, max time.Time, err error) {
|
||||||
fis, err := ioutil.ReadDir(r.SnapshotDir(generation))
|
fis, err := ioutil.ReadDir(r.SnapshotDir(generation))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return n, min, max, nil
|
return n, min, max, nil
|
||||||
@@ -184,7 +183,7 @@ func (r *FileReplicator) snapshotStats(generation string) (n int, min, max time.
|
|||||||
return n, min, max, nil
|
return n, min, max, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FileReplicator) walStats(generation string) (n int, min, max time.Time, err error) {
|
func (r *FileReplica) walStats(generation string) (n int, min, max time.Time, err error) {
|
||||||
fis, err := ioutil.ReadDir(r.WALDir(generation))
|
fis, err := ioutil.ReadDir(r.WALDir(generation))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return n, min, max, nil
|
return n, min, max, nil
|
||||||
@@ -217,7 +216,7 @@ type GenerationStats struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start starts replication for a given generation.
|
// Start starts replication for a given generation.
|
||||||
func (r *FileReplicator) Start(ctx context.Context) {
|
func (r *FileReplica) Start(ctx context.Context) {
|
||||||
// Stop previous replication.
|
// Stop previous replication.
|
||||||
r.Stop()
|
r.Stop()
|
||||||
|
|
||||||
@@ -230,13 +229,13 @@ func (r *FileReplicator) Start(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop cancels any outstanding replication and blocks until finished.
|
// Stop cancels any outstanding replication and blocks until finished.
|
||||||
func (r *FileReplicator) Stop() {
|
func (r *FileReplica) Stop() {
|
||||||
r.cancel()
|
r.cancel()
|
||||||
r.wg.Wait()
|
r.wg.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
// monitor runs in a separate goroutine and continuously replicates the DB.
|
// monitor runs in a separate goroutine and continuously replicates the DB.
|
||||||
func (r *FileReplicator) monitor(ctx context.Context) {
|
func (r *FileReplica) monitor(ctx context.Context) {
|
||||||
// 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(r.dst); err != nil {
|
if err := removeTmpFiles(r.dst); err != nil {
|
||||||
log.Printf("%s(%s): cannot remove tmp files: %w", r.db.Path(), r.Name(), err)
|
log.Printf("%s(%s): cannot remove tmp files: %w", r.db.Path(), r.Name(), err)
|
||||||
@@ -294,9 +293,9 @@ func (r *FileReplicator) monitor(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// pos returns the position for the replicator for the current generation.
|
// pos returns the position for the replica for the current generation.
|
||||||
// Returns a zero value if there is no active generation.
|
// Returns a zero value if there is no active generation.
|
||||||
func (r *FileReplicator) pos() (pos Pos, err error) {
|
func (r *FileReplica) pos() (pos Pos, err error) {
|
||||||
// Find the current generation from the DB. Return zero pos if no generation.
|
// Find the current generation from the DB. Return zero pos if no generation.
|
||||||
generation, err := r.db.CurrentGeneration()
|
generation, err := r.db.CurrentGeneration()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -346,7 +345,7 @@ func (r *FileReplicator) pos() (pos Pos, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// snapshot copies the entire database to the replica path.
|
// snapshot copies the entire database to the replica path.
|
||||||
func (r *FileReplicator) snapshot(ctx context.Context, generation string, index int) error {
|
func (r *FileReplica) snapshot(ctx context.Context, generation string, index int) error {
|
||||||
// Acquire a read lock on the database during snapshot to prevent checkpoints.
|
// Acquire a read lock on the database during snapshot to prevent checkpoints.
|
||||||
tx, err := r.db.db.Begin()
|
tx, err := r.db.db.Begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -371,7 +370,7 @@ func (r *FileReplicator) snapshot(ctx context.Context, generation string, index
|
|||||||
}
|
}
|
||||||
|
|
||||||
// snapshotN returns the number of snapshots for a generation.
|
// snapshotN returns the number of snapshots for a generation.
|
||||||
func (r *FileReplicator) snapshotN(generation string) (int, error) {
|
func (r *FileReplica) snapshotN(generation string) (int, error) {
|
||||||
fis, err := ioutil.ReadDir(r.SnapshotDir(generation))
|
fis, err := ioutil.ReadDir(r.SnapshotDir(generation))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
@@ -388,7 +387,7 @@ func (r *FileReplicator) snapshotN(generation string) (int, error) {
|
|||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FileReplicator) sync(ctx context.Context, pos Pos) (_ Pos, err error) {
|
func (r *FileReplica) sync(ctx context.Context, pos Pos) (_ Pos, err error) {
|
||||||
// Read all WAL files since the last position.
|
// Read all WAL files since the last position.
|
||||||
for {
|
for {
|
||||||
if pos, err = r.syncNext(ctx, pos); err == io.EOF {
|
if pos, err = r.syncNext(ctx, pos); err == io.EOF {
|
||||||
@@ -399,7 +398,7 @@ func (r *FileReplicator) sync(ctx context.Context, pos Pos) (_ Pos, err error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *FileReplicator) syncNext(ctx context.Context, pos Pos) (_ Pos, err error) {
|
func (r *FileReplica) syncNext(ctx context.Context, pos Pos) (_ Pos, err error) {
|
||||||
rd, err := r.db.ShadowWALReader(pos)
|
rd, err := r.db.ShadowWALReader(pos)
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
return pos, err
|
return pos, err
|
||||||
@@ -446,7 +445,7 @@ func (r *FileReplicator) syncNext(ctx context.Context, pos Pos) (_ Pos, err erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compress gzips all WAL files before the current one.
|
// compress gzips all WAL files before the current one.
|
||||||
func (r *FileReplicator) compress(ctx context.Context, generation string) error {
|
func (r *FileReplica) compress(ctx context.Context, generation string) error {
|
||||||
dir := r.WALDir(generation)
|
dir := r.WALDir(generation)
|
||||||
filenames, err := filepath.Glob(filepath.Join(dir, "*.wal"))
|
filenames, err := filepath.Glob(filepath.Join(dir, "*.wal"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -480,7 +479,7 @@ func (r *FileReplicator) compress(ctx context.Context, generation string) error
|
|||||||
|
|
||||||
// SnapsotIndexAt returns the highest index for a snapshot within a generation
|
// SnapsotIndexAt returns the highest index for a snapshot within a generation
|
||||||
// that occurs before timestamp. If timestamp is zero, returns the latest snapshot.
|
// that occurs before timestamp. If timestamp is zero, returns the latest snapshot.
|
||||||
func (r *FileReplicator) SnapshotIndexAt(ctx context.Context, generation string, timestamp time.Time) (int, error) {
|
func (r *FileReplica) SnapshotIndexAt(ctx context.Context, generation string, timestamp time.Time) (int, error) {
|
||||||
fis, err := ioutil.ReadDir(r.SnapshotDir(generation))
|
fis, err := ioutil.ReadDir(r.SnapshotDir(generation))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return 0, ErrNoSnapshots
|
return 0, ErrNoSnapshots
|
||||||
@@ -513,7 +512,7 @@ func (r *FileReplicator) SnapshotIndexAt(ctx context.Context, generation string,
|
|||||||
|
|
||||||
// Returns the highest index for a WAL file that occurs before timestamp.
|
// Returns the highest index for a WAL file that occurs before timestamp.
|
||||||
// If timestamp is zero, returns the highest WAL index.
|
// If timestamp is zero, returns the highest WAL index.
|
||||||
func (r *FileReplicator) WALIndexAt(ctx context.Context, generation string, timestamp time.Time) (int, error) {
|
func (r *FileReplica) WALIndexAt(ctx context.Context, generation string, timestamp time.Time) (int, error) {
|
||||||
fis, err := ioutil.ReadDir(r.WALDir(generation))
|
fis, err := ioutil.ReadDir(r.WALDir(generation))
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
return 0, nil
|
return 0, nil
|
||||||
@@ -544,7 +543,7 @@ func (r *FileReplicator) WALIndexAt(ctx context.Context, generation string, time
|
|||||||
|
|
||||||
// SnapshotReader returns a reader for snapshot data at the given generation/index.
|
// SnapshotReader returns a reader for snapshot data at the given generation/index.
|
||||||
// Returns os.ErrNotExist if no matching index is found.
|
// Returns os.ErrNotExist if no matching index is found.
|
||||||
func (r *FileReplicator) SnapshotReader(ctx context.Context, generation string, index int) (io.ReadCloser, error) {
|
func (r *FileReplica) SnapshotReader(ctx context.Context, generation string, index int) (io.ReadCloser, error) {
|
||||||
dir := r.SnapshotDir(generation)
|
dir := r.SnapshotDir(generation)
|
||||||
fis, err := ioutil.ReadDir(dir)
|
fis, err := ioutil.ReadDir(dir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -581,7 +580,7 @@ func (r *FileReplicator) SnapshotReader(ctx context.Context, generation string,
|
|||||||
|
|
||||||
// WALReader returns a reader for WAL data at the given index.
|
// WALReader returns a reader for WAL data at the given index.
|
||||||
// Returns os.ErrNotExist if no matching index is found.
|
// Returns os.ErrNotExist if no matching index is found.
|
||||||
func (r *FileReplicator) WALReader(ctx context.Context, generation string, index int) (io.ReadCloser, error) {
|
func (r *FileReplica) WALReader(ctx context.Context, generation string, index int) (io.ReadCloser, error) {
|
||||||
filename := r.WALPath(generation, index)
|
filename := r.WALPath(generation, index)
|
||||||
|
|
||||||
// Attempt to read uncompressed file first.
|
// Attempt to read uncompressed file first.
|
||||||
|
|||||||
Reference in New Issue
Block a user