---
title: "Proces roboczy padł. Synchronizacja nie."
description: "Zabij proces roboczy w połowie partii i śledź jeden kontakt: który kursor został zapisany, dlaczego powtórzony zapis nie trafia dwa razy i do kogo należy synchronizacja podczas restartu. A potem dwa incydenty, które pokazały, że odzyskiwanie to tylko połowa zadania."
url: https://tajo.io/pl/blog/worker-died-sync-didnt/
markdown: https://tajo.io/pl/blog/worker-died-sync-didnt.md
lang: pl-PL
author: "Set Noa"
author_url: https://tajo.io/pl/set-noa/
published: 2026-11-05
updated: 2026-11-05
alternates: {en-US: /blog/worker-died-sync-didnt.md, bg-BG: /bg/blog/worker-died-sync-didnt.md, cs-CZ: /cz/blog/worker-died-sync-didnt.md, de-DE: /de/blog/worker-died-sync-didnt.md, da-DK: /dk/blog/worker-died-sync-didnt.md, es-ES: /es/blog/worker-died-sync-didnt.md, fr-FR: /fr/blog/worker-died-sync-didnt.md, el-GR: /gr/blog/worker-died-sync-didnt.md, hi-IN: /hi/blog/worker-died-sync-didnt.md, id-ID: /in/blog/worker-died-sync-didnt.md, hr-HR: /hr/blog/worker-died-sync-didnt.md, hu-HU: /hu/blog/worker-died-sync-didnt.md, it-IT: /it/blog/worker-died-sync-didnt.md, ja-JP: /jp/blog/worker-died-sync-didnt.md, ko-KR: /kr/blog/worker-died-sync-didnt.md, ar-SA: /ar/blog/worker-died-sync-didnt.md, nl-NL: /nl/blog/worker-died-sync-didnt.md, no-NO: /no/blog/worker-died-sync-didnt.md, pt-BR: /pt/blog/worker-died-sync-didnt.md, ro-RO: /ro/blog/worker-died-sync-didnt.md, ru-RU: /ru/blog/worker-died-sync-didnt.md, sv-SE: /se/blog/worker-died-sync-didnt.md, zh-CN: /zh-cn/blog/worker-died-sync-didnt.md, sl-SI: /sl/blog/worker-died-sync-didnt.md, sr-Latn-RS: /sr/blog/worker-died-sync-didnt.md, th-TH: /th/blog/worker-died-sync-didnt.md, tr-TR: /tr/blog/worker-died-sync-didnt.md, ur-PK: /ur/blog/worker-died-sync-didnt.md, vi-VN: /vi/blog/worker-died-sync-didnt.md, sk-SK: /sk/blog/worker-died-sync-didnt.md}
---

[Synchronizacja danych](https://tajo.io/pl/blog/?category=data-sync)

# Proces roboczy padł. Synchronizacja nie.

Zabij proces roboczy w połowie partii i śledź jeden kontakt: który kursor został zapisany, dlaczego powtórzony zapis nie trafia dwa razy i do kogo należy synchronizacja podczas restartu. A potem dwa incydenty, które pokazały, że odzyskiwanie to tylko połowa zadania.

odzyskiwanie synchronizacji po awarii

Co dzieje się z trwającą synchronizacją, gdy proces roboczy padnie w połowie partii?

Kursor przesuwa się dopiero na końcu czystej partii, więc proces roboczy zabity w jej połowie zostawia go na początku tej partii, a następny przebieg czyta tę samą stronę. Klucz dostarczenia każdego rekordu jest wyprowadzany z kursora strony i jego pozycji, a siedmiodniowy rejestr ukończonych zapisów sprawia, że powtórka nie trafia dwa razy. Jedna dzierżawa na synchronizację nie pozwala, by dwa przebiegi pracowały jednocześnie. To była łatwa połowa. Jedna synchronizacja zawodziła przebieg za przebiegiem, zanim cokolwiek ją wstrzymało, a jedna przestrzeń robocza tkwiła w ciszy, z błędami i bez żadnego sukcesu, zanim cokolwiek to zauważyło. Dlatego jest teraz bezpiecznik, który wstrzymuje synchronizację po pięciu kolejnych awariach, i cogodzinny alert po dwudziestu czterech godzinach bez sukcesu.

[Dowiedz się więcej](https://tajo.io/pl/blog/worker-died-sync-didnt/#%C5%9Bled%C5%BA-jeden-kontakt)

W [wystąpieniu opublikowanym 3 października 2026 przez AI Engineer](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=701s) specjalista ds. relacji z deweloperami z firmy Crusoe uruchamia zadanie treningowe PyTorch na dwóch węzłach A100. Następnie zgłasza własnemu systemowi monitorowania z pokazu, że jedno GPU zwróciło błąd XID 79. Węzeł zostaje oznaczony jako niedostępny, a zadanie anulowane. Proces dostaje SIGTERM i „[do dwóch minut na obsłużenie tego SIGTERM, żeby zapisać punkty kontrolne albo opróżnić logi](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=633s)”. Wchodzi zapasowy węzeł i „[zadanie slurm uruchomi się ponownie. Wczyta punkt kontrolny i będzie kontynuować trening tam, gdzie go przerwało](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=769s)”. Całość zajmuje nieco poniżej piętnastu minut. Nikt nie dostał wezwania alarmowego.

Synchronizacja to znacznie mniejsze zwierzę niż przebieg treningowy. Pytanie jest jednak to samo. Czego potrzebuje przebieg, żeby zabicie procesu roboczego kosztowało minuty i zero duplikatów?

Oto odpowiedź dla [własnego mechanizmu synchronizacji Tajo](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/), odczytana z kodu, a nie z broszury. [Reverse ETL](https://tajo.io/pl/blog/what-is-reverse-etl/) opisuje kształt tego zadania. Tu opisujemy, co się dzieje, gdy to zadanie umiera.

## Śledź jeden kontakt

Przebieg czyta źródło strona po stronie, od zapisanego kursora. Nazwijmy kursor strony `c3`, a nasz kontakt 212. rekordem na tej stronie. Zanim cokolwiek zostanie zapisane, o tym kontakcie prawdziwe są trzy rzeczy.

Po pierwsze, ma klucz dostarczenia. Klucz jest skrótem identyfikatora synchronizacji, źródła, kursora strony, pozycji na stronie i samego rekordu. Kursor i rekord trafiają do skrótu i nigdy nie są osadzane w kluczu, więc klucz [nie zawiera adresu email](https://tajo.io/pl/resources/help/getting-started/understanding-data-sync/).

Po drugie, zapis przechodzi przez [rejestr](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger), a nie prosto do miejsca docelowego. Zanim miejsce docelowe zostanie wywołane, klucz zostaje zajęty ze statusem oczekującym. Gdy zapis się powiedzie, wiersz zostaje oznaczony jako ukończony i jest przechowywany przez siedem dni.

Po trzecie, kursor się nie przesunął. Przesuwa się dopiero na końcu partii, tylko jeśli dotarł każdy rekord z tej partii, i tylko wtedy, gdy przebieg udowodni, że nadal jest właścicielem synchronizacji.

A teraz zabij proces roboczy między zapisem a punktem kontrolnym.

Po SIGTERM każdy proces roboczy kolejki dokańcza bieżącą pracę w ramach jednego wspólnego, piętnastosekundowego terminu, a proces kończy działanie po dwudziestu pięciu sekundach bez względu na to, co jeszcze działa; systemd daje mu czterdzieści pięć, zanim go zabije. Przebieg, który nie skończył się w tym oknie, nadal jest oznaczony jako trwający, a następny proces roboczy przejmuje go dzięki odzyskiwaniu zablokowanych zadań w kolejce. Przy twardym zabiciu nie ma żadnego dokańczania. Tak czy inaczej obowiązują te same dwa fakty. Miejsce docelowe ma nasz kontakt. Nasz [kursor](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#cursor) nadal wskazuje `c3`.

## Powtórka

Następny przebieg startuje od `c3`, czyta tę samą stronę, wyprowadza ten sam klucz dla 212. rekordu i pyta rejestr. Rejestr odpowiada: ukończony. Miejsce docelowe nie jest wywoływane; zapisany wynik zostaje odtworzony, a przebieg idzie dalej. Na ścieżce zbiorczej, gdzie endpoint importu Brevo przyjmuje całą stronę w jednym wywołaniu, ta sama kontrola odbywa się dla każdego klucza, zanim zostanie zbudowane żądanie. Strona, na której każdy klucz jest już ukończony, niczego nie wysyła.

Na tym polega cały trik i warto powiedzieć, dlaczego działa. Klucz jest wyprowadzany z kursora strony na początku partii, a nie z przebiegu, który akurat się wykonywał. Awaria, ponowna próba sześćdziesiąt sekund później i zaplanowany przebieg jutro [wyprowadzają ten sam klucz](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger) dla tego samego rekordu. Rejestrowi jest wszystko jedno, który z nich pyta.

Teraz koszt. [Rejestr zapomina po siedmiu dniach](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger). Komentarz w kodzie mówi, że siedem dni obejmuje opóźnioną ponowną próbę i krótką awarię, i nic ponad to nie twierdzi. Powtórka od kursora starszego niż siedem dni zapisuje ponownie. A przebieg przerwany twardo może poczekać. Dzierżawa martwego przebiegu trwa do piętnastu minut, a w zaplanowanej synchronizacji przebieg z wolną dzierżawą zostaje [uprzątnięty i ponownie zaplanowany dopiero wtedy, gdy wystartował ponad godzinę temu](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#stuck-runs). Pokaz Crusoe [wraca do pracy w niecałe piętnaście minut](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=753s). U nas nie zawsze.

## Do kogo należy synchronizacja podczas restartu

W danym momencie synchronizacja należy do jednego przebiegu. Przebieg bierze [dzierżawę](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#lease) w Redis z własnym tokenem, piętnastominutowym czasem życia i odnowieniem co pięć minut. Przed każdym punktem kontrolnym sprawdza, czy nadal ją trzyma. Jeśli nie, zatrzymuje się. Przebieg zostaje zapisany ze [zwykłym zdaniem, które przeczyta człowiek](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures): „The run lost its slot part-way through and stopped to avoid writing twice.” (Przebieg w trakcie stracił swój slot i zatrzymał się, żeby nie zapisać dwa razy.) Drugi przebieg, który zderzy się z żywym właścicielem, nie jest ponawiany. [Kończy się komunikatem](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) „Another run of this sync was already in progress” (inny przebieg tej synchronizacji już trwał), a następny zaplanowany przebieg startuje normalnie.

Własność naprawy też jest zapisana. Każdy [kod błędu](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) ma jedno zdanie o tym, co się stało, jedno o tym, co zrobić dalej, i właściciela: Ciebie albo Tajo. Miejsce docelowe, które odrzuciło każdy rekord, bo mapowanie jest błędne, to Twoja sprawa. [Utracona dzierżawa to nasza](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures). Strona przebiegu pokazuje następny krok; [przewodnik po odzyskiwaniu synchronizacji](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) wymienia, do kogo należy naprawa.

Na razie to łatwa połowa. Awaria kosztuje jedną powtórkę i nic nie trafia dwa razy. Drugiej połowy nauczyły nas dwa incydenty.

## Awaria za awarią

Jedna synchronizacja zawodziła raz za razem. Nie w ciasnej pętli: raz na interwał harmonogramu, przebieg za przebiegiem, za każdym razem z tym samym komunikatem, że niestandardowy identyfikator nie może zawierać dwukropka. Przebieg nigdy nie dotarł do miejsca docelowego. Umierał podczas kolejkowania, zanim zobaczył go jakikolwiek moduł uruchamiający, więc alert powiązany z modułem uruchamiającym nigdy nie miał na czym się oprzeć.

Nic nie obserwowało tej serii. To całe odkrycie.

Rozwiązaniem jest bezpiecznik. Po każdej zapisanej awarii odczytuje pięć ostatnich zakończonych przebiegów synchronizacji od jej ostatniej zmiany. Jeśli wszystkie pięć to błędy, wstrzymuje synchronizację, zapisuje jeden wiersz audytu z powodem `circuit_breaker_tripped` i wysyła jeden krytyczny alert. Seria jest wyprowadzana z zapisanych przebiegów, a nie z licznika w procesie roboczym. Liczy się awaria zapisana dowolną ścieżką, także awaria kolejkowania, która spowodowała incydent. Komentarz w kodzie mówi, że bezpiecznik zatrzymałby ten incydent na piątym przebiegu. Jeden sukces zeruje serię. Wznowienie wstrzymanej synchronizacji ponownie uzbraja bezpiecznik, zamiast wyzwalać go znowu na starych wierszach. [Przewodnik po konektorze Shopify](https://tajo.io/pl/docs/ecommerce-platforms/shopify/) mówi to samo w jednym zdaniu: po pięciu kolejnych nieudanych przebiegach synchronizacja sama się wstrzymuje, a jej strona pokazuje ostatni błąd.

Bezpiecznik niczego jednak nie naprawia. Crusoe wymienia węzeł i restartuje zadanie bez pytania. Tajo zatrzymuje się i pyta: wstrzymana synchronizacja pozostaje wstrzymana, dopóki człowiek nie usunie przyczyny i nie [opublikuje jej ponownie](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#pause). To ostrożne ustawienie domyślne jest celowe: automatyczne ponowienie synchronizacji, która zapisuje do rekordów klientów, samo jest zapisem.

## Cisza, której nikt nie zauważył

Zarzut jest uczciwy i brzmi tak: „Bezpiecznik, który wstrzymuje po pięciu awariach, złapałby też drugi incydent. Po co budować drugiego strażnika?”. Bo drugi incydent nie wyglądał jak awaria. Przez długi czas pewna przestrzeń robocza miała aktywną synchronizację, rosnący stos wierszy z błędami i ani jednego sukcesu, nigdy, i nic nie wysłało alertu. Każdy istniejący sygnał był powiązany z aktywnością: przebieg się nie powiódł, przyszedł webhook, przekroczono budżet. Zero sukcesów to nie zdarzenie. To brak zdarzenia, a bezpiecznik działa tylko wtedy, gdy zostanie zapisana awaria. Martwy harmonogram, zakleszczona kolejka, proces roboczy, który nigdy nie startuje: nic z tego niczego nie zapisuje, a bezpiecznik nigdy się nie budzi.

Czuwak w lokomotywie działa odwrotnie. Maszynista musi go stale naciskać, a cisza zatrzymuje pociąg. Wersja dla synchronizacji [uruchamia się raz na godzinę](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check), trzynaście minut po pełnej godzinie. Dla każdej przestrzeni roboczej z aktywną synchronizacją zadaje jedno pytanie: czy jakikolwiek przebieg zakończył się sukcesem w ciągu ostatnich dwudziestu czterech godzin? Przestrzeń robocza, której najstarsza aktywna synchronizacja została włączona mniej niż dobę temu, zostaje pominięta; nie miała jeszcze doby na sukces. Starsza i milcząca dostaje jeden krytyczny alert. Alert mówi, o jaką ciszę chodzi: przebiegi są zapisywane, ale żaden się nie udaje, albo nie zapisano żadnego przebiegu. Uruchamia się raz na incydent. Znacznik w Redis blokuje go do pierwszego udanego przebiegu, potem zostaje usunięty, więc następny incydent znowu wywoła alert.

Obaj strażnicy trafili do kodu w jednym commicie, po fakcie. Komentarz bezpiecznika mówi, że zatrzymałby pierwszy incydent na piątym przebiegu. Komentarz czuwaka mówi, że synchronizacja włączona dawno temu z zerową liczbą przebiegów musi wywołać alert. Żaden z nich nie istniał, kiedy był potrzebny. Napisaliśmy je później, z oboma incydentami opisanymi w nagłówku pliku, żeby nikt nie zapomniał, dlaczego.

## Co jest zbudowane, a co nie

Zbudowane w chwili pisania:

- Kursor jest zapisywany na końcu każdej czystej partii i ponownie przy awarii.
- Klucz dostarczenia każdego rekordu jest wyprowadzany z kursora strony i jego pozycji oraz sprawdzany w [siedmiodniowym rejestrze](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger) przed każdym wywołaniem miejsca docelowego.
- Jedna [dzierżawa](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#lease) na synchronizację, z piętnastominutowym czasem życia.
- Pięć [prób](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#retries) na przebieg, z odstępem rosnącym od sześćdziesięciu sekund.
- [Bezpiecznik](https://tajo.io/pl/resources/help/getting-started/understanding-data-sync/), który wstrzymuje synchronizację po pięciu kolejnych awariach i zapisuje powód.
- [Cogodzinny alert](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check) po dwudziestu czterech godzinach bez sukcesu.

Niezbudowane, a warte poznania, zanim zaczniesz na tym polegać:

- Czuwak obserwuje przestrzeń roboczą, a nie synchronizację. Jedna zdrowa synchronizacja ukrywa milczącą sąsiednią synchronizację w tej samej przestrzeni roboczej.
- Jego alert [trafia do operatorów Tajo](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check): zawsze jako wpis w logu, a do Sentry, webhooka lub emaila tam, gdzie są skonfigurowane. Nie pojawia się na stronie synchronizacji. Wstrzymanie przez bezpiecznik się pojawia.
- Nic nie restartuje wstrzymanej synchronizacji. Robi to człowiek.
- Odzyskiwanie po twardym zabiciu nie jest szybkie. Dzierżawa może trwać piętnaście minut, a [przegląd porządkujący czeka godzinę](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#stuck-runs).
- Oba progi, pięć awarii i dwadzieścia cztery godziny, to [ustawienia wdrożenia](https://tajo.io/pl/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#limits). Nie możesz ustawić ich dla pojedynczej synchronizacji.

[Długi łańcuch niemal bezbłędnych kroków i tak zawodzi](https://tajo.io/pl/blog/almost-perfect-steps-unreliable-chain/); wyjściem jest określenie stanu końcowego i sprawdzanie, czy nastąpił. Ten artykuł to operacyjna połowa tamtego. Określ, co zostawia po sobie martwy przebieg, i sprawdzaj to nic, które zostawia po sobie cisza.

Zamykające zdanie Crusoe brzmiało: „[awarie są nieuniknione](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=955s)”. Nasze idzie o krok dalej. Awaria była łatwą połową, bo zostawiła wiersze. Cisza była tą połową, której musieliśmy szukać.

## Najczęściej Zadawane Pytania

**Co dzieje się z trwającą synchronizacją, gdy proces roboczy padnie w połowie partii?**

Kursor nadal wskazuje początek przerwanej partii, ponieważ Tajo przesuwa go dopiero wtedy, gdy partia zostanie zapisana bez błędów. Następny przebieg ponownie czyta tę samą stronę. Każdy rekord ma klucz dostarczenia wyprowadzony z kursora strony i swojej pozycji, a rejestr przechowuje każdy ukończony zapis przez siedem dni, więc rekordy już zapisane są odtwarzane z rejestru, zamiast trafiać do miejsca docelowego drugi raz.

**Dlaczego powtórzona synchronizacja nie zapisuje tego samego kontaktu dwa razy?**

Przed każdym wywołaniem miejsca docelowego przebieg sprawdza klucz dostarczenia rekordu w rejestrze. Klucz jest skrótem (hashem) synchronizacji, źródła, kursora strony, pozycji na stronie i samego rekordu, więc awaria, ponowna próba minutę później i zaplanowany przebieg następnego dnia wyprowadzają ten sam klucz dla tego samego rekordu. Klucz już oznaczony jako ukończony w siedmiodniowym oknie nie jest wysyłany ponownie.

**Czym jest alert typu czuwak dla synchronizacji?**

To kontrola, która uruchamia się przy braku zdarzenia, a nie przy awarii. Raz na godzinę Tajo sprawdza każdą przestrzeń roboczą z aktywną synchronizacją i wysyła alert, gdy żaden przebieg nie zakończył się sukcesem w ciągu ostatnich dwudziestu czterech godzin, także wtedy, gdy nie zapisano żadnego przebiegu. Uruchamia się raz na incydent i uzbraja się ponownie po pierwszym udanym przebiegu. Istnieje, bo alert o awarii widzi tylko te awarie, które zostały zapisane.

## Powiązane artykuły

### [Sześć zasad dla synchronizacji, która działa, gdy nikt nie patrzy](https://tajo.io/pl/blog/six-rules-unattended-sync/)

6 lis 2026 · 7 min czytania

7 sekcji

### [Proces między polami schematu](https://tajo.io/pl/blog/the-workflow-between-the-boxes/)

8 paź 2026 · 4 min czytania

Rekord sklepu → Poprawka operatora → System e-mailowy

### [Integracje Brevo: wybierz połączenie, które można sprawdzić](https://tajo.io/pl/blog/brevo-connector-guide/)

19 sie 2026 · 3 min czytania

6 sekcji
