I'm working on creating services that can do a logical MySQL backup as well as a physical MySQL backup. The logical backups would be done every 4 hours while the physical backups would be done once a day at a specific time. Both rely on shutting down the MySQL slave which the backup is based on. They also need to handle not running concurrently. In addition, when boots/reboots, these should not be run not the first invocation.
Logical backup is using mysqldump
and then uploading to S3.
Physical backup is taking a snapshot of the EBS.
I've been running a simple stress case version where both fire at an interval of 1 minute. The database is empty and small. The EBS Volume is 1GiB. Both can be done in less than one minute.
I use a timer service to trigger the oneshot. I have also made each timer a Conflicts
to each other as well as restating the timer in ExecStopPost
.
An example of the service file looks like. Each one references the other
[Unit]
After=mysql-slave.service
Conflicts=other-backup-type.timer
[Service]
Type=oneshot
# Just arbitrary name for this example
ExecStart=do_backup.sh
ExecStopPost=/bin/systemctl start other-backup-type.timer
What I have seen via systemctl list-timers
is that both timers are in sync. When both hit 0, one will trigger. What I have found is that once done, the other is will not be triggered. It seems that in this case, the timer is indeed stopped, but the trigger for the other oneshot never is made.
Is there a way to properly handle this without having to offset time? I have found if I make the time period offset slightly it works (seconds cannot be a factor of 60). I'm checking to see if there is a better/more elegant way of supporting this.