Darslik · 2026-08-16 · ~6 daqiqa o‘qiladi · o'rta
systemd timer va avtomatik backup: tiklanmagan zaxira — zaxira emas
Mundarija
Serverda muntazam bajariladigan ishlar bo'ladi: bazani zaxiralash, eski
loglarni tozalash, hisobot yig'ish. An'anaviy javob — cron. Lekin systemd
bilan ishlayotgan serverda (seriyaning 2-qismidan
beri hamma xizmatimiz shunda) timer'lar ancha qulay: ishga tushish loglari
journalctlda xizmatniki bilan yonma-yon turadi, vazifani qo'lda bir buyruq
bilan sinash mumkin, server o'chiq paytga to'g'ri kelgan ishga tushishni esa
keyin quvib yetish imkoni bor. Cron'da bularning har biri alohida bosh
og'rig'i edi.
Timer'ni eng kerakli ishda ko'rsataman — kunlik baza zaxirasi. Yo'l-yo'lakay zaxiraning eng katta sirini ham aytaman: hech qachon tiklab ko'rilmagan backup — backup emas, umid xolos.
Juftlik: service + timer#
systemd'da rejali vazifa ikki fayldan iborat: ishning o'zi (.service) va
jadval (.timer). Ular bir xil nomlanadi:
# /etc/systemd/system/db-backup.service
[Unit]
Description=Kunlik baza zaxirasi
[Service]
# oneshot: ishga tushdi, bajarib bo'ldi, chiqdi — doimiy xizmat emas
Type=oneshot
User=deploy
ExecStart=/opt/mysite/scripts/backup.sh
# /etc/systemd/system/db-backup.timer
[Unit]
Description=Har kuni 03:30 da zaxira
[Timer]
OnCalendar=*-*-* 03:30:00
# server o'sha payt o'chiq bo'lsa, yoqilgach darhol bajaradi —
# "kecha backup bo'lmabdi" degan bo'shliq qolmaydi
Persistent=true
[Install]
WantedBy=timers.target
E'tibor bering, yoqilganda service emas, timer enable qilinadi:
sudo systemctl daemon-reload
sudo systemctl enable --now db-backup.timer
systemctl list-timers db-backup.timer # NEXT ustunida ertangi 03:30 ko'rinadi
Sinash uchun kutish shart emas
Timer'ning eng yoqimli tomoni shu: vazifani hoziroq qo'lda ishga tushirib
ko'rasiz — sudo systemctl start db-backup.service — va natijani
journalctl -u db-backup bilan o'qiysiz. Cron'da "yarim tunni kutamiz
yoki jadvalni vaqtincha o'zgartiramiz" o'yini bor edi, bu yerda yo'q.
Zaxira skriptining o'zi#
Endi backup.shni yozamiz. Ikki keng tarqalgan holatni ko'rsataman —
qaysi baza bo'lsa, o'shanisini oling:
#!/usr/bin/env bash
# /opt/mysite/scripts/backup.sh
set -euo pipefail # xato bo'lsa jim davom etmasin — timer failed holatga tushsin
BACKUP_DIR=/var/backups/mysite
STAMP=$(date +%Y-%m-%d_%H%M)
mkdir -p "$BACKUP_DIR"
# --- SQLite bo'lsa ---
# oddiy cp EMAS: yozuv paytida ko'chirilgan fayl buzuq chiqishi mumkin.
# .backup buyrug'i esa bazani izchil holatda nusxalaydi
sqlite3 /opt/mysite/db.sqlite3 ".backup '$BACKUP_DIR/db_$STAMP.sqlite3'"
gzip "$BACKUP_DIR/db_$STAMP.sqlite3"
# --- PostgreSQL bo'lsa (yuqoridagi ikki qator o'rniga) ---
# pg_dump -Fc mysite > "$BACKUP_DIR/db_$STAMP.dump"
# 14 kundan eski nusxalarni tozalaymiz — disk cheksiz emas
find "$BACKUP_DIR" -name "db_*" -mtime +14 -delete
echo "backup tayyor: db_$STAMP"
chmod +x /opt/mysite/scripts/backup.sh
sudo systemctl start db-backup.service # birinchi sinov
ls -lh /var/backups/mysite/ # fayl paydo bo'ldi
set -euo pipefail qatori mayda ko'ringani bilan muhim: usiz skript o'rtada
xato bersa ham "muvaffaqiyatli" tugagan hisoblanadi va siz oylab bo'sh
zaxira yig'ib yurishingiz mumkin. U bilan esa xato timer'ni failed holatga
tushiradi — systemctl list-timers yoki monitoring buni darhol ko'rsatadi.
Zaxira serverning o'zida qolsa — bu ham yarim ish#
Server diski kuysa, undagi zaxiralar ham birga ketadi. Shuning uchun kamida bitta nusxa boshqa joyda turishi kerak. Eng arzon yo'l — skript oxiriga bitta qator qo'shib, faylni boshqa serverga yoki bulutga jo'natish:
# boshqa serverga (SSH kalit 1-qismda sozlangan edi):
rsync -a "$BACKUP_DIR/" backup@boshqa-server:/backups/mysite/
# yoki S3-ga o'xshash saqlashga (rclone oldindan sozlangan bo'lsa):
# rclone copy "$BACKUP_DIR" remote:mysite-backups
Eng muhim qadam: tiklashni sinash#
Endi va'da qilingan gap. Zaxira tizimini sozlagan odamlarning ko'pi bitta savolga javob berolmaydi: "shu fayldan bazani tiklab ko'rganmisiz?" Fayl har kuni yaratilayotgani hali hech narsani anglatmaydi — u buzuq bo'lishi, yarim bo'lishi, kerakli jadvallarsiz bo'lishi mumkin. Buni bilishning yagona yo'li — tiklab ko'rish:
# alohida papkada, jonli bazaga TEGMASDAN:
cd /tmp
gunzip -k /var/backups/mysite/db_2026-08-16_0330.sqlite3.gz -c > sinov.sqlite3
# ichi joyidami? jadvallar va yozuvlar sonini tekshiramiz:
sqlite3 sinov.sqlite3 ".tables"
sqlite3 sinov.sqlite3 "SELECT count(*) FROM auth_user;"
rm sinov.sqlite3
Tiklash mashqini kalendarga yozing
Bu bir martalik ish emas. Choraklik odat qiling: zaxiradan bazani sinov muhitiga tiklash, ilovani unga ulab bir aylanib chiqish. O'n besh daqiqa oladi, lekin "backup bor edi-ku!" degan eng achchiq jumladan saqlaydi — u odatda ma'lumot yo'qolgandan keyin, tiklash urinishi muvaffaqiyatsiz chiqqanda aytiladi.
Yakun#
Endi serverda o'zini o'zi qutqaradigan mexanizm bor: timer har kuni 03:30 da
uyg'onadi, skript bazani izchil nusxalab siqadi, eskilarini tozalaydi va
nusxani serverdan tashqariga jo'natadi. Xato bo'lsa failed holat ko'rinadi,
o'chiq qolgan kun esa Persistent=true tufayli o'tkazib yuborilmaydi.
Va siz vaqti-vaqti bilan tiklab ko'rasiz — chunki sinalmagan zaxira shunchaki
fayl.
Keyingi qismda shu qurilgan tizimning yaxlitligini tekshiramiz: reboot'ga chidamlilik — server o'chib yonganda hamma narsa o'z-o'zidan qaytadigan holatga kelganini qanday kafolatlaymiz.