Kopie MariaDB / MySQL poza TaxMachine
Opublikowano
TaxMachine ma wbudowany mechanizm kopii który działa zarówno dla SQLite, jak i dla MariaDB/MySQL. Wystarcza dla większości użytkowników. Ten artykuł opisuje dodatkowe, niezależne od programu sposoby tworzenia kopii bazy MariaDB — przydatne gdy:
- prowadzisz biuro rachunkowe i chcesz centralnie zarządzać backupami wielu baz / firm
- masz dedykowany serwer MariaDB obsługujący wiele aplikacji
- chcesz mieć kopię w infrastrukturze niezależnej od TaxMachine (np. nocny snapshot serwera + replikacja off-site)
- chcesz natywnej integracji z politykami backup-owymi firmy (Veeam, Bacula, Proxmox Backup, S3, B2)
Dwa rodzaje kopii MariaDB
1. Kopia logiczna — mysqldump
Eksport struktury i danych w formie pliku SQL (CREATE TABLE +
INSERT INTO). Plusy:
- Tekstowy format — czytelny, łatwo edytować przed restore'em
- Niezależny od wersji MariaDB (kopia z 10.6 wczyta się do 11.4)
- Niezależny od architektury (Windows ↔ Linux, x86 ↔ ARM)
- Możliwość wybrania konkretnych tabel
- Łatwe przesłanie / rozmieszczenie
Minusy:
- Wolniejszy przy bardzo dużych bazach (>10 GB)
- Restore odbudowuje indeksy od zera
To domyślna i zalecana metoda dla typowych instalacji TaxMachine (baza zwykle <1 GB).
2. Kopia fizyczna — mariabackup
Snapshot plików InnoDB na poziomie binarnym. Plusy:
- Bardzo szybka odtwarzalność
- Niska narzutka na działający serwer (online backup)
- Inkrementalność (kolejna kopia tylko zmiany)
Minusy:
- Wymaga tej samej (lub nowszej) wersji serwera przy restore
- Format binarny, większe pliki
- Mniej elastyczna manipulacja zawartością
Sensowna gdy baza jest bardzo duża (>10 GB) lub wymaga RPO (Recovery Point Objective) w minutach.
W tym artykule pokrywamy mysqldump (95% przypadków). Jeżeli
potrzebujesz mariabackup — patrz oficjalna dokumentacja:
mariadb.com/kb/en/mariabackup-overview/.
Przygotowanie
Konto z minimalnymi uprawnieniami do backup-u
Nie używaj root — utwórz dedykowane konto z prawami tylko do odczytu
struktur i lockowania:
CREATE USER 'backup'@'localhost' IDENTIFIED BY 'silne-haslo-backup';
GRANT SELECT, SHOW VIEW, EVENT, TRIGGER, LOCK TABLES, RELOAD,
PROCESS, REPLICATION CLIENT
ON *.*
TO 'backup'@'localhost';
FLUSH PRIVILEGES;
Wykonaj w HeidiSQL albo mysql -u root -p.
Plik z hasłem (zamiast w command-line)
Hasło w command-line trafia do logów / historii shella. Zamiast tego trzymaj je w pliku zabezpieczonym ACL-ami:
Windows: plik C:\Tools\backup\.my.cnf:
[client]
user=backup
password=silne-haslo-backup
host=localhost
Ogranicz prawa pliku — tylko Twoje konto i SYSTEM:
icacls C:\Tools\backup\.my.cnf /inheritance:r /grant:r "%USERNAME%:(R)" "SYSTEM:(R)"
Linux: ~/.my.cnf, prawa 600:
chmod 600 ~/.my.cnf
W komendach poniżej używamy --defaults-extra-file=.my.cnf — mysqldump
czyta hasło z pliku.
Skrypt backup — Windows (.cmd)
C:\Tools\backup\backup-taxmachine.cmd:
@echo off
setlocal enabledelayedexpansion
REM ---- konfiguracja --------------------------------------------------------
set BACKUP_DIR=D:\Backup\TaxMachine
set DB_NAME=taxmachine
set MYSQLDUMP="C:\Program Files\MariaDB 11.4\bin\mysqldump.exe"
set DEFAULTS=C:\Tools\backup\.my.cnf
set RETENTION_DAYS=30
set LOG=%BACKUP_DIR%\backup.log
REM ---- przygotowanie -------------------------------------------------------
if not exist "%BACKUP_DIR%" mkdir "%BACKUP_DIR%"
for /f "tokens=2 delims==" %%I in ('wmic os get LocalDateTime /value ^| find "="') do set DT=%%I
set TS=%DT:~0,8%-%DT:~8,4%
REM ---- mysqldump -----------------------------------------------------------
set OUT=%BACKUP_DIR%\%DB_NAME%-%TS%.sql.gz
echo [%date% %time%] start backup %OUT% >> "%LOG%"
%MYSQLDUMP% --defaults-extra-file=%DEFAULTS% ^
--single-transaction --quick --routines --triggers --events ^
--default-character-set=utf8mb4 ^
%DB_NAME% | "C:\Program Files\7-Zip\7z.exe" a -tgzip -si "%OUT%" >> "%LOG%" 2>&1
if errorlevel 1 (
echo [%date% %time%] BLAD podczas backup-u >> "%LOG%"
exit /b 1
)
echo [%date% %time%] OK rozmiar: >> "%LOG%"
for %%F in ("%OUT%") do echo %%~zF bajt >> "%LOG%"
REM ---- retencja: usun starsze niz RETENTION_DAYS dni ----------------------
forfiles /p "%BACKUP_DIR%" /m "%DB_NAME%-*.sql.gz" /d -%RETENTION_DAYS% /c "cmd /c del @path" 2>nul
echo [%date% %time%] retencja: %RETENTION_DAYS% dni >> "%LOG%"
echo. >> "%LOG%"
endlocal
Wymaga zainstalowanego 7-Zip (C:\Program Files\7-Zip\7z.exe) do kompresji.
Jeśli nie chcesz kompresować — wytnij pipe-a do 7z.exe i zmień OUT na
.sql zamiast .sql.gz.
Harmonogram (Task Scheduler)
$action = New-ScheduledTaskAction -Execute "C:\Tools\backup\backup-taxmachine.cmd"
$trigger = New-ScheduledTaskTrigger -Daily -At 2:30am
$principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -RunLevel Highest
Register-ScheduledTask -TaskName "TaxMachine Backup" `
-Action $action -Trigger $trigger -Principal $principal `
-Description "Codzienna kopia bazy taxmachine, 02:30"
Sprawdzanie:
Get-ScheduledTaskInfo -TaskName "TaxMachine Backup"
Skrypt backup — Linux (.sh)
/usr/local/bin/backup-taxmachine.sh:
#!/usr/bin/env bash
set -euo pipefail
# ---- konfiguracja ---------------------------------------------------------
BACKUP_DIR="/var/backups/taxmachine"
DB_NAME="taxmachine"
DEFAULTS="/root/.my.cnf"
RETENTION_DAYS=30
LOG="$BACKUP_DIR/backup.log"
# ---- przygotowanie --------------------------------------------------------
mkdir -p "$BACKUP_DIR"
TS=$(date +%Y%m%d-%H%M)
OUT="$BACKUP_DIR/$DB_NAME-$TS.sql.gz"
echo "[$(date '+%F %T')] start backup $OUT" >> "$LOG"
# ---- mysqldump ------------------------------------------------------------
mysqldump --defaults-extra-file="$DEFAULTS" \
--single-transaction --quick --routines --triggers --events \
--default-character-set=utf8mb4 \
"$DB_NAME" | gzip -9 > "$OUT"
if [[ ! -s "$OUT" ]]; then
echo "[$(date '+%F %T')] BLAD: pusty plik" >> "$LOG"
exit 1
fi
echo "[$(date '+%F %T')] OK rozmiar: $(stat -c %s "$OUT") B" >> "$LOG"
# ---- retencja -------------------------------------------------------------
find "$BACKUP_DIR" -name "$DB_NAME-*.sql.gz" -mtime +"$RETENTION_DAYS" -delete
echo "[$(date '+%F %T')] retencja: $RETENTION_DAYS dni" >> "$LOG"
echo "" >> "$LOG"
Pamiętaj o chmod +x /usr/local/bin/backup-taxmachine.sh.
Harmonogram (cron)
sudo crontab -e
Dodaj wiersz (codziennie 02:30):
30 2 * * * /usr/local/bin/backup-taxmachine.sh
Albo jako systemd timer dla precyzyjnego zarządzania logami:
# /etc/systemd/system/backup-taxmachine.service
[Unit]
Description=TaxMachine MariaDB backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup-taxmachine.sh
# /etc/systemd/system/backup-taxmachine.timer
[Unit]
Description=TaxMachine MariaDB backup — codziennie 02:30
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl enable --now backup-taxmachine.timer
sudo systemctl status backup-taxmachine.timer
journalctl -u backup-taxmachine.service -n 50
Szyfrowanie kopii
Wszystkie kopie wychodzące poza serwer powinny być zaszyfrowane — dane księgowe zawierają NIP-y, numery kont, adresy klientów.
gpg (Linux + Windows z gpg4win)
Jednorazowa generacja klucza:
gpg --gen-key
Szyfrowanie kopii (asymetryczne, hasło w kluczu):
gpg --encrypt --recipient backup@firma.pl < taxmachine.sql.gz > taxmachine.sql.gz.gpg
Deszyfrowanie (wymaga klucza prywatnego):
gpg --decrypt taxmachine.sql.gz.gpg > taxmachine.sql.gz
openssl (jeśli wolisz hasło symetryczne)
openssl enc -aes-256-cbc -salt -pbkdf2 -in taxmachine.sql.gz \
-out taxmachine.sql.gz.enc -pass file:/root/backup-passphrase.txt
Najważniejsze: klucz prywatny GPG / passphrase do openssl trzymaj poza serwerem na którym jest baza. Awaria serwera + brak dostępu do klucza = utrata kopii.
Off-site upload — rclone
rclone (rclone.org) wgrywa do dowolnej chmury
(S3, Backblaze B2, Wasabi, Dropbox, OneDrive, Mega, FTP, SFTP).
Konfiguracja jednorazowa:
rclone config
# wybierz n (new remote), nazwa: b2, typ: Backblaze B2 / S3 / cokolwiek
# wpisz klucze API
Upload do bucketa:
rclone copy /var/backups/taxmachine b2:taxmachine-backups/$(hostname)/ \
--include "taxmachine-*.sql.gz" --transfers 4 --checkers 8
Dorzuć w skrypcie backup po find ... -delete. Można też skonfigurować
rclone sync z lokalnym retention by mirror działał wstecznie.
Backblaze B2 — typowy koszt
Dla porównania — 10 GB kopii × 30 dni × ~2 zł / GB / miesiąc = ~5-6 zł / miesiąc za off-site backup biura rachunkowego (stan 2026-05). Najtańsza enterprise-grade chmura w Polsce / Europie.
Restore — odtwarzanie z kopii
1. Plik .sql (logiczny mysqldump)
# Linux
gunzip < taxmachine-20260504-0230.sql.gz | mysql -u root -p taxmachine_recovered
# Windows (PowerShell, wymaga 7-Zip):
& "C:\Program Files\7-Zip\7z.exe" x -so taxmachine-20260504-0230.sql.gz | `
& "C:\Program Files\MariaDB 11.4\bin\mysql.exe" -u root -p taxmachine_recovered
Tworzymy nową, pustą bazę (
taxmachine_recovered) zamiast nadpisywania działającej:CREATE DATABASE taxmachine_recovered CHARACTER SET utf8mb4 COLLATE utf8mb4_polish_ci;Po weryfikacji że dane są kompletne, możemy w TaxMachine wskazać nową bazę w opcjach i ewentualnie zrzucić starą.
2. Plik zaszyfrowany (gpg)
gpg --decrypt taxmachine.sql.gz.gpg | gunzip | mysql -u root -p taxmachine_recovered
3. Test po restore
USE taxmachine_recovered;
-- czy są tabele?
SHOW TABLES;
-- czy dane?
SELECT COUNT(*) FROM Faktury;
SELECT MAX(Data) FROM Dokumenty;
-- integralność?
CHECK TABLE Faktury;
Strategia 3-2-1 z mysqldump
Przykładowa konfiguracja zgodna z zasadą 3-2-1:
| Co | Jak | Gdzie |
|---|---|---|
| Oryginał | live MariaDB | dysk SSD serwera |
| Kopia 1 | mysqldump co dzień 02:30 | dysk wewnętrzny inny niż produkcyjny |
| Kopia 2 | rclone copy → B2 po backup-ie | Backblaze B2 (off-site) |
Cron / Task Scheduler:
30 2 * * * /usr/local/bin/backup-taxmachine.sh && \
rclone copy /var/backups/taxmachine \
b2:taxmachine-backups/$(hostname)/ \
--include "taxmachine-*.sql.gz"
Monitoring i alerty
Backup który cicho zawodzi przez tydzień to gorzej niż żaden — masz złudzenie ochrony. Dorzuć monitoring:
Healthchecks.io (najszybsze, darmowe do 20 checków)
- Załóż konto, utwórz Check „TaxMachine backup", interwał 24h, grace 1h
- Skopiuj UUID
- W skrypcie backup, na końcu:
curl -fsS --retry 3 "https://hc-ping.com/<UUID>" - Gdy backup nie wykona się dobę — Healthchecks wysyła email/SMS
Powiadomienia w Healthchecks
- start ping przed backup-em (
hc-ping.com/<UUID>/start) - success po sukcesie (
hc-ping.com/<UUID>) - fail po błędzie (
hc-ping.com/<UUID>/fail) — z||w skrypcie
Częste błędy do uniknięcia
- ❌ Backup root-em zamiast dedykowanego konta — przy lekach hasła ekspozycja całego serwera
- ❌ Hasło w argumencie
mysqldump -ppassword— wps/historii shell-a; używaj--defaults-extra-file - ❌ Brak
--single-transaction— backup może być niespójny przy równoczesnym zapisie z TaxMachine - ❌ Brak retencji — backupy rosną w nieskończoność, dysk się zapełnia, nowe backupy padają
- ❌ Brak monitoringu — backupy mogą cicho zawodzić tygodniami
- ❌ Brak testu restore — backup którego nigdy nie sprawdzono nie jest backupem; raz na kwartał odtwórz na test-bazę
- ❌ Klucz szyfrowania na tym samym serwerze — przy awarii tracisz kopię i klucz jednocześnie
Linki przydatne
- mysqldump options — pełna lista flag
- mariabackup — fizyczne kopie
- rclone supported services — chmury do off-site
- Healthchecks.io — monitoring backup-ów
- Strategia 3-2-1 + test odtworzenia
- Uszkodzenia bazy danych — diagnostyka
- Instalacja MariaDB