1
0
Fork 0

Stream backup from remote node

master
Philip O'Toole 9 months ago
parent 18e04dd079
commit 761cff14be

@ -208,38 +208,53 @@ func (c *Client) Request(r *command.ExecuteQueryRequest, nodeAddr string, creds
// Backup retrieves a backup from a remote node and writes to the io.Writer
func (c *Client) Backup(br *command.BackupRequest, nodeAddr string, creds *proto.Credentials, timeout time.Duration, w io.Writer) error {
conn, err := c.dial(nodeAddr, c.timeout)
if err != nil {
return err
}
defer conn.Close()
command := &proto.Command{
Type: proto.Command_COMMAND_TYPE_BACKUP,
Type: proto.Command_COMMAND_TYPE_BACKUP_STREAM,
Request: &proto.Command_BackupRequest{
BackupRequest: br,
},
Credentials: creds,
}
p, err := c.retry(command, nodeAddr, timeout)
if err != nil {
if err := writeCommand(conn, command, timeout); err != nil {
handleConnError(conn)
return err
}
// Decompress....
p, err = gzUncompress(p)
p, err := readResponse(conn, timeout)
if err != nil {
return fmt.Errorf("backup decompress: %w", err)
handleConnError(conn)
return err
}
resp := &proto.CommandBackupResponse{}
err = pb.Unmarshal(p, resp)
a := &proto.CommandBackupResponse{}
err = pb.Unmarshal(p, a)
if err != nil {
return fmt.Errorf("backup unmarshal: %w", err)
return err
}
if resp.Error != "" {
return errors.New(resp.Error)
if a.Error != "" {
return errors.New(a.Error)
}
if _, err := w.Write(resp.Data); err != nil {
return fmt.Errorf("backup write: %w", err)
// The backup stream is unconditionally compressed, so depending on whether
// the user requested compression, we may need to decompress the response.
var rc io.ReadCloser
rc = conn
if !br.Compress {
rc, err = gzip.NewReader(conn)
if err != nil {
return err
}
defer rc.Close()
}
return nil
_, err = io.Copy(w, rc)
return err
}
// Load loads a SQLite file into the database.

@ -35,6 +35,7 @@ const (
Command_COMMAND_TYPE_JOIN Command_Type = 8
Command_COMMAND_TYPE_REQUEST Command_Type = 9
Command_COMMAND_TYPE_LOAD_CHUNK Command_Type = 10
Command_COMMAND_TYPE_BACKUP_STREAM Command_Type = 11
)
// Enum value maps for Command_Type.
@ -51,6 +52,7 @@ var (
8: "COMMAND_TYPE_JOIN",
9: "COMMAND_TYPE_REQUEST",
10: "COMMAND_TYPE_LOAD_CHUNK",
11: "COMMAND_TYPE_BACKUP_STREAM",
}
Command_Type_value = map[string]int32{
"COMMAND_TYPE_UNKNOWN": 0,
@ -64,6 +66,7 @@ var (
"COMMAND_TYPE_JOIN": 8,
"COMMAND_TYPE_REQUEST": 9,
"COMMAND_TYPE_LOAD_CHUNK": 10,
"COMMAND_TYPE_BACKUP_STREAM": 11,
}
)
@ -866,7 +869,7 @@ var file_message_proto_rawDesc = []byte{
0x12, 0x1a, 0x0a, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x02, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x1b, 0x0a, 0x07,
0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0x8b, 0x08, 0x0a, 0x07, 0x43, 0x6f,
0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x22, 0xab, 0x08, 0x0a, 0x07, 0x43, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x6f,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
@ -912,7 +915,7 @@ var file_message_proto_rawDesc = []byte{
0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63,
0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61,
0x6c, 0x73, 0x52, 0x0b, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x22,
0xaa, 0x02, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4d, 0x4d,
0xca, 0x02, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4d, 0x4d,
0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e,
0x10, 0x00, 0x12, 0x21, 0x0a, 0x1d, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59,
0x50, 0x45, 0x5f, 0x47, 0x45, 0x54, 0x5f, 0x4e, 0x4f, 0x44, 0x45, 0x5f, 0x41, 0x50, 0x49, 0x5f,
@ -930,7 +933,9 @@ var file_message_proto_rawDesc = []byte{
0x4f, 0x49, 0x4e, 0x10, 0x08, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44,
0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x52, 0x45, 0x51, 0x55, 0x45, 0x53, 0x54, 0x10, 0x09, 0x12,
0x1b, 0x0a, 0x17, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f,
0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x10, 0x0a, 0x42, 0x09, 0x0a, 0x07,
0x4c, 0x4f, 0x41, 0x44, 0x5f, 0x43, 0x48, 0x55, 0x4e, 0x4b, 0x10, 0x0a, 0x12, 0x1e, 0x0a, 0x1a,
0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x41, 0x43,
0x4b, 0x55, 0x50, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x0b, 0x42, 0x09, 0x0a, 0x07,
0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x60, 0x0a, 0x16, 0x43, 0x6f, 0x6d, 0x6d, 0x61,
0x6e, 0x64, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,

@ -27,6 +27,7 @@ message Command {
COMMAND_TYPE_JOIN = 8;
COMMAND_TYPE_REQUEST = 9;
COMMAND_TYPE_LOAD_CHUNK = 10;
COMMAND_TYPE_BACKUP_STREAM = 11;
}
Type type = 1;

@ -374,6 +374,33 @@ func (s *Service) handleConn(conn net.Conn) {
}
writeBytesWithLength(conn, p)
case proto.Command_COMMAND_TYPE_BACKUP_STREAM:
stats.Add(numBackupRequest, 1)
resp := &proto.CommandBackupResponse{}
br := c.GetBackupRequest()
if br == nil {
resp.Error = "BackupRequest is nil"
} else if !s.checkCommandPerm(c, auth.PermBackup) {
resp.Error = "unauthorized"
}
p, err = pb.Marshal(resp)
if err != nil {
conn.Close()
return
}
writeBytesWithLength(conn, p)
// Now, start streaming the backup. Enable compressed mode
// regardless of whether the client requested it, so the client
// can easily detect the end of the stream, as well as saving
// space on the wire.
br.Compress = true
if err := s.db.Backup(br, conn); err != nil {
conn.Close()
return
}
case proto.Command_COMMAND_TYPE_LOAD:
stats.Add(numLoadRequest, 1)
resp := &proto.CommandLoadResponse{}

Loading…
Cancel
Save