Już sam tytuł może dla znawców tematu zabrzmieć kontrowersyjnie. Baza danych SMS-a 2003 na klastrze? Przecież sam producent (czyli Microsoft) twierdzi, że tego zrobić się nie da.
W poprzedniej części artykułu zaszliśmy jednak dość daleko – zainstalowaliśmy odpowiednią bazę oraz dokonaliśmy migracji danych. Co dalej?
Etap czwarty migracji
Ta część to już dostosowanie środowiska klastrowego oraz samej bazy danych do potrzeb usług systemu SMS. Cztery podstawowe problemy, z którymi przyjdzie się nam zmierzyć, to:
Po wykonaniu przeniesienia bazy danych na nowy serwer SQL i przekierowaniu na nią konfiguracji SMS-a należy również wskazać nową lokalizację w konsolach administracyjnych SMS-a. Na każdym komputerze z zainstalowaną konsolą SMS należy wykonać następujące kroki:
1. | Uruchomić konsolę administracyjną SMS. |
2. | Odczekać na pojawienie się komunikatu mówiącego o braku możliwości komunikacji z bazą danych. |
3. | Usunąć bieżące połączenie. |
4. | Utworzyć nowe połączenie, podając nazwę serwera będącego Site Serverem SMS (w naszym wypadku SMSSRV) |
| UWAGA: |
Nie wolno podawać w tym miejscu nazwy serwera SQL! |
Na tym etapie wdrożenia łatwo zaobserwować, iż nie wszystko funkcjonuje jeszcze tak, jak należy. Większość funkcji jest co prawda dostępna z konsoli administracyjnej SMS-a, lecz jeśli spróbujemy wykonać jakieś zadanie odnoszące się do bazy danych (na przykład odświeżenie kolekcji), zauważymy brak reakcji ze strony systemu. Przyczynę tego odnaleźć można po stronie serwera SQL, a dokładnie po stronie aktywnego węzła na klastrze. Jeżeli zajrzymy do logu smsdbmon.log znajdującego się w katalogu SMS_ NAZWASERWERASMS\Logs , wtedy na pewno znajdziemy tam następujący wpis:
Getting SQL connection Server=NODE1, DB=SMS_001, UID = $$<SMS_SQL_MONITOR_SMSSRV><Thu Feb 07 12:56:48.396 2008_ Central European Standard Time><thread=2320 (0x910)> *** [08001][17][Microsoft][ODBC SQL Server Driver][Shared Memory]SQL Server does not exist or access denied._ $$<SMS_SQL_MONITOR_SMSSRV><Thu Feb 07 12:57:50.894 2008 Central European Standard Time><thread=2320 (0x910)> *** [01000][2][Microsoft][ODBC SQL Server Driver][Shared Memory]ConnectionOpen (Connect())._ $$<SMS_SQL_MONITOR_SMSSRV><Thu Feb 07 12:57:50.894 2008 Central European Standard Time><thread=2320 (0x910)> *** Failed to connect to the SQL Server. $$<SMS_SQL_MONITOR_SMSSRV><Thu Feb 07 12:57:50.894_ 2008 Central European Standard Time><thread=2320 (0x910)> Could not get SQL connection $$<SMS_SQL_MONITOR_SMSSRV><Thu Feb 07 12:57:50.894 2008_ Central European Standard Time><thread=2320 (0x910)>
Jak widać usługa SMS_SQL_MONITOR odwołuje się do nazwy fizycznej węzła. W wypadku klastra SQL nie jest możliwe komunikowanie się z bazą SQL za pomocą nazwy węzła – koniecznie jest skorzystanie z nazwy wirtualnego serwera SQL. Usługa SMS_SQL_MONITOR zainstalowana na węzłach klastra odnosi się do nazwy serwera korzystając z następującego klucza w rejestrze:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ComputerName\ActiveComputerName
Jest to klucz dynamiczny, nie ma więc sensu dokonywać zmian na poziomie rejestru. Rozwiązaniem jest sklastrowanie samej usługi. Poza uzyskaniem prawidłowego efektu nazwy serwera SQL, zostanie zagwarantowane funkcjonowanie usługi tylko na aktywnym węźle klastra.
W celu poprawnego skonfigurowania usługi na klastrze należy:
1. | Uruchomić narzędzie Cluster Administrator i połączyć się z klastrem SQL. | ||
2. | Utworzyć nowy zasób typu Generic Service o nazwie SQL_MONITOR. ![]() Rys. 1 | ||
3. | Ustalić następującą zależność:
| ||
4. | W polu Service Name wprowadzić: SMS_SQL_MONITOR_NAZWASERWERASMS | ||
5. | Koniecznie zaznaczyć parametr Use Network Name for computer name. ![]() Rys. 2 | ||
6. | Zatrzymać i uruchomić usługę z poziomu Cluster Administratora |
W celu zweryfikowania poprawności konfiguracji należy ponownie sprawdzić zawartość logu smsdbmon.log na aktywnym węźle klastra. Nowe wpisy powinny wskazywać na prawidłowe podłączenie do bazy SQL przy wykorzystaniu nazwy wirtualnego serwera SQL.
Registering SQL Types $$<SMS_SQL_MONITOR_SMSSRV><Thu Feb 07 12:59:54.452 2008 Central European Standard Time><thread=3872 (0xF20)> Getting SQL connection Server=CLUSQL, DB=SMS_001, UID = $$<SMS_SQL_MONITOR_SMSSRV><Thu Feb 07 12:59:54.452)_ 2008 Central European Standard Time><thread=3872 (0xF20)> Got SQL connection. Checking for extended stored procedure.
Na tym etapie SMS funkcjonuje już prawie w 100% prawidłowo. Problemy napotkamy dopiero w momencie poszerzania zakresu inwentaryzacji „hardware inventory” poprzez edycję pliku sms_def.mof. Okaże się, iż stacje otrzymają prawidłową konfigurację, a w bazie SQL pojawią się odpowiednie tabele i wartości – nie będzie natomiast możliwości prawidłowego ich wyświetlenia za pomocą resource explorer-a. Przyczyna tego leży po stronie usługi providera WMI. Po rozszerzeniu zakresu inwentaryzacji, czego skutkiem jest pojawienie się nowych informacji w bazie danych, uruchamiana jest wbudowana procedura SQL (dbo.xp_SMS_notification), mająca za zadanie skontaktowanie się z usługą providera WMI w celu utworzenia odpowiednich klas odpowiedzialnych za widoki w resource explorerze. Operacja ta przy bieżącej konfiguracji nie przynosi jednak oczekiwanego efektu, co można zaobserwować w logu smsdbmon.log na aktywnym węźle klastra. Pojawią się w nim wpisy, które mają postać podobną do:
CTriggerManager::InstanceThread: pipe=988: 0007SMS_0010012ATTRIBUTEMAP0006INSERT000150002780021SCREENSAVEREXECUTABLE Received notification: Table=ATTRIBUTEMAP, Type=INSERT, KeyName=5. CTriggerManager::InstanceThread - could not open named pipe \\SMSSRV\PIPE\SMSPROVIDER_001, Err=2
Nazwa serwera, do której odnosi się usługa, zależy od tego, jaki sposób wdrożenia wybraliśmy. Jeżeli jest to migracja, będzie to nazwa pierwotnego serwera SQL, jeżeli natomiast była to nowa instalacja, system wyświetli nazwę wirtualnego serwera SQL. Niezależnie od wybranej opcji nazwa, do której odnosi się wbudowana procedura, nie daje możliwości prawidłowego wykonywania operacji. Do czego więc się odwołać, skoro nie może być to nazwa wirtualnego serwera SQL? Wyjściem jest odniesienie się do nazwy sieciowej klastra – w naszym wypadku CLUSRV.
Skoro już wiadomo, jaka nazwa jest prawidłowa, czas „zmusić” system do jej wykorzystania. Jest to możliwe poprzez edycję tabeli dbo.SMSData znajdującej się w bazie danych wykorzystywanej przez system SMS (nazwa bazy to SMS_sitecode).
Po otwarciu tabeli dbo.SMSData poleceniem Open Table, należy odnaleźć kolumnę SMSProviderServer i zastąpić jej wartość nazwą sieciową klastra (CLUSRV).

Rys. 3
Prawidłowe zachowanie się systemu po wykonaniu tej operacji można zaobserwować w pliku smsdbmon.log – w wypadku poszerzania zakresu inwentaryzacji pojawią się wpisy zbliżone do:
CTriggerManager::InstanceThread: pipe=904: 0007SMS_0010012ATTRIBUTEMAP0006INSERT000150002770006STATUS Received notification: Table=ATTRIBUTEMAP, Type=INSERT, KeyName=5. Wrote 59 bytes to \\CLUSRV\PIPE\SMSPROVIDER_001 (0007SMS_0010012ATTRIBUTEMAP0006INSERT000150002770006STATUS)
Chcąc zagwarantować natychmiastową dostępność konfiguracji WMI przy przenoszeniu zasobów pomiędzy węzłami klastra, dobrze jest utworzyć zasób klastrowy restartujący usługę WMI. Restart tej usługi zagwarantuje odświeżenie zasobów WMI i prawidłowe reprezentowanie obiektów inwentaryzacji w konsoli resource explorer-a.
Przykładowa postać takiego skryptu w sytuacji, w której na serwerze SQL zainstalowany jest również klient systemu SMS, to:
@echo off echo Stopowanie serwisu SMS Agent Host (CcmExec)... sc query CcmExec |find /I "The specified service does not exist as an installed service" if errorlevel 1 goto StopujCcmExec goto dalejCcmExec :StopujCcmExec net stop CcmExec /y :CheckCcmExec sc query CcmExec |find /I "STOPPED" if errorlevel 1 goto CheckCcmExec echo Zastopowalem serwis CcmExec :dalejCcmExec echo Stopowanie serwisu Windows Management Instrumentation (winmgmt)... sc query winmgmt |find /I "The specified service does not exist as an installed service" if errorlevel 1 goto Stopujwinmgmt goto dalejwinmgmt :Stopujwinmgmt net stop winmgmt /y :Checkwinmgmt sc query winmgmt |find /I "STOPPED" if errorlevel 1 goto Checkwinmgmt echo Zastopowalem serwis winmgmt :dalejwinmgmt echo Ponowny start serwisu winmgmt net start winmgmt echo Ponowny start serwisu CcmExec net start ccmexec
W wypadku braku oprogramowania klienckiego składnia batch-a będzie znacznie prostsza i odnosić się będzie tylko do usługi WMI. Skrypt taki należy zapisać w postaci pliku z rozszerzeniem *.bat na zasobie dostępnym dla obydwu węzłów klastra.
Skrypt ten należy skonfigurować jako zasób klastrowy. W tym celu trzeba:
1. | Uruchomić narzędzie Cluster Administrator i połączyć się z klastrem SQL. | ||||
2. | Utworzyć nowy zasób typu Generic Application o nazwie RestartWMI. | ||||
3. | Ustalić następującą zależność:
| ||||
4. | W parametrach startowych wprowadzić
![]() Rys. 4 | ||||
5. | We właściwościach zasobu, w zakładce Advanced zaznaczyć Do not restart ![]() Rys. 5 |
Ostatni element wymagający dokonfigurowania w środowisku klastrowym to prawidłowe wykonywanie kopii zapasowej systemu SMS. Przy obecnej konfiguracji, zadanie backupu napotka jeden mały, lecz niemożliwy do ominięcia problem. Jest nim zatrzymanie sklastrowanej usługi SMS_SQL_MONITOR. Efekt tego można zaobserwować w logu smsbkup.log. Znajdziemy tam następujący wpis:
Failed to stop service SMS_SQL_MONITOR_SMSSRV on site system \\CLUSQL: Overlapped I/O operation is in progress.
Jest to spowodowane tym iż sklastrowana usługa SMS_SQL_MONITOR domyślnie daje się zatrzymać tylko z poziomu klastra. Inne próby jej zastopowania, zakończą się jej ponownym uruchomieniem przez usługę klastrową. Cała „zabawa” polegać więc będzie na umiejętnym jej zatrzymaniu przez zadanie backup-u, oraz odpowiednim jej uruchomieniu po zakończeniu operacji wykonywania kopii zapasowej.
1. | Umożliwienie zatrzymania usługi SMS_SQL_MONITOR przez zadanie backupu W celu zrealizowania tego zadania należy:
![]() Rys. 6 | ||||||
2. | Stworzenie zadania uruchamiającego usługę SMS_SQL_MONITOR po wykonaniu kopii zapasowej systemu SMS. |
Ten cel zostanie osiągnięty poprzez wykorzystanie pliku afterbackup.bat. Utworzenie pliku o tej nazwie (i rozszerzeniu) w katalogu SMS\inboxes\smsbkup.box powoduje jego automatyczne wykonanie po zakończeniu operacji backupu, tak więc nadaje się on idealnie do naszego celu. Metod uruchamiania zdalnego usług klastrowych istnieje kilka, my skorzystamy z dobrodziejstw interfejsu WMI. Do zdalnego uruchomienia usługi posłuży następujący skrypt:
strOnline = "'nazwa_sklastrowanej_usługi'"
strCluster = "nazwa_wirtualna_sql"
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" _
& strCluster & "\root\mscluster")
Set brOnline = objWMIService.ExecQuery _
("Select * from mscluster_resource Where Name = " & strOnline )
For Each objProcess in brOnline
objProcess.bringonline(5)
Next
Gdzie:
nazwa_sklastrowanej_usługi to nazwa zasobu klastrowego reprezentującego usługę SMS_SQL_MOINTOR (zgodnie z poprzednimi punktami nazwa to SQL_MONITOR) nazwa_wirtualna_sql to nazwa wirtualnego serwera SQL (zgodnie z poprzednimi punktami nazwa to CLUSQL)
Skrypt ten zapisujemy pod dowolną nazwą z rozszerzeniem *.vbs (np. startsmssql.vbs) najlepiej w lokalizacji w której utworzymy plik afterbackup.bat. Pozostaje tylko stworzyć w katalogu SMS\inboxes\smsbkup.box plik afterbackup.bat uruchamiający nasz skrypt. Jego składnia będzie wyglądała następująco:
<ścieżka_do_pliku_vbs>\startsmssql.vbs
| • |
![]() | Maciej Bogucki (MCSE,MCSE+I,MCT) |