Narzędzie Database Upgrader
Narzędzie Database Upgrader służy do automatycznego uruchamiania skryptów SQL podczas aktualizacji oprogramowania VSoft (w ramach procesu upgrade’u baz danych). Narzędzie oraz skrypty do uruchomienia są częścią składową każdego pakietu instalacyjnego.
Przeznaczenie narzędzia
Dokumentacja przeznaczona jest dla administratora po stronie klienta, który uruchamia narzędzie w celu aktualizacji bazy danych oraz dla programistów zarówno po stronie VSoft, jak i programistów klienta korzystających z platformy archITekt i przygotowujących skrypty aktualizujące bazy danych do uruchomienia przez Database Upgrader.
Rola narzędzia Database Upgrader
Wraz z kolejnymi wersjami tworzonego oprogramowania, VSoft dostarcza w pakiecie instalacyjnym zarówno nowe pliki binarne, jak i skrypty SQL, które mają być uruchomione na bazach danych używanych przez docelowe środowiska. Narzędzie Database Upgrader służy właśnie do tego, aby w sposób kontrolowany uruchomić skrypty SQL na docelowych bazach danych.
Narzędzie wspiera możliwość upgrade’u więcej niż jednej bazy danych konkretnego środowiska. Rolą narzędzia Database Upgrader jest sprawdzenie, w jakiej wersji jest obecna baza danych, a także czy istnieją skrypty, które powinny być uruchomione na danej bazie. Narzędzie uruchamia wymagane skrypty i równocześnie śledzi poprawność ich wykonania oraz raportuje ewentualne błędy.
Przygotowanie skryptów do uruchomienia
- W procesie aktualizacji bazy danych bardzo ważną kwestię stanowi prawidłowa kolejność uruchamiania skryptów oraz informacja, czy zostały wykonane poprawnie, czy też wystąpiły jakieś błędy.
- Aby zapobiec nieprawidłowościom podczas uruchamiania skryptów, należy odpowiednio je przygotować w trakcie prac deweloperskich nad kolejną wersją oprogramowania.
- Przygotowanie skryptów do wykonania polega na stworzeniu odpowiedniego katalogu (np.
Scripts), który powinien zawierać kolejne foldery o nazwach zgodnych z nazwami bazy danych (np.ConfigiData). Następnie w każdym z tych folderów (ich struktura opisana jest poniżej) należy umieścić skrypty, które mają zostać uruchomione na określonej bazie danych. Wszystkie skrypty powinny być zakodowane przy użyciu kodowania UTF-8.
Przykładowa struktura katalogów zawierających skrypty:

Katalogi odpowiadające bazom danych mają następującą strukturę (zawierają):
Katalogi o specjalnym przeznaczeniu:
!BEGIN!FINISH!INITIALIZATION
Zwyczajne katalogi ze skryptami dla poszczególnych wersji aplikacji (numeracja katalogu odpowiada wersji aplikacji), np.:
- 1.0.1 - … (opcjonalny opis w nazwie pliku)
- 1.0.2 - …
W tak ponumerowanych katalogach ze skryptami należy umieszczać pliki z rozszerzeniem *.sql, które powinny być również tak nazwane (ponumerowane), aby dało się je posortować od najwcześniejszego do najpóźniejszego. Opcjonalny opis w nazwie folderu (po znaku minus „-”) ma charakter informacyjnego komentarza do zawartości folderu. Nazwy (numery) folderów ze skryptami, jak i same nazwy plików *.sql, są szczególnie istotne dla prawidłowego działania procesu upgrade’u bazy danych, czyli uruchomienia skryptów w kolejności naturalnego sortowania katalogów i samych plików (czyli takiego samego jak w Windows Explorerze). Np.:
- 1.8
- 1.9
- 1.10
- 1.11…
W trakcie pracy nad kolejnymi wersjami systemu należy zatem zakładać katalogi i pliki zgodnie z opisaną w tym rozdziale procedurą. Najlepszym sposobem, aby sprawdzić, w jakiej kolejności będą uruchamiane skrypty, jest otwarcie katalogu ze skryptami w Windows Explorerze i posortowanie ich po nazwie.
Przykład naturalnego sortowania numerów wersji:

Dostarczanie skryptów w postaci archiwów
- Dowolne elementy katalogu skryptów mogą być dostarczone w postaci normalnej lub skompresowanej do jednego z formatów:
*.zip,*.rar,*.7z - Narzędzie w przypadku napotkania pliku archiwum w katalogu skryptów zmienia swój sposób działania: nie używa źródłowego katalogu ze skryptami, lecz zakłada katalog tymczasowy, do którego kopiuje wszystkie elementy nie będące archiwami, a następnie rozpakowuje do niego zawartość napotkanych archiwów (zarówno katalogów jak i pojedynczych plików).
- Po zakończeniu procesu dekompresji wykonuje dalsze operacje traktując tymczasowo stworzony katalog jako źródło skryptów.
Przykład działania mechanizmu dekompresji
Tak dostarczony katalog zawierający archiwa na różnych poziomach zagłębień:

Zostanie rozpakowany do katalogu tymczasowego o takiej zawartości:
Katalogi o specjalnym przeznaczeniu
Katalogi odpowiadające bazom danych zawierają, oprócz zwykłych katalogów ze skryptami, katalogi o specjalnym przeznaczeniu. Są to katalogi !BEGIN, !FINISH oraz !INITIALIZATION.
| Katalog | Opis |
|---|---|
!INITIALIZATION | Skrypty z tego katalogu uruchamiane są w specjalnym trybie, który służy do zakładania baz danych lub wgrywania pierwszej wersji. Tryb inicjalizacji opisany jest szczegółowo w rozdziale Uruchomienie w trybie inicjalizacyjnym. |
!BEGIN | Skrypty z tego katalogu zostaną uruchomione przed każdym procesem upgrade’u. Jeżeli narzędzie wykryje, że ma uruchomić skrypty ze zwyczajnych katalogów, to dodatkowo, na początku każdego procesu upgrade’u, uruchomi skrypty z katalogu !BEGIN. W katalogu !BEGIN można umieścić np. skrypty, które coś sprawdzają, weryfikują, czy baza danych jest w prawidłowym stanie, czy wszyscy są z niej wylogowani itp. |
!FINISH | Skrypty z tego katalogu zostaną uruchomione każdorazowo po zakończeniu pełnego procesu upgrade’u. W katalogu !FINISH można umieścić np. skrypty, które wykonują rebuild indeksów, przeliczenie statystyk itp. |
Uruchomienie Database Upgradera
- Database Upgrader jest aplikacją konsolową uruchamianą z wiersza polecenia.
- Aby dowiedzieć się, jak to zrobić, należy otworzyć konsolę, przejść do lokalizacji programu i go uruchomić.
- Wyświetli się składnia programu, czyli wszystkie polecenia, które można wydać.

- Po podaniu odpowiednich parametrów Database Upgrader uruchamia przetwarzanie wg zadanych parametrów.

- Najczęstszym przypadkiem uruchamiania programu jest uruchamianie w ramach skryptów instalacyjnych – skrypty te przekazują programowi wszelkie niezbędne parametry.
- Zostanie to szczegółowo omówione w rozdziale Używanie zmiennych w skryptach.
Diagnostyka uruchomienia
- W trakcie startu aplikacji Database Upgrader wszelkie logi z uruchomienia wyświetlane są w konsoli, a także zapisywane są w pliku na dysku.
- Logi zawierają wszystkie informacje o tym, jakie skrypty zostały uruchomione, a także informacje o wynikach i ewentualnych błędach.
- Informacje wyświetlone na konsoli oraz zapisane w logach są podstawowym źródłem informacji o przetwarzaniu, dlatego aby zdiagnozować ewentualny błąd, należy dokładnie sprawdzić zapisane tam informacje.
Log zawiera w szczególności informacje takie jak:
- data wystąpienia akcji,
- rodzaj komunikatu (debug, info, error),
- komentarz informacyjny (co zostało zrobione, wartość jakiegoś parametru, nazwa skryptów, które zostały uruchomione itp.).

Przykładowy log przedstawiający błąd wykonania skryptu
- Oprócz zapisywania informacji do logów, narzędzie Database Upgrader zapisuje informacje do docelowej bazy danych – do tabeli
_DATABASE_UPDATE_JOURNAL - W tabeli tej zapisywane są wszelkie uruchomione skrypty na danej bazie łącznie z dodatkowymi informacjami, takimi jak data uruchomienia, rezultat, użytkownik uruchamiający upgrade itp.
- Analizując rekordy zapisane w tabeli, można zatem odtworzyć wszelkie operacje upgrade’u konkretnej bazy, które kiedykolwiek zostały wykonane przez Database Upgrader.

Przykładowa zawartość tabeli _DATABASE_UPDATE_JOURNAL
Uruchomienie w trybie inicjalizacyjnym
Tryb inicjalizacyjny narzędzia Database Upgrader pozwala między innymi na:
- założenie bazy danych,
- wgranie wstępnych danych do bazy danych,
- założenie w tej strukturze tabeli
_DATABASE_UPDATE_JOURNALumożliwiającej późniejsze uruchamianie skryptów w normalnym trybie działania.
Tryb inicjalizacyjny jest wykonywany najczęściej tylko jeden raz dla konkretnej bazy danych. W trybie tym są wykonywane jedynie skrypty z katalogu !INITILIZATION
Podczas uruchomienia trybu inicjalizacyjnego NIE jest sprawdzana obecna wersja bazy – są jedynie zawsze wykonywane wszystkie skrypty z ww katalogu.
Uruchomienie w trybie WhatIf
- Aby administrator mógł się upewnić, czy narzędzie Database Upgrader wykona prawidłowe skrypty, został stworzony specjalny tryb
WhatIf - W trakcie uruchomienia, narzędzie Database Upgrader podłącza się do docelowych baz danych, które mają być zaktualizowane i sprawdza, w jakiej wersji są obecnie te bazy. Program odczytuje w tym celu numer wersji i nazwę ostatniego poprawnie wykonanego skryptu zapisanego w tabeli
_DATABASE_UPDATE_JOURNAL, a następnie porównuje z nią odpowiadające tej bazie katalogi ze skryptami (czyli z ich wersjami), i na tej podstawie ustala listę skryptów, które należy uruchomić na danej bazie. - W normalnym trybie uruchomienia kolejnym krokiem jest wykonanie poszczególnych skryptów.
- Natomiast w trybie
WhatIfnastępuje jedynie analiza wersji bazy danych, analiza numerów skryptów przygotowanych do uruchomienia oraz prezentacja tych skryptów, które miałyby zostać uruchomione. - Same skrypty NIE zostają jednak uruchomione.
- Dzięki trybowi
WhatIfmożna zatem sprawdzić przed uruchomieniem rezultat hipotetycznego upgrade’u bazy bez dokonywania na niej jakichkolwiek zmian.
Używanie zmiennych w skryptach
- W trakcie przygotowywania skryptów SQL do aktualizacji bazy danych może wyniknąć konieczność użycia zmiennej, której wartość jest określona i przekazana dopiero w runtimie podczas uruchamiania danego skryptu.
- Nie należy mylić opisywanych tutaj zmiennych przekazywanych z zewnątrz ze zmiennymi języka SQL deklarowanymi i używanymi wewnątrz skryptu przy pomocy instrukcji
DECLARE @zmienna - W takim wypadku należy tą zmienną zapisać w skrypcie SQL w następujący sposób:

Przykładowe użycie zmiennej w skrypcie
- Fragment tekstu oznaczony w ten sposób jest informacją dla Database Upgradera, że jest to zmienna i że w jej miejsce należy podstawić konkretną wartość w momencie wykonywania skryptu.
Database Upgrader wspiera pobieranie wartości zmiennych na trzy sposoby:
- Podanie wartości bezpośrednio w wierszu polecenia.
- Zapisanie wartości zmiennych do pliku
*.inii podanie nazwy tego pliku przy wywołaniu w wierszu polecenia.

Plik .ini zawierający wartości zmiennych
- Użycie wartości zmiennych wcześniej zapisanych w konfiguracji technicznej VSoft, czyli w bazodanowej tabeli
CONFIG_KEY. W takim przypadku należy wskazać programowi connection string do bazy danych zawierającej tę tabelę.
Database Upgrader, po otrzymaniu wartości zmiennych podanych na jeden z tych sposobów, będzie je automatycznie ustawiał przed wykonaniem do skryptów, tak aby uruchomić skrypt, który w miejsce zmiennej ma już podstawioną konkretną wartość.
- Dzięki temu można przygotować skrypty raz, a następnie uruchamiać je w razie potrzeby na różnych środowiskach.
- W przypadku niepodania wartości jakiejś zmiennej występującej w skrypcie wykonanie procesu upgrade’u zakończy się błędem.
Integracja ze skryptami instalacyjnymi
- Database Upgrader jest narzędziem niezależnym i można je uruchomić samodzielnie, podając odpowiednie parametry w konsoli.
- Najczęściej jednak Database Upgrader używany jest jako składowa część procesu instalacji nowej wersji oprogramowania VSoft.
- W takim przypadku, narzędzie jest zawołane z większego skryptu instalacyjnego napisanego w PowerShell’u.
- Biblioteka
VSoft InstallToolssłużąca do opisania skryptów instalacyjnych w PowerShell’u posiada funkcjęInvoke-VSOFTDbUpgrader, która wywołuje Database Upgradera i przekazuje mu wszystkie potrzebne parametry. - Biblioteka i funkcja nie wnoszą żadnej nowej funkcjonalności – umożliwiają jedynie wygodne zawołanie Database Upgradera w odpowiednim momencie całego procesu instalacyjno-aktualizującego napisanego w PowerShell’u.
Więcej informacji o bibliotece VSoft InstallTools w osobnym dokumencie Skrypty Instalacyjne.
Postępowanie w przypadku błędów
Podczas przygotowania procesu upgrade’u oraz skryptów aktualizujących bazy danych może się zdarzyć, że wystąpi jakiś błąd. Rozdział ten opisuje, co należy zrobić, jeżeli podczas aktualizacji baz danych wystąpi taki przypadek.
- Należy pamiętać, że Database Upgrader uruchamia skrypty w odpowiedniej kolejności.
- Jeżeli okaże się, że jakiś skrypt jest niepoprawny lub niepoprawne są dane w bazie, na której operuje program (baza znajduje się w takim stanie, którego skrypt nie przewiduje), to w takim przypadku skrypt zgłosi błąd.
- Ponieważ Database Upgrader nie jest w stanie naprawić docelowej bazy danych, to też zatrzyma dalsze przetwarzanie na pierwszym skrypcie, który ów błąd zgłosił.
- W takim wypadku należy przejrzeć tabelę
_DATABASE_UPDATE_JOURNALoraz logi wyświetlane na ekranie i odnaleźć skrypt powodujący błąd, a w szczególności informacje – która baza danych, który to skrypt i jaki rodzaj błędu. - Aby poznać dokładną przyczynę błędu, można w sposób kontrolowany uruchomić skrypt powodujący problem w SQL Server Management Studio w celu prześledzenia, jak skrypt się zachowywał oraz jak doszło do błędu.
- Szczegóły uruchamiania skryptów Database Upgradera w SQL Server Management Studio opisane są w rozdziale Uruchamianie skryptów w SQL Server Management Studio.
- Najczęstsze przyczyny błędu to nieprawidłowy skrypt lub błędne dane w bazie danych. W zależności od sytuacji, należy usunąć ręcznie jedną bądź drugą przyczynę.
- Najprostszym i najpewniejszym krokiem po usunięciu błędu jest przywrócenie wykonanego wcześniej backupu bazy danych, w której wystąpił błąd i rozpoczęcie procesu od początku. Spowoduje to automatyczne powtórzenie całego procesu. Jeżeli nie jest to możliwe, to należy użyć jednego z poniższych rozwiązań.
- Jeżeli skrypt powodujący błąd nie wykonał żadnej modyfikacji bazy danych do momentu błędu lub jest skryptem idempotentnym (czyli takim, którego wielokrotne uruchomienie daje taki sam efekt, jak użycie jednorazowe), to wystarczy ponownie uruchomić Database Upgrader. Program będzie kontynuował proces upgrade’u, czyli spróbuje wykonać jeszcze raz ten sam skrypt i jeżeli ta operacja się powiedzie, będzie kontynuował cały proces, czyli wykonywał kolejne skrypty.
- Jeżeli skrypt powodujący błąd wykonał się częściowo, to należy przeprowadzić jedną z dwóch operacji:
- Ręcznie wycofać częściowe zmiany i uruchomić ponownie Database Upgrader. W tym przypadku Database Upgrader wykona jeszcze raz ten sam skrypt.
- Wykonać ręcznie do końca operacje ze skryptu powodującego błąd oraz ręcznie dopisać informacje o poprawnym wykonaniu tego skryptu w tabeli
_DATABASE_UPDATE_JOURNALNastępnie należy uruchomić ponownie Database Upgrader. W tym przypadku Database Upgrader będzie kontynuował proces aktualizacji od kolejnego skryptu.
Praca w trybie deweloperskim – dopisywanie do ostatniej wersji
Database Upgrader w normalnym trybie zaraz po uruchomieniu sprawdza, w jakiej wersji jest baza danych i jeżeli w katalogu ze skryptami znajdzie następne wersje, to przystępuje do uruchamiania kolejnych skryptów.
Proces ten został szczegółowo opisany w rozdziale Przykładowy przebieg procesu upgrade’u.
- Natomiast podczas prac deweloperskich nad rozwojem aplikacji (prac w trybie ciągłej integracji, czyli w sytuacji, gdy zmiany dokonywane przez programistów są na bieżąco wgrywane na serwery w celach testowych) nie zmienia się numer wersji bazy, ale mogą pojawiać się nowe skrypty w obrębie tej samej wersji. Jest to sytuacja występująca jedynie po stronie producenta oprogramowania (w dziale rozwoju oprogramowania firmy VSoft).
- Narzędzie Database Upgrader posiada specjalny tryb działania AppendLastVersion (roboczo zwany trybem deweloperskim), który w odróżnieniu od standardowego działania polega na tym, że narzędzie sprawdza w tabeli
_DATABASE_UPDATE_JOURNAL, jaka jest ostatnia wersja bazy, i dodatkowo, jaki skrypt został ostatnio uruchomiony w tej wersji bazy. - Następnie narzędzie sprawdza w katalogu ze skryptami, czy w obrębie tej samej wersji nie ma dostępnego kolejnego skryptu.
- Inaczej mówiąc, w normalnym trybie narzędzie sprawdza dane na poziomie wersji, a w trybie deweloperskim na poziomie skryptów konkretnej wersji. Jeżeli zostaną wykryte jakieś nowe skrypty w obrębie tej samej wersji (np. napisane przez programistę w ciągu poprzedniego dnia), to Database Upgrader działający w trybie deweloperskim uruchomi je. Dzięki temu można dopisywać kolejne skrypty bez konieczności zakładania codziennie nowych wersji baz danych.
Tabela _DATABASE_UPDATE_JOURNAL
- Tabela
_DATABASE_UPDATE_JOURNALjest używana przez Database Upgrader do zapisywania historii wykonanych skryptów w danej bazie danych. - Tabela przechowuje także informację o aktualnej wersji tej bazy.
- Na podstawie zawartości tabeli Database Upgrader ustala również, jakie kolejne skrypty powinny być uruchomione podczas aktualizacji bazy.
- Aby Database Upgrader działał poprawnie, tabela
_DATABASE_UPDATE_JOURNALmusi być umieszczona w każdej bazie podlegającej procesowi upgrade’u. - Tabelę taką należy sporządzić w momencie tworzenia czystej bazy danych lub w momencie aktualizacji istniejącej bazy z wykorzystaniem narzędzia Database Upgrader.
- Jednym ze sposobów utworzenia tabeli jest użycie samego Database Upgradera uruchomionego w trybie inicjalnym z umieszczonym skryptem tworzącym tabelę
_DATABASE_UPDATE_JOURNALw folderze!INITIALIZATIONodpowiedniej bazy. - Skrypt taki powinien również dodać do tabeli pojedynczy wiersz określający numer wersji startowej bazy danych.
Opis poszczególnych opcji wywołania
Rozdział opisuje znaczenie poszczególnych opcji, z których można korzystać podczas wywoływania narzędzia Database Upgrader wraz z przykładami ich użycia.
| Nazwa opcji | Opis i przykład |
|---|---|
| -s, --scripts | Parametr wymagany. Ścieżka do katalogu, który zawiera skrypty do uruchomienia. Struktura przygotowania tego katalogu jest szczegółowo opisana w innych rozdziałach. Przykład: Vsoft.DbUpgrader.exe --scripts "Scripts" … |
| -d, --database | Parametr wymagany. Nazwa bazy danych i connection string umożliwiający podłączenie się do bazy z prawami administratora w formacie : . Parametr może być używany wielokrotnie, aby zdefiniować połączenia do wielu baz danych. Przykład: Vsoft.DbUpgrader.exe --scripts "Scripts" --database "DATA:Data source=…" --database "CONFIG:Data source=… " |
| -w, --WhatIf | Parametr opcjonalny. Jeżeli zostanie podany ten parametr, to aplikacja zadziała zgodnie z rozdziałem Uruchomienie w trybie WhatIf. Nie zostaną wykonane żadne skrypty na bazach danych. Przykład: Vsoft.DbUpgrader.exe --scripts "Scripts" --database "DATA:Data source=…" --database "CONFIG:Data source=… " –WhatIf |
| a, --AppendLastVersion | Parametr opcjonalny. Parametr włącza specjalny tryb narzędzia Database Upgrader, w którym mimo poprawnego uruchomienia wszystkich skryptów z ostatniej wersji, sprawdzana jest obecność nowych skryptów na dysku, i jeżeli występują, to zostaną one także uruchomione. Tryb jest używany jedynie podczas tworzenia aplikacji – nie do użytku w trakcie produkcyjnej aktualizacji bazy danych. Aplikacja wymaga, aby serwer wspierał rozszerzenie protokołu STARTTLS. We wstępnej fazie połączenie nie będzie zabezpieczone. Przykład: Vsoft.DbUpgrader.exe --scripts "Scripts" --database "DATA:Data source=…" --database "CONFIG:Data source=… " –AppendLastVersion |
| -i, --initialization | Parametr opcjonalny. Powoduje uruchomienie narzędzia Database Upgrader w trybie inicjalizacyjnym, zgodnie z rozdziałem Uruchomienie w trybie inicjalizacyjnym i wykonanie skryptów z katalogu !INITALIZATION bez wersjonowania.Przykład: Vsoft.DbUpgrader.exe --scripts "Scripts" --database "DATA:Data source=…" --database "CONFIG:Data source=… " –initialization |
| --VarIni | Parametr opcjonalny. W przypadku skryptów posiadających zmienne – ścieżka do pliku *.ini, który zawiera wartości tych zmiennych. Szczegóły użycia zmiennych zostały opisane w rozdziale Używanie zmiennych w skryptach. Przykład: Vsoft.DbUpgrader.exe --scripts "Scripts" --database "DATA:Data source=…" --database "CONFIG:Data source=… " --VarIni "zmienne.ini" |
| --VarDatabase | Parametr opcjonalny. Connection string do bazy danych, która zawiera tabelę CONFIG\_KEYS z wartościami zmiennych. Szczegóły użycia zmiennych zostały opisane w rozdziale Używanie zmiennych w skryptach.Przykład: Vsoft.DbUpgrader.exe --scripts "Scripts" --database "DATA:Data source=…" --database "CONFIG:Data source=… " –VarDatabase "Data source=…" |
| --var | Parametr opcjonalny. Wartość konkretnej zmiennej podawana w command line w formacie <variable name>:<variable value>. Parametr może być używany wielokrotnie, aby zdefiniować wartości wielu zmiennych. Przykład: Vsoft.DbUpgrader.exe --scripts "Scripts" --database "DATA:Data source=…" --database "CONFIG:Data source=… " --var Zmienna1:wartosc1 --var Zmienna2:wartosc2 |
| --Extensive | Parametr opcjonalny. Zawiera listę baz, dla których będzie wymuszane uruchomienie procedury aktualizacji nawet, jeśli analiza wykaże, że nie istnieją żadne nowe skrypty do uruchomienia na danej bazie danych. |
| --temp | Parametr opcjonalny. Katalog tymczasowy, który będzie używany do rozpakowywania archiwów. W przypadku braku podania będzie wykorzystywany standardowy katalog tymczasowy systemu Windows. |
| --AccessToken | Parametr opcjonalny. Umożliwia połączenie z bazami Azure SQL za pomocą tokena dostępowego. Wartość tokena można podać wprost, lub w przypadku podania w tym parametrze wartości [azure-managed-identity] token zostanie pobrany automatycznie (w przypadku uruchomienia programu na zasobie Azure z włączonym mechanizmem Managed Identity). |
Równoległy upgrade kilku baz
Aby kolejność wykonywania skryptów (wersji ze skryptami) podczas aktualizacji baz danych odpowiadała kolejności przygotowania skryptów (wersji) podczas prac deweloperskich nad danym rozwiązaniem, narzędzie Database Upgrader podczas równoczesnej aktualizacji kilku baz wykona uruchomienie skryptów z wersji dla poszczególnych baz zgodnie z algorytmem przedstawionym w tym rozdziale.
- Tabela poniżej przedstawia stan (wersję) bazy danych 1 oraz bazy danych 2 w momencie rozpoczęcia procesu aktualizacji.
| Baza danych 1 | Baza danych 2 | |
|---|---|---|
| Stan bazy | 1.2 | 1.3 |
Kolejna tabela przedstawia katalogi ze skryptami do uruchomienia na poszczególnych bazach danych (katalogi ze skryptami z pakietu instalacyjnego).
| Baza danych 1 | Baza danych 2 | |
|---|---|---|
| Katalog ze skryptami | 1.1 | 1.1 |
| 1.2 | 1.2 | |
| 1.4 | 1.3 | |
| 1.5 | 1.4 | |
| 1.8 | 1.6 | |
| 1.9 | 1.7 | |
| - | 1.8 |
Narzędzie po sprawdzeniu wersji baz danych przystąpi do ich aktualizacji (baza danych 1 w wersji 1.2 oraz baza danych 2 w wersji 1.3) i będzie uruchamiać (aktualizować) wersje poszczególnych baz w kolejności zgodnej z numerami kroków opisanych w tabeli poniżej.
| Nr kroku | Upgrade dla bazy danych 1 (do wersji) | Upgrade dla bazy danych 2 (do wersji) |
|---|---|---|
| 1. | 1.4 | |
| 2. | 1.4 | |
| 3. | 1.5 | |
| 4. | 1.6 | |
| 5. | 1.7 | |
| 6. | 1.8 | |
| 7. | 1.8 | |
| 8. | 1.9 |
- Jak pokazano na powyższym przykładzie, Database Upgrader uruchamia jedynie skrypty z katalogów o numerach wersji wyższych od aktualnych wersji baz danych i robi to równolegle (naprzemiennie) na obu bazach – w każdym kolejnym kroku uruchamia skrypty niezbędne do zaktualizowania bazy 1, a następnie bazy 2, przy równoczesnym zachowaniu kolejności uruchamiania zgodnej z numerami wersji z pakietu instalacyjnego.
Przykładowy przebieg procesu upgrade’u
W tym rozdziale reguły z poprzednich części zostały zademonstrowane na konkretnym przypadku.
- Załóżmy, że mamy następujące skrypty do wykonania:
| Baza | Katalog | Skrypt |
|---|---|---|
| BAZA1 | !BEGIN | 1 - sprawdzenie integralności.sql |
| 1.1 - modyfikacje tabeli faktura | 1 - dodanie możliwości anulowania faktury.sql | |
| 1.2 - modyfikacje tabeli klient | 1 - dołożenie kolumny telefon.sql 2 - dołożenie tabeli kontakty.sql | |
| 1.3 - rozbudowa tabel polis | 1 - dodanie tabel dla szkód.sql 2 - usunięcie tabeli starej mail.sql | |
| !FINISH | 1 - przeliczenie statystyk.sql |
- Przed rozpoczęciem aktualizacji w tabeli
_DATABASE_UPDATE_JOURNALsą następujące wpisy:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| ... | ... | ... | |||
| 9 | 1.1 | IN_PROGRESS | COMPLETED_VERSION | 1 - dodanie możliwości anulowania faktury.sql | OK |
| 10 | 1.1 | COMPLETED | FINISHING | 1 - przeliczenie statystyk.sql | OK |
Oznacza to, że poprzednia aktualizacja do wersji 1.1 zakończyła się poprawnie i można rozpocząć nowy upgrade. Narzędzie wykrywa fakt istnienia nowych skryptów do wykonania (wersje 1.2 i 1.3), a zatem przystępuje do wykonania aktualizacji.
- W poniższych tabelach kolorem niebieskim zaznaczono elementy zmienione w danym kroku.
- Na początek zapisywana jest informacja (dodanie nowego wiersza) o przystąpieniu do wykonywania skryptów z katalogu
!BEGIN:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | RUNNING |
- Następuje wykonanie skryptu. W tym scenariuszu zakładamy, że skrypt wykonał się poprawnie. Informacja o tym zostaje zapisana do tabeli (aktualizacja poprzedniego wiersza):
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
- Narzędzie przystępuje do wykonywania skryptów związanych z wersją 1.2, czyli tak jak przednio, najpierw zapisuje informację przed wykonaniem skryptu:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
| 12 | 1.2 | IN_PROGRESS | UPGRADING_VERSION | 1 - dołożenie kolumny telefon.sql | RUNNING |
- Wykonywany jest skrypt (zakładamy, że poprawnie) i po jego zakończeniu zapisywana jest informacja o poprawnym zakończeniu:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
| 12 | 1.2 | IN_PROGRESS | UPGRADING_VERSION | 1 - dołożenie kolumny telefon.sql | OK |
- W analogiczny sposób obsługiwany jest drugi skrypt z wersji 1.2 i po jego poprawnym wykonaniu mamy następujący stan w tabeli:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
| 12 | 1.2 | IN_PROGRESS | UPGRADING_VERSION | 1 - dołożenie kolumny telefon.sql | OK |
| 13 | 1.2 | IN_PROGRESS | COMPLETED_VERSION | 2 - dołożenie tabeli kontakty.sql | OK |
- W przypadku równoległego upgrade’u kilku baz, Database Upgrader może teraz sprawdzić, czy inna baza nie wymaga aktualizacji do wersji 1.2.
- Jeżeli tak, to dokonuje upgrade’u innej bazy w analogiczny sposób.
- W tym scenariuszu zakładamy, że albo nie ma takiej potrzeby, albo upgrade innej bazy zakończył się sukcesem.
- W takim przypadku Upgrader wraca to tej bazy i przystępuje do uruchamiania skryptów z kolejnej wersji – 1.3.
- Analogicznie jak poprzednio wykonuje z sukcesem pierwszy skrypt.
- Po jego wykonaniu mamy stan:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
| 12 | 1.2 | IN_PROGRESS | UPGRADING_VERSION | 1 - dołożenie kolumny telefon.sql | OK |
| 13 | 1.2 | IN_PROGRESS | COMPLETED_VERSION | 2 - dołożenie tabeli kontakty.sql | OK |
| 14 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 1 - dodanie tabel dla szkód.sql | OK |
- Kolejnym skryptem do wykonania jest skrypt „2 - usunięcie tabeli starej mail.sql”. Przed przystąpieniem do uruchomienia tego skryptu ta informacja jest zapisywana:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
| 12 | 1.2 | IN_PROGRESS | UPGRADING_VERSION | 1 - dołożenie kolumny telefon.sql | OK |
| 13 | 1.2 | IN_PROGRESS | COMPLETED_VERSION | 2 - dołożenie tabeli kontakty.sql | OK |
| 14 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 1 - dodanie tabel dla szkód.sql | OK |
| 15 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 2 - usunięcie starej tabeli mail.sql | RUNNING |
- Załóżmy, że ten skrypt zakończy się błędem. W takim przypadku informacja jest zapisywana w następujący sposób:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
| 12 | 1.2 | IN_PROGRESS | UPGRADING_VERSION | 1 - dołożenie kolumny telefon.sql | OK |
| 13 | 1.2 | IN_PROGRESS | COMPLETED_VERSION | 2 - dołożenie tabeli kontakty.sql | OK |
| 14 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 1 - dodanie tabel dla szkód.sql | OK |
| 15 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 2 - usunięcie starej tabeli mail.sql | ERROR |
- W tym momencie Upgrader kończy swoje działanie, sygnalizując użytkownikowi błąd upgrade’u.
- Ostatni rekord pokazuje numer wersji oraz nazwę skryptu, który był wykonywany jako ostatni.
- Dodatkowo statusy pokazują, że baza danych jest w trakcie aktualizacji i nie może być normalnie używana.
- Zadaniem użytkownika jest ręczne naprawienie sytuacji zgodnie z wcześniej opisanymi zasadami (naprawa danych, naprawa skryptu, dodanie dodatkowego skryptu itp.). Po dokonaniu ręcznych czynności użytkownik musi uruchomić ponowne Database Upgrader aby dokończyć aktualizację.
- Załóżmy, że rozwiązanie problemu polegało na naprawie danych w bazie lub na poprawieniu skryptu „2 - usunięcie tabeli starej mail.sql”.
- Po ponownym uruchomieniu Upgradera narzędzie wyszukuje w tabeli ostatni uruchomiony skrypt (jest on w wierszu ID=15), sprawdza rezultat poprzedniego wykonania, a ponieważ jest to błąd to następnie przystępuje do ponownego wykonania tego samego skryptu („2 - usunięcie starej tabeli mail.sql”).
- Jak zawsze zapisywana jest informacja o przystąpieniu do uruchomienia skryptu (nowy wiersz ze SCRIPT_EXECUTION_STATUS = RUNNIG).
- Po zakończeniu wykonania wiersz ten jest modyfikowany zgodnie z wynikami wykonania.
- Załóżmy, że tym razem skrypt wykona się poprawnie i jest to ostatni skrypt z danej wersji.
- Tabela wygląda w takim przypadku następująco:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
| 12 | 1.2 | IN_PROGRESS | UPGRADING_VERSION | 1 - dołożenie kolumny telefon.sql | OK |
| 13 | 1.2 | IN_PROGRESS | COMPLETED_VERSION | 2 - dołożenie tabeli kontakty.sql | OK |
| 14 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 1 - dodanie tabel dla szkód.sql | OK |
| 15 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 2 - usunięcie starej tabeli mail.sql | ERROR |
| 16 | 1.3 | IN_PROGRESS | COMPLETED_VERSION | 2 - usunięcie starej tabeli mail.sql | OK |
- Ponieważ zostało zakończone aplikowanie wszystkich skryptów danej wersji, Upgrader sprawdza, czy nie ma potrzeby aktualizacji innej bazy danych do tej samej wersji.
- Jeżeli tak, to dokonuje upgrade’u.
- Ostatnim krokiem jest wykonanie skryptów z katalogu !FINISH. Po ich udanym wykonaniu zawartość tabeli wygląda następująco:
| ID | DB_VERSION | UPDATE_STATUS | UPDATE_PHASE | SCRIPT_NAME | SCRIPT_EXECUTION_STATUS |
|---|---|---|---|---|---|
| 11 | 1.2 | IN_PROGRESS | BEGINNING | 1 - Sprawdzenie integralności.sql | OK |
| 12 | 1.2 | IN_PROGRESS | UPGRADING_VERSION | 1 - dołożenie kolumny telefon.sql | OK |
| 13 | 1.2 | IN_PROGRESS | COMPLETED_VERSION | 2 - dołożenie tabeli kontakty.sql | OK |
| 14 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 1 - dodanie tabel dla szkód.sql | OK |
| 15 | 1.3 | IN_PROGRESS | UPGRADING_VERSION | 2 - usunięcie starej tabeli mail.sql | ERROR |
| 16 | 1.3 | IN_PROGRESS | COMPLETED_VERSION | 2 - usunięcie starej tabeli mail.sql | OK |
| 17 | 1.3 | COMPLETED | FINISHING | 1 - przeliczenie statystyk.sql | OK |
- Z ostatniego wiersza tabeli można odczytać wersję bazy (1.3) oraz informację o udanym zakończeniu upgrade’u, czyli o możliwości używania bazy do celów produkcyjnych.
Tryb Extensive
- Włączenie trybu Extensive na danej bazie danych wymusza każdorazowo uruchomienie procedury aktualizacji nawet w przypadku, gdy z analizy wykonania wynika, że żaden skrypt nie powinien być uruchomiony na tej bazie danych.
- Użycie tego trybu warto rozważyć jeśli w katalogach
!BEGINi!FINISHzawarte są skrypty, które chcemy wykonywać przy każdej podmianie bazy danych – nawet wówczas, gdy nie uległa zmianie struktura bazy danych.
Uruchamianie skryptów w SQL Server Management Studio
- Database Upgrader uruchamia skrypty zapisane na dysku w sposób automatyczny.
- Jeżeli z jakiejś przyczyny istnieje potrzeba wykonania skryptów „ręcznie”, np. w procesie diagnozy lub w czasie przygotowania skryptów, to można tego dokonać w SQL Server Management Studio. W szczególnych przypadkach można w ten sposób uruchomić ręcznie wszystkie skrypty z katalogu.
- Jeżeli skrypt, który chcemy uruchomić w SQL Server Management Studio, nie zawiera zmiennych, to po wczytaniu pliku przez program i połączeniu z odpowiednią bazą danych, należy skrypt uruchomić. Plik zostanie wczytany w identyczny sposób jak przez narzędzie Database Upgrader. Jeśli zaś skrypt zawiera zmienne, to należy pamiętać o czynnościach związanych z ich obsługą.
- Pierwszą czynnością w takim przypadku jest włączenie w SQL Server Management Studio w menu Query opcji SQLCMD Mode (rysunek poniżej).

- Następnie w skrypcie, który zawiera jakieś zmienne, należy na początku dopisać instrukcję :SETVAR, podając nazwę zmiennej i jej wartość.
- W ten sam sposób należy nadać wartości wszystkim kolejnym zmiennym ze skryptu. Po takim rozszerzeniu skryptu można uruchomić go przyciskiem F5 – zostanie on wykonany tak samo jak przez narzędzie Database Upgrader. Taką sytuację przedstawia poniższy rysunek.

Minimalna wersja bazy danych
- Aby uniknąć konieczności umieszczania bardzo starych skryptów w każdym pakiecie instalacyjnym zawierającym narzędzie Database Upgrader, istnieje możliwość określenia, jaką najstarszą wersję bazy obsługuje dany zestaw skryptów.
- Jest to przydatne w sytuacji, kiedy wiemy, że wszystkie używane bazy zostały już zaktualizowane do danej wersji i nie będzie konieczności obsługi wersji wcześniejszych.
- Numer najstarszej możliwej do obsłużenia wersji bazy danych należy umieścić w pliku MinimumDatabaseVersion.txt znajdującym się w głównym katalogu ze skryptami. Po określeniu minimalnej wspieranej wersji bazy danych można z zestawu skryptów usunąć te dotyczące wcześniejszych wersji.
- Database Upgrader sprawdza, czy zastane bazy danych podlegające procesowi upgrade’u posiadają przynajmniej wersję podaną w pliku. Jeżeli tak, to załączony zestaw skryptów pozwala na dokonanie aktualizacji tych baz.
- Jeżeli przynajmniej jedna z baz danych jest w wersji wcześniejszej niż podana w pliku, to Database Upgrader nie dokona żadnych modyfikacji i zgłosi błąd. Oznacza to konieczność dysponowania zestawem skryptów, który zawiera skrypty starsze, niezbędne do upgrade’u starej bazy.
Database Upgrader - najlepsze praktyki
Zrobić backup bazy danych przed uruchomieniem procesu upgrade’u
- Database Upgrader jest narzędziem, którego głównym zadaniem jest uruchomienie odpowiednich skryptów w odpowiedniej kolejności na właściwej bazie danych.
- W oczekiwanym przypadku wszystkie skrypty zostaną wykonane poprawnie. Może jednak wystąpić sytuacja, w której któryś ze skryptów zakończy się błędem, co w najgorszym przypadku może doprowadzić nawet do uszkodzenia danych w bazie danych.
- Dlatego bardzo mocno zaleca się, aby przed aktualizacją wykonać backup bazy danych przy pomocy osobnych narzędzi administracyjnych przeznaczonych do tego celu.
- W przypadku nieoczekiwanego błędu zapewni to dodatkową możliwość powtórzenia od początku całego procesu upgrade’u po przywróceniu ostatniej wersji bazy danych.
Przetestować proces upgrade’u na kopii bazy danych
- Database Upgrader wykonuje proces aktualizacji w sposób całkowicie automatyczny.
- Pozwala to na pełne przetestowanie przebiegu procesu produkcyjnego na kopii baz danych przed uruchomieniem go na środowisku produkcyjnym.
- Można w ten sposób przetestować poprawność przebiegu samego procesu, jak również oszacować czas jego trwania.
Odpowiednio przygotowywać zawartość każdego skryptu
- Dobrą praktyką jest umieszczanie każdej logicznie spójnej zmiany w osobnym pliku ze skryptem.
- Na początku treści skryptu można dokonać nieinwazyjnych sprawdzeń i weryfikacji zapewniających poprawne wykonanie pozostałej części skryptu.
- W przypadku wystąpienia błędu wykonania danego skryptu Database Upgrader wstrzyma wykonywanie aktualizacji na instrukcji powodującej błąd, a podczas ponownego uruchomienia wznowi jeszcze raz błędny skrypt od początku.
- Oznacza to, że lepiej, jeżeli ewentualny błąd zostanie zgłoszony przez instrukcję weryfikującą, niż zmieniającą dane, gdyż w tej pierwszej sytuacji nie następuje uszkodzenie danych i konieczność ręcznej ich naprawy.