Browse Source

wal: use page buffered writer for writing records

Forces torn writes to only happen on sector boundaries.

Fixes #6271
Anthony Romano 9 years ago
parent
commit
28277b5a65
1 changed files with 8 additions and 3 deletions
  1. 8 3
      wal/encoder.go

+ 8 - 3
wal/encoder.go

@@ -15,19 +15,24 @@
 package wal
 package wal
 
 
 import (
 import (
-	"bufio"
 	"encoding/binary"
 	"encoding/binary"
 	"hash"
 	"hash"
 	"io"
 	"io"
 	"sync"
 	"sync"
 
 
 	"github.com/coreos/etcd/pkg/crc"
 	"github.com/coreos/etcd/pkg/crc"
+	"github.com/coreos/etcd/pkg/ioutil"
 	"github.com/coreos/etcd/wal/walpb"
 	"github.com/coreos/etcd/wal/walpb"
 )
 )
 
 
+// walPageBytes is the alignment for flushing records to the backing Writer.
+// It should be a multiple of the minimum sector size so that WAL repair can
+// safely between torn writes and ordinary data corruption.
+const walPageBytes = 8 * minSectorSize
+
 type encoder struct {
 type encoder struct {
 	mu sync.Mutex
 	mu sync.Mutex
-	bw *bufio.Writer
+	bw *ioutil.PageWriter
 
 
 	crc       hash.Hash32
 	crc       hash.Hash32
 	buf       []byte
 	buf       []byte
@@ -36,7 +41,7 @@ type encoder struct {
 
 
 func newEncoder(w io.Writer, prevCrc uint32) *encoder {
 func newEncoder(w io.Writer, prevCrc uint32) *encoder {
 	return &encoder{
 	return &encoder{
-		bw:  bufio.NewWriter(w),
+		bw:  ioutil.NewPageWriter(w, walPageBytes),
 		crc: crc.New(prevCrc, crcTable),
 		crc: crc.New(prevCrc, crcTable),
 		// 1MB buffer
 		// 1MB buffer
 		buf:       make([]byte, 1024*1024),
 		buf:       make([]byte, 1024*1024),