Documentation
¶
Index ¶
Examples ¶
Constants ¶
View Source
const (
// PageSize is the size of a page in Wal logfile
PageSize = 4096
)
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Transaction ¶
type Transaction struct {
ID uint64 // Each transaction is assigned a unique id
Operations []Operation // Each transaction is composed of a list of Operations
InitComplete chan struct{}
InitErr error
// contains filtered or unexported fields
}
Transaction is a batch of Operations to be committed as a whole
func (*Transaction) Append ¶
func (t *Transaction) Append(ops []Operation) <-chan error
Append appends additional updates to a transaction
func (*Transaction) Commit ¶
func (t *Transaction) Commit() <-chan error
Commit returns a error channel which will block until commit finished. The content is error nil if no error in commit, and error if there is an error
func (*Transaction) Release ¶
func (t *Transaction) Release() error
Release informs the WAL that it is safe to reuse t's pages.
type Wal ¶
type Wal struct {
// contains filtered or unexported fields
}
Wal is a golang implementation of write-ahead-log to perform ACID transactions
Example ¶
testDir := tempDir("ExampleWal")
_ = os.Mkdir(testDir, 0777)
// create a new wal
wal, txns, err := New(filepath.Join(testDir, "test.wal"))
if len(txns) != 0 {
fmt.Printf("Unexpected transaction number. Got %d, Expect %d\n", len(txns), 0)
return
}
if err != nil {
fmt.Printf("Cannot new wal: %v\n", err)
return
}
// struct to be modified
p := person{name: "jacky"}
newName := "wyx"
op := Operation{
Name: "person_rename",
Data: []byte(newName),
}
t, err := wal.NewTransaction([]Operation{op})
fmt.Println("Add a new transaction")
if err != nil {
fmt.Printf("new transaction error: %v\n", err)
return
}
p.name = newName
<-t.InitComplete
if t.InitErr != nil {
fmt.Println(t.InitErr)
return
}
commitDone := t.Commit()
if err := <-commitDone; err != nil {
fmt.Println("error commit")
return
}
err = wal.Close()
fmt.Printf("Close: %v\n", err)
// reopen
recoveredWal, recoveredTxn, err := New(filepath.Join(testDir, "test.wal"))
if err != nil {
fmt.Println("reopen wal error:", err)
return
}
if len(recoveredTxn) != 1 {
fmt.Printf("expected recovered txn 1, got %d\n", len(recoveredTxn))
return
}
for _, txn := range recoveredTxn {
for _, op := range txn.Operations {
p.name = string(op.Data)
err := p.saveToDisk(filepath.Join(testDir, "jacky_person.dat"))
if err != nil {
fmt.Printf("failed save to disk: %v", err)
return
}
}
txn.Release()
}
err = recoveredWal.Close()
if err != nil {
fmt.Printf("wal doesn't close clean: %v", err)
}
Output: Add a new transaction Close: wal closed with 1 unfinished transactions
func (*Wal) CloseIncomplete ¶
CloseIncomplete close the Wal. Return number of unfinished transactions, and an error for closing the logfile.
func (*Wal) NewTransaction ¶
func (w *Wal) NewTransaction(ops []Operation) (*Transaction, error)
NewTransaction create a new transaction. Start a thread to write the Operations to disk.
Click to show internal directories.
Click to hide internal directories.