commit
f92114d8f2
|
@ -5,7 +5,7 @@
|
|||
- [#5201](https://github.com/influxdb/influxdb/pull/5201): Allow max UDP buffer size to be configurable. Thanks @sebito91
|
||||
- [#5194](https://github.com/influxdb/influxdb/pull/5194): Custom continuous query options per query rather than per node.
|
||||
- [#5224](https://github.com/influxdb/influxdb/pull/5224): Online backup/incremental backup. Restore (for TSM).
|
||||
- [#5226](https://github.com/influxdata/influxdb/pull/5226): b*1 to tsm1 shard conversion tool.
|
||||
- [#5226](https://github.com/influxdata/influxdb/pull/5226): b\*1 to tsm1 shard conversion tool.
|
||||
|
||||
### Bugfixes
|
||||
- [#5129](https://github.com/influxdata/influxdb/pull/5129): Ensure precision flag is respected by CLI. Thanks @e-dard
|
||||
|
@ -27,6 +27,7 @@
|
|||
- [#5350](https://github.com/influxdata/influxdb/issues/5350): 'influxd backup' should create backup directory
|
||||
- [#5262](https://github.com/influxdata/influxdb/issues/5262): Fix a panic when a tag value was empty.
|
||||
- [#5382](https://github.com/influxdata/influxdb/pull/5382): Fixes some escaping bugs with tag keys and values.
|
||||
- [#5349](https://github.com/influxdata/influxdb/issues/5349): Validate metadata blob for 'influxd backup'
|
||||
|
||||
## v0.9.6 [2015-12-09]
|
||||
|
||||
|
|
|
@ -6,15 +6,17 @@ import (
|
|||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/influxdb/influxdb/meta"
|
||||
"github.com/influxdb/influxdb/services/snapshotter"
|
||||
"github.com/influxdb/influxdb/tcp"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -146,7 +148,8 @@ func (cmd *Command) backupShard(retentionPolicy string, shardID string, since ti
|
|||
Since: since,
|
||||
}
|
||||
|
||||
return cmd.downloadAndVerify(req, shardArchivePath)
|
||||
// TODO: verify shard backup data
|
||||
return cmd.downloadAndVerify(req, shardArchivePath, nil)
|
||||
}
|
||||
|
||||
// backupDatabase will request the database information from the server and then backup the metastore and
|
||||
|
@ -221,7 +224,18 @@ func (cmd *Command) backupMetastore() error {
|
|||
Type: snapshotter.RequestMetastoreBackup,
|
||||
}
|
||||
|
||||
return cmd.downloadAndVerify(req, metastoreArchivePath)
|
||||
return cmd.downloadAndVerify(req, metastoreArchivePath, func(file string) error {
|
||||
var data meta.Data
|
||||
binData, err := ioutil.ReadFile(file)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if data.UnmarshalBinary(binData) != nil {
|
||||
cmd.Logger.Println("Invalid metadata blob, ensure the metadata service is running (default port 8088)")
|
||||
return errors.New("invalid metadata received")
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// nextPath returns the next file to write to.
|
||||
|
@ -239,18 +253,26 @@ func (cmd *Command) nextPath(path string) (string, error) {
|
|||
|
||||
// downloadAndVerify will download either the metastore or shard to a temp file and then
|
||||
// rename it to a good backup file name after complete
|
||||
func (cmd *Command) downloadAndVerify(req *snapshotter.Request, path string) error {
|
||||
func (cmd *Command) downloadAndVerify(req *snapshotter.Request, path string, validator func(string) error) error {
|
||||
tmppath := path + Suffix
|
||||
if err := cmd.download(req, tmppath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if validator != nil {
|
||||
if err := validator(tmppath); err != nil {
|
||||
if rmErr := os.Remove(tmppath); rmErr != nil {
|
||||
cmd.Logger.Printf("Error cleaning up temporary file: %v", rmErr)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Rename temporary file to final path.
|
||||
if err := os.Rename(tmppath, path); err != nil {
|
||||
return fmt.Errorf("rename: %s", err)
|
||||
}
|
||||
|
||||
// TODO: Check file integrity.
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -264,25 +286,20 @@ func (cmd *Command) download(req *snapshotter.Request, path string) error {
|
|||
defer f.Close()
|
||||
|
||||
// Connect to snapshotter service.
|
||||
conn, err := net.Dial("tcp", cmd.host)
|
||||
conn, err := tcp.Dial("tcp", cmd.host, snapshotter.MuxHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Send snapshotter marker byte
|
||||
if _, err := conn.Write([]byte{snapshotter.MuxHeader}); err != nil {
|
||||
return fmt.Errorf("write snapshot header byte: %s", err)
|
||||
}
|
||||
|
||||
// Write the request
|
||||
if err := json.NewEncoder(conn).Encode(req); err != nil {
|
||||
return fmt.Errorf("encode snapshot manifest: %s", err)
|
||||
return fmt.Errorf("encode snapshot request: %s", err)
|
||||
}
|
||||
|
||||
// Read snapshot from the connection
|
||||
if _, err := io.Copy(f, conn); err != nil {
|
||||
return fmt.Errorf("copy snapshot to file: %s", err)
|
||||
return fmt.Errorf("copy backup to file: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -291,20 +308,15 @@ func (cmd *Command) download(req *snapshotter.Request, path string) error {
|
|||
// requestInfo will request the database or retention policy information from the host
|
||||
func (cmd *Command) requestInfo(request *snapshotter.Request) (*snapshotter.Response, error) {
|
||||
// Connect to snapshotter service.
|
||||
conn, err := net.Dial("tcp", cmd.host)
|
||||
conn, err := tcp.Dial("tcp", cmd.host, snapshotter.MuxHeader)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// Send snapshotter marker byte
|
||||
if _, err := conn.Write([]byte{snapshotter.MuxHeader}); err != nil {
|
||||
return nil, fmt.Errorf("write snapshot header byte: %s", err)
|
||||
}
|
||||
|
||||
// Write the request
|
||||
if err := json.NewEncoder(conn).Encode(request); err != nil {
|
||||
return nil, fmt.Errorf("encode snapshot manifest: %s", err)
|
||||
return nil, fmt.Errorf("encode snapshot request: %s", err)
|
||||
}
|
||||
|
||||
// Read the response
|
||||
|
|
Loading…
Reference in New Issue