Skip to content

Commit 3c62c0f

Browse files
committed
Improvenents
check that table is created before restore-data was added support comma list for 'table' flag was added
1 parent b268973 commit 3c62c0f

File tree

1 file changed

+88
-32
lines changed

1 file changed

+88
-32
lines changed

Diff for: main.go

+88-32
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ func main() {
9898
Flags: cliapp.Flags,
9999
},
100100
{
101-
Name: "delete",
102-
Usage: "Delete specific backup",
101+
Name: "delete",
102+
Usage: "Delete specific backup",
103103
UsageText: "clickhouse-backup delete <local|s3> <backup_name>",
104104
Action: func(c *cli.Context) error {
105105
config := getConfig(c)
@@ -223,36 +223,73 @@ func main() {
223223
}
224224
}
225225

226+
func addTable(tables []Table, table Table) []Table {
227+
for _, t := range tables {
228+
if (t.Database == table.Database) && (t.Name == table.Name) {
229+
return tables
230+
}
231+
}
232+
return append(tables, table)
233+
}
234+
235+
func addBackupTable(tables []BackupTable, table BackupTable) []BackupTable {
236+
for _, t := range tables {
237+
if (t.Database == table.Database) && (t.Name == table.Name) {
238+
return tables
239+
}
240+
}
241+
return append(tables, table)
242+
}
243+
244+
func addRestoreTable(tables []RestoreTable, table RestoreTable) []RestoreTable {
245+
for _, t := range tables {
246+
if (t.Database == table.Database) && (t.Table == table.Table) {
247+
return tables
248+
}
249+
}
250+
return append(tables, table)
251+
}
252+
226253
func parseTablePatternForFreeze(tables []Table, tablePattern string) ([]Table, error) {
227254
if tablePattern == "" {
228255
return tables, nil
229256
}
257+
tablePatterns := strings.Split(tablePattern, ",")
230258
var result []Table
231259
for _, t := range tables {
232-
if matched, _ := filepath.Match(tablePattern, fmt.Sprintf("%s.%s", t.Database, t.Name)); matched {
233-
result = append(result, t)
260+
for _, pattern := range tablePatterns {
261+
if matched, _ := filepath.Match(pattern, fmt.Sprintf("%s.%s", t.Database, t.Name)); matched {
262+
result = addTable(result, t)
263+
}
234264
}
235265
}
236266
return result, nil
237267
}
238268

239269
func parseTablePatternForRestoreData(tables map[string]BackupTable, tablePattern string) ([]BackupTable, error) {
240-
if tablePattern == "" {
241-
tablePattern = "*"
270+
tablePatterns := []string{"*"}
271+
if tablePattern != "" {
272+
tablePatterns = strings.Split(tablePattern, ",")
242273
}
243274
result := []BackupTable{}
244275
for _, t := range tables {
245-
tableName := fmt.Sprintf("%s.%s", t.Database, t.Name)
246-
if matched, _ := filepath.Match(tablePattern, tableName); matched {
247-
result = append(result, t)
276+
for _, pattern := range tablePatterns {
277+
tableName := fmt.Sprintf("%s.%s", t.Database, t.Name)
278+
if matched, _ := filepath.Match(pattern, tableName); matched {
279+
result = addBackupTable(result, t)
280+
}
248281
}
249282
}
250283
return result, nil
251284
}
252285

253-
func parseTablePatternForRestoreSchema(metadataPath, tablePattern string) ([]RestoreTable, error) {
286+
func parseTablePatternForRestoreSchema(metadataPath string, tablePattern string) ([]RestoreTable, error) {
254287
regularTables := []RestoreTable{}
255288
distributedTables := []RestoreTable{}
289+
tablePatterns := []string{"*"}
290+
if tablePattern != "" {
291+
tablePatterns = strings.Split(tablePattern, ",")
292+
}
256293
filepath.Walk(metadataPath, func(filePath string, info os.FileInfo, err error) error {
257294
if !strings.HasSuffix(filePath, ".sql") || !info.Mode().IsRegular() {
258295
return nil
@@ -268,23 +305,25 @@ func parseTablePatternForRestoreSchema(metadataPath, tablePattern string) ([]Res
268305
return nil
269306
}
270307
tableName := fmt.Sprintf("%s.%s", database, table)
271-
if matched, _ := filepath.Match(tablePattern, tableName); !matched {
272-
return nil
273-
}
274-
data, err := ioutil.ReadFile(filePath)
275-
if err != nil {
276-
return err
277-
}
278-
restoreTable := RestoreTable{
279-
Database: database,
280-
Table: table,
281-
Query: strings.Replace(string(data), "ATTACH", "CREATE", 1),
282-
}
283-
if strings.Contains(restoreTable.Query, "ENGINE = Distributed") {
284-
distributedTables = append(distributedTables, restoreTable)
285-
return nil
308+
for _, p := range tablePatterns {
309+
if matched, _ := filepath.Match(p, tableName); matched {
310+
data, err := ioutil.ReadFile(filePath)
311+
if err != nil {
312+
return err
313+
}
314+
restoreTable := RestoreTable{
315+
Database: database,
316+
Table: table,
317+
Query: strings.Replace(string(data), "ATTACH", "CREATE", 1),
318+
}
319+
if strings.Contains(restoreTable.Query, "ENGINE = Distributed") {
320+
distributedTables = addRestoreTable(distributedTables, restoreTable)
321+
return nil
322+
}
323+
regularTables = addRestoreTable(regularTables, restoreTable)
324+
return nil
325+
}
286326
}
287-
regularTables = append(regularTables, restoreTable)
288327
return nil
289328
})
290329
return append(regularTables, distributedTables...), nil
@@ -327,9 +366,6 @@ func restoreSchema(config Config, backupName string, tablePattern string, dryRun
327366
if dataPath == "" {
328367
return ErrUnknownClickhouseDataPath
329368
}
330-
if tablePattern == "" {
331-
tablePattern = "*"
332-
}
333369
metadataPath := path.Join(dataPath, "backup", backupName, "metadata")
334370
info, err := os.Stat(metadataPath)
335371
if err != nil {
@@ -569,17 +605,38 @@ func restoreData(config Config, backupName string, tablePattern string, dryRun b
569605
}
570606
defer ch.Close()
571607

572-
allTables, err := ch.GetBackupTables(backupName)
608+
allBackupTables, err := ch.GetBackupTables(backupName)
573609
if err != nil {
574610
return err
575611
}
576-
restoreTables, err := parseTablePatternForRestoreData(allTables, tablePattern)
612+
restoreTables, err := parseTablePatternForRestoreData(allBackupTables, tablePattern)
613+
if err != nil {
614+
return err
615+
}
616+
chTables, err := ch.GetTables()
577617
if err != nil {
578618
return err
579619
}
580620
if len(restoreTables) == 0 {
581621
return fmt.Errorf("Backup doesn't have tables to restore")
582622
}
623+
allTablesCreated := true
624+
for _, restoreTable := range restoreTables {
625+
found := false
626+
for _, chTable := range chTables {
627+
if (restoreTable.Database == chTable.Database) && (restoreTable.Name == chTable.Name) {
628+
found = true
629+
break
630+
}
631+
}
632+
if !found {
633+
log.Printf("Table '%s.%s' is not created", restoreTable.Database, restoreTable.Name)
634+
allTablesCreated = false
635+
}
636+
}
637+
if !allTablesCreated {
638+
return fmt.Errorf("Run 'restore-schema' first")
639+
}
583640
for _, table := range restoreTables {
584641
if err := ch.CopyData(table); err != nil {
585642
return fmt.Errorf("can't restore '%s.%s' with %v", table.Database, table.Name, err)
@@ -784,7 +841,6 @@ func removeBackupS3(config Config, backupName string) error {
784841
return fmt.Errorf("backup '%s' not found on s3", backupName)
785842
}
786843

787-
788844
func getConfig(ctx *cli.Context) *Config {
789845
configPath := ctx.String("config")
790846
if configPath == defaultConfigPath {

0 commit comments

Comments
 (0)