Synchronizacja SQL
Podsumowanie:Synchronizacja SQL to mechanizm cyklicznego importu danych organizacyjnych (użytkowników i jednostek organizacyjnych) z systemu źródłowego do nAxiom i ich aktualizacji. Umożliwia zsynchronizowanie struktury organizacyjnej w nAxiom z dowolnym systemem, z którego dane można wyeksportować do bazy danych SQL nAxiom. Proces obejmuje dwa etapy: import danych do tabel przejściowych oraz automatyczną aktualizację struktury docelowej.
Informacje o przebiegu synchronizacji są dostępne poprzez monitorowanie statusu synchronizacji tabel core.SyncUserProfiles i core.SyncOUInstances w tabeli core.SqlTableStatuses.
Czym jest synchronizacja SQL
Synchronizacja SQL jest uniwersalnym mechanizmem importu danych organizacyjnych z systemu źródłowego do nAxiom. W odróżnieniu od synchronizacji wbudowanej , która komunikuje się bezpośrednio z źródłem danych (AD, OpenLDAP), synchronizacja SQL polega na:
- Imporcie danych — wyeksportowanie informacji o użytkownikach i jednostkach organizacyjnych z systemu źródłowego do tabel przejściowych w bazie danych nAxiom
- Automatycznej synchronizacji — przetworzenie danych z tabel przejściowych i aktualizacja struktury organizacyjnej w nAxiom
Takie rozdzielenie pozwala na:
- Elastyczne integracje z dowolnymi systemami źródłowymi
- Przygotowanie i walidację danych przed synchronizacją
- Zmianę trybu synchronizacji bez wpływu na proces importu
- Łatwe debugowanie — dane z tabel przejściowych są dostępne dla administracji
Wymagania i przygotowanie
Dane niezbędne do synchronizacji
Synchronizacja wymaga następujących informacji dla każdego użytkownika:
- Identyfikator użytkownika (login, ID z systemu źródłowego)
- Imię i nazwisko (opcjonalnie rozdzielone na imię i nazwisko)
- Adres e-mail
- Przypisanie do jednostki organizacyjnej
- Status (aktywny/nieaktywny)
- Data wygaśnięcia profilu
Dla jednostek organizacyjnych:
- Identyfikator OU (kod, ID z systemu źródłowego)
- Identyfikator OU nadrzędnej (relacja hierarchiczna)
- Kod
- Nazwa
- Status (aktywna/nieaktywna)
- Data początkowa aktywności
- Data końcowa aktywności
Przygotowanie danych
Dane z systemu źródłowego muszą być wyeksportowane w formacie, który można załadować do tabel synchronizacyjnych nAxiom. Typowym podejściem jest:
- Eksport z systemu źródłowego do pliku CSV lub formatu tekstowego
- Transformacja danych (jeśli wymagana) za pomocą skryptu lub narzędzia ETL
- Załadowanie do tabel przejściowych (
SyncUserProfiles,SyncOUInstances,SyncOUInstanceUsers) za pośrednictwem procedury SQL lub skryptu
Konfiguracja
Synchronizacja SQL jest sterowana przez konfigurację tenanta. W konfiguracji tenanta określa się między innymi:
- tryb synchronizacji (
SynchronizationType) - częstotliwość sprawdzania statusów (
RepeatInterval) - domyślne wartości używane podczas synchronizacji, np. język, role i adres e-mail
- dodatkowe opcje wpływające na sposób aktualizacji użytkowników i jednostek organizacyjnych
TaskService odczytuje te ustawienia z konfiguracji tenanta i na ich podstawie wykonuje cykliczną synchronizację.
Tabele synchronizacyjne
Dane przejściowe są przechowywane w czterech tabelach:
core.SyncUserProfiles — profile użytkowników
-
Id— unikalny identyfikator rekordu (auto-increment) -
UserId(nvarchar, UNIQUE) — identyfikator użytkownika z systemu źródłowego (login, GUID itp.) -
ParentId— FK do UserId (dla hierarchii, np. manager użytkownika) -
UserName— nazwa użytkownika (login wyświetlany) -
FirstName,LastName— imię i nazwisko -
Email— adres e-mail -
IsActive(bit) — czy użytkownik jest aktywny (1 = tak, 0 = nie) -
ExpireDate(datetime2) — data wygaśnięcia dostępu
core.SyncOUInstances — jednostki organizacyjne
-
Id— unikalny identyfikator rekordu (auto-increment) -
OrgUnitId(nvarchar, UNIQUE) — identyfikator OU z systemu źródłowego (kod OU, GUID itp.) -
ParentId— FK do OrgUnitId (OU nadrzędna dla hierarchii) -
Code— kod organizacyjny OU (np. “IT”, “HR”, “SALES”) -
Name— nazwa jednostki organizacyjnej -
IsActive(bit) — czy OU jest aktywna -
ActiveFrom(datetime2) — data aktywacji -
ActiveUntil(datetime2) — data deaktywacji (NULL jeśli bez ograniczenia)
core.SyncOUInstanceUsers — przypisania użytkowników do OU
-
OrgUnitId(nvarchar, FK) — referencja doSyncOUInstances.OrgUnitId -
UserId(nvarchar, FK) — referencja doSyncUserProfiles.UserId - Tabela asocjacyjna bez własnego ID — określa powiązania użytkowników z jednostkami
core.SqlTableStatuses — statusy synchronizacji
-
Id— unikalny identyfikator -
Name(nvarchar) — nazwa tabeli (SyncUserProfileslubSyncOUInstances) -
Status(int) — kod statusu (0=ReadyForData, 1=DataInput, 2=ReadyForSync, 3=InSync, 4=Error.)
Statusy synchronizacji są przechowywane w core.SqlTableStatuses na poziomie tabeli, nie na poziomie poszczególnych rekordów. Stan wskazuje na postęp całej partii danych dla danej tabeli. Tabela
SyncOUInstanceUsersnie ma własnego statusu wSqlTableStatuses— jej synchronizacja jest zintegrowana z przetwarzaniemSyncOUInstances. Przypisania użytkowników do OU (zawarte wSyncOUInstanceUsers) są automatycznie przetwarzane w ramach synchronizacji jednostek organizacyjnych, bez osobnej kontroli statusu. Oznacza to, że:
- Gdy załadujesz dane do
SyncOUInstanceUsers, nie zmienią się statusy wSqlTableStatuses- Synchronizacja przypisań następuje automatycznie gdy
SyncOUInstancesma statusInSync- Ewentualne błędy w przypisaniach będą zaraportowane w logach TaskService podczas przetwarzania
SyncOUInstances
Przygotowanie do pierwszej synchronizacji
Przed załadowaniem danych do tabel synchronizacyjnych:
- Przygotuj dane w systemie źródłowym i wyeksportuj je w wybranym formacie
-
Zweryfikuj dane przed załadowaniem:
- Czy identyfikatory użytkowników (
UserId) są unikalne - Czy identyfikatory OU (
OrgUnitId) są unikalne - Czy hierarchia OU jest spójna (wszystkie
ParentIdwskazują na istniejąceOrgUnitId) - Czy przypisania użytkowników do OU są prawidłowe (
SyncOUInstanceUserszawiera tylko istniejąceUserIdiOrgUnitId)
- Czy identyfikatory użytkowników (
-
Załaduj dane do tabel synchronizacyjnych
-
SyncUserProfiles— profili użytkowników -
SyncOUInstances— jednostek organizacyjnych -
SyncOUInstanceUsers— przypisań użytkowników do OU
-
- Upewnij się, że status = ReadyForSync — jeśli załadujesz przez API, status ustawia się automatycznie; jeśli bezpośrednio SQL, musisz ustawić ręcznie
-
Synchronizacja uruchomi się automatycznie — TaskService ma wbudowany timer, który zgodnie z konfiguracją tenanta co
RepeatIntervalsekund wyzwala synchronizację (patrz sekcja Jak działa synchronizacja)
Przebieg synchronizacji
Fazy synchronizacji
1. Import danych
Administrator lub skrypt ETL przygotowuje dane w tabelach przejściowych. Dane mogą być załadowane poprzez:
- Procedury SQL (
INSERT INTO SyncUserProfiles ...) - Skrypty ETL
- Public API nAxiom (które obsługuje walidację i zmianę statusu)
Tabele są zasilane danymi z systemu źródłowego:
-
SyncUserProfiles— lista użytkowników -
SyncOUInstances— struktura organizacyjna -
SyncOUInstanceUsers— przypisania użytkowników do OU
Endpointy PublicAPI do zasilania tabel przejściowych
Jeśli dane są ładowane przez PublicAPI (zamiast bezpośrednio SQL), można użyć endpointów kontrolera StructureSynchronization.
Ogólny wzorzec ścieżki w PublicAPI to:
/{Controller}/{Action}
W praktyce dla synchronizacji struktury używane są:
-
POST /StructureSynchronization/UserProfileList- Zasila tabelę
core.SyncUserProfiles - Body: obiekt z listą
UserProfiles(dla każdego elementu m.in.UserId,ParentId,UserName,Email,FirstName,LastName,IsActive,ExpireDate)
- Zasila tabelę
-
POST /StructureSynchronization/OUInstanceList- Zasila tabelę
core.SyncOUInstances - Body: obiekt z listą
OUInstances(dla każdego elementu m.in.OrgUnitId,ParentId,Code,Name,IsActive,ActiveFrom,ActiveUntil)
- Zasila tabelę
-
POST /StructureSynchronization/OUInstanceUsersList- Zasila tabelę
core.SyncOUInstanceUsers - Body: obiekt z listą
OUInstanceUsers(dla każdego elementu:OrgUnitId,UserId)
- Zasila tabelę
Endpointy PublicAPI do importu danych wymagają poprawnej autoryzacji PublicAPI i odpowiednich uprawnień użytkownika technicznego. Przy imporcie przez API status tabel (
core.SqlTableStatuses) jest obsługiwany automatycznie przez aplikację (w tym przejście doReadyForSync).
Uwaga: endpoint POST /StructureSynchronization/SynchronizeStructure nie służy do zasilania tabel przejściowych. Służy do uruchomienia synchronizacji danych już załadowanych do tabel Sync*.
Przykładowe payloady JSON (PublicAPI)
Przykład dla POST /StructureSynchronization/UserProfileList:
{
"userProfiles": [
{
"userProfile": {
"id": 0,
"userId": "u-001",
"parentId": null,
"userName": "jan.kowalski",
"email": "jan.kowalski@acme.pl",
"firstName": "Jan",
"lastName": "Kowalski",
"isActive": true,
"expireDate": "2026-12-31T00:00:00"
}
}
]
}
Przykład dla POST /StructureSynchronization/OUInstanceList:
{
"ouInstances": [
{
"ouInstance": {
"id": 0,
"orgUnitId": "OU-IT",
"parentId": null,
"code": "IT",
"name": "Dzial IT",
"isActive": true,
"activeFrom": "2026-01-01T00:00:00",
"activeUntil": null
}
}
]
}
Przykład dla POST /StructureSynchronization/OUInstanceUsersList:
{
"ouInstanceUsers": [
{
"ouInstanceUser": {
"orgUnitId": "OU-IT",
"userId": "u-001"
}
}
]
}
Nazwy właściwości JSON podawaj zgodnie z kontraktem API (jak w przykładach powyżej). W praktyce integracyjnej najbezpieczniej najpierw wykonać test na pojedynczym rekordzie, a dopiero potem wysyłać pełne paczki danych.
2. Automatyczne wyzwolenie synchronizacji (nie ma ręcznego “uruchamiania”)
TaskService ma wbudowany timer (StructureSynchronizationConnector), który:
- Co
RepeatIntervalsekund (z konfiguracji) sprawdza status tabel wSqlTableStatuses - Szuka tabel ze statusem
ReadyForSync(kod 2) - Jeśli znaleziona, zmienia status na
InSync(kod 3) i uruchamia synchronizację
Wymagane kroki:
- Załaduj dane do tabel przejściowych
- Upewnij się, że status w
SqlTableStatusesdla obu tabel (SyncUserProfiles,SyncOUInstances) wynosiReadyForSync(= 2) - Czekaj na timer TaskService — synchronizacja uruchomi się automatycznie w następnym cyklu
Jeśli dane są załadowane przez Public API, zmiana statusu na ReadyForSync następuje automatycznie. Jeśli załadujesz dane bezpośrednio SQL, musisz ręcznie ustawić status:
UPDATE core.SqlTableStatuses SET Status = 2 WHERE Name = 'SyncUserProfiles'
UPDATE core.SqlTableStatuses SET Status = 2 WHERE Name = 'SyncOUInstances'
3. Przetwarzanie i aktualizacja struktury
TaskService:
- Odczytuje dane z tabel przejściowych (
SyncUserProfiles,SyncOUInstances,SyncOUInstanceUsers) - Przetwarza je zgodnie z wybranym trybem (Full, Update, Differential)
- Aktualizuje strukturę w tabelach docelowych (
UserProfiles,OUInstances,OUInstanceUsers) -
Przypisania użytkowników z
SyncOUInstanceUserssą przetwarzane automatycznie w ramach synchronizacjiSyncOUInstances
4. Monitorowanie i weryfikacja
Administrator monitoruje statusy synchronizacji:
- Statusy w
SqlTableStatuseswskazują postęp (ReadyForData→DataInput[przy imporcie przez API] →ReadyForSync→InSync→ReadyForDatalubError) - Błędy są zaraportowane w logach TaskService
- W razie problemów dane w tabelach przejściowych pozostają dostępne do analizy
Schemat czasowy
Synchronizacja jest w pełni automatyczna:
- TaskService ma timer, który co
RepeatIntervalsekund (typowo 60-300 sekund, zależy od konfiguracji tenanta) sprawdza status - Synchronizacja jest wyzwalana automatycznie gdy status =
ReadyForSync - Administrator nie ma GUI ani polecenia do ręcznego uruchamiania — synchronizacja działa w tle
- Jedynym sposobem kontroli jest:
- Zmiana
RepeatIntervalw konfiguracji tenanta (aby zmieniła się częstotliwość polingu) - Ustawienie statusu na
ReadyForSync(aby wyzwolić synchronizację w następnym cyklu timera) - Monitorowanie logów — aby zobaczyć czy synchronizacja się powiodła
- Zmiana
Tryby synchronizacji
W konfiguracji tenanta ustawienie ‘SynchrozationType’ określa tryb synchronizacji czyli, jak dane z tabel przejściowych są stosowane do struktury docelowej. Do dyspozycji są trzy główne tryby:
| Tryb | Dodawanie nowych rekordów | Aktualizacja istniejących | Deaktywacja brakujących | Typowe zastosowanie |
|---|---|---|---|---|
| Full | Tak | Tak | Tak | Pełne odświeżenie struktury na podstawie kompletnego źródła danych |
| Update | Nie | Tak | Tak | Aktualizacja rekordów już istniejących w nAxiom, bez zakładania nowych |
| Differential | Tak | Tak | Tak | Synchronizacja oparta o dane różnicowe; w praktyce bardzo zbliżona do trybu Full |
Tryb
Updatenie tworzy nowych użytkowników ani nowych jednostek organizacyjnych. Jeżeli podczas synchronizacji system nie znajdzie odpowiednika danego rekordu w strukturze docelowej, rekord zostanie pominięty. Jednocześnie tryb ten nadal może deaktywować obiekty brakujące w danych źródłowych.
Tryb Full (Pełna synchronizacja)
Tryb ten implementuje najpełniejszą synchronizację danych:
- Dodaje nowych użytkowników i OU
- Aktualizuje istniejące rekordy (dane, status)
- Deaktywuje użytkowników i OU brakujące w danych źródłowych (użytkownik istnieje w nAxiom, ale nie ma go w tabelach przejściowych)
Zastosowanie: Idealne do pełnego odświeżenia struktury, gdzie dane źródłowe zawsze odzwierciedlają aktualną rzeczywistość. Po synchronizacji struktura w nAxiom będzie dokładnym odzwierciedleniem danych źródłowych.
Uwaga: Deaktywowanie brakujących użytkowników może wpłynąć na dostęp i uprawnienia. Należy upewnić się, że dane źródłowe zawierają wszystkich użytkowników, którzy powinni być aktywni.
Tryb Update (Aktualizacja)
Tryb ten jest bardziej konserwatywny:
- Aktualizuje istniejące użytkowników i OU (dane i status)
- Nie dodaje nowych rekordów
- Deaktywuje użytkowników i OU brakujące (tak jak w trybie Full)
Zastosowanie: Gdy struktura bazowa istnieje już w nAxiom, a chcemy aktualizować tylko dane istniejących rekordów. Zapobiega przypadkowemu dodaniu duplikatów, ale nadal stosuje deaktywowanie brakujących rekordów.
Uwaga: Semantycznie tryb “Update” zawiera również akcję deaktywowania, co może być nieintuicyjne. Umownie, deaktywowanie brakujących jest powszechnym zachowaniem synchronizacji.
Tryb Differential (Synchronizacja różnicowa)
Praktycznie zachowuje się podobnie do trybu Full, ale logika wewnętrzna jest zoptymalizowana do wskaźników różnic między danymi:
- Dodaje nowe rekordy
- Aktualizuje istniejące
- Deaktywuje brakujące
Zastosowanie: Gdy chcemy zachować logikę Full, ale dane źródłowe są dostępne jako zbiory delta (wpisy nowe, zmienione, usunięte) zamiast całej listy.
Wybór trybu
Decyzja o wyborze trybu zależy od:
- Dostępności kompletnych danych — jeśli dane źródłowe zawsze zawierają pełną listę, stosuj tryb Full
- Bezpieczeństwa — jeśli chcesz uniknąć przypadkowej deaktywacji, rozważ ograniczenia na poziomie bazy danych
- Nowych vs. istniejących danych — tryb Update jest bezpieczniejszy dla struktur, które już zawierają dane lokalne
Jak działa synchronizacja — techniczny przebieg
Timer TaskService (StructureSynchronizationConnector)
TaskService zawiera wbudowany usługę SynchronizeStructureTimedHostedService, która:
Inicjowanie:
- Startuje automatycznie gdy tenant jest aktywowany
- Konfiguracja pobierana z
StructureSynchronizationConfiguration.RepeatInterval(czas w sekundach)
Cykliczny monitoring:
- Co
RepeatIntervalsekund timer sprawdza tabelęcore.SqlTableStatuses - Szuka wpisów dla
SyncUserProfilesiSyncOUInstances - Sprawdza czy
Status=2(ReadyForSync)
Wyzwolenie synchronizacji:
Jeśli Status == ReadyForSync (2):
1. Zmiana Status → InSync (3)
2. Uruchomienie SynchronizeStructureFromSyncTableHandler
3. Odczyt danych z tabel przejściowych
4. Przetworzenie zgodnie z trybem
5. Aktualizacja tabel docelowych
6. Zmiana Status → ReadyForData (0) [sukces] lub Error (4) [błąd]
Parametry:
-
RepeatInterval: domyślnie 60-300 sekund (zależy od instalacji) - Parametry pochodzą z konfiguracji tenanta, w szczególności z sekcji
StructureSynchronizationConfiguration; wartość 0 wyłącza synchronizację -
UWAGA:
RepeatIntervalnie jest ustawieniem tabel synchronizacyjnych ani bazy danych. Jest elementem konfiguracji tenanta odczytywanej przez TaskService.
Ustawienie statusu ReadyForSync
Status ReadyForSync (kod 2) powinien być ustawiony na dwa sposoby:
1. API (zalecane):
- Załadowanie danych przez API automatycznie ustawia
Status = ReadyForSyncpo wkładzie danych - Przykład:
SaveSyncTableUserProfileListHandlerpo INSERT danych zmienia status na 2
2. Ręcznie SQL (dla zaawansowanych):
- Jeśli załadujesz dane bezpośrednio INSERT, musisz ręcznie ustawić status:
UPDATE core.SqlTableStatuses SET Status = 2 WHERE Name = 'SyncUserProfiles' UPDATE core.SqlTableStatuses SET Status = 2 WHERE Name = 'SyncOUInstances' - Po tym kroku timer TaskService w następnym cyklu wyzwoli synchronizację
Statusy i monitorowanie
Cykl statusów synchronizacji
Statusy synchronizacji są przechowywane w tabeli core.SqlTableStatuses na poziomie całej tabeli (nie na poziomie poszczególnych rekordów). Dla tabel przejściowych SyncUserProfiles i SyncOUInstances istnieje rekord w SqlTableStatuses z jego aktualnym stanem:
| Status | Znaczenie | Opis |
|---|---|---|
| 0 — ReadyForData | Gotów do przyjęcia danych | Tabela oczekuje na załadowanie danych z systemu źródłowego |
| 1 — DataInput | Dane są ładowane | Trwa wczytywanie danych do tabeli |
| 2 — ReadyForSync | Gotów do synchronizacji | Dane są kompletne i gotowe do przetworzenia |
| 3 — InSync | Synchronizacja w trakcie | Trwa przetwarzanie danych i aktualizacja tabel systemowych |
| 4 — Error | Błąd | Podczas synchronizacji wystąpił błąd; szczegóły są dostępne w logach TaskService |
Uwaga: Tabela SyncOUInstanceUsers nie ma własnego statusu w SqlTableStatuses. Jej synchronizacja jest automatyczną częścią przetwarzania SyncOUInstances. To oznacza:
- Przypisania użytkowników do OU są przetwarzane razem z OU na podstawie statusu
SyncOUInstances - Gdy
SyncOUInstancesma statusInSync(3), również dane zSyncOUInstanceUserssą synchronizowane w tym samym cyklu - Brakuje osobnej kontroli statusu dla przypisań — są one zawsze przetwarzane razem z jednostkami
Monitorowanie synchronizacji
Aby monitorować przebieg synchronizacji:
-
Sprawdź statusy tabeli —
SELECT * FROM core.SqlTableStatuses WHERE Name IN ('SyncUserProfiles', 'SyncOUInstances')-
Uwaga: Brak statusu dla
SyncOUInstanceUsers— jest ona przetwarzana razem zSyncOUInstances
-
Uwaga: Brak statusu dla
-
Obserwuj zawartość tabel — czy rekordy w
SyncUserProfiles,SyncOUInstancesiSyncOUInstanceUserszawierają oczekiwane dane -
Przeanalizuj błędy — jeśli status to
4 (Error), przejrzyj logi TaskService w celu znalezienia szczegółów -
Porównaj dane — porównaj zawartość tabel przejściowych z tabelami docelowymi (
UserProfiles,OUInstances)
Logi synchronizacji
TaskService loguje każde uruchomienie synchronizacji, w tym:
- Datę i godzinę
- Tryb synchronizacji
- Liczbę przetworzonych rekordów
- Błędy i ostrzeżenia
- Czas trwania
Logi pomagają w diagnostyce problemów i analizie historii synchronizacji.
Status nie zawsze odzwierciedla rzeczywisty stan synchronizacji
TaskService uruchamia cykl synchronizacji co
RepeatIntervali po zakończeniu cyklu może ustawić status naReadyForData(0), nawet jeśli w poprzednim cyklu wystąpiłError(4). W praktyce można zaobserwować sekwencję:2 (ReadyForSync)->3 (InSync)->4 (Error)-> po kolejnym odświeżeniu/cyklu0 (ReadyForData).Oznacza to, że status=ReadyForData nie gwarantuje, że poprzednia próba synchronizacji przebiegła bez błędów. Status informuje o bieżącej gotowości tabeli do przyjęcia kolejnych danych, a nie o jakości poprzedniego przebiegu.
Administrator MUSI regularnie sprawdzać logi TaskService, aby upewnić się, że synchronizacja faktycznie się powiodła. Błędy (np. duplikaty, naruszenia FK, konflikty danych) mogą być zaraportowane tylko w logach, a status będzie wyglądać na “OK”.
Praktyka: Po każdej synchronizacji:
- Sprawdź status w
SqlTableStatuses— czy zmienił się na0 (ReadyForData)- Przejrzyj logi TaskService z ostatnich minut — szukaj błędów, ostrzeżeń, liczby przetworzonych rekordów
- Opcjonalnie: Porównaj liczbę rekordów w tabelach przejściowych z liczbą zsynchronizowanych rekordów (może się nie zgadzać jeśli były błędy)
Rozwiązywanie problemów
Synchronizacja nie zaczyna się
Przyczyny:
- Timer TaskService nie jest uruchomiony (serwis nie działa itp.)
- Tabele przejściowe są puste (brak danych w SyncUserProfiles lub SyncOUInstances)
- Status w
SqlTableStatusesnie jestReadyForSync(2) — synchronizacja czeka tylko na ten status -
RepeatIntervaljest bardzo duży — timer sprawdza rzadko, czekaj dłużej
Rozwiązanie:
- Sprawdź, czy TaskService jest uruchomiony (pula aplikacji lub kontener)
- Weryfikuj, czy dane zostały załadowane do tabel przejściowych:
SELECT COUNT(*) FROM core.SyncUserProfiles; SELECT COUNT(*) FROM core.SyncOUInstances; - Sprawdź statusy i
RepeatInterval:SELECT * FROM core.SqlTableStatuses WHERE Name IN ('SyncUserProfiles', 'SyncOUInstances');- Sprawdź
RepeatIntervalw konfiguracji tenanta, w sekcjiStructureSynchronizationConfiguration. JeśliRepeatIntervaljest równe 0 lub brak tego ustawienia, timer się nie uruchamia lub sprawdza status zbyt rzadko.
- Sprawdź
- Jeśli status to
0 (ReadyForData)a chcesz wyzwolić synchronizację, ustaw go na2:UPDATE core.SqlTableStatuses SET Status = 2 WHERE Name IN ('SyncUserProfiles', 'SyncOUInstances') - Czekaj
RepeatIntervalsekund na uruchomienie timera (np. jeśli RepeatInterval=60, czekaj minutę)
Użytkownicy lub OU nie są synchronizowani
Przyczyny:
- Brakujące dane w tabelach przejściowych
- Hierarchia OU jest uszkodzona (OU nadrzędna nie istnieje)
- Przypisania użytkowników (
SyncOUInstanceUsers) są niekompletne - Identyfikatory użytkowników nie zgadzają się między tabelami
Rozwiązanie:
- Sprawdź dane w
SyncUserProfilesiSyncOUInstances— czy wszystkie wymagane pola są wypełnione - Zweryfikuj hierarchię OU — wszystkie OU nadrzędne muszą być zdefiniowane
- Sprawdź przypisania w
SyncOUInstanceUsers— czy użytkownicy są przypisani do OU - Porównaj wartości identyfikatorów między tabelami
Błędy synchronizacji — status Error
Przyczyny:
- Naruszenie integralności danych (duplikaty UserId lub OrgUnitId, wartości NULL w wymaganych polach)
- Uszkodzona hierarchia (ParentId wskazuje na nieistniejący rekord)
- Konflikt z istniejącymi danymi w tabelach docelowych
- Problem z uprawnieniami bazy danych dla TaskService
Rozwiązanie:
- Odczytaj komunikat błędu z logów TaskService
- Wyczyść dane tabel przejściowych i spróbuj ponownie załadować dane (bezpiecznie dla relacji FK):
DELETE FROM core.SyncOUInstanceUsers; DELETE FROM core.SyncUserProfiles; DELETE FROM core.SyncOUInstances; - Zweryfikuj integrację danych przed załadowaniem:
- Czy
UserIdsą unikalne wSyncUserProfiles? - Czy
OrgUnitIdsą unikalne wSyncOUInstances? - Czy wszystkie
ParentIdwSyncOUInstanceswskazują na istniejąceOrgUnitId? - Czy wszyscy użytkownicy w
SyncOUInstanceUsersistnieją wSyncUserProfiles?
- Czy
- Jeśli problem utrzymuje się, zweryfikuj konta bazy danych — czy TaskService ma uprawnienia do odczytu i zapisu
Deaktywowani użytkownicy utracili dostęp
Przyczyna:
- Uruchomiono synchronizację w trybie Full lub Update, a użytkowników nie ma w danych źródłowych
Rozwiązanie:
- Sprawdź, czy użytkownicy faktycznie powinni być deaktywowani
- Jeśli deaktywacja była błędem, przywróć dane z kopii zapasowej
- Zmień tryb synchronizacji na bardziej konserwatywny (np. Update zamiast Full)
- Jeśli to możliwe, skonfiguruj filtrowanie na poziomie TaskService, aby nie deaktywować wybranych użytkowników
Przypisania użytkowników do OU nie są synchronizowane
Przyczyny:
- Dane w
SyncOUInstanceUserssą załadowane, ale statusSyncOUInstancesjest0 (ReadyForData)— synchronizacja nie została uruchomiona - Uszkodzone referencje FK —
UserIdlubOrgUnitIdwSyncOUInstanceUserswskazują na nieistniejące rekordy - Luka w danych — niektórych użytkowników lub OU nie ma w
SyncUserProfileslubSyncOUInstances
Rozwiązanie:
- Upewnij się, że status
SyncOUInstancesto2 (ReadyForSync)— przypisania są przetwarzane razem z OU - Sprawdź integrość danych (patrz skrypt walidacji FK w sekcji Przydatne skrypty SQL)
- Jeśli wszystkie dane są prawidłowe, ale przypisania nie zostały zsynchronizowane, poczekaj aż synchronizacja przejdzie do statusu
3 (InSync) - Sprawdź logi TaskService
Przyczyna (w wersji wcześniejszej):
- W starszych wersjach nAxiom przed wersją 1.15.6.4 synchronizacja agresywnie czyszczała przypisania użytkowników do OU
Rozwiązanie:
- Upewnij się, że korzystasz z wersji 1.15.6.4 lub nowszej, która zawiera poprawkę
- Przy aktualizacji z wersji starszej przywróć przypisania z kopii zapasowej lub przesynchronizuj dane
Synchronizacja wygląda na udaną, ale dane nie są aktualizowane
Przyczyna:
- Status zmienił się na
ReadyForData(0), ale w logach TaskService są błędy - Część danych została zsynchronizowana, część odrzucona z powodu błędów
- Status nie wskazuje na błędy — zmienia się na
ReadyForDataniezależnie od powodzenia
Rozwiązanie:
-
Zawsze sprawdzaj logi TaskService — status
ReadyForDatanie gwarantuje powodzenia - Przejrzyj logi z czasu synchronizacji — szukaj:
- Błędów: “Error”, “Exception”, “Failed”
- Ostrzeżeń: “Warning”, “skipped”, “ignored”
- Liczby przetworzonych vs. załadowanych rekordów — czy się zgadzają?
- Porównaj dane w tabelach docelowych (
UserProfiles,OUInstances) z liczbą w tabelach przejściowych — jeśli liczby się nie zgadzają, część danych została odrzucona - Sprawdź szczegóły błędów w logach — mogą wskazywać na:
- Duplikaty klucza w danych źródłowych
- Naruszenia integralności danych (NULL w wymaganych polach)
- Konflikty z istniejącymi danymi
Praktyka bezpieczna:
- Po każdej synchronizacji odczekaj kilka minut
- Sprawdzaj status — czy zmienił się na
0 (ReadyForData) - Przejrzyj logi TaskService z ostatniego okresu (co najmniej 10 minut wstecz)
- Sprawdź liczbę rekordów:
-- Liczba w tabelach przejściowych SELECT COUNT(*) FROM core.SyncUserProfiles; SELECT COUNT(*) FROM core.SyncOUInstances; -- Liczba w tabelach docelowych SELECT COUNT(*) FROM core.UserProfiles; SELECT COUNT(*) FROM core.OUInstances; - Jeśli liczby się nie zgadzają lub są błędy w logach — przeprowadź diagnostykę
Timer TaskService nie wyzwala synchronizacji mimo ustawienia ReadyForSync
Przyczyny:
- Timer nie jest uruchomiony (serwis nie startuje, zawiesił się)
- Konfiguracja
RepeatIntervaljest ustawiona na 0 lub bardzo dużą wartość - Serwis TaskService ma błędy w logach, które uniemożliwiają działanie timera
Rozwiązanie:
- Sprawdź, czy TaskService jest aktywny — czy serwis uruchamia się, czy ma statusu “running”
- Przeczytaj logi TaskService z ostatnich minut — szukaj błędów wokół “StructureSynchronizationConnector”, “SynchronizeStructure”
- Sprawdź konfigurację
RepeatIntervalw konfiguracji tenanta, w sekcjiStructureSynchronizationConfiguration. JeśliRepeatIntervalwynosi 0 lub brak tego ustawienia, timer się nie uruchamia. Zmień wartość na rozsądną (60-300 sekund) i zrestartuj TaskService. - Jeśli timer startuje ale nie reaguje, spróbuj zrestartować serwis TaskService
- Jeśli problem utrzymuje się, sprawdź czy nie ma deadlocka w bazie — czy inne procesy blokują
SqlTableStatuses
Przydatne skrypty SQL
Sprawdzenie statusów synchronizacji
-- Pokaż aktualny status każdej tabeli synchronizacyjnej
SELECT Name, Status,
CASE Status
WHEN 0 THEN 'ReadyForData'
WHEN 1 THEN 'DataInput'
WHEN 2 THEN 'ReadyForSync'
WHEN 3 THEN 'InSync'
WHEN 4 THEN 'Error'
ELSE 'Unknown'
END AS StatusName
FROM core.SqlTableStatuses
WHERE Name IN ('SyncUserProfiles', 'SyncOUInstances')
ORDER BY Name;
Liczba załadowanych danych
-- Liczba rekordów w tabelach synchronizacyjnych
SELECT
'SyncUserProfiles' AS TableName, COUNT(*) AS RecordCount FROM core.SyncUserProfiles
UNION ALL
SELECT 'SyncOUInstances', COUNT(*) FROM core.SyncOUInstances
UNION ALL
SELECT 'SyncOUInstanceUsers', COUNT(*) FROM core.SyncOUInstanceUsers;
Walidacja integracji danych
-- Sprawdzenie duplikatów UserId
SELECT UserId, COUNT(*) AS DupCount
FROM core.SyncUserProfiles
GROUP BY UserId
HAVING COUNT(*) > 1;
-- Sprawdzenie duplikatów OrgUnitId
SELECT OrgUnitId, COUNT(*) AS DupCount
FROM core.SyncOUInstances
GROUP BY OrgUnitId
HAVING COUNT(*) > 1;
-- Sprawdzenie, czy ParentId w OU wskazują na istniejące OrgUnitId
SELECT DISTINCT ParentId
FROM core.SyncOUInstances
WHERE ParentId IS NOT NULL
AND ParentId NOT IN (SELECT OrgUnitId FROM core.SyncOUInstances);
-- Sprawdzenie, czy wszyscy użytkownicy w przypisaniach istnieją
SELECT DISTINCT u.UserId
FROM core.SyncOUInstanceUsers u
WHERE u.UserId NOT IN (SELECT UserId FROM core.SyncUserProfiles);
-- Sprawdzenie, czy wszystkie OU w przypisaniach istnieją
SELECT DISTINCT o.OrgUnitId
FROM core.SyncOUInstanceUsers o
WHERE o.OrgUnitId NOT IN (SELECT OrgUnitId FROM core.SyncOUInstances);
Resetowanie statusu synchronizacji
-- Ustaw status na ReadyForSync (2) aby wyzwolić synchronizację w następnym cyklu timera
UPDATE core.SqlTableStatuses SET Status = 2 WHERE Name = 'SyncUserProfiles'
UPDATE core.SqlTableStatuses SET Status = 2 WHERE Name = 'SyncOUInstances'
Monitoring timera TaskService i konfiguracji
Aby sprawdzić RepeatInterval w konfiguracji tenanta:
- Szukaj sekcji
StructureSynchronizationConfiguration - Parametr:
RepeatInterval - Wartość w sekundach — jak często timer sprawdza
SqlTableStatuses - Po zmianie
RepeatInterval: zrestartuj TaskService
Wyzwolenie synchronizacji (manual trigger)
-- 1. Załaduj dane (przykład)
DELETE FROM [core].[SyncOUInstanceUsers];
DELETE FROM [core].[SyncUserProfiles];
DELETE FROM [core].[SyncOUInstances];
INSERT INTO [core].[SyncUserProfiles] (UserId, UserName, FirstName, LastName, Email, IsActive, ExpireDate)
VALUES ('user001', 'john.doe', 'John', 'Doe', 'john@company.com', 1, '2026-12-31');
INSERT INTO [core].[SyncOUInstances] (OrgUnitId, Code, Name, IsActive, ActiveFrom, ActiveUntil, ParentId)
VALUES ('IT001', 'IT', 'Information Technology', 1, '2026-01-01', NULL, NULL);
-- 2. Ustaw status na ReadyForSync (2)
UPDATE [core].[SqlTableStatuses] SET Status = 2 WHERE Name = 'SyncUserProfiles';
UPDATE [core].[SqlTableStatuses] SET Status = 2 WHERE Name = 'SyncOUInstances';
-- 3. Czekaj RepeatInterval sekund — timer TaskService wyzwoli synchronizację
-- 4. Sprawdzaj status:
SELECT Name, Status,
CASE Status
WHEN 0 THEN 'ReadyForData (gotowe)'
WHEN 1 THEN 'DataInput (ładowanie)'
WHEN 2 THEN 'ReadyForSync (czeka na timer)'
WHEN 3 THEN 'InSync (synchronizacja w trakcie)'
WHEN 4 THEN 'Error (błąd)'
END AS StatusText
FROM [core].[SqlTableStatuses]
WHERE Name IN ('SyncUserProfiles', 'SyncOUInstances');
Czyszczenie tabel (UWAGA: nieodwracalne!)
-- Usuń wszystkie dane z tabel synchronizacyjnych
-- UWAGA: Najpierw wykonaj kopię zapasową!
DELETE FROM core.SyncOUInstanceUsers;
DELETE FROM core.SyncUserProfiles;
DELETE FROM core.SyncOUInstances;
Bezpieczne praktyki
- Zawsze wykonaj kopię zapasową przed uruchomieniem synchronizacji w trybie Full
- Testuj na środowisku testowym przed wdrożeniem na produkcji
- Monitoruj logi TaskService — status
ReadyForDatanie gwarantuje powodzenia synchronizacji; zawsze sprawdzaj logi pod kątem błędów- Sprawdzaj liczę rekordów po synchronizacji — porównaj dane w tabelach przejściowych z tabelami docelowymi
- Dokumentuj zmiany — kiedy przeprowadzono synchronizację, w jakim trybie, jakie były wyniki (szczególnie czy były błędy w logach)
- Waliduj dane źródłowe przed załadowaniem do tabel przejściowych — brakujące lub nieprawidłowe dane mogą prowadzić do niespójności struktury
- Regularne przeglądy logów — ustaw proces monitorowania logów TaskService (np. codzienne przeglądy, alerting na błędy)
Powiązane tematy: