FIPS 140-3 w OpenEdge 13

Wraz z premierą Progress OpenEdge 13, twórcy oprogramowania i administratorzy systemów otrzymali potężne narzędzie do walki o cyberbezpieczeństwo. Wersja ta wprowadza pierwsze produkcyjne wdrożenie standardu kryptograficznego FIPS 140-3 dla kluczowych komponentów systemu. FIPS 140-3 jest najnowszym standardem rządu USA, który definiuje wymagania bezpieczeństwa dla modułów kryptograficznych. W OpenEdge 13 aktywacja FIPS mode sprawia, że środowisko wykonawcze (AVM), bazy danych RDBMS oraz serwery aplikacyjne PASOE wymuszają stosowanie wyłącznie zwalidowanych przez NIST* bibliotek oraz silnych algorytmów do szyfrowania i zarządzania kluczami.

Jeśli pracujesz w branży finansowej, medycznej lub rządowej, wdrożenie trybu FIPS (Federal Information Processing Standards) staje się fundamentem zgodności regulacyjnej. Jak zatem podejść do tego tematu jako administrator?

Po pierwsze, do uruchomienia trybu FIPS wymagany jest pakiet licencyjny Progress OpenEdge Advanced Security (OEAS). Upewnijmy się, że posiadamy go w instalacji.
Poza tym, przeprowadzając audyt certyfikatów SSL/TLS pod kątem zgodności z FIPS, musimy pamiętać, że tryb ten bezwzględnie odrzuci słabą kryptografię. Wszystkie asymetryczne klucze certyfikatów oparte na algorytmie RSA, używane w komunikacji sieciowej lub do ochrony kluczy szyfrujących bazy danych (TDE), muszą mieć długość minimum 2048 bitów. W przypadku stosowania nowoczesnych certyfikatów z użyciem krzywych eliptycznych (ECC/ECDSA) wymagana jest długość klucza wynosząca minimum 256 bitów.


Tryb
FIPS włączamy w środowisku OpenEdge za pomocą narzędzia ESAM/POLMAN.
Przypomnijmy, że ESAM (Embedded Security Architecture Module) to wewnętrzny system bezpieczeństwa wprowadzony w OpenEdge 12.6. Monitoruje procesy Progressa i blokuje uruchamianie plików z nieautoryzowanych ścieżek. Stanowi fundament pod bezpieczną architekturę i wymuszanie trybu FIPS.
POLMAN (Policy Manager) to narzędzie wiersza poleceń do zarządzania systemem ESAM. Służy do tworzenia, edycji i podpisywania polityk bezpieczeństwa platformy. Za jego pomocą administratorzy aktywują i konfigurują zgodność środowiska z normami FIPS.

Warto więc na poczatku sprawdzić czy ESAM jest poprawnie zainstalowany. Ponieważ miałem wcześniej zainstalowane w Windows niższe wersje OE od 12.6 do 12.8, to po ich wyinstalowaniu pozostały katalogi/pliki ESAM:
C:\Windows\System32\openedge.d
C:\Windows\System32\openedge

Skorzystałem z rozwiązania z bazy wiedzy (nr 000297865) żeby je usunąć jako administrator. Uwaga! możemy tak zrobić tylko jeśli nie mamy już zainstalowanych tych wersji. Ta operacja nie jest niezbędna ale warto wyczyścić struktrurę ESAM jeśli odnosi się do wyinstalowanych już wersji.

Po zainstalowaniu OE 13, sprawdziłem w logach, że ESAM został poprawnie zainstalowany jednak uruchamiając komendę C:\Windows\System32\openedge.d\bin>valdlc -dlc C:\OpenEdge130 okazało się, że walidacja katalogu DLC kończy się niepowodzeniem. To dość częsty przypadek. Możemy jednak zarejestrować ten katalog ręcznie poleceniem:
C:\Windows\System32\openedge.d\sbin>setdlc.bat -esamregisterDLC C:\OpenEdge130

Sprawdzamy jeszcze raz walidację:
C:\Windows\System32\openedge.d\bin>valdlc -dlc C:\OpenEdge130

Aby aktywować FIPS trzeba uruchomić terminal OpenEdge proenv z uprawnieniami administratora.
Najpierw warto wyświetlić aktualny status polityki globalnej ESAM oraz sprawdzić, czy tryb FIPS jest już aktywny, wpisujemy polecenie:
proenv>polman get -policy urn:esam:fips140:can-run-without
Walidacja kończy się teraz sukcesem.

Tryb FIPS włącza się komendą:
polman set -policy urn:esam:fips140:can-run-without -value no

Po wprowadzeniu zmiany, ponownie zweryfikuj stan polityki w ESAM, aby upewnić się, że flaga została poprawnie zapisana:
proenv>polman get -policy urn:esam:fips140:can-run-without
Wyłączamy FIPS poleceniem:
polman set -policy urn:esam:fips140:can-run-without -value yes
i ponownie testujemy.
Obie komendy przedstawione są poniżej.

Wdrożenie trybu FIPS po stronie infrastruktury to właściwie mniej niż połowa sukcesu. Administrator musi ściśle współpracować z programistami, ponieważ FIPS blokuje starsze funkcje w kodzie ABL.
Na przykłąd użycie funkcji ENCODE() zakończy się błędem ponieważ tradycyjna metoda tworzenia skrótów haseł nie spełnia wymogów standardu. Deweloperzy muszą zastąpić ją nowszą funkcją GENERATE-PASSWORD-HASH. Podobnie funkcja MD5-DIGEST() czy SHA1-DIGEST().
Przed włączeniem FIPS warto dokładnie zapoznać się z dokumentacją i sprawdzić kod źródłowy – część problemów pojawia się dopiero podczas runtime’u, a nie podczas kompilacji.
Testowanie warunkowe: Programiści mogą zabezpieczyć kod przed błędami kryptograficznymi, sprawdzając stan środowiska za pomocą systemowego atrybutu: SECURITY-POLICY:FIPS-MODE.
Poniżej mamy prosty kod do wykrywania trybu FIPS.

//test_fips.p
IF SECURITY-POLICY:FIPS-MODE THEN DO:
	MESSAGE "Success: FIPS 140-3 is on!" 
    	VIEW-AS ALERT-BOX INFORMATION.
END.
ELSE DO:
	MESSAGE "Warning: FIPS is not working!" 
    	VIEW-AS ALERT-BOX WARNING.
END.


Wdrożenie FIPS 140-3 w Progress OpenEdge 13 to kamień milowy w zabezpieczaniu danych przedsiębiorstwa. Choć wymaga przygotowania infrastruktury i audytu kodu, to widzimy, że centralne wymuszenie restrykcyjnych reguł bezpieczeństwa jest dość proste.

Na koniec jeszcze jedna ważna kwestia – pamiętajmy o tym, że OpenEdge nie działa w próżni. Jeśli włączymy FIPS w OpenEdge, ale nasz system operacyjny (Windows Server lub Linux) będzie skonfigurowany niezgodnie z tym standardem, środowisko nie osiągnie pełnej zgodności.

Poniżej podaję przykładową instrukcję konfiguracji systemu operacyjnego.
Windows Server – w menu komend uruchom gpedit.msc aby otworzyć Edytor lokalnych zasad grupy.
W lewym panelu przejdź kolejno do ścieżki: Konfiguracja komputera -> Ustawienia systemu Windows -> Ustawienia zabezpieczeń -> Zasady lokalne -> Opcje zabezpieczeń.
W prawym panelu znajdź i kliknij dwukrotnie zasadę: Kryptografia systemu: Użyj zgodnych algorytmów FIPS do szyfrowania, haszowania i podpisywania. Zmień ustawienie na Włączone, kliknij Zastosuj, a następnie OK.
Otwórz wiersz poleceń (cmd) jako administrator i wymuś aktualizację zasad komendą: gpupdate /force

Linux – zaloguj się na serwer jako użytkownik z uprawnieniami root lub użyj sudo. Sprawdź obecny status za pomocą polecenia: fips-mode-setup –check
Jeśli tryb FIPS jest wyłączony, aktywuj go systemowo wpisując: fips-mode-setup –enable
Uruchom ponownie serwer (komendą reboot), aby system operacyjny przełączył jądro (kernel) oraz systemowe biblioteki w restrykcyjny tryb FIPS 140-3. Po restarcie upewnij się, że system działa poprawnie, powtarzając pierwszą komendę: fips-mode-setup –check.

Powyższe informacje na temat konfiguracji systemu operacyjnego przedstawiłem opcjonlanie. Przykładowe włączenie FIPS w OpenEdge 13 przeprowadziłem bez zmian systemowych.
Ciąg dalszy nastąpi.

* NIST to skrót od National Institute of Standards and Technology (Narodowy Instytut Standardów i Technologii).Jest to amerykańska agencja rządowa, która podlega pod Departament Handlu USA. To właśnie NIST tworzy i publikuje standardy z serii FIPS (w tym opisywany FIPS 140-3). Definiują one, jakie algorytmy kryptograficzne i moduły bezpieczeństwa są bezpieczne i dopuszczone do użytku w instytucjach rządowych oraz branżach regulowanych.

DDM – rozszerzenie tematu

O technologii Dynamic Data Masking pisałem dwukrotnie w 2025 roku, aby przybliżyć jej działanie użytkownikom baz danych Progress OpenEdge od wersji 12.8. W poprzednich artykułach skupiłem się głównie na podstawach: omówiłem sposób aktywacji mechanizmu DDM w bazie danych oraz konfigurację czterech dostępnych typów masek dla wybranych pól i tabel.

Dynamic Data Masking jest jednak rozwiązaniem, które poza samą konfiguracją wymaga również dobrego zrozumienia sposobu działania mechanizmu maskowania, jego wpływu na aplikacje oraz pewnych ograniczeń. W praktyce oznacza to, że wdrożenie DDM nie sprowadza się wyłącznie do zdefiniowania reguł maskowania, ale powinno być poprzedzone analizą wymagań bezpieczeństwa, zgodności oraz wpływu na istniejące reguły biznesowe.

W tym artykule chciałbym więc spojrzeć na tę technologię z bardziej praktycznej i technicznej perspektywy. Pokażę nie tylko zalety wynikające z zastosowania Dynamic Data Masking, ale również ograniczenia i potencjalne problemy, które mogą pojawić się podczas wdrożenia. Odniosę się także do kilku nieporozumień dotyczących działania DDM, które pojawiały się w pytaniach i dyskusjach po publikacji wcześniejszych materiałów.

Jednym z pytań było: co się stanie jeśli pole typu INTEGER będzie przesłane do obiektu, jako wartość wymagana, a administrator nałoży na nie maskę PARTIAL. Otóż należy pamiętać, że dla każdego rodzaju maski obowiązuje zasada zgodności typów. Spróbujmy zastosować taką maskę na pole Balance (DECIMAL). Postępujemy dokładnie tak jak w poprzednich artykułach, a na koniec nakładamy maskę:

USING OpenEdge.DataAdmin.DataAdminService FROM PROPATH.

DEFINE VARIABLE service AS DataAdminService NO-UNDO. 
DEFINE VARIABLE lResult AS LOGICAL NO-UNDO.

service = NEW DataAdminService(LDBNAME("DICTDB")).
lResult = service:setDDMConfig("Customer","Balance","P:2,*","#DDM_SEE_ContactInfo").

Dostajemy komunikat o błędzie wynikający z konfliktu pola liczbowego z maską znakową.


Przejdę teraz do ważniejszej kwestii związanej z DDM, ale najpierw zdefiniuję maskę domyślną dla pola Balance.

USING OpenEdge.DataAdmin.DataAdminService FROM PROPATH.

DEFINE VARIABLE service AS DataAdminService NO-UNDO. 
DEFINE VARIABLE lResult AS LOGICAL NO-UNDO.

service = NEW DataAdminService(LDBNAME("DICTDB")).
lResult = service:setDDMConfig("Customer","Balance","D:","#DDM_SEE_ContactInfo").

Startuję dwie sesje w edytorze procedur, logując się do bazy jako Admin i jako User. Uruchamiam prosty program wyświetlający wartość pola Balance dla pierwszego rekordu Customer. Zgodnie z przewidywaniem dla Admina jest to prawdziwa wartość (z lewej), a dla Usera wartość zamaskowana, czyli zero (z prawej).

Podstawowe pytanie brzmi: na jakim poziomie odbywa się maskowanie danych? Czy na warstwie prezentacji czy dostępu do danych? Jest to kwestia zasadnicza, ale zanim to wyjaśnimy uruchomię jeszcze jeden prosty przykład. Dodałem do tablicy Customer pole znakowe cStatus. W zależności od wartości pola Balance ustawiany jest status klienta. Jeśli jego Balance, czyli “saldo” wynosi zero to status zmienia się na “Blocked”.
Pole Balance nie jest tutaj wyświetlane. Uruchamiam program ponownie jako Admin

… i jako User.

Widzimy, że chociaż wartość pola Balance jest niezerowa, to logika aplikacji w drugim oknie widzi ją jako właśnie zerową. Ten przykład pokazuje najważniejszy problem związany z Dynamic Data Masking — mechanizm maskowania może wpływać nie tylko na prezentację danych, ale również na działanie logiki biznesowej. Zresztą, nie ma co się dziwić. Gdyby maskowanie dotyczyło tylko wyświetlania danych wystarczyłoby przypisać pole do zmiennej i je wyświetlić.

A zatem w wielu przypadkach aplikacja otrzymuje już zamaskowaną wartość podczas odczytu danych z bazy. Oznacza to, że warunki biznesowe, walidacje czy obliczenia mogą działać na danych zmodyfikowanych przez mechanizm DDM. Dlatego maskowanie danych nie powinno być traktowane jako element logiki aplikacyjnej.

Najbezpieczniejszym podejściem jest rozdzielenie warstw odpowiedzialności:
– logika biznesowa powinna operować na rzeczywistych danych,
– maskowanie powinno być stosowane na etapie prezentacji danych użytkownikowi,
– mechanizm DDM warto wykorzystywać głównie dla raportowania, odczytu danych oraz ograniczania dostępu do danych poufnych dla użytkowników biznesowych, audytorów czy pracowników wsparcia technicznego.


Rozważmy kolejny przypadek.

Admin uruchamia zapytanie dla 5 pierwszych rekordów Customer. Widać, że dwa z nich mają wartość pola Balance powyżej 1000.

A teraz uruchamiam poniższy program jako User.

Nie powinno nas dziwić, że licznik cnt wynosi zero ponieważ wartości pola Blanace są dla Usera zamaskowane i program widzi same zera.
Ale co się dzieje w poniższym przykładzie?

Zmieniliśmy nieco logikę przesuwając warunek na pole Balance do otwarcia pętli (fraza WHERE) i licznik wychwytuje teraz te dwie wartości > 1000.

Możecie sprawdzić sami, że jeśli wyświetlilibyśmy teraz to pole w pętli to nadal byłoby zamaskowane.
Dlaczego tak się dzieje? Otóż tutaj filtrowanie jest wykonywane bezpośrednio przez silnik bazy danych przed zastosowaniem maskowania. Oznacza to, że rekord może zostać wybrany na podstawie rzeczywistej wartości Balance, mimo że użytkownik po odczycie nadal zobaczy wartość 0. I choć maskowanie nie pozwoli nam na poejrzenie wartości możemy dostać pewną informację na temat ilości klientów których saldo jest większe od określonej wartości. Jeśli zbiór danych nie jest duży to dość łatwo możemy zawęzić zakres wartości pola Balance dla poszczególnych klientów.

Samo maskowanie wartości często nie wystarcza, ponieważ liczba rekordów, wyniki agregacji czy czas wykonania zapytania również mogą ujawniać informacje o danych.
W praktyce oznacza to, że mechanizm DDM musi być projektowany razem z logiką aplikacji, a nie traktowany jako niezależna warstwa bezpieczeństwa.

Na zakończenie: nie tylko OpenEdge

Warto podkreślić, że opisane ograniczenia nie są specyficzne wyłącznie dla Dynamic Data Masking w Progress OpenEdge. Podobne ograniczenia mają również inne technologie tego typu dostępne na rynku.

To nie jest więc „bug” konkretnego rozwiązania, ale raczej naturalna cecha samego podejścia do maskowania danych. DDM ukrywa wartości pól, ale nie zawsze ukrywa informacje wynikające z działania aplikacji, zapytań czy agregacji.

Dlatego nawet jeśli użytkownik nie widzi danych bezpośrednio, nadal może czasem wyciągać pewne wnioski na podstawie:

– liczby rekordów,
– działania warunków,
– agregacji,
– sortowania,
itp.

W praktyce oznacza to, że Dynamic Data Masking warto traktować jako dodatkową warstwę ochrony danych, a nie jedyne zabezpieczenie systemu.

OpenEdge 13

10 lutego 2026 roku pojawiła się pierwsza wersja OpenEdge 13, jako tzw, Innovation Release, co stanowi przygotowanie pod wersję długoterminową (LTS). Platforma rozwijana przez Progress wchodzi na kolejny poziom nowoczesności. To wydanie skupia się przede wszystkim na zwiększeniu wydajności, bezpieczeństwa oraz lepszej integracji z nowoczesnymi technologiami w chmurze i kontenerowymi. Dla firm korzystających z OpenEdge oznacza to większą elastyczność, łatwiejsze skalowanie aplikacji oraz lepsze przygotowanie na przyszłe wyzwania technologiczne.

OpenEdge 13 to wydanie zaprojektowane z myślą o nowoczesnych wymaganiach biznesowych i technologicznych. Twórcy platformy położyli szczególny nacisk na bezpieczeństwo, dostępność, wydajność aplikacji oraz coraz ważniejsze obszary, takie jak sztuczna inteligencja i zaawansowane zarządzanie danymi.

Nowa wersja przynosi szereg usprawnień, które mogą realnie wpłynąć na funkcjonowanie systemów w organizacji – niezależnie od jej wielkości. OpenEdge konsekwentnie rozwija się jako platforma wspierająca modernizację istniejących aplikacji, jednocześnie przygotowując je na integrację z nowymi nowoczesnymi technologiami.

W praktyce OpenEdge 13 wprowadza zmiany, które przekładają się na codzienną pracę zespołów IT. Platforma zwiększa produktywność w całym swoim ekosystemie, usprawniając zarówno proces developmentu, jak i zarządzanie środowiskiem. Jednocześnie oferuje lepszą, zoptymalizowaną wydajność – zarówno na poziomie aplikacji, jak i operacji bazodanowych.

Istotnym kierunkiem rozwoju jest również otwarcie na rozwiązania oparte o sztuczną inteligencję. OpenEdge 13 tworzy fundamenty, które umożliwiają integrację aplikacji z ekosystemem AI, co staje się coraz ważniejsze w kontekście analityki i automatyzacji procesów biznesowych.

Nie bez znaczenia są także usprawnienia w obszarze bazy danych. Nowa wersja poprawia przepustowość oraz skraca czas działania narzędzi administracyjnych, co przekłada się na zmniejszenie czasu potrzebnego na konserwację systemu. Równocześnie wzmacnia fundamenty bezpieczeństwa, zapewniając solidne i zgodne ze standardami środowisko pracy.

Niektóre z wprowadzonych nowości możecie znać z wersji 12.8 gdzie były testowane.
Zacznijmy od wybranych nowości w administrowaniu bazy danych.

Wielowątkowe tworzenie kopii zapasowych

Skrócenie czasu wykonywania kopii zapasowych ma bezpośredni wpływ na ograniczenie okien serwisowych i zwiększenie dostępności systemu. W OpenEdge 13 wprowadzono mechanizm wielowątkowego backupu, który znacząco przyspiesza operacje tworzenia kopii zapasowych baz danych w trybie offline.

Tryb wielowątkowy został ustawiony jako domyślny zarówno dla backupów offline, jak i online. Dzięki temu system automatycznie wykorzystuje dostępne zasoby CPU, co przekłada się na krótszy czas realizacji operacji. W razie potrzeby zachowanie to można skonfigurować lub całkowicie wyłączyć za pomocą narzędzia PROBKUP.

probkup [baza] … [ -thread 0 | 1 ] [ -threadnum num-threads ]

Jeśli przed wykonaniem komendy pojawia sie ostrzeżenie ESAM to wynika to stąd, że po wyinstalowaniu poprzedniej wersji nie usunąłem katalogów ESAM.

Wielowątkowe sprawdzanie indeksów (offline)

Sprawdzanie indeksów to kluczowe narzędzie administracyjne wykorzystywane do oceny stanu bazy danych, identyfikacji problemów oraz zapewnienia integralności danych. Odgrywa również istotną rolę w planowaniu i realizacji strategii odzyskiwania po awariach.

W OpenEdge 13 rozszerzono to mechanizm o możliwość wielowątkowego sprawdzania indeksów w trybie offline. Administratorzy mogą teraz równolegle walidować rekordy dla poszczególnych kluczy oraz ich kolejność, co znacząco przyspiesza cały proces.

Zarówno w trybie online, jak i offline, operacje realizowane w ramach opcji 2, 3 i 4 wykorzystują domyślnie przetwarzanie wielowątkowe — pod warunkiem, że środowisko dysponuje odpowiednimi zasobami (CPU, pamięć oraz wydajny dostęp do dysku). Dzięki temu możliwe jest równoległe wykonywanie operacji, które wcześniej były realizowane sekwencyjnie.

proutil [baza] -C idxcheck [ -thread 0 | 1 ] [ -threadnum num-threads ]

Wprowadzono ulepszenia polecenia PROUTIL IDXCOMPACT, służącego do kompresji indeksów.
Jednym z nich jest parametr -compactonly — można jej używać do kompresji drzewa indeksu wyłącznie wtedy, gdy indeks jest unikalny. Opcja ta:
– wyłącza skanowanie drzewa w poszukiwaniu symboli zastępczych usuniętych wpisów indeksu, a zamiast tego przeprowadza jego kompresję;
– wpływa na działanie operacji IDXCOMPACT w zależności od tego, czy określono również opcję -unusedblocks
Aby dokładniej zrozumieć działanie operacji warto przeczytać w dokumentacji z jakich faz składa sie kompaktowanie indexów.

Format notacji naukowej w ABL
ABL obsługuje obecnie odczyt i zapis liczb w notacji naukowej, wykorzystywanej m.in. w formatach takich jak JSON czy XML. Taki zapis umożliwia reprezentowanie bardzo małych lub bardzo dużych wartości za pomocą notacji naukowej.

Dzięki tej funkcji programiści ABL mogą uprościć swój kod i zaoszczędzić czas, eliminując konieczność tworzenia dodatkowych procedur konwersji.

Należy podkreślić, że funkcja ta nie wprowadza nowego typu danych, lecz umożliwia przetwarzanie liczb zapisanych w notacji naukowej. Po ich odczytaniu wartości są nadal reprezentowane wewnętrznie jako jeden ze standardowych typów danych ABL: INTEGER, INT64 lub DECIMAL. W dokumentacji są podane ciekawe przykłady takich liczb, ale zobaczmy dla przykładu dwie poniższe wartości.

/* Średnica czerwonej krwinki człowieka w [m] */
VAR DECIMAL RedBloodCellDiameter = 7e-6.

/* Średnica wszechświata w [m] */
VAR DECIMAL UniverseDiameter = 8.8e26.

DISPLAY RedBloodCellDiameter FORMAT "9.99999E-99".
DISPLAY UniverseDiameter FORMAT "9.99999E+99".

PAUSE.

Przy wyświetlaniu ważne jest podanie formatu. Na takim zapisie można robić konwersję z wartości znakowych.

Pisałem w zeszłym roku o integracji OE Developr’s Studio z AI Coding Assistant. Wymagało to wykonania kilku czynności. W OpenEdge 13.0 to środowisko zawiera już zintegrowanego Asystenta Kodowania AI obsługiwanego przez ChatGPT.

Inną ważną informacją jest to, że platforma .NET 8 uzyskała certyfikat zgodności z OpenEdge 13.0 zarówno dla aplikacji ABL, jak i .NET Open Client. Certyfikat ten gwarantuje, że aplikacje ABL oraz .NET Open Client po aktualizacji do .NET 8 mogą korzystać z funkcji tej platformy, pozostając jednocześnie w ramach wspieranej wersji środowiska .NET.
.NET 8 jest wersją objętą długoterminowym wsparciem technicznym (LTS), którego zakończenie planowane jest na listopad 2026 roku (od 2023 r.).

Wprowadzono jak zawsze wiele ulepszęń w dziedzinie zabezpieczeń, np. wsparcie dla FIPS 140-3.
FIPS (Federal Information Processing Standards) to zestaw standardów opracowanych przez rząd USA, określających wymagania m.in. w zakresie bezpieczeństwa danych i stosowania algorytmów kryptograficznych.

W kontekście OpenEdge ich znaczenie polega na tym, że zapewniają zgodność z uznanymi normami bezpieczeństwa. Dzięki wsparciu FIPS system może korzystać wyłącznie z certyfikowanych, bezpiecznych mechanizmów kryptograficznych, co jest szczególnie istotne w środowiskach wymagających wysokiego poziomu ochrony danych (np. w instytucjach finansowych lub administracji).

Po więcej szczegółów zapraszam do dokumentacji.

Promon 4 – strojenie sieci

W środowisku aplikacji wielowarstwowej komunikaty sieciowe są nieustannie przesyłane pomiędzy klientami zdalnymi a serwerem bazy danych. Komunikacja sieciowa może stanowić potencjalne wąskie gardło, które negatywnie wpływa na wydajność systemu.
Podczas pracy bazy danych należy proaktywnie monitorować parametry komunikacji sieciowej. W przypadku zauważenia jej pogorszenia warto rozważyć dostrojenie odpowiednich parametrów, aby poprawić wydajność.

Aby skutecznie monitorować wydajność komunikacji w czasie, należy najpierw ustalić punkt odniesienia (baseline), obejmujący m.in.:
– czas reakcji operacji pobierania danych,
– liczbę komunikatów sieciowych wysłanych i odebranych w ramach pojedynczego zapytania.

Jeżeli w trakcie dalszego monitorowania zaobserwujesz wydłużenie czasu reakcji na zapytania lub istotny wzrost liczby wysyłanych i odbieranych komunikatów sieciowych, może to oznaczać konieczność dostrojenia parametrów komunikacji w celu przywrócenia optymalnej wydajności.

Podstawowym parametrem jest tutaj rozmiar komunikatu sieciowego, w którym przesyłane są rekordy -Mm. Jeśli zaobserwujesz wzrost liczby wysyłanych i odbieranych komunikatów sieciowych lub wydłużenie czasu odpowiedzi na zapytanie, warto rozważyć zwiększenie wartości parametru –Mm. Większy rozmiar bufora komunikatów pozwala przesyłać więcej rekordów w ramach mniejszej liczby komunikatów, co ogranicza fragmentację rekordów pomiędzy pakietami i może przełożyć się na poprawę czasu odpowiedzi. Zaleca się ustawić wartość -Mm na 8192 i taka wartość domyslna jest w OE 12.

Należy pamiętać, że aby zmienić rozmiar bufora komunikatów trzeba zamknąć serwer bazy danych.
Od wersji OpenEdge 11.6 w przypadku rozbieżności między ustawieniem parametru –Mm po stronie serwera i klienta, pierwszeństwo ma wartość określona na serwerze, a wartość po stronie klienta ustawi się automatycznie na taką samą jak na serwerze. We wcześniejszych wersjach OE sygnalizowany był błąd.

Kilka kolejnych parametró strojenia komunikacji sieciowej bazy danych zostało wprowadzonych w systemie OpenEdge w wersji OE 10.2B oraz 11.1. Ich celem jest poprawienie wydajności komunikacji sieciowej, szczególnie w dużych instalacjach.

Umożliwiają one precyzyjne dostrojenie mechanizmu pakowania komunikatów dla zapytań typu prefetch, a także regulację częstotliwości wywoływania funkcji systemowej poll().

Poniższe parametry uruchamiania bazy danych są dostępne wyłącznie w ramach licencji Enterprise i mogą być strojone online:

  • -prefetchDelay – po włączeniu tego parametru (nie ma on wartości) serwer przed wysłaniem do klienta pierwszego komunikatu sieciowego z pierwszym rekordem wypełnia go większą liczbą rekordów. Dzięki temu zmniejsza się liczba przesyłanych komunikatów, co przekłada się na lepszą wydajność. Włączając ten parametr trzeba ustawić przynajmniej jeden z dwóch poniższych, określających jak mają być wypełnione komunikaty.
  • -prefetchFactor – parametr ten określa stopień (w %) wypełnienia komunikatu przed wysłaniem go do klienta. Zalecaną wartością jest 100.
  • -prefetchNumRecs – określa liczbę rekordów umieszczanych w komunikacie przed jego wysłaniem przez sieć. Dopuszczalny zakres mieści się w przedziale od 1 do 32 766. Z reguły im więcej rekordów można umieścić w pojedynczym komunikacie, tym wydajniejsze jest ich pobieranie, co pozytywnie wpływa na ogólną wydajność bazy danych.
  • -prefetchPriority – To dość ciekawy parametr. Po ustawieniu powyższych parametrów typu prefetch, serwer działa domyślnie w następujący sposób: kopiuje pierwszy rekord zapytania do bufora komunikatów, a następnie sprawdza, czy inni użytkownicy zgłaszają jakieś żądania. Jest to tzw. mechanizm poll(). Jeśli nie ma innych żądań, serwer kopiuje kolejny rekord do bufora komunikatów i ponownie sprawdza kolejkę żądań. Jeśli pojawi się żądanie od innego użytkownika, serwer przetwarza je, wstrzymując tymczasowo obsługę zapytania prefetch. Po zakończeniu jego obsługi wraca do kopiowania kolejnych rekordów.

    Mechanizm poll() generuje stosunkowo duże obciążenie procesora systemowego. Z kolei samo kopiowanie rekordów zapytania do bufora komunikatów powoduje znacznie mniejsze obciążenie CPU.

    Z tego względu bardziej efektywne jest skopiowanie kilku lub więcej rekordów do bufora przed kolejnym sprawdzeniem nowych żądań użytkowników. W tym celu można użyć parametru –prefetchPriority, który określa liczbę rekordów prefetch dodawanych do bufora bez wywoływania mechanizmu odpytywania.

    Dzięki temu zapytanie prefetch zyskuje wyższy priorytet względem nowych żądań z innych połączeń zdalnych.

    Zastosowanie parametru –prefetchPriority pozwala zmniejszyć obciążenie procesora systemowego kosztem większego wykorzystania procesora po stronie użytkownika, co w praktyce może przełożyć się na poprawę ogólnej wydajności bazy danych. Dobrą wartością tego parametru jest 100.

  • -Nmsgwait – określa liczbę sekund, przez które serwer zdalny czeka na zdalny komunikat sieciowy przed sprawdzeniem innych zdarzeń, takich jak quiet point w bazie danych, wyłączenie (shutdown) lub wymuszone wyłączenie (forced shutdown) zdalnego klienta. Domyślna dobra wartości tego parametru wynosi 2 sekundy.

Parametry te możemy stroić w promonie: R&D -> 4. Administrative Functions -> 7. Server Options
Pamiętajmy, żeby wystartować serwer z parametrem -S [numer portu/nazwa serwisu]. Proces klienta też musi być wystartowany z parametrem -S.


Do monitorowania napiszmy procedurę zawierającą proste zapytanie do bazy sports2000, którą uruchamiamy z poziomu zdalnego klienta.

// timer.p
DEFINE VARIABLE i AS INTEGER NO-UNDO.

// Start stopera
i  = ETIME(YES).

FOR EACH customer NO-LOCK:
END.

// Złapanie czasu
i  = ETIME.
MESSAGE i " milisekund"
    VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.

W celu monitorowania wchodzimy w promonie: R&D -> 2. Activity -> Servers
Najpierw naciskamy “z” żeby wyzerować liczniki, potem uruchamiamy procedurę i wreszcie naciskamu “u” dla uaktualnienia statystyk.

W menu ustawienia opcji serwera naciśnijmy 2 a następnie wartość 0, żeby wyłączyć opcję prefetch. Enabled zmieni się w Disabled. Uruchamiamy ponownie procedurę i uaktualniamy statystyki, jak poprzednio. Widzimy, że liczba komunikatów nieznacznie się zwiększyła, ale to w końcu proste zapytanie i niezbyt duża ilość rekordów.

Na koniec zmienię rozmiar parametru -Mm z 8192 do 1024 B. Robimy to oczywiście na zamkniętej bazie i powtarzamy test.

Widać wielokrotne zwiększenie liczby komunikatów. Czas wywołania procedury zwiększył się z 6 ms do ok. 20 ms. Ilość komunikatów rzadko kiedy zmienia się proporcjonalnie do rozmiaru -Mm. W końcu transfer sieciowy jest oparty o protokół tcp, a ten z kolei ma swoje mechanizmy i tzw. Maximum Transfer Unit, więc komunikaty z bazy mogą byc dzielone na mniejsze, ale znamy już podstawowe sposoby strojenia od strony OpenEdge’a.

Nowe typy extentów w bazach OpenEdge

Extenty są podstawowym elementem obszaru przechowywania (storage area) bazy danych OpenEdge. O ile bazę można podzielić na elementy logiczne jak tabele, indexy itp. to extenty są elementami fizycznymi – po prostu plikami na dysku.
Rozmiar, typ i lokalizację extentów definiuje się za pomocą pliku [nazwa_bazy].st.
Są dwa podstawowe typy extentów:

  • Extent stały (fixed extent) umożliwia kontrolę nad tym, ile miejsca na dysku przydzielić każdemu extentowi oraz ile extentów użyć. Przestrzeń w takich extentach jest sformatowana podczas tworzenia struktury bazy przez co wydajność zapisu do nich jest lepsza. Administrator musi jednak monitorować stopień wypełnienie danych.
  • Extent zmienny (variable extent) może przyrastać dynamicznie, stanowiąc taki “wentyl bezpieczeństwa” gdyby extenty stałe się zapełniły. Ułatwia to utrzymanie systemu, ponieważ nie trzeba regularnie monitorować rozmiaru extentów, ale powoduje spadek wydajności, gdyż OpenEdge RDBMS musi w trakcie zapisu do extentu zmiennego stale przydzielać i formatować przestrzeń.

    Co ważne, domyślnie ten typ extentu rośnie, aż osiągnie maksymalny rozmiar pliku dozwolony przez system operacyjny albo zajmie cały dysk lub system plików!
    Dlatego opcjonalnie można podać określony maksymalny rozmiar. Nie oznacza to jednak, że przestrzeń dla tego extentu jest przydzielona i sformatowana z góry (jak w przypadku extentu stałego). Po prostu rośnie on tylko do określonego rozmiaru.

Tak wygląda definicja przykładowych extentów w pliku .st bazy.

# extent stały
d "Cust_Data":9,32;1 . f 640
# extent zmienny z maksymalnym rozmiarem
d "Cust_Data":9,32;1 . v 1280

Wiadomo, że administrator powinien pilnować żeby dane w obszarze nie przekroczyły 80% jego objetości. Gdy sie to stannie należy dodać extenty stałe i oczywiście ostatni zmienny. Istniejący wtedy extent stały zmieni sie na stały ale jego rozmiar może być zupełnie inny od pozostałych zmiennych, często jest on bardzo mały jak extent .d3 na poniższym rysunku.

Nie jest to błędem ale po pewnym czasie możemy mieć wiele takich małych extentów w których będzie bardzo mało danych.
W OpenEdge 12 możemy temu zaradzić ponieważ dodano nowe tokeny do tworzenia i zarządzania zmiennymi extentami.

  • e rozszerza istniejący extent o zmiennej długości.
  • ev rozszerza istniejący extent o zmiennej długości i ustala maksymalny rozmiar.
  • x tworzy nowy, wstępnie rozszerzony extent o zmiennej długości.
  • xv tworzy nowy, wstępnie rozszerzony extent o zmiennej długości i ustala maksymalny rozmiar.

Np. w obszarze Cust_Data mamy dwa extenty, jeden stały i jeden zmienny jak poniżej.

Chcę dodać nowy extent zmienny z preformatowanym rozmiarem 320 kB i maksymalnym rozmiarem 640 kB, a istniejący zmienny zrobić preformatowany do wartości 320 kB. Extent ten będzie zamieniony na extent stały o określonej przez mnie długości. Plik t_add.st wygląda tak:

d "Cust_Data":9,32;1   t_9.d2   e   320  
d "Cust_Data":9,32;1   t_9.d3   xv  320  640

Uruchamiam komendę prostrct add z opcją -validate i jeśli format jest poprawny to ponownie ale już bez opcji -validate.


W pliku struktury t.st widać dodany extent. Extent .d2 ma tę samą długośc co .d1.

d "Cust_Data":9,32;1 C:\WrkOpenEdge128\db\t_9.d1 f 320
d "Cust_Data":9,32;1 C:\WrkOpenEdge128\db\t_9.d2 f 320
d "Cust_Data":9,32;1 C:\WrkOpenEdge128\db\t_9.d3 xv 320 640

A tak widać pliki w katalogu.

A gdy wylistujemy strukturę bazy poleceniem prostrct list [baza] > mylist.st mamy dodatkowe informacje:

...
   Area Name: Cust_Data, Type 6, Block Size 4096, Extents 3, Records/Block 32, Cluster Size 1
   Ext # 1, Type FIXED, Size 320 KByte, Name: ...\t_9.d1
   Ext # 2, Type FIXED, Size 320 KByte, Name: ...\t_9.d2
   Ext # 3, Type PRE-EXTENDED VARIABLE w/MAX SIZE, Size 320 KByte, Name: ...\t_9.d3
   ...

Obie wartości pre-extended i maksimum rozmiaru pliku możemy usunąć poleceniem:
prostrct add [baza] add.st gdzie plik add.st wygląda następująco:

d "Cust_Data":9,32;1   t_9.d3   ev   0  0

Pamiętajmy, że nie ma flagi v, więc nie można usunąć tylko tej drugiej wartości.

Memory Profiler 2

Wracamy do tematu związanego z użyciem Memory Profilera, dostępnego od wersji OE 12.8.9.
W poprzednim artykule pokazałem jak zainstalować i uruchomić to narzędzie.
Startujemy zatem MP, który jest instancją PASOE komendą: oemp startup

Teraz przygotujemy prosty plik konfiguracyjny mpconfig.cfg, zawierący informacje co ile ma odbyć się zrzut pamięci (cadence = 5 sek.) i do którego katalogu. Parametrów może być więcej ale na razie te wystarczą.
mpconfig.cfg

cadence 5
report-dir ./mpfiles

Można w ogóle pominąć te ustawienia i wtedy zrzut będzie odbywać się domyślnie co 10 sek. do aktualnego katalogu roboczego.
W AVM profilowanie pamięci włącza się za pomocą parametru -profileMemory.
Startuję sesję edytora prowin ./db/t -1 -profileMemory mpconfig.cfg
Jako przykład wezmę aplikację wykorzystywaną kiedyś podczas szkolenia z dynamicznych obiektów baz danych. Składa się z dwóch okienek wyswietlających dane dla dowolnych wybranych tabel, pól i zapytania. Uruchamiam aplikację i wybieram różne dane dla dynamicznych obiektów. Powtarzam cały proces jeszcze raz. Kończę sesję – w katalogu ./mpfiles wygenerowały się pliki.

Wchodzę do narzędzia MP podając w przeglądarce adres http://localhost:8880.
Widać od razu następujący komunikat:
Displays all the memory profiler recording files from the watched directories: C:/WrkOpenEdge128/oemp/upload, C:/WrkOpenEdge128/oemp/import
Kopiuję zatem do katalogu .oemp/upload te pliki .oem, których zawartośc chcę wyświetlić.

WYbrany plik najpierw trzeba zaimportować, klikam na przycisk Import, a następnie Review.

Otrzymuję wykres zmian pamięci aplikacji w funkcji czasu. Poniżej znajdują się dane dla wyswietlanej próbki.

Nazwa aplikacji _edit jest stąd, że uruchomiłem najpierw sesję edytora. Gdybym chciał rozróżnić nazwy trzeba uruchomić sesję bezpośrednio z parametrem -p [nazwa procedury.p].

Na zakończenie dodam, że zrzuty pamięci można realizować programowo wstawiając odpowiednie komendy w wybranych miejscach w kodzie. Tę metodę powinno się stosować kiedy podejrzewamy gdzie może być wyciek pamięci. Do tego tematu jeszcze powrócę.

Memory Profiler 1

W OpenEdge od wersji 12.8.9 mamy długo oczekiwane narzędzie Memory Profiler.

Umożliwia ono analizę wykorzystania pamięci przez aplikację w funkcji czasu a także w określonych interwałach, umożliwiając wizualizację wykorzystania pamięci przez kod aplikacji.
Wycieki pamięci występują, gdy aplikacja nie zwalnia niepotrzebnej już pamięci. W konsekwencji wykorzystanie jej przez aplikację rośnie z czasem, co może prowadzić do spadku wydajności, a ostatecznie do wyczerpania zasobów pamięci i awarii aplikacji lub systemu. Wycieki pamięci są szczególnie problematyczne w długo działających aplikacjach lub systemach wymagających wysokiej wydajności i niezawodności działania.
Memory Profiler zapewnia wizualizację wykorzystania pamięci i pomaga programistom ABL w skutecznym wykrywaniu i diagnozowaniu problemów z wykorzystaniem pamięci w ich aplikacjach ABL.

Korzyści płynące z używania narzędzia:

  • Identyfikacja wycieków pamięci — poprzez śledzenie nadmiernego zużycia pamięci i identyfikację wykorzystania pamięci w celu poprawy wydajności aplikacji.
  • Zwiększenie stabilności systemu i aplikacji — śledząc wykorzystanie pamięci, które nie jest zwalniane w działających aplikacjach lub w fazach testowania, zapobiegając w ten sposób potencjalnym awariom i niestabilności systemu w środowiskach produkcyjnych.
  • Debugowanie złożonych problemów — udostępniając statystyki i wizualizację, które upraszczają proces debugowania i przyspieszają rozwiązywanie problemów związanych z pamięcią.
  • Optymalizacja wydajności — identyfikując nieefektywne wykorzystanie pamięci.
  • Zapewnienie stosowania najlepszych praktyk — identyfikując obszary wymagające odpowiednich operacji czyszczenia i zachęcając do stosowania efektywnych praktyk kodowania.

    Z technicznego punktu widzenia to narzędzie jest specjalną instancją PASOE, którą możemy utworzyć korzystając z dostarczonych plików.
    Spakowane pliki te znajdują sie w katalogu [DLC]/servers/redist/oemp-[wersja oe].zip (np. oemp-12.8.9.zip).
    Plik zip kopiujemy do jakiegoś katalogu z pełnymi uprawnieniami i rozpakowujemy, przechodzimy do podkatalogu oemp\bin, a następnie w oknie komend proenv uruchamiamy komendę oemp install.
    Należy pamiętać żeby katalogiem, w którym umieścimy pliki nie byl podkatalog oemp w lokalizacji working directory ponieważ pojawi się wtedy poniższy błąd:

    Jak wybrałem podkatalog c:\oemp i wszystko poszło jak po maśle.

    Proces instalacji jest dość długi, u mnie trwał prawie 5 minut.

    Po zakończonej instalacji mamy nową instancję PASOE oemp, która odwołuje się do bazy danych /db/reportdb. Narzędzie startujemy poleceniem: oemp startup.
    Kiedy instancja jest już uruchomiona, wpisujemy następujący URL w przeglądarce: http://localhost:8880 i dostajemy główny widok Memory Profilera.

    Niedługo napiszę jak korzystać z OE Memory Profilera.

    Promon – analiza danych 3

    Dziś napiszę znowu o promonie odpowiadając przy okazji na kilka Waszych pytań, za które bardzo dziękuję.

    Pierwsze dotyczy strojenia parametru -spin (tylko dla licencji serwera Enterprise).
    Parametr „Spin Lock Retries” (–spin N) służy do określania, ile razy proces próbuje uzyskać zatrzask (latch) do zablokowanego zasobu w pamięci współdzielonej przed “pójściem na drzemkę”. Po wstrzymaniu procesu na określoną liczbę milisekund, proces uruchamia się ponownie i ponownie próbuje uzyskać zatrzask. Proces ten bardzo obciąża procesor dlatego uzywa się go wyłącznie w maszynach wieloprocesorowych, choć w starych systemach jednoprocesorowych zalecano użycie tego parametru z wartością 1, ze względu na to, że i tak był on szybszy niż mechanizm oparty na semaforach. Liczba nieudanych prób uzyskania zatrzasku określana jest w promonie Latch timeouts. Im jest ich więcej tym częściej dochodzi do konfliktów między zatrzaskami i tym gorsza jest wydajność bazy danych.

    Domyślne obliczenie brokera bazy danych to 6.000 x liczba procesorów zgłoszonych przez system operacyjny, co prawdopodobnie było odpowiednie, gdy na serwer przypadało 2 lub 4 rdzenie/procesory, ale teraz, w przypadku maszyn wielordzeniowych z 16 lub więcej rdzeniami, automatycznie obliczona liczba jest prawdopodobnie zbyt wysoka.
    Np. w moim laptopie procesor ma 4 rdzenie i 8 wątków i parametr ten ma domyślną wartość 48.000.
    Miejcie więc na względzie aby sprawdzić tę wartość w promonie:
    R&D -> 4. Administrative Functions 4. Adjust Latch Options


    W tym samym miejscu możemy zmienić tę wartość online (podopcja 1).

    Expert z White Star Software uważa, że wartości z przedziału 5.000 do 20.000 są wystarczające dla zdecydowanej większości baz danych, więc nie ma co szaleć. Należy przede wszystkim monitorować wykorzystanie CPU i w razie gdy osiąga ono duże wartości (90% lub więcej) zmniejszyć -spin online.

    Analizę timeoutów możemy podejrzeć na poniższym ekranie promona – ostatni wiersz.
    R&D -> 3. Other Displays -> 1. Performance Indicators -> Latch timeouts

    Drugim parametrem, o którym chcę tutaj napisać jest -lruskips dostępny także tylko dla serwera Enterprise i ma związek z zatrzaskami przy próbie dostępu do zasobu w puli buforów.
    Łańcuch LRU (Least Recently Used) składa się ze wskaźników do buforów w puli i przy każdym odczycie z tej puli (dla -lruskips = 0) potrzebne jest uzyskanie zatrzasku aby uaktualnić ten łańcuch. Jeśli ustawimy -lruskips = 100 (dobra wartość stosowana obecnie domyślnie) to próba uzyskania zatrzasku LRU będzie co 100-tny dostęp do bufora, co poprawia współbieżność i wydajność.
    Wartość parametru możemy dostosować także online w tym samym miejscu promona co dla -spin (patrz poniższy obrazek). Jeśli mamy dwie pule buforów (-B i -B2) to możemy określić osobno -lruskip i -lruskip2. Mechanizm ten nie jest wykorzystywany w prywatnej puli buforów.

    Jak dobrać długość clustra BI

    W poprzednim wpisie napisałem pod koniec jak z grubsza określić długośc clustra BI. Oczywiście wydłużanie tego clustra ma sens tylko dla licencji serwera bazy Enterprise. W Workgroup nie ma procesów asynchronicznych, a więc duża liczba buforów Dirty nie będzie “rozładowana” przed checkpointemi i cały system znacznie spowolni.
    A zatem, w bazie Enterprise chcemy aby odstęp między checkpointami był np. 4 razy większy niż obecnie, więc wydłużamy 4 razy cluster BI. Operacja jest bardzo prosta i odbywa się na zamkniętej bazie. Jednakże nie możemy kierować się tylko takim podejściem ponieważ szybkość dysków ma swoje granice.

    Do określenia maksymalnego rozmiaru clustra przydatny i powszechnie stosowany jest Furgal Storage Device Test lub po prostu Furgal Test zwany tak od nazwiska autora Mike’a Furgala. Polega on na wykonaniu polecenia BIGROW do pomiaru szybkości dysku poprzez pomiar czasu potrzebnego na utworzenie pliku BI o określonym rozmiarze.

    Po obcięciu pliku BI i wystartowaniu serwera bazy tworzone są domyślnie 4 clustry BI. Jednakże w trakcie normalnej pracy systemu mogą one być niewystarczające i plik BI urośnie do np. 6 clustrów.
    Operacja proutil z opcją bigrow służy do tego aby zwiększyć liczbę clustrów zanim uruchomimy bazę, poprzez wstępne sformatowanie określonej liczby clustrów. Pamiętajmy, że jeśli chcemy mieć liczbę clustrów 6 to podajemy jako parametr 2 (bo 4 są już i tak domyślne). Furgal Test wykazuje silną korelację między czasami wykonania bigrow a wydajnością systemu bazy danych.

    Warto dodać, że mechanizm rozszerzania pliku BI o dodatkowe sformatowane klastry został przeprojektowany i przyśpieszony (buforowany). Wcześniej tylko na Solarisie i AIX, obecnie (od OE 11.7.6 i OE 12.1) jest dostępny na wszystkich platformach w tym Linux i Windows.

    Mamy poniżej dwie komendy.
    proutil [baza] –C truncate bi –bi 16384
    time proutil [baza] –C bigrow 2

    Pierwsza ustawia większy niż domyślny rozmiar clustra bi na 16 MB, a druga mierzy czas sformatowania 6 clustrów (4 + 2).
    Plik BI urośnie zatem do 96 MB. Mamy zatem dwa parametry rozmiar BI i czas sformatowania. Dzielimy je przez siebie i otrzymujemy szybkość dysku w MB na sekundę.
    Nasz maksymalny rozmiar klastra BI powinien być nie większy niż 2-krotność szybkości dysku.
    Zróbmy ten test na testowej bazie na Windows – zamiast polecenia time możemy posłużyć się poniższym skryptem (timer.bat).

    @echo off
    echo %time% < nul
    cmd /c %1
    echo %time% < nul
    

    timer "proutil [baza] –C bigrow 2"

    Czas wykonania komendy to ok. 1 sekunda, czli prędkość wynosi w przybliżeniu 100 MB/sec. Maksymalny cluster zatem to 200 MB. Oczywiście taką komendę warto wykonać kilka razy i wziąć średni pomiar. No i nie ustawiamy od razu ten maksymalny rozmiar clustra ale zwiększamy go stopniowo, obserwując jak działa system (analiza checkpointów w promonie).

    W bazie wiedzy możemy znaleźć informację, że zgodnie z powszechnie akceptowanym od lat punktem odniesienia BIGROW w wielu różnych systemach, zapisanie pliku BI o rozmiarze 100 MB nie powinno zająć dłużej niż 10 sekund. W naszym teście zajęło to tylko 1 sekundę (dysk SSD).

    Promon – analiza danych 2

    Powracając do tematyki związanej z tym najbardziej znanym narzędziem dla administratorów baz, chciałbym napisać dwa słowa o ukrytej opcji, którą, jak się okazuje, nie wszyscy znają.
    Kiedyś była to opcja R&D, niewidoczna z głównego menu ale to było dawno temu.
    Drugie menu było bardziej ukryte. Trzeba było napisać devdbh, Enter i następnie 6.
    Obecnie w nowym promonie ta opcja jest widoczna właśnie na pozycji 6 w meny R&D chociaż możemy wejść do niej także “po staremu”.

    Zawiera zaawansowane opcje dogłębnego monitorowania aktywności i wydajności systemu baz danych OpenEdge.

    Jak widać lista jest całiem długa, ale są to informacje dla zaawansowanych administratorów, lub raczej dla techsupportu PSC. Może się zdarzyć że będziemy poproszeni o przesłanie konkretnych danych z tej listy.

    Powróćmy do danych, które możemy pobrać do własnej analizy. Myślę, że jednymi z najważniejszych są te związane z checkpointami.
    Uruchamiam własny program generujący transakcje w bazie testowej (kopia sports2000) i wchodzę do promona.
    W opcji R&D -> 1. Status Displays -> 9. BI Log sprawdzam parametry zapisu BI na dysku. Blok BI ma 8kB, a cluster tylko 512 kB (domyślna wartość). Zobaczmy jaki to będzie miało efekt w działaniu.

    Przechodzę do głównego menu, a następnie 3. Other Displays -> 4. Checkpoints.
    Popatrzmy na poniższą analizę. Nie wygląda to dobrze…

    Co oznaczają niektóre kolumny (wg dokumentacji):
    Dirty – liczba zmodyfikowanych buforów zaplanowanych do zapisania.
    CPT Q – Liczba buforów zapisanych z kolejki checkpoint przez procesy APW.
    Scan – Liczba buforów zapisanych przez procesy APW podczas cyklu skanowania.
    APW Q – Liczba buforów zapisanych przez kolejkę APW i zastąpionych w łańcuchu LRU przez procesy APW.
    DB Writes – Całkowita liczba buforów bazy danych zapisanych na końcu checkpointu.

    Administratorzy baz chcą aby odstęp między checkpointami (kolumna Len) był rzędu kilku minut, a tu mamy 2 sekundy. Ponadto podczas checkpointu jest nienaturalnie duża ilość zapisów na dysk – kolumna DB Writes (ten parametr w starszych wersjach jest określany jako Flushes). Tak liczne zapisy powodują spadek wydajności.
    Nie uruchomiłem jeszcze procesu APW, więc kolejka APW jest pusta, ale i tak widać od razu, że trzeba koniecznie wydłużyć cluster. Zwiększę go zatem z 0.5 MB do 16 MB. Rozmiar bloku BI zwiększę przy okazji z 8 KB do 16 KB.
    proutil [baza] -C truncate bi -bi 16384 -biblocksize 16

    Ponieważ rozmiar clustra został zwiększony 32 razy to dostęp między checkpointami zwiększy się z 2-3 sekund do ok. 70 sekund. Po odczekaniu zobaczmy jak teraz wygląda analiza checkpointów.

    Zobaczmy, że wartości Dirty nie przekraczają wartości DB Writes, jak poprzednio. Oznacza to, że jest dość czasu podczas checkpointu żeby zapisy zostały dokonane. Jednakże duża liczba tych zapisów może powodować spowolnienie systemu podczas checkpointu. Nie mamy tu na razie procesów asynchronicznych (tylko serwer Enterprise) i kolumna CPT Q pokazuje same zera.

    A teraz co się zmieni po uruchomieniu procesu APW (niebieska ramka). Wszystkie bufory do zapisu są umieszczone w kolejce checkpoint i zapisane przez procesy APW tak, że podczas checkpointu nie ma już żadnych zapisów i system nie będzie spowalniał

    Metoda wydłużenia czasu między checkpointami jest dość prosta i możemy pokusić się o dalsze zwiększenie clustra BI żeby czas wynosił tutaj 2-3 a nawet 5 minut. Pytanie tylko czy nasze dyski są dostatecznie szybkie aby temu podołać. Clustra nie można zwiększać bez końca bez żadnych konsekwencji.

    W następnym wpisie napiszę o prostym teście jak można taką graniczną wartość określić.

    Na koniec jeszcze mała uwaga dotycząca zbierania danych z promona poprzez skrypt. Większość parametrów znajduje się w tablicach VST, zawierających tylko jeden rekord (podawana wartość to różnica wartości z danego pola w czasie) ale czasem tych rekordów jest więcej, jak w przypadku checkpointów. Nie ma dla nich w promonie opcji automatycznego odświeżania. Najłatwiej jest oczywiście napisać program w ABL ale jeśli nie mamy takiej możliwości, to obliczamy po ilu minutach zapełnią się dane wszystkich checkpointów na ekranie (tutaj ok. 15 minut) i ustawiamy uruchomienie skryptu zapisującego tylko ten ekran (np. w cronie) co ten czas.

    1 2 3 6