// GetValue - Returns the key value from rdpg.config func GetValue(keyName string) (defaultBasePath string, err error) { address := `127.0.0.1` sq := fmt.Sprintf(`SELECT value AS keyvalue FROM rdpg.config WHERE key = '%s' AND cluster_id = '%s' ; `, keyName, globals.ClusterID) keyValue, err := rdpgpg.GetList(address, sq) if err != nil { if err == sql.ErrNoRows { log.Error(fmt.Sprintf("config.GetValue ! No default value found for %s ! %s", keyName, err)) } else { log.Error(fmt.Sprintf("config.GetValue ! Error when retrieving key value %s ! %s", keyName, err)) } return ``, err } if len(keyValue) == 0 { log.Error(fmt.Sprintf("config.GetValue ! No value found for %s ! %s", keyName, err)) return ``, fmt.Errorf("Key name %s not found", keyName) } return keyValue[0], nil }
//ScheduleNewDatabaseBackups - Responsible for adding any databases which are in //cfsb.instances and aren't already scheduled in tasks.schedules func (t *Task) ScheduleNewDatabaseBackups() (err error) { //SELECT active databases in cfsb.instances which aren't in tasks.schedules address := `127.0.0.1` sq := `SELECT name FROM ( (SELECT dbname AS name FROM cfsb.instances WHERE effective_at IS NOT NULL AND decommissioned_at IS NULL) EXCEPT (SELECT data AS name FROM tasks.schedules WHERE action = 'BackupDatabase' ) ) AS missing_databases; ` listMissingDatabases, err := rdpgpg.GetList(address, sq) if err != nil { log.Error(fmt.Sprintf(`tasks.Task<%d>#ScheduleNewDatabaseBackups() Failed to load list of databases ! %s`, t.ID, err)) } for _, databaseName := range listMissingDatabases { log.Trace(fmt.Sprintf("tasks.BackupDatabase() > Attempting to add %s", databaseName)) nodeType := `write` if t.ClusterService == "pgbdr" { nodeType = `read` } newScheduledTask := Schedule{ClusterID: ClusterID, ClusterService: t.ClusterService, Role: `service`, Action: `BackupDatabase`, Data: databaseName, NodeType: nodeType, Frequency: `1 hour`, Enabled: true} err = newScheduledTask.Add() } return }
//BackupDatabase - Perform a schema and database backup of a given database to local disk func (t *Task) BackupDatabase() (err error) { b := backupParams{} //Make sure database actually exists first. b.databaseName = t.Data if b.databaseName != "rdpg" { address := `127.0.0.1` sq := fmt.Sprintf(`SELECT 1 FROM cfsb.instances WHERE effective_at IS NOT NULL AND decommissioned_at IS NULL AND dbname = '%s';`, b.databaseName) databasesWithThatName, err := rdpgpg.GetList(address, sq) if err != nil { log.Error(fmt.Sprintf("Tasks.BackupDatabase() utils/backup.GetList(%s, %s) Error trying to query for database.", address, b.databaseName)) return err } if len(databasesWithThatName) == 0 { log.Error(fmt.Sprintf("Task.BackupDatabase() Attempt to back up non-existant or non-commissioned database with name: %s", b.databaseName)) return errors.New("Database doesn't exist.") } } lockAcquired, sessID := acquireBackupLock(b.databaseName) if !lockAcquired { log.Warn("Aborting Backup: Unable to acquire database lock. Is another backup already in progress?") return errors.New("Unable to acquire database lock") } defer releaseBackupLock(b.databaseName, sessID) b.pgDumpPath, err = config.GetValue(`pgDumpBinaryLocation`) if err != nil { return err } b.pgPort, err = config.GetValue(`BackupPort`) if err != nil { return err } b.basePath, err = config.GetValue(`BackupsPath`) if err != nil { return err } b.node, err = rdpgconsul.GetNode() if err != nil { return err } b.baseFileName = getBaseFileName() //Use this to keep schema and data file names the same err = createTargetFolder(b.basePath + `/` + b.databaseName) if err != nil { log.Error(fmt.Sprintf("tasks.BackupDatabase() Could not create target folder %s ! %s", b.basePath, err)) return err } schemaDataFileHistory, err := createSchemaAndDataFile(b) if err != nil { log.Error(fmt.Sprintf("tasks.BackupDatabase() Could not create schema and data file for database %s ! %s", b.databaseName, err)) schemaDataFileHistory.Status = `error` } err = history.InsertBackupHistory(schemaDataFileHistory) if b.databaseName == `rdpg` { globalsFileHistory, err := createGlobalsFile(b) if err != nil { log.Error(fmt.Sprintf("tasks.BackupDatabase() Could not create globals file for database %s ! %s", b.databaseName, err)) globalsFileHistory.Status = `error` } err = history.InsertBackupHistory(globalsFileHistory) } return }