mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Initial implementation of HeadBlock Snapshots
Signed-off-by: Goutham Veeramachaneni <cs14btech11014@iith.ac.in>
This commit is contained in:
parent
3a5ae6b1a4
commit
a1c8425357
6
block.go
6
block.go
|
@ -58,6 +58,12 @@ type Block interface {
|
||||||
type headBlock interface {
|
type headBlock interface {
|
||||||
Block
|
Block
|
||||||
Appendable
|
Appendable
|
||||||
|
Snapshottable
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snapshottable defines an entity that can be backedup online.
|
||||||
|
type Snapshottable interface {
|
||||||
|
Snapshot(dir string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Appendable defines an entity to which data can be appended.
|
// Appendable defines an entity to which data can be appended.
|
||||||
|
|
|
@ -246,7 +246,7 @@ func (c *compactor) write(uid ulid.ULID, blocks ...Block) (err error) {
|
||||||
return errors.Wrap(err, "open index writer")
|
return errors.Wrap(err, "open index writer")
|
||||||
}
|
}
|
||||||
|
|
||||||
meta, err := c.populate(blocks, indexw, chunkw)
|
meta, err := populateBlock(blocks, indexw, chunkw)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "write compaction")
|
return errors.Wrap(err, "write compaction")
|
||||||
}
|
}
|
||||||
|
@ -289,9 +289,9 @@ func (c *compactor) write(uid ulid.ULID, blocks ...Block) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate fills the index and chunk writers with new data gathered as the union
|
// populateBlock fills the index and chunk writers with new data gathered as the union
|
||||||
// of the provided blocks. It returns meta information for the new block.
|
// of the provided blocks. It returns meta information for the new block.
|
||||||
func (c *compactor) populate(blocks []Block, indexw IndexWriter, chunkw ChunkWriter) (*BlockMeta, error) {
|
func populateBlock(blocks []Block, indexw IndexWriter, chunkw ChunkWriter) (*BlockMeta, error) {
|
||||||
var set compactionSet
|
var set compactionSet
|
||||||
|
|
||||||
for i, b := range blocks {
|
for i, b := range blocks {
|
||||||
|
|
28
db.go
28
db.go
|
@ -528,6 +528,34 @@ func (db *DB) Close() error {
|
||||||
return merr.Err()
|
return merr.Err()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DisableCompactions disables compactions.
|
||||||
|
func (db *DB) DisableCompactions() error {
|
||||||
|
db.stopc <- struct{}{} // TODO: Can this block?
|
||||||
|
db.cmtx.Lock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableCompactions enables compactions.
|
||||||
|
func (db *DB) EnableCompactions() error {
|
||||||
|
db.cmtx.Unlock()
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Snapshot writes the current headBlock snapshots to snapshots directory.
|
||||||
|
func (db *DB) Snapshot(dir string) error {
|
||||||
|
db.headmtx.RLock()
|
||||||
|
heads := db.heads[:]
|
||||||
|
db.headmtx.RUnlock()
|
||||||
|
|
||||||
|
for _, h := range heads {
|
||||||
|
if err := h.Snapshot(dir); err != nil {
|
||||||
|
return errors.Wrap(err, "error snapshotting headblock")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Appender returns a new Appender on the database.
|
// Appender returns a new Appender on the database.
|
||||||
func (db *DB) Appender() Appender {
|
func (db *DB) Appender() Appender {
|
||||||
db.metrics.activeAppenders.Inc()
|
db.metrics.activeAppenders.Inc()
|
||||||
|
|
65
head.go
65
head.go
|
@ -262,6 +262,71 @@ Outer:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Snapshot persists the current state of the headblock to the given directory.
|
||||||
|
func (h *HeadBlock) Snapshot(snapshotDir string) error {
|
||||||
|
// Needed to stop any appenders.
|
||||||
|
h.mtx.Lock()
|
||||||
|
defer h.mtx.Unlock()
|
||||||
|
|
||||||
|
if h.meta.Stats.NumSeries == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
entropy := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
|
uid := ulid.MustNew(ulid.Now(), entropy)
|
||||||
|
|
||||||
|
dir := filepath.Join(snapshotDir, uid.String())
|
||||||
|
tmp := dir + ".tmp"
|
||||||
|
|
||||||
|
if err := os.RemoveAll(tmp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.MkdirAll(tmp, 0777); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate chunk and index files into temporary directory with
|
||||||
|
// data of all blocks.
|
||||||
|
chunkw, err := newChunkWriter(chunkDir(tmp))
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "open chunk writer")
|
||||||
|
}
|
||||||
|
indexw, err := newIndexWriter(tmp)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "open index writer")
|
||||||
|
}
|
||||||
|
|
||||||
|
meta, err := populateBlock([]Block{h}, indexw, chunkw)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "write snapshot")
|
||||||
|
}
|
||||||
|
meta.ULID = uid
|
||||||
|
|
||||||
|
if err = writeMetaFile(tmp, meta); err != nil {
|
||||||
|
return errors.Wrap(err, "write merged meta")
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = chunkw.Close(); err != nil {
|
||||||
|
return errors.Wrap(err, "close chunk writer")
|
||||||
|
}
|
||||||
|
if err = indexw.Close(); err != nil {
|
||||||
|
return errors.Wrap(err, "close index writer")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an empty tombstones file.
|
||||||
|
if err := writeTombstoneFile(tmp, newEmptyTombstoneReader()); err != nil {
|
||||||
|
return errors.Wrap(err, "write new tombstones file")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Block successfully written, make visible
|
||||||
|
if err := renameFile(tmp, dir); err != nil {
|
||||||
|
return errors.Wrap(err, "rename block dir")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Dir returns the directory of the block.
|
// Dir returns the directory of the block.
|
||||||
func (h *HeadBlock) Dir() string { return h.dir }
|
func (h *HeadBlock) Dir() string { return h.dir }
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue