forked from influxdata/influxdb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
level_db_delete_check.go
123 lines (113 loc) · 3.63 KB
/
level_db_delete_check.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package main
/*
This is a little program that writes 100m keys to a level db to check the size.
Then deletes a bunch of keys to see how that is reflected.
*/
import (
"fmt"
"github.com/jmhodges/levigo"
"math/rand"
"os"
"os/exec"
"time"
)
func main() {
seriesNames := []string{"events",
"some_host_2342.stats.cpu.idle", "actions", "host_another_2.stats.cpu.idle",
"some_long_name.with-other_stuff.in.it.and_whatnot"}
pointsWritten := 0
dbDir := "/tmp/chronos_db_test"
os.RemoveAll(dbDir)
pointsToWritePerSeries := 2000000
pointsToDeletePerSeries := pointsToWritePerSeries / 2
opts := levigo.NewOptions()
hundredMegabytes := 100 * 1048576
opts.SetCache(levigo.NewLRUCache(hundredMegabytes))
opts.SetCreateIfMissing(true)
opts.SetBlockSize(262144)
os.MkdirAll(dbDir, 0744)
db, err := levigo.Open(dbDir, opts)
if err != nil {
panic(err)
}
writeOptions := levigo.NewWriteOptions()
defer writeOptions.Close()
// this initializes the ends of the keyspace so seeks don't mess with us.
db.Put(writeOptions, []byte("a"), []byte(""))
db.Put(writeOptions, []byte("z"), []byte(""))
start := time.Now()
for _, seriesName := range seriesNames {
fmt.Println("Writing Series: ", seriesName)
for i := 0; i < pointsToWritePerSeries; i++ {
key := fmt.Sprintf("c~%s~1381456156%012d~%d", seriesName, i, rand.Int())
db.Put(writeOptions, []byte(key), []byte(fmt.Sprintf("%f", rand.Float64())))
pointsWritten += 1
if pointsWritten%500000 == 0 {
fmt.Println("COUNT: ", pointsWritten)
}
}
out, _ := exec.Command("du", "-h", dbDir).Output()
fmt.Println("SIZE: ", string(out))
}
diff := time.Now().Sub(start)
fmt.Printf("DONE. %d points written in %s\n", pointsWritten, diff.String())
out, _ := exec.Command("du", "-h", dbDir).Output()
fmt.Println("SIZE: ", string(out))
deleteCount := 0
start = time.Now()
ranges := make([]*levigo.Range, 0)
for _, seriesName := range seriesNames {
fmt.Println("Deleting: ", seriesName)
count := 0
key := fmt.Sprintf("c~%s~", seriesName)
ro := levigo.NewReadOptions()
it := db.NewIterator(ro)
it.Seek([]byte(key))
var lastKey []byte
for it = it; it.Valid() && count < pointsToDeletePerSeries; it.Next() {
lastKey = it.Key()
db.Delete(writeOptions, it.Key())
count += 1
deleteCount += 1
}
it.Close()
ro.Close()
rangeToCompact := &levigo.Range{[]byte(key), lastKey}
ranges = append(ranges, rangeToCompact)
out, _ := exec.Command("du", "-h", dbDir).Output()
fmt.Println("SIZE: ", string(out))
}
fmt.Printf("DONE. %d points deleted in %s\n", deleteCount, diff.String())
fmt.Println("Starting compaction in background...")
compactionDone := make(chan int)
for _, r := range ranges {
go func(r *levigo.Range) {
db.CompactRange(*r)
compactionDone <- 1
}(r)
}
start = time.Now()
fmt.Println("Writing new points...")
pointsWritten = 0
for _, seriesName := range seriesNames {
fmt.Println("Writing Series: ", seriesName)
for i := pointsToWritePerSeries; i < pointsToWritePerSeries*2; i++ {
key := fmt.Sprintf("c~%s~1381456156%012d~%d", seriesName, i, rand.Int())
db.Put(writeOptions, []byte(key), []byte(fmt.Sprintf("%f", rand.Float64())))
pointsWritten += 1
if pointsWritten%500000 == 0 {
fmt.Println("COUNT: ", pointsWritten)
}
}
out, _ := exec.Command("du", "-h", dbDir).Output()
fmt.Println("SIZE: ", string(out))
}
fmt.Println("waiting for compaction to finish...")
for i := 0; i < len(ranges); i++ {
<-compactionDone
}
diff = time.Now().Sub(start)
out, _ = exec.Command("du", "-h", dbDir).Output()
fmt.Printf("DONE. %d points written during compaction in %s\n", deleteCount, diff.String())
fmt.Println("SIZE: ", string(out))
}