mirror of
https://github.com/zalando/postgres-operator.git
synced 2026-10-18 15:27:58 +02:00
Add logical backup (#442)
* Add k8s cron job to spawn logical backups * Minor doc updates
This commit is contained in:
+56
-2
@@ -81,6 +81,7 @@ type Cluster struct {
|
||||
currentProcess Process
|
||||
processMu sync.RWMutex // protects the current operation for reporting, no need to hold the master mutex
|
||||
specMu sync.RWMutex // protects the spec for reporting, no need to hold the master mutex
|
||||
|
||||
}
|
||||
|
||||
type compareStatefulsetResult struct {
|
||||
@@ -298,6 +299,13 @@ func (c *Cluster) Create() error {
|
||||
c.logger.Infof("databases have been successfully created")
|
||||
}
|
||||
|
||||
if c.Postgresql.Spec.EnableLogicalBackup {
|
||||
if err := c.createLogicalBackupJob(); err != nil {
|
||||
return fmt.Errorf("could not create a k8s cron job for logical backups: %v", err)
|
||||
}
|
||||
c.logger.Info("a k8s cron job for logical backup has been successfully created")
|
||||
}
|
||||
|
||||
if err := c.listResources(); err != nil {
|
||||
c.logger.Errorf("could not list resources: %v", err)
|
||||
}
|
||||
@@ -481,8 +489,10 @@ func compareResoucesAssumeFirstNotNil(a *v1.ResourceRequirements, b *v1.Resource
|
||||
|
||||
}
|
||||
|
||||
// Update changes Kubernetes objects according to the new specification. Unlike the sync case, the missing object.
|
||||
// (i.e. service) is treated as an error.
|
||||
// Update changes Kubernetes objects according to the new specification. Unlike the sync case, the missing object
|
||||
// (i.e. service) is treated as an error
|
||||
// logical backup cron jobs are an exception: a user-initiated Update can enable a logical backup job
|
||||
// for a cluster that had no such job before. In this case a missing job is not an error.
|
||||
func (c *Cluster) Update(oldSpec, newSpec *acidv1.Postgresql) error {
|
||||
updateFailed := false
|
||||
|
||||
@@ -569,6 +579,43 @@ func (c *Cluster) Update(oldSpec, newSpec *acidv1.Postgresql) error {
|
||||
}
|
||||
}()
|
||||
|
||||
// logical backup job
|
||||
func() {
|
||||
|
||||
// create if it did not exist
|
||||
if !oldSpec.Spec.EnableLogicalBackup && newSpec.Spec.EnableLogicalBackup {
|
||||
c.logger.Debugf("creating backup cron job")
|
||||
if err := c.createLogicalBackupJob(); err != nil {
|
||||
c.logger.Errorf("could not create a k8s cron job for logical backups: %v", err)
|
||||
updateFailed = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// delete if no longer needed
|
||||
if oldSpec.Spec.EnableLogicalBackup && !newSpec.Spec.EnableLogicalBackup {
|
||||
c.logger.Debugf("deleting backup cron job")
|
||||
if err := c.deleteLogicalBackupJob(); err != nil {
|
||||
c.logger.Errorf("could not delete a k8s cron job for logical backups: %v", err)
|
||||
updateFailed = true
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// apply schedule changes
|
||||
// this is the only parameter of logical backups a user can overwrite in the cluster manifest
|
||||
if (oldSpec.Spec.EnableLogicalBackup && newSpec.Spec.EnableLogicalBackup) &&
|
||||
(newSpec.Spec.LogicalBackupSchedule != oldSpec.Spec.LogicalBackupSchedule) {
|
||||
c.logger.Debugf("updating schedule of the backup cron job")
|
||||
if err := c.syncLogicalBackupJob(); err != nil {
|
||||
c.logger.Errorf("could not sync logical backup jobs: %v", err)
|
||||
updateFailed = true
|
||||
}
|
||||
}
|
||||
|
||||
}()
|
||||
|
||||
// Roles and Databases
|
||||
if !(c.databaseAccessDisabled() || c.getNumberOfInstances(&c.Spec) <= 0) {
|
||||
c.logger.Debugf("syncing roles")
|
||||
@@ -597,6 +644,12 @@ func (c *Cluster) Delete() {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
// delete the backup job before the stateful set of the cluster to prevent connections to non-existing pods
|
||||
// deleting the cron job also removes pods and batch jobs it created
|
||||
if err := c.deleteLogicalBackupJob(); err != nil {
|
||||
c.logger.Warningf("could not remove the logical backup k8s cron job; %v", err)
|
||||
}
|
||||
|
||||
if err := c.deleteStatefulSet(); err != nil {
|
||||
c.logger.Warningf("could not delete statefulset: %v", err)
|
||||
}
|
||||
@@ -629,6 +682,7 @@ func (c *Cluster) Delete() {
|
||||
if err := c.deletePatroniClusterObjects(); err != nil {
|
||||
c.logger.Warningf("could not remove leftover patroni objects; %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//NeedsRepair returns true if the cluster should be included in the repair scan (based on its in-memory status).
|
||||
|
||||
Reference in New Issue
Block a user