Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5220433

Browse files
committedMar 10, 2016
use tx.meta during Tx.WriteTo()
This commit changes `Tx.WriteTo()` to use the transaction's in-memory meta page instead of copying from the disk. This is needed because the transaction uses the size from its meta page but writes the current meta page on disk which may have allocated additional pages since the transaction started. Fixes boltdb#513
1 parent b514920 commit 5220433

File tree

2 files changed

+28
-6
lines changed

2 files changed

+28
-6
lines changed
 

‎tx.go

+27-5
Original file line numberDiff line numberDiff line change
@@ -297,12 +297,34 @@ func (tx *Tx) WriteTo(w io.Writer) (n int64, err error) {
297297
}
298298
defer func() { _ = f.Close() }()
299299

300-
// Copy the meta pages.
301-
tx.db.metalock.Lock()
302-
n, err = io.CopyN(w, f, int64(tx.db.pageSize*2))
303-
tx.db.metalock.Unlock()
300+
// Generate a meta page. We use the same page data for both meta pages.
301+
buf := make([]byte, tx.db.pageSize)
302+
page := (*page)(unsafe.Pointer(&buf[0]))
303+
page.flags = metaPageFlag
304+
*page.meta() = *tx.meta
305+
306+
// Write meta 0.
307+
page.id = 0
308+
page.meta().checksum = page.meta().sum64()
309+
nn, err := w.Write(buf)
310+
n += int64(nn)
311+
if err != nil {
312+
return n, fmt.Errorf("meta 0 copy: %s", err)
313+
}
314+
315+
// Write meta 1 with a lower transaction id.
316+
page.id = 1
317+
page.meta().txid -= 1
318+
page.meta().checksum = page.meta().sum64()
319+
nn, err = w.Write(buf)
320+
n += int64(nn)
304321
if err != nil {
305-
return n, fmt.Errorf("meta copy: %s", err)
322+
return n, fmt.Errorf("meta 1 copy: %s", err)
323+
}
324+
325+
// Move past the meta pages in the file.
326+
if _, err := f.Seek(int64(tx.db.pageSize*2), os.SEEK_SET); err != nil {
327+
return n, fmt.Errorf("seek: %s", err)
306328
}
307329

308330
// Copy data pages.

‎tx_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ func TestTx_CopyFile_Error_Meta(t *testing.T) {
570570

571571
if err := db.View(func(tx *bolt.Tx) error {
572572
return tx.Copy(&failWriter{})
573-
}); err == nil || err.Error() != "meta copy: error injected for tests" {
573+
}); err == nil || err.Error() != "meta 0 copy: error injected for tests" {
574574
t.Fatalf("unexpected error: %v", err)
575575
}
576576
}

0 commit comments

Comments
 (0)
Please sign in to comment.