/
delete.go
111 lines (98 loc) · 3.23 KB
/
delete.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
package mysql
import (
"path"
"strings"
"github.com/spf13/cobra"
"github.com/wal-g/wal-g/internal"
"github.com/wal-g/wal-g/internal/databases/mysql"
"github.com/wal-g/wal-g/internal/storages/storage"
"github.com/wal-g/wal-g/internal/tracelog"
"github.com/wal-g/wal-g/utility"
)
var confirmed = false
// deleteCmd represents the delete command
var deleteCmd = &cobra.Command{
Use: "delete", //for example "delete mysql before time"
Short: "Clears old backups and binlogs",
}
var deleteBeforeCmd = &cobra.Command{
Use: "before [FIND_FULL] backup_name|timestamp", // TODO : improve description
Example: internal.DeleteBeforeExamples,
Args: internal.DeleteBeforeArgsValidator,
Run: runDeleteBefore,
}
var deleteRetainCmd = &cobra.Command{
Use: "retain [FULL|FIND_FULL] backup_count", // TODO : improve description
Example: internal.DeleteRetainExamples,
ValidArgs: internal.StringModifiers,
Args: internal.DeleteRetainArgsValidator,
Run: runDeleteRetain,
}
func runDeleteBefore(cmd *cobra.Command, args []string) {
folder, err := internal.ConfigureFolder()
if err != nil {
tracelog.ErrorLogger.FatalError(err)
}
isFullBackup := func(object storage.Object) bool {
return IsFullBackup(folder, object)
}
internal.HandleDeleteBefore(folder, args, confirmed, isFullBackup, GetLessFunc(folder))
}
func runDeleteRetain(cmd *cobra.Command, args []string) {
folder, err := internal.ConfigureFolder()
if err != nil {
tracelog.ErrorLogger.FatalError(err)
}
isFullBackup := func(object storage.Object) bool {
return IsFullBackup(folder, object)
}
internal.HandleDeleteRetain(folder, args, confirmed, isFullBackup, GetLessFunc(folder))
}
func init() {
MySQLCmd.AddCommand(deleteCmd)
deleteCmd.AddCommand(deleteBeforeCmd, deleteRetainCmd)
deleteCmd.PersistentFlags().BoolVar(&confirmed, internal.ConfirmFlag, false, "Confirms backup deletion")
}
func IsFullBackup(folder storage.Folder, object storage.Object) bool {
return true
}
func GetLessFunc(folder storage.Folder) func(object1, object2 storage.Object) bool {
return func(object1, object2 storage.Object) bool {
time1, ok := utility.TryFetchTimeRFC3999(object1.GetName())
if !ok {
return binlogLess(folder, object1, object2)
}
time2, ok := utility.TryFetchTimeRFC3999(object2.GetName())
if !ok {
return binlogLess(folder, object1, object2)
}
return time1 < time2
}
}
func binlogLess(folder storage.Folder, object1, object2 storage.Object) bool {
binlogName1, ok := tryFetchBinlogName(folder, object1)
if !ok {
return false
}
binlogName2, ok := tryFetchBinlogName(folder, object2)
if !ok {
return false
}
return binlogName1 < binlogName2
}
func tryFetchBinlogName(folder storage.Folder, object storage.Object) (string, bool) {
name := object.GetName()
if strings.HasPrefix(name, mysql.BinlogPath) {
_, name = path.Split(name)
return name, true
}
name = strings.Replace(name, utility.SentinelSuffix, "", 1)
baseBackupFolder := folder.GetSubFolder(utility.BaseBackupPath)
backup := mysql.Backup{Backup: internal.NewBackup(baseBackupFolder, name)}
sentinel, err := backup.FetchStreamSentinel()
if err != nil {
tracelog.InfoLogger.Println("Fail to fetch stream sentinel " + name)
return "", false
}
return sentinel.BinLogStart, true
}