mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
volume: add deletion capability for previously readonly volumes
This commit is contained in:
parent
deb03ecfa3
commit
f61de28c69
|
@ -4,12 +4,13 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||||
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
|
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
|
||||||
"github.com/chrislusf/seaweedfs/weed/stats"
|
"github.com/chrislusf/seaweedfs/weed/stats"
|
||||||
"github.com/chrislusf/seaweedfs/weed/storage/needle"
|
"github.com/chrislusf/seaweedfs/weed/storage/needle"
|
||||||
. "github.com/chrislusf/seaweedfs/weed/storage/types"
|
. "github.com/chrislusf/seaweedfs/weed/storage/types"
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -140,7 +141,7 @@ func (s *Store) VolumeInfos() []*VolumeInfo {
|
||||||
FileCount: int(v.FileCount()),
|
FileCount: int(v.FileCount()),
|
||||||
DeleteCount: int(v.DeletedCount()),
|
DeleteCount: int(v.DeletedCount()),
|
||||||
DeletedByteCount: v.DeletedSize(),
|
DeletedByteCount: v.DeletedSize(),
|
||||||
ReadOnly: v.readOnly,
|
ReadOnly: v.noWriteOrDelete || v.noWriteCanDelete,
|
||||||
Ttl: v.Ttl,
|
Ttl: v.Ttl,
|
||||||
CompactRevision: uint32(v.CompactionRevision),
|
CompactRevision: uint32(v.CompactionRevision),
|
||||||
}
|
}
|
||||||
|
@ -224,7 +225,7 @@ func (s *Store) Close() {
|
||||||
|
|
||||||
func (s *Store) WriteVolumeNeedle(i needle.VolumeId, n *needle.Needle) (size uint32, isUnchanged bool, err error) {
|
func (s *Store) WriteVolumeNeedle(i needle.VolumeId, n *needle.Needle) (size uint32, isUnchanged bool, err error) {
|
||||||
if v := s.findVolume(i); v != nil {
|
if v := s.findVolume(i); v != nil {
|
||||||
if v.readOnly {
|
if v.noWriteOrDelete || v.noWriteCanDelete {
|
||||||
err = fmt.Errorf("volume %d is read only", i)
|
err = fmt.Errorf("volume %d is read only", i)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -242,7 +243,7 @@ func (s *Store) WriteVolumeNeedle(i needle.VolumeId, n *needle.Needle) (size uin
|
||||||
|
|
||||||
func (s *Store) DeleteVolumeNeedle(i needle.VolumeId, n *needle.Needle) (uint32, error) {
|
func (s *Store) DeleteVolumeNeedle(i needle.VolumeId, n *needle.Needle) (uint32, error) {
|
||||||
if v := s.findVolume(i); v != nil {
|
if v := s.findVolume(i); v != nil {
|
||||||
if v.readOnly {
|
if v.noWriteOrDelete {
|
||||||
return 0, fmt.Errorf("volume %d is read only", i)
|
return 0, fmt.Errorf("volume %d is read only", i)
|
||||||
}
|
}
|
||||||
if MaxPossibleVolumeSize >= v.ContentSize()+uint64(needle.GetActualSize(0, v.version)) {
|
if MaxPossibleVolumeSize >= v.ContentSize()+uint64(needle.GetActualSize(0, v.version)) {
|
||||||
|
@ -274,7 +275,7 @@ func (s *Store) MarkVolumeReadonly(i needle.VolumeId) error {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return fmt.Errorf("volume %d not found", i)
|
return fmt.Errorf("volume %d not found", i)
|
||||||
}
|
}
|
||||||
v.readOnly = true
|
v.noWriteOrDelete = true
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@ package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"path"
|
||||||
|
"strconv"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
|
"github.com/chrislusf/seaweedfs/weed/pb/master_pb"
|
||||||
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
|
"github.com/chrislusf/seaweedfs/weed/pb/volume_server_pb"
|
||||||
|
@ -10,11 +14,6 @@ import (
|
||||||
"github.com/chrislusf/seaweedfs/weed/storage/needle"
|
"github.com/chrislusf/seaweedfs/weed/storage/needle"
|
||||||
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
||||||
|
|
||||||
"path"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,7 +24,8 @@ type Volume struct {
|
||||||
DataBackend backend.BackendStorageFile
|
DataBackend backend.BackendStorageFile
|
||||||
nm NeedleMapper
|
nm NeedleMapper
|
||||||
needleMapKind NeedleMapType
|
needleMapKind NeedleMapType
|
||||||
readOnly bool
|
noWriteOrDelete bool // if readonly, either noWriteOrDelete or noWriteCanDelete
|
||||||
|
noWriteCanDelete bool // if readonly, either noWriteOrDelete or noWriteCanDelete
|
||||||
MemoryMapMaxSizeMb uint32
|
MemoryMapMaxSizeMb uint32
|
||||||
|
|
||||||
SuperBlock
|
SuperBlock
|
||||||
|
@ -51,7 +51,7 @@ func NewVolume(dirname string, collection string, id needle.VolumeId, needleMapK
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
func (v *Volume) String() string {
|
func (v *Volume) String() string {
|
||||||
return fmt.Sprintf("Id:%v, dir:%s, Collection:%s, dataFile:%v, nm:%v, readOnly:%v", v.Id, v.dir, v.Collection, v.DataBackend, v.nm, v.readOnly)
|
return fmt.Sprintf("Id:%v, dir:%s, Collection:%s, dataFile:%v, nm:%v, noWrite:%v canDelete:%v", v.Id, v.dir, v.Collection, v.DataBackend, v.nm, v.noWriteOrDelete || v.noWriteCanDelete, v.noWriteCanDelete)
|
||||||
}
|
}
|
||||||
|
|
||||||
func VolumeFileName(dir string, collection string, id int) (fileName string) {
|
func VolumeFileName(dir string, collection string, id int) (fileName string) {
|
||||||
|
@ -210,7 +210,7 @@ func (v *Volume) ToVolumeInformationMessage() *master_pb.VolumeInformationMessag
|
||||||
FileCount: uint64(v.FileCount()),
|
FileCount: uint64(v.FileCount()),
|
||||||
DeleteCount: uint64(v.DeletedCount()),
|
DeleteCount: uint64(v.DeletedCount()),
|
||||||
DeletedByteCount: v.DeletedSize(),
|
DeletedByteCount: v.DeletedSize(),
|
||||||
ReadOnly: v.readOnly,
|
ReadOnly: v.noWriteOrDelete,
|
||||||
ReplicaPlacement: uint32(v.ReplicaPlacement.Byte()),
|
ReplicaPlacement: uint32(v.ReplicaPlacement.Byte()),
|
||||||
Version: uint32(v.Version()),
|
Version: uint32(v.Version()),
|
||||||
Ttl: v.Ttl.ToUint32(),
|
Ttl: v.Ttl.ToUint32(),
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (v *Volume) load(alsoLoadIndex bool, createDatIfMissing bool, needleMapKind
|
||||||
alreadyHasSuperBlock := false
|
alreadyHasSuperBlock := false
|
||||||
|
|
||||||
if v.maybeLoadVolumeTierInfo() {
|
if v.maybeLoadVolumeTierInfo() {
|
||||||
v.readOnly = true
|
v.noWriteCanDelete = true
|
||||||
// open remote file
|
// open remote file
|
||||||
alreadyHasSuperBlock = true
|
alreadyHasSuperBlock = true
|
||||||
} else if exists, canRead, canWrite, modifiedTime, fileSize := checkFile(fileName + ".dat"); exists {
|
} else if exists, canRead, canWrite, modifiedTime, fileSize := checkFile(fileName + ".dat"); exists {
|
||||||
|
@ -41,7 +41,7 @@ func (v *Volume) load(alsoLoadIndex bool, createDatIfMissing bool, needleMapKind
|
||||||
} else {
|
} else {
|
||||||
glog.V(0).Infoln("opening " + fileName + ".dat in READONLY mode")
|
glog.V(0).Infoln("opening " + fileName + ".dat in READONLY mode")
|
||||||
dataFile, e = os.Open(fileName + ".dat")
|
dataFile, e = os.Open(fileName + ".dat")
|
||||||
v.readOnly = true
|
v.noWriteOrDelete = true
|
||||||
}
|
}
|
||||||
v.lastModifiedTsSeconds = uint64(modifiedTime.Unix())
|
v.lastModifiedTsSeconds = uint64(modifiedTime.Unix())
|
||||||
if fileSize >= _SuperBlockSize {
|
if fileSize >= _SuperBlockSize {
|
||||||
|
@ -74,7 +74,7 @@ func (v *Volume) load(alsoLoadIndex bool, createDatIfMissing bool, needleMapKind
|
||||||
}
|
}
|
||||||
if e == nil && alsoLoadIndex {
|
if e == nil && alsoLoadIndex {
|
||||||
var indexFile *os.File
|
var indexFile *os.File
|
||||||
if v.readOnly {
|
if v.noWriteOrDelete {
|
||||||
glog.V(1).Infoln("open to read file", fileName+".idx")
|
glog.V(1).Infoln("open to read file", fileName+".idx")
|
||||||
if indexFile, e = os.OpenFile(fileName+".idx", os.O_RDONLY, 0644); e != nil {
|
if indexFile, e = os.OpenFile(fileName+".idx", os.O_RDONLY, 0644); e != nil {
|
||||||
return fmt.Errorf("cannot read Volume Index %s.idx: %v", fileName, e)
|
return fmt.Errorf("cannot read Volume Index %s.idx: %v", fileName, e)
|
||||||
|
@ -86,11 +86,11 @@ func (v *Volume) load(alsoLoadIndex bool, createDatIfMissing bool, needleMapKind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if v.lastAppendAtNs, e = CheckVolumeDataIntegrity(v, indexFile); e != nil {
|
if v.lastAppendAtNs, e = CheckVolumeDataIntegrity(v, indexFile); e != nil {
|
||||||
v.readOnly = true
|
v.noWriteOrDelete = true
|
||||||
glog.V(0).Infof("volumeDataIntegrityChecking failed %v", e)
|
glog.V(0).Infof("volumeDataIntegrityChecking failed %v", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if v.readOnly {
|
if v.noWriteOrDelete || v.noWriteCanDelete {
|
||||||
if v.nm, e = NewSortedFileNeedleMap(fileName, indexFile); e != nil {
|
if v.nm, e = NewSortedFileNeedleMap(fileName, indexFile); e != nil {
|
||||||
glog.V(0).Infof("loading sorted db %s error: %v", fileName+".sdb", e)
|
glog.V(0).Infof("loading sorted db %s error: %v", fileName+".sdb", e)
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,8 @@ func (v *Volume) maybeWriteSuperBlock() error {
|
||||||
if dataFile, e = os.Create(v.DataBackend.Name()); e == nil {
|
if dataFile, e = os.Create(v.DataBackend.Name()); e == nil {
|
||||||
v.DataBackend = backend.NewDiskFile(dataFile)
|
v.DataBackend = backend.NewDiskFile(dataFile)
|
||||||
if _, e = v.DataBackend.WriteAt(v.SuperBlock.Bytes(), 0); e == nil {
|
if _, e = v.DataBackend.WriteAt(v.SuperBlock.Bytes(), 0); e == nil {
|
||||||
v.readOnly = false
|
v.noWriteOrDelete = false
|
||||||
|
v.noWriteCanDelete = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,8 @@ func (v *Volume) maybeLoadVolumeTierInfo() bool {
|
||||||
glog.V(0).Infof("volume %d is tiered to %s as %s and read only", v.Id,
|
glog.V(0).Infof("volume %d is tiered to %s as %s and read only", v.Id,
|
||||||
v.volumeTierInfo.Files[0].BackendName(), v.volumeTierInfo.Files[0].Key)
|
v.volumeTierInfo.Files[0].BackendName(), v.volumeTierInfo.Files[0].Key)
|
||||||
|
|
||||||
v.readOnly = true
|
v.noWriteCanDelete = true
|
||||||
|
v.noWriteOrDelete = false
|
||||||
|
|
||||||
glog.V(0).Infof("loading volume %d from remote %v", v.Id, v.volumeTierInfo.Files)
|
glog.V(0).Infof("loading volume %d from remote %v", v.Id, v.volumeTierInfo.Files)
|
||||||
v.LoadRemoteFile()
|
v.LoadRemoteFile()
|
||||||
|
|
Loading…
Reference in a new issue