884 lines
16 KiB
Markdown
884 lines
16 KiB
Markdown
---
|
||
title: Daily Note - 2026-06-18
|
||
date: 2026-06-18 09:26:51
|
||
tags: []
|
||
Status: Active
|
||
type: DailyNote
|
||
---
|
||
|
||
Oracle database backup server (euniappbakprl01)
|
||
Oracle databases
|
||
product.bisnode.cz
|
||
public.bisnode.cz
|
||
|
||
|
||
|
||
https://dnbenterprise.atlassian.net/wiki/spaces/AllmantITKredit/pages/1855684994/CZ+disaster+recovery+plan
|
||
|
||
|
||
dev servers
|
||
devel1.bisnode.cz - free to restart
|
||
devel2.bisnode.cz
|
||
|
||
---
|
||
|
||
### 🧾 Kluczowe wnioski
|
||
|
||
**1. Przegląd architektury kopii zapasowych**
|
||
Oceniane są dwa główne podejścia:
|
||
- Kopia zapasowa wypychana (push) z hosta Oracle do systemu backupu VM
|
||
- Kopia zapasowa pobierana (pull) przez system backupu VM bezpośrednio z bazy danych/serwera
|
||
Decyzja nie została ostatecznie podjęta → wymaga testów i porównania.
|
||
|
||
**2. Potrzeba walidacji w środowisku testowym**
|
||
Wymagane jest środowisko testowe (Oracle + backup + przywracanie) w celu walidacji:
|
||
- wykonalności
|
||
- scenariuszy przywracania
|
||
Dostępne zasoby:
|
||
- Istniejące serwery deweloperskie (jeden można bez problemu restartować w ciągu dnia)
|
||
- Dodatkowy serwer testowy Linux dostępny do izolowanych testów
|
||
|
||
**3. Obecna strategia kopii zapasowych jest nieefektywna**
|
||
Obecnie skonfigurowane są codzienne pełne kopie zapasowe (full backups).
|
||
Zidentyfikowane problemy:
|
||
- duża rotacja wolumenu danych
|
||
- wpływ na wydajność maszyny wirtualnej i bazy danych
|
||
- nieefektywne wykorzystanie przestrzeni dyskowej
|
||
Ogólna zgoda zespołu: to podejście należy zmienić.
|
||
|
||
**4. Proponowana zmiana strategii kopii zapasowych**
|
||
Przejście na:
|
||
- Cotygodniowe pełne kopie zapasowe
|
||
- Codzienne przyrostowe/różnicowe kopie zapasowe
|
||
- Częste kopie zapasowe logów (co kilka godzin)
|
||
Omówione korzyści:
|
||
- mniejsze zużycie przestrzeni dyskowej
|
||
- poprawa wydajności
|
||
- możliwość przywrócenia bazy do określonego momentu w czasie (point-in-time recovery)
|
||
|
||
**5. Zarządzanie zmianą i kwestie komunikacyjne**
|
||
Zmiana musi przejść przez standardowy proces zarządzania zmianami (~5 dni roboczych).
|
||
Wymagana komunikacja:
|
||
- Dostawca Oracle (Digitech)
|
||
- Wewnętrzni interesariusze
|
||
Jeśli wymagana będzie przerwa w działaniu (downtime):
|
||
- Konieczne powiadomienie klienta z co najmniej 2-tygodniowym wyprzedzeniem (ze względu na SLA).
|
||
Obecnie nie jest jasne, czy wymagany będzie restart bazy danych → należy to zweryfikować.
|
||
|
||
**6. Planowanie kolejnych kroków**
|
||
Spotkanie kontrolne (follow-up) prawdopodobnie zostanie zaplanowane na przyszły tydzień.
|
||
|
||
### ✅ Zadania do wykonania (z przypisanymi osobami)
|
||
|
||
**🔧 Techniczne / Wdrożeniowe**
|
||
- Ocena podejść do kopii zapasowych (push vs pull z VM) — **Właściciel:** Paweł Domański (wsparcie: Łukasz)
|
||
- Konfiguracja środowiska testowego (walidacja Oracle + backup + przywracanie) — **Właściciel:** Paweł Domański (wsparcie: Michal Pavlina ws. dostępności serwerów dev)
|
||
- Użycie serwerów deweloperskich do testów — **Właściciel:** Michal Pavlina (uwaga: jeden z serwerów potwierdzony jako bezpieczny do restartów w ciągu dnia)
|
||
- Sprawdzenie, czy zmiana strategii kopii zapasowych wymaga restartu bazy danych — **Właściciel:** Paweł Domański
|
||
|
||
**📦 Zmiana strategii kopii zapasowych**
|
||
- Zaprojektowanie nowego harmonogramu kopii zapasowych (cotygodniowy full + przyrostowe + logi) — **Właściciel:** Paweł Domański
|
||
- Zaplanowanie i ustalenie harmonogramu zmiany na produkcji (standardowy proces zmiany) — **Właściciel:** Paweł Domański
|
||
|
||
**📢 Komunikacja**
|
||
- Koordynacja komunikacji z interesariuszami — **Właściciel:** Jan Dvořák + Michal Pavlina
|
||
- Powiadomienie dostawcy Oracle (Digitech) o zmianie — **Właściciel:** Jan Dvořák (potwierdził odpowiedzialność)
|
||
- Ocena potrzeby powiadomienia klienta (jeśli wymagany jest downtime) — **Właściciel:** Zespół (zależy od wyników weryfikacji konieczności restartu bazy)
|
||
|
||
**📅 Koordynacja**
|
||
- Zaplanowanie spotkania kontrolnego na przyszły tydzień — **Właściciel:** Leszek Wroński
|
||
|
||
### ⚡ Szybkie podsumowanie (bardzo zwięzłe)
|
||
- **Obecnie:** Codzienne pełne kopie zapasowe → nieefektywne → podlegają zmianie.
|
||
- **Cel:** Cotygodniowe pełne + przyrostowe + kopie logów.
|
||
- Wymagane testy i ostateczna decyzja między architekturami (push vs pull).
|
||
- Zmiana wymaga przejścia formalnego procesu i zakomunikowania interesariuszom.
|
||
- Otwarte ryzyko: weryfikacja czy wdrożenie wymusi restart lub downtime.
|
||
|
||
|
||
Okej — zrobię Ci **pełny, spójny raport DBA** z całej analizy: skryptu + warningów + planu wykonania + realnych rekomendacji.
|
||
|
||
To będzie coś, co możesz praktycznie potraktować jako:
|
||
✅ dokument techniczny
|
||
✅ materiał do review / knowledge sharing
|
||
✅ podstawę do decyzji produkcyjnej
|
||
|
||
***
|
||
|
||
# 📘 RAPORT: Optymalizacja migracji kolumny (SQL Server)
|
||
|
||
## 🔍 1. Cel skryptu
|
||
|
||
Skrypt służy do:
|
||
|
||
👉 masowej zmiany typu kolumn (np. `VARCHAR(9)`)
|
||
👉 w wielu tabelach
|
||
👉 z podziałem na strategię:
|
||
|
||
| przypadek | metoda |
|
||
| ------------------ | ------------------------ |
|
||
| małe tabele (≤20M) | `ALTER COLUMN` |
|
||
| duże tabele (>20M) | migracja “shadow column” |
|
||
|
||
***
|
||
|
||
## 🧱 2. Mechanizm dla dużych tabel
|
||
|
||
Dla dużych tabel stosowany jest wzorzec:
|
||
|
||
1. `ADD new_column`
|
||
2. kopiowanie danych batchami:
|
||
```sql
|
||
UPDATE TOP (99000)
|
||
```
|
||
3. (później) drop + rename
|
||
|
||
👉 to jest **poprawny enterprise pattern**
|
||
|
||
***
|
||
|
||
# 📊 3. Diagnoza planu wykonania
|
||
|
||
Na podstawie XML i operatorów:
|
||
|
||
## ✅ Fakty
|
||
|
||
* tabela: `REPORT_XML_STACK`
|
||
* liczba wierszy: **\~52 841 100**
|
||
* typ: **HEAP (brak clustered index)**
|
||
* batch: `TOP (99000)`
|
||
* używane:
|
||
* `Table Scan`
|
||
* `Parallelism`
|
||
* `Sort`
|
||
* `Table Update`
|
||
* `Index Update`
|
||
|
||
***
|
||
|
||
## ❗ KLUCZOWY PROBLEM
|
||
|
||
### ❌ 1. FULL / LARGE TABLE SCAN
|
||
|
||
```xml
|
||
PhysicalOp="Table Scan"
|
||
```
|
||
|
||
➡️ SQL Server czyta **dużą część 52M wierszy** dla każdego batcha
|
||
|
||
👉 to jest główne wąskie gardło
|
||
|
||
***
|
||
|
||
## ❗ 2. Słaby indeks filtrowany
|
||
|
||
Masz:
|
||
|
||
```sql
|
||
ON (DUNS_NBR_NEW1)
|
||
WHERE DUNS_NBR_NEW1 IS NULL
|
||
```
|
||
|
||
### Problem:
|
||
|
||
* wszystkie wartości = `NULL`
|
||
* brak selektywności
|
||
* brak sensownego porządku
|
||
|
||
👉 indeks istnieje, ale **nie prowadzi planu**
|
||
|
||
***
|
||
|
||
## ❗ 3. Batch `TOP (99000)` bez ORDER
|
||
|
||
```sql
|
||
UPDATE TOP (99000)
|
||
```
|
||
|
||
➡️ brak deterministycznego wyboru wierszy
|
||
|
||
👉 skutki:
|
||
|
||
* sort
|
||
* niespójne batchowanie
|
||
* trudniejsza optymalizacja
|
||
|
||
***
|
||
|
||
## ⚠️ 4. Warning: CONVERT()
|
||
|
||
```
|
||
Type conversion may affect cardinality estimate
|
||
```
|
||
|
||
### Wniosek:
|
||
|
||
👉 **prawdziwy, ale drugorzędny**
|
||
|
||
bo:
|
||
|
||
* CAST jest tylko w SET
|
||
* nie w predicate
|
||
|
||
👉 NIE jest główny problem
|
||
|
||
***
|
||
|
||
## ⚙️ 4. Dodatkowe obserwacje
|
||
|
||
### Parallelism
|
||
|
||
* `Gather Streams`
|
||
* wiele wątków
|
||
* dodatkowy overhead
|
||
|
||
***
|
||
|
||
### Sort przed update
|
||
|
||
* koszt \~13 CPU w planie
|
||
* wynika z braku uporządkowania danych
|
||
|
||
***
|
||
|
||
### Heap
|
||
|
||
* brak uporządkowania fizycznego
|
||
* więcej IO
|
||
* trudniejsze update’y
|
||
|
||
***
|
||
|
||
# 🎯 4. ROOT CAUSE
|
||
|
||
Największy problem to:
|
||
|
||
> ❗ SQL Server nie ma dobrej ścieżki dostępu do „następnych 99000 rekordów do update”
|
||
|
||
czyli:
|
||
|
||
* słaby indeks
|
||
* brak ORDER
|
||
* heap
|
||
* TOP
|
||
|
||
***
|
||
|
||
# 🚀 5. STRATEGIA OPTYMALIZACJI
|
||
|
||
## 🥇 PRIORYTET 1 — popraw indeks
|
||
|
||
Zamiast:
|
||
|
||
```sql
|
||
ON (DUNS_NBR_NEW1)
|
||
```
|
||
|
||
zrób indeks **na kluczu tabeli**:
|
||
|
||
```sql
|
||
CREATE NONCLUSTERED INDEX IX_REPORT_XML_STACK_MIGRATION
|
||
ON dbo.REPORT_XML_STACK (ID) -- <- KLUCZ!
|
||
INCLUDE (DUNS_NBR)
|
||
WHERE DUNS_NBR_NEW1 IS NULL
|
||
AND DUNS_NBR IS NOT NULL;
|
||
```
|
||
|
||
### Efekt:
|
||
|
||
✅ fast seek
|
||
✅ brak full scan
|
||
✅ mniej IO
|
||
✅ brak sort
|
||
|
||
***
|
||
|
||
## 🥇 PRIORYTET 2 — zmień UPDATE
|
||
|
||
Zamiast:
|
||
|
||
```sql
|
||
UPDATE TOP (99000)
|
||
```
|
||
|
||
użyj:
|
||
|
||
### ✅ wersja CTE
|
||
|
||
```sql
|
||
;WITH batch AS
|
||
(
|
||
SELECT TOP (20000)
|
||
ID,
|
||
DUNS_NBR
|
||
FROM dbo.REPORT_XML_STACK
|
||
WHERE DUNS_NBR_NEW1 IS NULL
|
||
AND DUNS_NBR IS NOT NULL
|
||
ORDER BY ID
|
||
)
|
||
UPDATE T
|
||
SET T.DUNS_NBR_NEW1 = CAST(B.DUNS_NBR AS VARCHAR(9))
|
||
FROM dbo.REPORT_XML_STACK T
|
||
JOIN batch B ON B.ID = T.ID
|
||
OPTION (RECOMPILE);
|
||
```
|
||
|
||
***
|
||
|
||
## 🥇 PRIORYTET 3 — zmniejsz batch
|
||
|
||
Z:
|
||
|
||
```sql
|
||
TOP (99000)
|
||
```
|
||
|
||
👉 testuj:
|
||
|
||
* 10k
|
||
* 20k
|
||
* 50k
|
||
|
||
### Korzyści:
|
||
|
||
✅ mniejszy log
|
||
✅ mniej blokad
|
||
✅ bardziej stabilny runtime
|
||
|
||
***
|
||
|
||
## 🥇 PRIORYTET 4 — dodaj RECOMPILE
|
||
|
||
```sql
|
||
OPTION (RECOMPILE)
|
||
```
|
||
|
||
👉 bo dataset się zmienia (NULL → NOT NULL)
|
||
|
||
***
|
||
|
||
## 🥈 PRIORYTET 5 — kontrola parallelism
|
||
|
||
Test:
|
||
|
||
```sql
|
||
OPTION (RECOMPILE, MAXDOP 1)
|
||
```
|
||
|
||
👉 często:
|
||
|
||
* mniej overhead
|
||
* bardziej przewidywalne batchy
|
||
|
||
***
|
||
|
||
## 🥈 PRIORYTET 6 — lock strategy
|
||
|
||
### obecnie:
|
||
|
||
```sql
|
||
TABLOCK
|
||
```
|
||
|
||
### alternatywa (bardziej OLTP-friendly):
|
||
|
||
```sql
|
||
WITH (UPDLOCK, READPAST)
|
||
```
|
||
|
||
***
|
||
|
||
## 🥈 PRIORYTET 7 — statystyki
|
||
|
||
```sql
|
||
UPDATE STATISTICS dbo.REPORT_XML_STACK IX_REPORT_XML_STACK_MIGRATION;
|
||
```
|
||
|
||
👉 ważne dla planu
|
||
|
||
***
|
||
|
||
# 🧠 6. FINALNY WZORZEC (PROD READY)
|
||
|
||
```sql
|
||
SET NOCOUNT ON;
|
||
SET XACT_ABORT ON;
|
||
|
||
DECLARE @Rows int = 1;
|
||
|
||
WHILE @Rows > 0
|
||
BEGIN
|
||
;WITH batch AS
|
||
(
|
||
SELECT TOP (20000)
|
||
T.ID,
|
||
T.DUNS_NBR
|
||
FROM dbo.REPORT_XML_STACK AS T
|
||
WITH (INDEX(IX_REPORT_XML_STACK_MIGRATION), UPDLOCK, READPAST)
|
||
WHERE T.DUNS_NBR_NEW1 IS NULL
|
||
AND T.DUNS_NBR IS NOT NULL
|
||
ORDER BY T.ID
|
||
)
|
||
UPDATE T
|
||
SET T.DUNS_NBR_NEW1 = CAST(B.DUNS_NBR AS VARCHAR(9))
|
||
FROM dbo.REPORT_XML_STACK AS T
|
||
JOIN batch AS B
|
||
ON B.ID = T.ID
|
||
OPTION (RECOMPILE, MAXDOP 1);
|
||
|
||
SET @Rows = @@ROWCOUNT;
|
||
|
||
PRINT CONCAT('Updated rows: ', @Rows);
|
||
END
|
||
```
|
||
|
||
***
|
||
|
||
# 📉 7. Oczekiwany efekt po optymalizacji
|
||
|
||
| obszar | efekt |
|
||
| ----------- | --------------------- |
|
||
| IO | ↓ znacząco |
|
||
| CPU | ↓ (mniej sort/scan) |
|
||
| log | ↓ |
|
||
| czas batcha | ↓ |
|
||
| stabilność | ↑ |
|
||
| blokady | ↓ (jeśli bez TABLOCK) |
|
||
|
||
***
|
||
|
||
# ✅ 8. TL;DR
|
||
|
||
👉 największy problem:
|
||
|
||
> ❌ batch TOP + heap + słaby indeks → table scan
|
||
|
||
👉 najważniejsze fixy:
|
||
|
||
1. ✅ indeks na kluczu (ID) + INCLUDE
|
||
2. ✅ batchowanie po ORDER BY ID
|
||
3. ✅ mniejszy TOP
|
||
4. ✅ RECOMPILE
|
||
|
||
👉 warning o CAST:
|
||
|
||
> ℹ️ istnieje, ale nie jest głównym problemem
|
||
|
||
Super — to jest bardzo dobry drugi kawałek Twojego frameworka 🔥
|
||
I teraz możemy zrobić **pełną analizę architektury (Step 8)**, bo to jest kluczowy moment: *odtwarzanie constraints, indeksów i obiektów* po migracji.
|
||
|
||
***
|
||
|
||
# 📘 TL;DR (co robi Step 8)
|
||
|
||
👉 Ten fragment:
|
||
|
||
* zbiera **skrypty odtwarzające** (constraints, indexy, statystyki, view-indexy)
|
||
* wrzuca je do kolejki (`Step8Queue`)
|
||
* sortuje wg kolejności zależności
|
||
* wykonuje je **sekwencyjnie przez cursor**
|
||
|
||
👉 to jest poprawny pattern typu **rebuild pipeline**
|
||
|
||
***
|
||
|
||
# 🧠 Co działa BARDZO dobrze
|
||
|
||
## ✅ 1. Kolejka wykonania (Step8Queue)
|
||
|
||
To jest bardzo dobry design:
|
||
|
||
```sql
|
||
CREATE TABLE Step8Queue (...)
|
||
```
|
||
|
||
👉 masz:
|
||
|
||
* centralny queue
|
||
* kontrolę kolejności
|
||
* możliwość debugowania
|
||
* możliwość DRY RUN
|
||
|
||
💡 to jest **bardziej kontrolowalne niż dynamiczne wykonania ad-hoc**
|
||
|
||
***
|
||
|
||
## ✅ 2. Priorytety (ExecutionOrder)
|
||
|
||
```sql
|
||
CASE ObjectType
|
||
WHEN 'PK/UNIQUE' THEN 1
|
||
WHEN 'DEFAULT' THEN 3
|
||
WHEN 'FOREIGN_KEY' THEN 5
|
||
WHEN 'INDEX' THEN 7
|
||
```
|
||
|
||
👉 bardzo ważne — bo:
|
||
|
||
| obiekt | zależność |
|
||
| ------ | ----------------- |
|
||
| PK | musi być pierwszy |
|
||
| FK | potrzebują PK |
|
||
| INDEX | na końcu |
|
||
|
||
✅ to jest poprawna kolejność odbudowy
|
||
|
||
***
|
||
|
||
## ✅ 3. DryRun mode
|
||
|
||
```sql
|
||
IF @DryRun = 1
|
||
```
|
||
|
||
👉 super ważne przy takich operacjach
|
||
|
||
***
|
||
|
||
## ✅ 4. TRY/CATCH + logowanie
|
||
|
||
```sql
|
||
BEGIN TRY
|
||
EXEC ...
|
||
END TRY
|
||
BEGIN CATCH
|
||
EXEC dbo.usp_LogError
|
||
```
|
||
|
||
👉 dobrze, bo:
|
||
|
||
* nie wywala całego procesu
|
||
* masz audit
|
||
|
||
***
|
||
|
||
# ⚠️ Problemy i miejsca do poprawy (ważne)
|
||
|
||
Teraz sedno — co bym poprawił jako DBA produkcyjny:
|
||
|
||
***
|
||
|
||
# ❌ 1. Cursor = wąskie gardło (ale… tu jest OK)
|
||
|
||
Masz:
|
||
|
||
```sql
|
||
CURSOR FAST_FORWARD
|
||
```
|
||
|
||
👉 normalnie powiedziałbym: "cursor zły"
|
||
|
||
ALE w tym przypadku:
|
||
|
||
* tworzysz obiekty (DDL)
|
||
* kolejność jest ważna
|
||
* trzeba sekwencyjnie
|
||
|
||
👉 ✅ cursor jest tu **UZASADNIONY**
|
||
|
||
***
|
||
|
||
# ❌ 2. Brak jawnej transakcji per obiekt
|
||
|
||
Masz:
|
||
|
||
```sql
|
||
SET XACT_ABORT ON;
|
||
```
|
||
|
||
ALE nie masz:
|
||
|
||
```sql
|
||
BEGIN TRAN
|
||
COMMIT
|
||
```
|
||
|
||
### Problem
|
||
|
||
Jeśli obiekt:
|
||
|
||
* padnie w połowie (np. index CREATE)
|
||
* i nie rollbacknie się poprawnie
|
||
|
||
👉 możesz mieć niespójny stan
|
||
|
||
***
|
||
|
||
## ✅ Fix
|
||
|
||
Dodać per-obiekt:
|
||
|
||
```sql
|
||
BEGIN TRY
|
||
BEGIN TRAN
|
||
|
||
EXEC sp_executesql @stmt1
|
||
|
||
COMMIT
|
||
END TRY
|
||
BEGIN CATCH
|
||
IF XACT_STATE() <> 0 ROLLBACK
|
||
```
|
||
|
||
***
|
||
|
||
# ❌ 3. PRINT zamiast realnego logowania
|
||
|
||
Masz:
|
||
|
||
```sql
|
||
PRINT @OBJT1 + '---' + @stmt1
|
||
```
|
||
|
||
👉 PRINT:
|
||
|
||
* znika przy dłuższych operacjach
|
||
* tnie się
|
||
* nie jest audytowalny
|
||
|
||
***
|
||
|
||
## ✅ Fix
|
||
|
||
Zostaw PRINT, ale dodaj:
|
||
|
||
```sql
|
||
INSERT INTO MyprintLog (...)
|
||
VALUES (...)
|
||
```
|
||
|
||
PRZED wykonaniem, nie tylko po
|
||
|
||
***
|
||
|
||
# ❌ 4. Brak retry logic
|
||
|
||
DDL potrafi failować przez:
|
||
|
||
* blocking
|
||
* deadlock
|
||
* metadane
|
||
|
||
👉 obecnie:
|
||
|
||
* jeden fail = log + jedziemy dalej
|
||
|
||
***
|
||
|
||
## ✅ Fix (mini retry)
|
||
|
||
```sql
|
||
DECLARE @retry INT = 0;
|
||
|
||
WHILE @retry < 3
|
||
BEGIN
|
||
BEGIN TRY
|
||
EXEC sp_executesql @stmt1
|
||
BREAK
|
||
END TRY
|
||
BEGIN CATCH
|
||
SET @retry = @retry + 1
|
||
WAITFOR DELAY '00:00:02'
|
||
END CATCH
|
||
END
|
||
```
|
||
|
||
***
|
||
|
||
# ❌ 5. Literówka w ObjectType
|
||
|
||
Masz:
|
||
|
||
```sql
|
||
'Foregin_sweep_Key'
|
||
```
|
||
|
||
👉 może powodować:
|
||
|
||
* brak dopasowania
|
||
* złe sortowanie
|
||
|
||
***
|
||
|
||
# ❌ 6. ORDER BY w INSERT (niezdeterminowane)
|
||
|
||
```sql
|
||
INSERT INTO Step8Queue
|
||
SELECT ...
|
||
ORDER BY ...
|
||
```
|
||
|
||
👉 SQL Server ignoruje `ORDER BY` w INSERT bez TOP
|
||
|
||
***
|
||
|
||
## ✅ Fix
|
||
|
||
Sortuj tylko przy SELECT w cursorze (już robisz ✅)
|
||
|
||
***
|
||
|
||
# ❌ 7. Brak walidacji duplikatów
|
||
|
||
Nie masz:
|
||
|
||
```sql
|
||
PRIMARY KEY na Step8Queue
|
||
```
|
||
|
||
👉 możesz mieć:
|
||
|
||
* duplikaty create scriptów
|
||
* ponowne wykonanie DDL
|
||
|
||
***
|
||
|
||
## ✅ Fix
|
||
|
||
Dodaj:
|
||
|
||
```sql
|
||
ALTER TABLE Step8Queue
|
||
ADD CONSTRAINT PK_Step8Queue UNIQUE(ObjectType, ObjectName, ParentTable);
|
||
```
|
||
|
||
***
|
||
|
||
# ❌ 8. Brak kontroli zależności między tabelami
|
||
|
||
Sortowanie:
|
||
|
||
```sql
|
||
ORDER BY ExecutionOrder, ObjectType
|
||
```
|
||
|
||
ALE:
|
||
|
||
👉 dwa FK między tabelami mogą się „gryźć”
|
||
|
||
***
|
||
|
||
## ✅ advanced fix (opcjonalne)
|
||
|
||
Topologiczne sortowanie zależności FK
|
||
(albo retry loop — prostsze)
|
||
|
||
***
|
||
|
||
# ❌ 9. Możliwy błąd: VARCHAR(MAX) dla CreateScript
|
||
|
||
Może powodować:
|
||
|
||
* duże użycie tempdb / memory
|
||
|
||
👉 OK przy małej liczbie obiektów
|
||
👉 przy tysiącach → problem
|
||
|
||
***
|
||
|
||
# 🔥 Najważniejszy problem architektoniczny
|
||
|
||
## Step 8 zakłada, że wszystko się odtworzy „bez oporu”
|
||
|
||
w praktyce:
|
||
|
||
* FK mogą failować
|
||
* PK mogą failować
|
||
* index może failować
|
||
|
||
👉 i Twój flow:
|
||
|
||
```
|
||
FAIL → log → NEXT
|
||
```
|
||
|
||
czyli:
|
||
|
||
❗ możesz skończyć ze środowiskiem:
|
||
|
||
* bez FK
|
||
* bez indeksów
|
||
* częściowo odtworzonym
|
||
|
||
***
|
||
|
||
# ✅ Lepszy pattern (produkcyjny)
|
||
|
||
## podejście 2-fazowe
|
||
|
||
### FAZA 1 – CREATE (niekrytyczne błędy OK)
|
||
|
||
* PK, INDEX, DEFAULT, CHECK
|
||
|
||
### FAZA 2 – FK (retry loop)
|
||
|
||
```sql
|
||
WHILE EXISTS (FK do odtworzenia)
|
||
BEGIN
|
||
spróbuj odtworzyć
|
||
jeśli fail → zostaw
|
||
END
|
||
```
|
||
|
||
👉 aż nic się nie da już zrobić
|
||
|
||
***
|
||
|
||
# 📊 FINALNA OCENA
|
||
|
||
| obszar | ocena |
|
||
| ------------------ | ----- |
|
||
| architektura | ⭐⭐⭐⭐⭐ |
|
||
| bezpieczeństwo | ⭐⭐⭐⭐ |
|
||
| odporność na błędy | ⭐⭐⭐ |
|
||
| wydajność | ⭐⭐⭐⭐ |
|
||
| produkcyjność | ⭐⭐⭐⭐ |
|
||
|
||
***
|
||
|
||
# 🚀 Co bym zrobił jako DBA (konkrety)
|
||
|
||
## ✅ MUST HAVE
|
||
|
||
1. transakcja per obiekt
|
||
2. logging pre + post
|
||
3. poprawa indeksów migracji (z poprzedniego wątku)
|
||
|
||
***
|
||
|
||
## ✅ SHOULD HAVE
|
||
|
||
4. retry logic
|
||
5. eliminacja literówek
|
||
6. unique constraint na queue
|
||
|
||
***
|
||
|
||
## ✅ NICE TO HAVE
|
||
|
||
7. FK retry loop
|
||
8. dependency-aware ordering
|
||
|
||
***
|
||
|
||
# 🧠 Finalny wniosek
|
||
|
||
👉 Step 8 jest:
|
||
|
||
✅ dobrze zaprojektowany
|
||
✅ zgodny z enterprise patternem
|
||
❗ ale wymaga hardeningu pod produkcję
|
||
|
||
***
|
||
|
||
# 👍 Jeśli chcesz
|
||
|
||
Mogę Ci:
|
||
|
||
✅ przepisać cały Step 8 w wersji **production-grade (hardcore DBA)**
|
||
✅ dodać retry engine + dependency resolver
|
||
✅ zrobić wersję z checkpointami (resume after fail)
|
||
✅ dodać metryki: ile % zrobione
|
||
|
||
Powiedz tylko — zrobimy z tego narzędzie, którego będziesz używać latami 👍
|