You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
4.2 KiB

9 years ago
6 years ago
6 years ago
9 years ago
9 years ago
9 years ago
  1. package storage
  2. import (
  3. "fmt"
  4. "os"
  5. "time"
  6. "github.com/chrislusf/seaweedfs/weed/storage/needle"
  7. "github.com/syndtr/goleveldb/leveldb/opt"
  8. "github.com/chrislusf/seaweedfs/weed/glog"
  9. )
  10. func loadVolumeWithoutIndex(dirname string, collection string, id needle.VolumeId, needleMapKind NeedleMapType) (v *Volume, e error) {
  11. v = &Volume{dir: dirname, Collection: collection, Id: id}
  12. v.SuperBlock = SuperBlock{}
  13. v.needleMapKind = needleMapKind
  14. e = v.load(false, false, needleMapKind, 0)
  15. return
  16. }
  17. func (v *Volume) load(alsoLoadIndex bool, createDatIfMissing bool, needleMapKind NeedleMapType, preallocate int64) error {
  18. var e error
  19. fileName := v.FileName()
  20. alreadyHasSuperBlock := false
  21. if exists, canRead, canWrite, modifiedTime, fileSize := checkFile(fileName + ".dat"); exists {
  22. if !canRead {
  23. return fmt.Errorf("cannot read Volume Data file %s.dat", fileName)
  24. }
  25. if canWrite {
  26. v.dataFile, e = os.OpenFile(fileName+".dat", os.O_RDWR|os.O_CREATE, 0644)
  27. v.lastModifiedTsSeconds = uint64(modifiedTime.Unix())
  28. } else {
  29. glog.V(0).Infoln("opening " + fileName + ".dat in READONLY mode")
  30. v.dataFile, e = os.Open(fileName + ".dat")
  31. v.readOnly = true
  32. }
  33. if fileSize >= _SuperBlockSize {
  34. alreadyHasSuperBlock = true
  35. }
  36. } else {
  37. if createDatIfMissing {
  38. v.dataFile, e = createVolumeFile(fileName+".dat", preallocate)
  39. } else {
  40. return fmt.Errorf("Volume Data file %s.dat does not exist.", fileName)
  41. }
  42. }
  43. if e != nil {
  44. if !os.IsPermission(e) {
  45. return fmt.Errorf("cannot load Volume Data %s.dat: %v", fileName, e)
  46. } else {
  47. return fmt.Errorf("load data file %s.dat: %v", fileName, e)
  48. }
  49. }
  50. if alreadyHasSuperBlock {
  51. e = v.readSuperBlock()
  52. } else {
  53. e = v.maybeWriteSuperBlock()
  54. }
  55. if e == nil && alsoLoadIndex {
  56. var indexFile *os.File
  57. if v.readOnly {
  58. glog.V(1).Infoln("open to read file", fileName+".idx")
  59. if indexFile, e = os.OpenFile(fileName+".idx", os.O_RDONLY, 0644); e != nil {
  60. return fmt.Errorf("cannot read Volume Index %s.idx: %v", fileName, e)
  61. }
  62. } else {
  63. glog.V(1).Infoln("open to write file", fileName+".idx")
  64. if indexFile, e = os.OpenFile(fileName+".idx", os.O_RDWR|os.O_CREATE, 0644); e != nil {
  65. return fmt.Errorf("cannot write Volume Index %s.idx: %v", fileName, e)
  66. }
  67. }
  68. if v.lastAppendAtNs, e = CheckVolumeDataIntegrity(v, indexFile); e != nil {
  69. v.readOnly = true
  70. glog.V(0).Infof("volumeDataIntegrityChecking failed %v", e)
  71. }
  72. switch needleMapKind {
  73. case NeedleMapInMemory:
  74. glog.V(0).Infoln("loading index", fileName+".idx", "to memory readonly", v.readOnly)
  75. if v.nm, e = LoadCompactNeedleMap(indexFile); e != nil {
  76. glog.V(0).Infof("loading index %s to memory error: %v", fileName+".idx", e)
  77. }
  78. case NeedleMapLevelDb:
  79. glog.V(0).Infoln("loading leveldb", fileName+".ldb")
  80. opts := &opt.Options{
  81. BlockCacheCapacity: 2 * 1024 * 1024, // default value is 8MiB
  82. WriteBuffer: 1 * 1024 * 1024, // default value is 4MiB
  83. }
  84. if v.nm, e = NewLevelDbNeedleMap(fileName+".ldb", indexFile, opts); e != nil {
  85. glog.V(0).Infof("loading leveldb %s error: %v", fileName+".ldb", e)
  86. }
  87. case NeedleMapLevelDbMedium:
  88. glog.V(0).Infoln("loading leveldb medium", fileName+".ldb")
  89. opts := &opt.Options{
  90. BlockCacheCapacity: 4 * 1024 * 1024, // default value is 8MiB
  91. WriteBuffer: 2 * 1024 * 1024, // default value is 4MiB
  92. }
  93. if v.nm, e = NewLevelDbNeedleMap(fileName+".ldb", indexFile, opts); e != nil {
  94. glog.V(0).Infof("loading leveldb %s error: %v", fileName+".ldb", e)
  95. }
  96. case NeedleMapLevelDbLarge:
  97. glog.V(0).Infoln("loading leveldb large", fileName+".ldb")
  98. opts := &opt.Options{
  99. BlockCacheCapacity: 8 * 1024 * 1024, // default value is 8MiB
  100. WriteBuffer: 4 * 1024 * 1024, // default value is 4MiB
  101. }
  102. if v.nm, e = NewLevelDbNeedleMap(fileName+".ldb", indexFile, opts); e != nil {
  103. glog.V(0).Infof("loading leveldb %s error: %v", fileName+".ldb", e)
  104. }
  105. }
  106. }
  107. return e
  108. }
  109. func checkFile(filename string) (exists, canRead, canWrite bool, modTime time.Time, fileSize int64) {
  110. exists = true
  111. fi, err := os.Stat(filename)
  112. if os.IsNotExist(err) {
  113. exists = false
  114. return
  115. }
  116. if fi.Mode()&0400 != 0 {
  117. canRead = true
  118. }
  119. if fi.Mode()&0200 != 0 {
  120. canWrite = true
  121. }
  122. modTime = fi.ModTime()
  123. fileSize = fi.Size()
  124. return
  125. }