Files
admin/.tasks/mssql-vds-migration.md
vitya 86a94d7f9d tasks(vds-migration): decompose umbrella → 3 child tasks
- mssql-vds-migration : Express edition, BACKUP/RESTORE method, mssql.kzntsv.site:1433
- minio-imgproxy-vds-migration : MinIO upgrade 2020→latest, mc mirror, includes imgproxy+nginx
- iis-cutover-to-vds-services 🔵: atomic web.config repoint (1 file → 11 hosts), blocked on both migrations
- umbrella mssql-minio-migration-to-vds 🟢: decomposed (kept for history)

Discovery: 5 prod DBs ≤ 968 MB (Express OK), .ldf logs 12 GB → SHRINKFILE
pre-cutover. VDS: 79 GB free, 5.8 GB RAM avail. ownCloud capped 1G.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 09:02:49 +03:00

8.2 KiB
Raw Permalink Blame History

mssql-vds-migration

Goal

Перенести MSSQL контейнер с ../entities/windows-recovery-host на ../entities/vds-kzntsv (/opt/stacks/databases/mssql/), Express Edition для прода, доступ снаружи через mssql.kzntsv.site:1433 (traefik TCP passthrough), интеграция в существующий vds-backup-rsync-kreknin pipeline.

Это MSSQL-only половина umbrella'ы mssql-minio-migration-to-vds (декомпозирована 2026-05-22). Вторая половина — minio-imgproxy-vds-migration.

Key files / refs

  • Source: docker container mssql на windows-recovery-host, image mcr.microsoft.com/mssql/server:2019-latest, volume mssql_mssql_data (26.6 GB total, real data ~2.4 GB, остальное .ldf logs).
  • Source DBs (verified via docker exec mssql ls /var/opt/mssql/data/, 2026-05-22):
    • MoreThenCms.mdf 867 MB + log 9.9 GB
    • StayerCalculator.mdf 504 MB + log 1.2 GB
    • StayerPrice.mdf 38 MB + log 215 MB
    • TireService.mdf 8 MB + log 8 MB
    • stostayer.mdf 968 MB + log 264 MB
    • Max .mdf 968 MB < 10 GB Express limit ✓ all fit
  • Target: /opt/stacks/databases/mssql/{data,docker-compose.yml,.env} на VDS, паттерн как у postgres (/opt/stacks/databases/postgres/data bind, network proxy + shared-dbs).
  • Image: mcr.microsoft.com/mssql/server:2022-latest Express Edition (MSSQL_PID=Express).
  • CMS connection strings: Data Source=localhost,1433Data Source=mssql.kzntsv.site,1433 в IIS web.config / appsettings.
  • TLS: self-signed, traefik raw-TCP passthrough — pattern ../.wiki/concepts/db-tls-self-signed-via-traefik-raw-tcp + ../.wiki/concepts/traefik-tcp-passthrough-vs-starttls.
  • Backup pipeline: /opt/stacks/backup/scripts/run.sh на VDS — добавить новые ноги (см. acceptance 6).

Decisions

  • Edition: Express (user 2026-05-22). Max DB size 10 GB соблюдён всеми текущими базами. RAM cap Express = 1.4 GB built-in. Дополнительно MSSQL_MEMORY_LIMIT_MB=2048 (user-confirmed), но Express всё равно сам зажмёт до 1410.
  • Method: BACKUP DATABASE … WITH COMPRESSION, COPY_ONLY → scp .bak → RESTORE на VDS. Не detach/attach — кросс-edition (Developer → Express) supported только через backup/restore. Compression ≈ 80% reduction, ожидаемый transfer ~500 MB.
  • Pre-cutover SHRINKFILE на .ldf — срежет 12 GB logs до минимума (не для transfer — для cleanup source перед миграцией; transfer идёт через .bak, который и так не включает inactive log space).
  • Hostname: mssql.kzntsv.site (не mssql.vds.kzntsv.site — user decision 2026-05-22). DNS A-record указать на VDS IP.

Acceptance

  1. Pre-cutover на source (windows-host):
    • BACKUP LOG <db> WITH TRUNCATE_ONLY + CHECKPOINT + DBCC SHRINKFILE для .ldf всех 5 prod DBs.
    • Verify du -sh /var/opt/mssql/data/*_log.ldf → каждый < 100 MB.
    • WARNING: SHRINKFILE с TRUNCATE_ONLY ломает log-chain → no point-in-time restore до следующего FULL backup. Делается только в migration window, новый FULL снимается сразу после RESTORE на VDS.
  2. MSSQL container на VDS запущен:
    • mcr.microsoft.com/mssql/server:2022-latest, ACCEPT_EULA=Y, MSSQL_PID=Express, MSSQL_MEMORY_LIMIT_MB=2048, SA_PASSWORD из pass show mssql-vds/sa-password (новый pass entry).
    • Volume bind /opt/stacks/databases/mssql/data:/var/opt/mssql:rw.
    • Networks proxy + shared-dbs. Traefik labels TCP entrypoint mssql :1433 → HostSNI(*).
  3. Traefik static config (/opt/stacks/proxy/traefik/traefik.yml):
    entryPoints:
      mssql:
        address: ":1433"
    
    • ufw allow 1433/tcp.
  4. 5 prod DBs restored на VDS:
    • BACKUP DATABASE … WITH COMPRESSION, COPY_ONLY на source → 5 .bak файлов.
    • scp → /opt/stacks/databases/mssql/data/backups/ на VDS.
    • RESTORE DATABASE … FROM DISK='/var/opt/mssql/backups/<db>.bak' WITH MOVE.
    • Verify SELECT name, state_desc FROM sys.databases → все 5 ONLINE, DBCC CHECKDB('<db>') → 0 errors на каждой.
  5. CMS connection strings updated в web.config (или эквиваленте), 8 sites smoke:
    • 200 OK + asset loading + admin/assets/getList (известный hot-path).
    • Pre-cutover benchmark обязателен — admin assets UI / search / catalogs latency измерены до и после, degradation <2x target. Если worse — discuss перед commit'ом cutover (10-30ms WAN vs localhost).
  6. Backup pipeline на VDS расширен (/opt/stacks/backup/scripts/run.sh):
    • mssql_dump_full ежедневно (BACKUP DATABASE WITH COMPRESSION для каждой DB → tar.gz → rsync nightly).
    • mssql_tx_log_backup ежечасно (BACKUP LOG для каждой DB через docker exec mssql /opt/mssql-tools/bin/sqlcmd …) → rsync hourly. Достигает target RPO 1ч.
  7. ntfy push verified для расширенного pipeline (включает MSSQL dump size/duration).
  8. Source windows-host MSSQL — после 48ч uptime на VDS: stop container (read-only fallback пропустить — pass), через неделю — docker rm + docker volume rm mssql_mssql_data.
  9. Documented в ../.wiki/concepts/mssql-on-vds (создать): architecture, rollback recipe (revert connection strings + start windows-host MSSQL container), migration runbook.

Open questions

  • DNS A-record mssql.kzntsv.site → VDS IP (89.253.255.94) — сделать через REGRU API или manual?
  • Hermes service на windows-host — зависит от local MSSQL? Если да — мигрируется заодно или ломается. См. ../.wiki/entities/vds-kzntsv Open issues.
  • CMS connection-string location — web.config? appsettings? hardcoded в DLL? Если hardcoded — нужен rebuild (build env вопрос). См. note в ../.wiki/concepts/cms-admin-assets-root-folder-seed §"Долгосрочный TODO".

Risks

  • WAN latency IIS→MSSQL: 10-30ms vs localhost. Большинство CMS-операций batchey, не latency-sensitive. Pre-cutover benchmark обязателен (acceptance 5).
  • Express Edition limits: 10 GB/DB, 1.4 GB RAM, 1 socket / 4 cores. Max .mdf сейчас 968 MB — запас 10x. Если stostayer начнёт расти — early warning через monitoring (separate task).
  • MSSQL Linux compat: некоторые edge-case T-SQL отличаются (CLR, FileStream, full-text). Smoke обязателен — EXEC sp_helpdb + проверить нет ли CLR assemblies / FileStream filegroups в prod DBs.
  • TLS overhead: raw-TCP через traefik adds <1ms — negligible.
  • VDS RAM tight: owncloud anon 282 MB + gitea 834 MB + verdaccio 226 MB + DBs 285 MB + traefik 52 MB + redis 6 MB = ~1.7 GB реально используется (page-cache reclaimable). MSSQL 2 GB влезает с запасом 4 GB до OOM.
  • Disk free на VDS не проверен (ops-mcp read-only docker). Нужно ~3 GB MSSQL restored + ~5 GB free для backup'ов. Проверить df -h /opt/stacks ssh'ем перед стартом.
  • Cutover rollback: revert возможен только если windows-host MSSQL container оставлен running (read-only желательно но не критично) 48ч после cutover. Acceptance 8 это закладывает.

Notes

  • Зависит от: minio-imgproxy-vds-migration (нет — независимы).
  • Зависимая follow-up: списать cms-stopgap-backup-daily cron после успешного first VDS backup-pipeline run.
  • Atomic revert (full): revert CMS web.config → windows-host MSSQL; восстановить cms-stopgap-backup-daily cron; на VDS — docker compose down -v для mssql stack; удалить mssql ноги из run.sh; remove traefik mssql entrypoint; ufw deny 1433/tcp.