Я работаю над созданием сервисов, которые могут выполнять логическое резервное копирование MySQL, а также физическое резервное копирование MySQL. Логическое резервное копирование будет выполняться каждые 4 часа, в то время как физическое резервное копирование будет выполняться один раз в день в определенное время. Оба сервиса полагаются на выключение подчиненного сервера MySQL, на котором основано резервное копирование. Они также должны обрабатывать неработающие одновременно. Кроме того, при загрузке/перезагрузке они не должны запускаться при первом вызове.
Логическое резервное копирование использует mysqldump
и затем загружает в S3. Физическое резервное копирование делает снимок EBS.
Я запускал простую версию стресс-кейса, где оба срабатывают с интервалом в 1 минуту. База данных пустая и маленькая. Объем EBS составляет 1 ГиБ. Оба могут быть выполнены менее чем за одну минуту.
Я использую службу таймера для запуска oneshot. Я также сделал каждый таймер a Conflicts
для каждого другого, а также переустановил таймер в ExecStopPost
.
Пример файла сервиса выглядит так. Каждый ссылается на другой
[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
Я видел systemctl list-timers
, что оба таймера синхронизированы. Когда оба достигают 0, один из них срабатывает. Я обнаружил, что после этого другой не срабатывает. Похоже, что в этом случае таймер действительно останавливается, но срабатывание другого oneshot никогда не происходит.
Есть ли способ правильно справиться с этим без необходимости смещения времени? Я обнаружил, что если я немного смещаю период времени, это работает (секунды не могут быть множителем 60). Я проверяю, есть ли лучший/более элегантный способ поддержки этого.
решение1
Я не совсем уверен, что это 100% правильный ответ. Я перебрал много вариантов и на основе этого пришёл к такому.
Наблюдая, кажется, что если у меня есть 2 таймера (A и B), которые настроены как Conflicts=
и также имеют коллизию по истечении срока с другим таймером (например, оба настроены на срабатывание каждую минуту), то тот, который срабатывает (скажем, это A), сначала останавливает другой, а затем запускает его обслуживание. Однако эта остановка приводит к потере триггера на обслуживании таймера B. Я предполагаю, что триггер вытягивается из какой-то очереди и в конечном итоге выбрасывается в процессе остановки.