2016-10-07 16:22:24 +08:00
|
|
|
package storage
|
|
|
|
|
|
|
|
import (
|
2018-06-24 07:48:19 +08:00
|
|
|
"io/ioutil"
|
|
|
|
"math/rand"
|
2018-06-25 06:19:57 +08:00
|
|
|
"os"
|
|
|
|
"testing"
|
2019-05-04 08:22:39 +08:00
|
|
|
"time"
|
2019-04-19 12:43:36 +08:00
|
|
|
|
2019-09-12 21:18:21 +08:00
|
|
|
"github.com/chrislusf/seaweedfs/weed/storage/needle"
|
2019-12-24 04:48:20 +08:00
|
|
|
"github.com/chrislusf/seaweedfs/weed/storage/super_block"
|
2019-09-12 21:18:21 +08:00
|
|
|
"github.com/chrislusf/seaweedfs/weed/storage/types"
|
2016-10-07 16:22:24 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
/*
|
|
|
|
makediff test steps
|
|
|
|
1. launch weed server at your local/dev environment, (option
|
|
|
|
"garbageThreshold" for master and option "max" for volume should be set with specific value which would let
|
|
|
|
preparing test prerequisite easier )
|
|
|
|
a) ./weed master -garbageThreshold=0.99 -mdir=./m
|
|
|
|
b) ./weed volume -dir=./data -max=1 -mserver=localhost:9333 -port=8080
|
|
|
|
2. upload 4 different files, you could call dir/assign to get 4 different fids
|
|
|
|
a) upload file A with fid a
|
|
|
|
b) upload file B with fid b
|
|
|
|
c) upload file C with fid c
|
|
|
|
d) upload file D with fid d
|
|
|
|
3. update file A and C
|
|
|
|
a) modify file A and upload file A with fid a
|
|
|
|
b) modify file C and upload file C with fid c
|
|
|
|
c) record the current 1.idx's file size(lastCompactIndexOffset value)
|
|
|
|
4. Compacting the data file
|
|
|
|
a) run curl http://localhost:8080/admin/vacuum/compact?volumeId=1
|
|
|
|
b) verify the 1.cpd and 1.cpx is created under volume directory
|
|
|
|
5. update file B and delete file D
|
|
|
|
a) modify file B and upload file B with fid b
|
|
|
|
d) delete file B with fid b
|
|
|
|
6. Now you could run the following UT case, the case should be run successfully
|
|
|
|
7. Compact commit manually
|
|
|
|
a) mv 1.cpd 1.dat
|
|
|
|
b) mv 1.cpx 1.idx
|
|
|
|
8. Restart Volume Server
|
|
|
|
9. Now you should get updated file A,B,C
|
|
|
|
*/
|
|
|
|
|
|
|
|
func TestMakeDiff(t *testing.T) {
|
|
|
|
|
|
|
|
v := new(Volume)
|
|
|
|
//lastCompactIndexOffset value is the index file size before step 4
|
|
|
|
v.lastCompactIndexOffset = 96
|
2019-12-24 04:48:20 +08:00
|
|
|
v.SuperBlock.Version = 0x2
|
2016-10-07 16:40:51 +08:00
|
|
|
/*
|
|
|
|
err := v.makeupDiff(
|
|
|
|
"/yourpath/1.cpd",
|
|
|
|
"/yourpath/1.cpx",
|
|
|
|
"/yourpath/1.dat",
|
|
|
|
"/yourpath/1.idx")
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("makeupDiff err is %v", err)
|
|
|
|
} else {
|
|
|
|
t.Log("makeupDiff Succeeded")
|
|
|
|
}
|
|
|
|
*/
|
2016-10-07 16:22:24 +08:00
|
|
|
}
|
2018-06-24 07:48:19 +08:00
|
|
|
|
|
|
|
func TestCompaction(t *testing.T) {
|
|
|
|
dir, err := ioutil.TempDir("", "example")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("temp dir creation: %v", err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(dir) // clean up
|
|
|
|
|
2020-11-27 19:17:10 +08:00
|
|
|
v, err := NewVolume(dir, dir, "", 1, NeedleMapInMemory, &super_block.ReplicaPlacement{}, &needle.TTL{}, 0, 0)
|
2018-06-24 07:48:19 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("volume creation: %v", err)
|
|
|
|
}
|
|
|
|
|
2019-05-04 08:22:39 +08:00
|
|
|
beforeCommitFileCount := 10000
|
|
|
|
afterCommitFileCount := 10000
|
2018-06-24 07:48:19 +08:00
|
|
|
|
2018-06-24 09:24:59 +08:00
|
|
|
infos := make([]*needleInfo, beforeCommitFileCount+afterCommitFileCount)
|
2018-06-24 07:48:19 +08:00
|
|
|
|
2018-06-24 09:24:59 +08:00
|
|
|
for i := 1; i <= beforeCommitFileCount; i++ {
|
|
|
|
doSomeWritesDeletes(i, v, t, infos)
|
2018-06-24 07:48:19 +08:00
|
|
|
}
|
|
|
|
|
2019-05-04 08:22:39 +08:00
|
|
|
startTime := time.Now()
|
2020-03-12 01:32:17 +08:00
|
|
|
v.Compact2(0, 0)
|
2019-05-04 08:22:39 +08:00
|
|
|
speed := float64(v.ContentSize()) / time.Now().Sub(startTime).Seconds()
|
|
|
|
t.Logf("compaction speed: %.2f bytes/s", speed)
|
2018-06-24 09:24:59 +08:00
|
|
|
|
|
|
|
for i := 1; i <= afterCommitFileCount; i++ {
|
|
|
|
doSomeWritesDeletes(i+beforeCommitFileCount, v, t, infos)
|
|
|
|
}
|
|
|
|
|
2019-03-26 00:16:12 +08:00
|
|
|
v.CommitCompact()
|
2018-06-24 07:48:19 +08:00
|
|
|
|
|
|
|
v.Close()
|
|
|
|
|
2020-11-27 19:17:10 +08:00
|
|
|
v, err = NewVolume(dir, dir, "", 1, NeedleMapInMemory, nil, nil, 0, 0)
|
2018-06-24 07:48:19 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("volume reloading: %v", err)
|
|
|
|
}
|
|
|
|
|
2018-06-24 09:24:59 +08:00
|
|
|
for i := 1; i <= beforeCommitFileCount+afterCommitFileCount; i++ {
|
|
|
|
|
|
|
|
if infos[i-1] == nil {
|
|
|
|
t.Fatal("not found file", i)
|
|
|
|
continue
|
|
|
|
}
|
2018-06-24 07:48:19 +08:00
|
|
|
|
|
|
|
if infos[i-1].size == 0 {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
n := newEmptyNeedle(uint64(i))
|
2020-08-19 16:37:56 +08:00
|
|
|
size, err := v.readNeedle(n, nil)
|
2018-06-24 07:48:19 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("read file %d: %v", i, err)
|
|
|
|
}
|
2020-08-19 08:04:28 +08:00
|
|
|
if infos[i-1].size != types.Size(size) {
|
2018-06-24 07:48:19 +08:00
|
|
|
t.Fatalf("read file %d size mismatch expected %d found %d", i, infos[i-1].size, size)
|
|
|
|
}
|
|
|
|
if infos[i-1].crc != n.Checksum {
|
|
|
|
t.Fatalf("read file %d checksum mismatch expected %d found %d", i, infos[i-1].crc, n.Checksum)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2018-06-24 09:24:59 +08:00
|
|
|
func doSomeWritesDeletes(i int, v *Volume, t *testing.T, infos []*needleInfo) {
|
|
|
|
n := newRandomNeedle(uint64(i))
|
2020-05-07 19:58:06 +08:00
|
|
|
_, size, _, err := v.writeNeedle2(n, false)
|
2018-06-24 09:24:59 +08:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("write file %d: %v", i, err)
|
|
|
|
}
|
|
|
|
infos[i-1] = &needleInfo{
|
|
|
|
size: size,
|
|
|
|
crc: n.Checksum,
|
|
|
|
}
|
2018-07-07 15:48:58 +08:00
|
|
|
// println("written file", i, "checksum", n.Checksum.Value(), "size", size)
|
2018-12-23 03:05:29 +08:00
|
|
|
if rand.Float64() < 0.03 {
|
2018-06-24 09:24:59 +08:00
|
|
|
toBeDeleted := rand.Intn(i) + 1
|
|
|
|
oldNeedle := newEmptyNeedle(uint64(toBeDeleted))
|
2020-05-07 19:58:06 +08:00
|
|
|
v.deleteNeedle2(oldNeedle)
|
2018-07-07 15:48:58 +08:00
|
|
|
// println("deleted file", toBeDeleted)
|
2018-06-24 09:24:59 +08:00
|
|
|
infos[toBeDeleted-1] = &needleInfo{
|
|
|
|
size: 0,
|
|
|
|
crc: n.Checksum,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-06-24 07:48:19 +08:00
|
|
|
|
|
|
|
type needleInfo struct {
|
2020-08-19 08:04:28 +08:00
|
|
|
size types.Size
|
2019-04-19 12:43:36 +08:00
|
|
|
crc needle.CRC
|
2018-06-24 07:48:19 +08:00
|
|
|
}
|
|
|
|
|
2019-04-19 12:43:36 +08:00
|
|
|
func newRandomNeedle(id uint64) *needle.Needle {
|
|
|
|
n := new(needle.Needle)
|
2018-06-24 07:48:19 +08:00
|
|
|
n.Data = make([]byte, rand.Intn(1024))
|
|
|
|
rand.Read(n.Data)
|
|
|
|
|
2019-04-19 12:43:36 +08:00
|
|
|
n.Checksum = needle.NewCRC(n.Data)
|
2018-07-08 17:39:04 +08:00
|
|
|
n.Id = types.Uint64ToNeedleId(id)
|
2018-06-24 07:48:19 +08:00
|
|
|
return n
|
|
|
|
}
|
|
|
|
|
2019-04-19 12:43:36 +08:00
|
|
|
func newEmptyNeedle(id uint64) *needle.Needle {
|
|
|
|
n := new(needle.Needle)
|
2018-07-08 17:39:04 +08:00
|
|
|
n.Id = types.Uint64ToNeedleId(id)
|
2018-06-24 07:48:19 +08:00
|
|
|
return n
|
|
|
|
}
|