Skip to content
This repository was archived by the owner on Aug 13, 2019. It is now read-only.

Commit f1cfeae

Browse files
author
Krasi Georgiev
committed
tmps prety display,overlapping blocks
Signed-off-by: Krasi Georgiev <[email protected]>
1 parent b474a40 commit f1cfeae

File tree

2 files changed

+68
-30
lines changed

2 files changed

+68
-30
lines changed

cmd/tsdb/main.go

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ func main() {
7070
printBlocks(db.Blocks(), listCmdHumanReadable)
7171

7272
case scanCmd.FullCommand():
73-
fmt.Println("Scanning for temporary files...")
7473
var tmpFiles []string
7574
filepath.Walk(*scanPath, func(path string, f os.FileInfo, _ error) error {
7675
if !f.IsDir() {
@@ -86,17 +85,35 @@ These are usually caused by a crash or incomplete compaction and
8685
are safe to delete as long as you are sure that no other application is currently using this database.`)
8786

8887
promptDelete(tmpFiles, scanCmdHumanReadable)
89-
9088
}
9189

9290
scanner, err := tsdb.NewDBScanner(*scanPath)
9391
if err != nil {
9492
exitWithError(err)
9593
}
9694

97-
for err, useless := range scanner.Scan() {
98-
fmt.Printf("Deleting these will loose all data in the listed time ranges.%v", err)
99-
promptDelete(useless, scanCmdHumanReadable)
95+
for err, unreadable := range scanner.Scan() {
96+
switch err.(type) {
97+
case tsdb.ErrOverlap:
98+
var biggestIndex int
99+
biggest := &tsdb.Block{}
100+
for i, b := range unreadable {
101+
if b.Meta().Stats.NumSamples > biggest.Meta().Stats.NumSamples {
102+
biggest = b
103+
biggestIndex = i
104+
}
105+
}
106+
// Don't delete the bigest block in the overlaps.
107+
unreadable = append(unreadable[:biggestIndex], unreadable[biggestIndex+1:]...)
108+
109+
fmt.Printf("\n%v \nDeleting these will loose all data in the listed time ranges.\n\n", err)
110+
fmt.Printf("\nBlock %v contains most samples is ommited from the list and it won't be deleted! \n\n", biggest)
111+
112+
default:
113+
fmt.Printf("\nUnreadable blocks : %v \nDeleting these will loose all data in the listed time ranges.\n\n", err)
114+
115+
}
116+
promptDelete(unreadable, scanCmdHumanReadable)
100117
}
101118
}
102119
flag.CommandLine.Set("log.level", "debug")
@@ -116,7 +133,7 @@ func promptDelete(i interface{}, humanReadable *bool) {
116133
printTmps(paths, humanReadable)
117134
}
118135

119-
fmt.Printf("Do you want to delete these (y/N)? ")
136+
fmt.Printf("DELETE (y/N)? ")
120137
var s string
121138
_, err := fmt.Scanln(&s)
122139
if err != nil {
@@ -131,8 +148,8 @@ func promptDelete(i interface{}, humanReadable *bool) {
131148
if err := os.Remove(path); err != nil {
132149
fmt.Printf("error deleting: %v, %v", path, err)
133150
}
134-
fmt.Printf("%v \n", path)
135151
}
152+
return
136153
}
137154
if s == "n" || s == "no" {
138155
return
@@ -420,26 +437,39 @@ func exitWithError(err error) {
420437
}
421438

422439
func printTmps(tmps []string, humanReadable *bool) {
440+
tw := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
441+
defer tw.Flush()
423442

424-
fmt.Println(tmps)
443+
fmt.Fprintln(tw, "PATH\tSIZE\tDATE\t")
444+
for _, path := range tmps {
445+
f, e := os.Stat(path)
446+
if e != nil {
447+
exitWithError(e)
448+
}
449+
fmt.Fprintf(tw,
450+
"%v\t%v\t%v\n",
451+
path, f.Size(), f.ModTime().Format("2006-Jan-2 15:04:05 -07:00 MST"),
452+
)
453+
}
425454
}
426455

427456
func printBlocks(blocks []*tsdb.Block, humanReadable *bool) {
428457
tw := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
429458
defer tw.Flush()
430459

431-
fmt.Fprintln(tw, "BLOCK ULID\tMIN TIME\tMAX TIME\tNUM SAMPLES\tNUM CHUNKS\tNUM SERIES")
460+
fmt.Fprintln(tw, "BLOCK ULID\tMIN TIME\tMAX TIME\tNUM SAMPLES\tNUM CHUNKS\tNUM SERIES\tPATH")
432461
for _, b := range blocks {
433462
meta := b.Meta()
434463

435464
fmt.Fprintf(tw,
436-
"%v\t%v\t%v\t%v\t%v\t%v\n",
465+
"%v\t%v\t%v\t%v\t%v\t%v\t%v\n",
437466
meta.ULID,
438467
getFormatedTime(meta.MinTime, humanReadable),
439468
getFormatedTime(meta.MaxTime, humanReadable),
440469
meta.Stats.NumSamples,
441470
meta.Stats.NumChunks,
442471
meta.Stats.NumSeries,
472+
b.Dir(),
443473
)
444474
}
445475
}

scan.go

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@ package tsdb
33
import (
44
"fmt"
55
"path/filepath"
6+
"time"
67

78
"github.com/pkg/errors"
89
"github.com/prometheus/tsdb/chunks"
910
"github.com/prometheus/tsdb/index"
1011
)
1112

13+
type ErrOverlap string
14+
15+
func (e ErrOverlap) Error() string {
16+
return string(e)
17+
}
18+
1219
type DBScanner struct {
1320
db *DB
1421
dirs []string
@@ -32,63 +39,64 @@ func NewDBScanner(dir string) (*DBScanner, error) {
3239
return dbScanner, nil
3340
}
3441

35-
// Scan checks the integrity of the tsdb and returns a slice of blocks that return an error while processing.
42+
// Scan checks the integrity of the tsdb and returns a slice of unreadable blocks.
3643
// The blocks are grouped in a map by the error.
3744
func (db *DBScanner) Scan() map[error][]*Block {
3845

39-
uselessBlocks := make(map[error][]*Block)
46+
unreadableBlocks := make(map[error][]*Block)
4047
var goodBlocks []*Block
4148

4249
for _, dir := range db.dirs {
4350
var err error
4451
block := &Block{
4552
dir: dir,
4653
}
54+
55+
loop:
4756
for {
48-
meta, err := readMetaFile(dir)
57+
var meta = &BlockMeta{}
58+
meta, err = readMetaFile(dir)
4959
if err != nil {
50-
err = errors.Wrap(err, "reading block meta")
51-
break
60+
err = errors.Wrap(err, "meta error")
61+
break loop
5262
}
5363
block.meta = *meta
5464

5565
if block.chunkr, err = chunks.NewDirReader(chunkDir(dir), nil); err != nil {
56-
err = errors.Wrap(err, "reading block chunk")
57-
break
66+
err = errors.Wrap(err, "chunk error")
67+
break loop
5868
}
5969

6070
if block.indexr, err = index.NewFileReader(filepath.Join(dir, "index")); err != nil {
61-
err = errors.Wrap(err, "reading block index")
62-
break
71+
err = errors.Wrap(err, "index error")
72+
break loop
6373
}
6474

6575
if block.tombstones, err = readTombstones(dir); err != nil {
66-
err = errors.Wrap(err, "reading block tumbstone")
67-
break
76+
err = errors.Wrap(err, "tumbstone error")
77+
break loop
6878
}
69-
break
79+
break loop
7080
}
7181

7282
if err != nil {
73-
uselessBlocks[err] = append(uselessBlocks[err], block)
83+
unreadableBlocks[err] = append(unreadableBlocks[err], block)
7484
} else {
7585
goodBlocks = append(goodBlocks, block)
7686
}
77-
7887
}
7988

8089
// Scan for overlaping blocks.
81-
for time, overlappingMetas := range validateBlockSequence(goodBlocks) {
82-
err := fmt.Errorf("overlapping blocks range: %v , %v", time.Min, time.Min)
90+
for t, overlappingMetas := range validateBlockSequence(goodBlocks) {
91+
err := ErrOverlap(fmt.Sprintf("overlapping blocks : %v-%v ", time.Unix(t.Min/1000, 0).Format("06/01/02 15:04"), time.Unix(t.Max/1000, 0).Format("15:04 06/01/02")))
8392
for _, m := range overlappingMetas {
8493
for _, b := range goodBlocks {
85-
if m.ULID == b.Meta().ULID {
86-
uselessBlocks[err] = append(uselessBlocks[err], b)
94+
if m.ULID == b.Meta().ULID && m.Stats == b.Meta().Stats {
95+
unreadableBlocks[err] = append(unreadableBlocks[err], b)
8796
break
8897
}
8998
}
9099
}
91-
92100
}
93-
return uselessBlocks
101+
return unreadableBlocks
94102
}

0 commit comments

Comments
 (0)