litefs

package module
v0.1.0-alpha2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 22, 2022 License: Apache-2.0 Imports: 16 Imported by: 1

README

litefs

A FUSE filesystem for replicating SQLite databases.

Development

To develop & test LiteFS, you must run an instance of Consul. To run a Consul agent in dev mode, run the following:

consul agent -dev

Consul should then be available at http://localhost:8500

Documentation

Index

Constants

View Source
const (
	/// Magic header string that identifies a SQLite journal header.
	/// https://www.sqlite.org/fileformat.html#the_rollback_journal
	SQLITE_JOURNAL_HEADER_STRING = "\xd9\xd5\x05\xf9\x20\xa1\x63\xd7"

	// Location of the database size, in pages, in the main database file.
	SQLITE_DATABASE_SIZE_OFFSET = 28
)
View Source
const (
	LockTypePending  = 0x40000000
	LockTypeReserved = 0x40000001
	LockTypeShared   = 0x40000002
)
View Source
const (
	WALHeaderSize      = 32
	WALFrameHeaderSize = 24
	WALIndexHeaderSize = 136
)

SQLite constants

View Source
const (
	PENDING_BYTE  = 0x40000000
	RESERVED_BYTE = (PENDING_BYTE + 1)
	SHARED_FIRST  = (PENDING_BYTE + 2)
	SHARED_SIZE   = 510
)

SQLite rollback journal lock constants.

View Source
const (
	WAL_WRITE_LOCK   = 120
	WAL_CKPT_LOCK    = 121
	WAL_RECOVER_LOCK = 122
	WAL_READ_LOCK0   = 123
	WAL_READ_LOCK1   = 124
	WAL_READ_LOCK2   = 125
	WAL_READ_LOCK3   = 126
	WAL_READ_LOCK4   = 127
)

SQLite WAL lock constants.

View Source
const (
	F_OFD_GETLK  = 36
	F_OFD_SETLK  = 37
	F_OFD_SETLKW = 38
)

Open file description lock constants.

View Source
const (
	JournalModeDelete   = "DELETE"
	JournalModeTruncate = "TRUNCATE"
	JournalModePersist  = "PERSIST"
	JournalModeWAL      = "WAL"
)
View Source
const (
	FileTypeNone = FileType(iota)
	FileTypeDatabase
	FileTypeJournal
	FileTypeWAL
	FileTypeSHM
)

SQLite file types.

View Source
const (
	StreamFrameTypeDB  = StreamFrameType(1)
	StreamFrameTypeLTX = StreamFrameType(2)
)
View Source
const (
	RWMutexStateUnlocked = iota
	RWMutexStateShared
	RWMutexStateExclusive
)
View Source
const PageSize = 4096

Variables

View Source
var (
	ErrDatabaseNotFound = fmt.Errorf("database not found")
	ErrDatabaseExists   = fmt.Errorf("database already exists")

	ErrNoPrimary     = errors.New("no primary")
	ErrPrimaryExists = errors.New("primary exists")
	ErrLeaseExpired  = errors.New("lease expired")

	ErrReadOnlyReplica = fmt.Errorf("read only replica")
)

LiteFS errors

Functions

func FormatDBID

func FormatDBID(id uint32) string

FormatDBID formats id as a 16-character hex string.

func ParseDBID

func ParseDBID(s string) (uint32, error)

ParseDBID parses a 16-character hex string into a database ID.

func TrimName

func TrimName(name string) string

TrimName removes "-journal", "-shm" or "-wal" from the given name.

func WriteStreamFrame

func WriteStreamFrame(w io.Writer, f StreamFrame) error

WriteStreamFrame writes the stream type & frame to the writer.

Types

type Client

type Client interface {
	// Stream starts a long-running connection to stream changes from another node.
	Stream(ctx context.Context, rawurl string, posMap map[uint32]Pos) (StreamReader, error)
}

Client represents a client for connecting to other LiteFS nodes.

type DB

type DB struct {
	// contains filtered or unexported fields
}

DB represents a SQLite database.

func NewDB

func NewDB(store *Store, id uint32, path string) *DB

NewDB returns a new instance of DB.

func (*DB) CommitJournal

func (db *DB) CommitJournal(mode JournalMode) error

CommitJournal deletes the journal file which commits or rolls back the transaction.

func (*DB) CreateJournal

func (db *DB) CreateJournal() (*os.File, error)

CreateJournal creates a new journal file on disk.

func (*DB) ID

func (db *DB) ID() uint32

ID returns the database ID.

func (*DB) InWriteTx

func (db *DB) InWriteTx() bool

InWriteTx returns true if the RESERVED lock has an exclusive lock.

func (*DB) LTXDir

func (db *DB) LTXDir() string

LTXDir returns the path to the directory of LTX transaction files.

func (*DB) LTXPath

func (db *DB) LTXPath(minTXID, maxTXID uint64) string

LTXPath returns the path of an LTX file.

func (*DB) Name

func (db *DB) Name() string

Name of the database name.

func (*DB) Open

func (db *DB) Open() error

Open initializes the database from files in its data directory.

func (*DB) OpenLTXFile

func (db *DB) OpenLTXFile(txID uint64) (*os.File, error)

OpenLTXFile returns a file handle to an LTX file that contains the given TXID.

func (*DB) Path

func (db *DB) Path() string

Path of the database's data directory.

func (*DB) PendingLock

func (db *DB) PendingLock() *RWMutex

func (*DB) Pos

func (db *DB) Pos() Pos

Pos returns the current transaction position of the database.

func (*DB) ReservedLock

func (db *DB) ReservedLock() *RWMutex

func (*DB) SharedLock

func (db *DB) SharedLock() *RWMutex

func (*DB) TXID

func (db *DB) TXID() uint64

TXID returns the current transaction ID.

func (*DB) TryApplyLTX

func (db *DB) TryApplyLTX(path string) error

TryApplyLTX attempts to apply an LTX file to the database.

func (*DB) WriteDatabase

func (db *DB) WriteDatabase(f *os.File, data []byte, offset int64) error

WriteDatabase writes data to the main database file.

func (*DB) WriteJournal

func (db *DB) WriteJournal(f *os.File, data []byte, offset int64) error

WriteJournal writes data to the rollback journal file.

type DBStreamFrame

type DBStreamFrame struct {
	DBID uint32
	Name string
}

DBStreamFrame represents a frame with basic database information. This is sent at the beginning of the stream and when a new database is created.

func (*DBStreamFrame) ReadFrom

func (f *DBStreamFrame) ReadFrom(r io.Reader) (int64, error)

func (*DBStreamFrame) Type

Type returns the type of stream frame.

func (*DBStreamFrame) WriteTo

func (f *DBStreamFrame) WriteTo(w io.Writer) (int64, error)

type FileType

type FileType int

FileType represents a type of SQLite file.

func (FileType) IsValid

func (t FileType) IsValid() bool

IsValid returns true if t is a valid file type.

type InodeNotifier

type InodeNotifier interface {
	InodeNotify(dbID uint32, off int64, length int64) error
}

InodeNotifier is a callback for the store to use to invalidate the kernel page cache.

type JournalMode

type JournalMode string

JournalMode represents a SQLite journal mode.

type LTXStreamFrame

type LTXStreamFrame struct {
	Size int64
}

func (*LTXStreamFrame) ReadFrom

func (f *LTXStreamFrame) ReadFrom(r io.Reader) (int64, error)

func (*LTXStreamFrame) Type

Type returns the type of stream frame.

func (*LTXStreamFrame) WriteTo

func (f *LTXStreamFrame) WriteTo(w io.Writer) (int64, error)

type Lease

type Lease interface {
	RenewedAt() time.Time
	TTL() time.Duration

	// Renew attempts to reset the TTL on the lease.
	// Returns ErrLeaseExpired if the lease has expired or was deleted.
	Renew(ctx context.Context) error

	// Close attempts to remove the lease from the server.
	Close() error
}

Lease represents an acquired lease from a Leaser.

type Leaser

type Leaser interface {
	io.Closer

	AdvertiseURL() string

	// Acquire attempts to acquire the lease to become the primary.
	Acquire(ctx context.Context) (Lease, error)

	// PrimaryURL attempts to read the current primary URL.
	// Returns ErrNoPrimary if no primary has the lease.
	PrimaryURL(ctx context.Context) (string, error)
}

Leaser represents an API for obtaining a lease for leader election.

type LockType

type LockType int

LockType represents a SQLite lock type.

func ParseLockRange

func ParseLockRange(start, end uint64) []LockType

ParseLockRange returns a list of SQLite locks that are within a range.

type Pos

type Pos struct {
	TXID   uint64
	Chksum uint64
}

Pos represents the transactional position of a database.

func (Pos) IsZero

func (p Pos) IsZero() bool

IsZero returns true if the position is empty.

type RWMutex

type RWMutex struct {
	// contains filtered or unexported fields
}

RWMutex is a reader/writer mutual exclusion lock. It wraps the sync package to provide additional capabilities such as lock upgrades & downgrades. It only supports TryLock() & TryRLock() as that is what's supported by our FUSE file system.

func (*RWMutex) CanLock

func (rw *RWMutex) CanLock() bool

CanLock returns true if the write lock could be acquired.

func (*RWMutex) CanRLock

func (rw *RWMutex) CanRLock() bool

CanRLock returns true if the read lock could be acquired.

func (*RWMutex) State

func (rw *RWMutex) State() RWMutexState

State returns whether the mutex has a exclusive lock, one or more shared locks, or if the mutex is unlocked.

func (*RWMutex) TryLock

func (rw *RWMutex) TryLock() *RWMutexGuard

TryLock tries to lock the mutex for writing and returns a guard if it succeeds.

func (*RWMutex) TryRLock

func (rw *RWMutex) TryRLock() *RWMutexGuard

TryRLock tries to lock rw for reading and reports whether it succeeded.

type RWMutexGuard

type RWMutexGuard struct {
	// contains filtered or unexported fields
}

RWMutexGuard is a reference to a held lock.

func (*RWMutexGuard) CanLock

func (g *RWMutexGuard) CanLock() bool

CanLock returns true if the guard can become an exclusive lock.

func (*RWMutexGuard) RLock

func (g *RWMutexGuard) RLock()

RLock downgrades the lock from an exclusive lock to a shared lock. This is a no-op if the lock is already a shared lock.

func (*RWMutexGuard) TryLock

func (g *RWMutexGuard) TryLock() bool

TryLock upgrades the lock from a shared lock to an exclusive lock. This is a no-op if the lock is already an exclusive lock.

func (*RWMutexGuard) Unlock

func (g *RWMutexGuard) Unlock()

Unlock unlocks the underlying mutex. Guard must be discarded after Unlock().

type RWMutexState

type RWMutexState int

RWMutexState represents the lock state of an RWMutexGuard.

type Store

type Store struct {

	// Client used to connect to other LiteFS instances.
	Client Client

	// Leaser manages the lease that controls leader election.
	Leaser Leaser

	// Callback to notify kernel of inode changes.
	InodeNotifier InodeNotifier
	// contains filtered or unexported fields
}

Store represents a collection of databases.

func NewStore

func NewStore(path string) *Store

NewStore returns a new instance of Store.

func (*Store) Close

func (s *Store) Close() error

Close signals for the store to shut down.

func (*Store) CreateDB

func (s *Store) CreateDB(name string) (*DB, *os.File, error)

CreateDB creates a new database with the given name. The returned file handle must be closed by the caller. Returns an error if a database with the same name already exists.

func (*Store) DB

func (s *Store) DB(id uint32) *DB

DB returns a database by ID. Returns nil if the database does not exist.

func (*Store) DBByName

func (s *Store) DBByName(name string) *DB

DBByName returns a database by name. Returns nil if the database does not exist.

func (*Store) DBDir

func (s *Store) DBDir(id uint32) string

DBDir returns the folder that stores a single database.

func (*Store) DBs

func (s *Store) DBs() []*DB

DBs returns a list of databases.

func (*Store) ForceCreateDB

func (s *Store) ForceCreateDB(id uint32, name string) (*DB, error)

ForceCreateDB creates a database with the given ID & name. This occurs when replicating from a primary server.

func (*Store) IsPrimary

func (s *Store) IsPrimary() bool

IsPrimary returns true if store has a lease to be the primary.

func (*Store) MarkDirty

func (s *Store) MarkDirty(dbID uint32)

MarkDirty marks a database ID dirty on all subscribers.

func (*Store) Open

func (s *Store) Open() error

Open initializes the store based on files in the data directory.

func (*Store) Path

func (s *Store) Path() string

Path returns underlying data directory.

func (*Store) PosMap

func (s *Store) PosMap() map[uint32]Pos

PosMap returns a map of databases and their transactional position.

func (*Store) PrimaryURL

func (s *Store) PrimaryURL() string

PrimaryURL returns the advertising URL of the current primary.

func (*Store) Subscribe

func (s *Store) Subscribe() *Subscriber

Subscribe creates a new subscriber for store changes.

func (*Store) Unsubscribe

func (s *Store) Unsubscribe(sub *Subscriber)

Unsubscribe removes a subscriber from the store.

type StreamFrame

type StreamFrame interface {
	io.ReaderFrom
	io.WriterTo
	Type() StreamFrameType
}

func ReadStreamFrame

func ReadStreamFrame(r io.Reader) (StreamFrame, error)

ReadStreamFrame reads a the stream type & frame from the reader.

type StreamFrameType

type StreamFrameType uint32

type StreamReader

type StreamReader interface {
	io.ReadCloser

	// NextFrame reads the next frame from the stream. After a frame is read,
	// it may have a payload that can be read via Read() until io.EOF.
	NextFrame() (StreamFrame, error)
}

StreamReader represents a stream of changes from a primary server.

type Subscriber

type Subscriber struct {
	// contains filtered or unexported fields
}

Subscriber subscribes to changes to databases in the store.

It implements a set of "dirty" databases instead of a channel of all events as clients can be slow and we don't want to cause channels to back up. It is the responsibility of the caller to determine the state changes which is usually just checking the position of the client versus the store's database.

func (*Subscriber) Close

func (s *Subscriber) Close() error

Close removes the subscriber from the store.

func (*Subscriber) DirtySet

func (s *Subscriber) DirtySet() map[uint32]struct{}

DirtySet returns a set of database IDs that have changed since the last call to DirtySet(). This call clears the set.

func (*Subscriber) MarkDirty

func (s *Subscriber) MarkDirty(dbID uint32)

MarkDirty marks a database ID as dirty.

func (*Subscriber) NotifyCh

func (s *Subscriber) NotifyCh() <-chan struct{}

NotifyCh returns a channel that receives a value when the dirty set has changed.

Directories

Path Synopsis
cmd
litefs command
go:build linux
go:build linux

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL