---
title: "Workerul a murit. Sincronizarea, nu."
description: "Oprește forțat workerul în mijlocul unui lot și urmărește un contact: ce cursor a fost salvat, de ce scrierea reluată nu ajunge de două ori, cine deține sincronizarea cât timp repornește. Apoi cele două incidente care au arătat că recuperarea era doar jumătate din treabă."
url: https://tajo.io/ro/blog/worker-died-sync-didnt/
markdown: https://tajo.io/ro/blog/worker-died-sync-didnt.md
lang: ro-RO
author: "Set Noa"
author_url: https://tajo.io/ro/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, pl-PL: /pl/blog/worker-died-sync-didnt.md, pt-BR: /pt/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}
---

[Sincronizarea datelor](https://tajo.io/ro/blog/?category=data-sync)

# Workerul a murit. Sincronizarea, nu.

Oprește forțat workerul în mijlocul unui lot și urmărește un contact: ce cursor a fost salvat, de ce scrierea reluată nu ajunge de două ori, cine deține sincronizarea cât timp repornește. Apoi cele două incidente care au arătat că recuperarea era doar jumătate din treabă.

recuperare după eșecul sincronizării

Ce se întâmplă cu o sincronizare în curs când workerul moare în mijlocul unui lot?

Cursorul avansează doar la finalul unui lot fără erori, așa că un worker oprit forțat în mijlocul unui lot îl lasă la începutul acelui lot, iar următoarea rulare citește aceeași pagină. Cheia de livrare a fiecărei înregistrări este derivată din cursorul paginii și din poziția ei, iar un registru de șapte zile al scrierilor finalizate împiedică reluarea să ajungă de două ori. O singură concesiune temporară pe sincronizare împiedică două rulări să lucreze în același timp. Asta era jumătatea ușoară. O sincronizare a tot eșuat, rulare după rulare, până ca ceva să o pună pe pauză, iar un spațiu de lucru a stat în tăcere, cu erori și fără niciun succes, până ca ceva să observe. Așa că acum există un disjunctor care pune pe pauză după cinci eșecuri consecutive și o alertă orară după douăzeci și patru de ore fără niciun succes.

[Află mai mult](https://tajo.io/ro/blog/worker-died-sync-didnt/#urm%C4%83re%C8%99te-un-contact)

Într-o [prezentare a echipei de relații cu dezvoltatorii de la Crusoe, publicată pe 3 octombrie 2026 de AI Engineer](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=701s), a fost pornit un job de antrenare PyTorch pe două noduri A100. Apoi chiar sistemului de monitorizare al demonstrației i s-a transmis că un GPU a generat o eroare XID 79. Nodul a fost marcat ca indisponibil, iar jobul a fost anulat. Procesul a primit un SIGTERM și „[până la două minute ca să gestionezi acel SIGTERM, fie ca să îți salvezi checkpointurile, fie ca să îți golești logurile](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=633s)”. A intrat un nod de rezervă, iar „[jobul slurm va reporni. Va încărca checkpointul și va continua antrenarea de unde a rămas](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=769s)”. Puțin sub cincisprezece minute de la un capăt la altul. Nimeni nu a fost chemat de gardă.

O sincronizare este un animal mult mai mic decât o antrenare. Întrebarea este aceeași. De ce are nevoie o rulare pentru ca oprirea forțată a workerului să coste câteva minute și niciun duplicat?

Acesta este răspunsul pentru [motorul de sincronizare al Tajo](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/), citit din cod, nu dintr-o broșură. [Reverse ETL](https://tajo.io/ro/blog/what-is-reverse-etl/) descrie forma muncii. Iată ce se întâmplă când munca moare.

## Urmărește un contact

O rulare citește sursa pagină cu pagină, pornind de la un cursor salvat. Să numim cursorul paginii `c3`, iar contactul nostru a 212-a înregistrare de pe acea pagină. Trei lucruri sunt adevărate despre acest contact înainte să fie scris ceva.

Primul: are o cheie de livrare. Cheia este un hash al id-ului sincronizării, al sursei, al cursorului paginii, al poziției pe pagină și al înregistrării însăși. Cursorul și înregistrarea intră în hash și nu sunt niciodată incluse în cheie, așa că cheia nu conține [nicio adresă de email](https://tajo.io/ro/resources/help/getting-started/understanding-data-sync/).

Al doilea: scrierea trece printr-un [registru](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger), nu direct către destinație. Înainte de apelul către destinație, cheia este revendicată ca fiind în așteptare. Când scrierea reușește, rândul este marcat ca finalizat și păstrat șapte zile.

Al treilea: cursorul nu s-a mișcat. Se mișcă doar la finalul unui lot, doar dacă fiecare înregistrare din acel lot a ajuns și doar după ce rularea a dovedit că încă deține sincronizarea.

Acum oprește forțat workerul între scriere și punctul de control.

La un SIGTERM, fiecare worker de coadă se golește într-un singur termen comun de cincisprezece secunde, iar procesul se închide după douăzeci și cinci de secunde, indiferent ce mai rulează; systemd îi acordă patruzeci și cinci înainte să îl oprească forțat. O rulare care nu s-a încheiat în acea fereastră rămâne marcată ca fiind în curs, iar următorul worker o preia prin mecanismul cozii de recuperare a joburilor blocate. La o oprire brutală nu există nicio golire. În ambele cazuri, rămân valabile aceleași două fapte. Destinația are contactul nostru. [Cursorul](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#cursor) nostru indică încă `c3`.

## Reluarea

Următoarea rulare pornește de la `c3`, citește aceeași pagină, derivă aceeași cheie pentru a 212-a înregistrare și întreabă registrul. Registrul răspunde: finalizat. Destinația nu este apelată; rezultatul stocat este reluat, iar rularea merge mai departe. Pe calea în masă, unde endpointul de import al Brevo primește o pagină întreagă într-un singur apel, aceeași verificare rulează pentru fiecare cheie înainte să fie construită cererea. O pagină în care toate cheile sunt deja finalizate nu trimite nimic.

Acesta e tot trucul și merită spus de ce funcționează. Cheia este derivată din cursorul paginii de la începutul lotului, nu din rularea care se întâmpla să fie în execuție. O cădere, o reîncercare după șaizeci de secunde și o rulare programată mâine [derivă toate aceeași cheie](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger) pentru aceeași înregistrare. Registrului nu îi pasă care dintre ele întreabă.

Acum, costul. [Registrul uită după șapte zile](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger). Chiar comentariul din cod spune că șapte zile acoperă o reîncercare întârziată și o întrerupere scurtă, și nu pretinde mai mult. O reluare de la un cursor mai vechi de atât scrie din nou. Iar o rulare întreruptă brutal poate avea de așteptat. Concesiunea temporară a rulării moarte se poate menține până la cincisprezece minute, iar la o sincronizare programată, o rulare a cărei concesiune temporară este liberă este [preluată de verificarea periodică și reprogramată abia dacă a pornit acum mai bine de o oră](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#stuck-runs). Demonstrația Crusoe [își revine în sub cincisprezece minute](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=753s). A noastră, nu întotdeauna.

## Cine deține sincronizarea cât timp repornește

O singură rulare deține o sincronizare la un moment dat. Rularea ia o [concesiune temporară](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#lease) în Redis cu propriul token, o durată de viață de cincisprezece minute și o reînnoire la fiecare cinci minute. Înainte de fiecare punct de control, verifică faptul că încă deține acea concesiune. Dacă nu o mai deține, se oprește. Rularea este înregistrată cu [propoziția simplă pe care o va citi persoana](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures): „The run lost its slot part-way through and stopped to avoid writing twice.” (Rularea și-a pierdut locul pe parcurs și s-a oprit ca să evite o scriere dublă.) O a doua rulare care se ciocnește de un deținător activ nu este reîncercată. [Se încheie cu](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) „Another run of this sync was already in progress” (O altă rulare a acestei sincronizări era deja în curs), iar următoarea rulare programată pornește normal.

Și responsabilitatea pentru remediere este scrisă. Fiecare [cod de eșec](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) corespunde unei propoziții despre ce s-a întâmplat, uneia despre ce trebuie făcut în continuare și unui responsabil: tu sau Tajo. O destinație care a respins fiecare înregistrare pentru că maparea este greșită ține de tine. O [concesiune temporară pierdută ține de noi](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures). Pagina rulării arată pasul următor; [ghidul de recuperare a sincronizării](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) arată care dintre ele.

Până aici, aceasta este jumătatea ușoară. O cădere costă o reluare și nimic nu ajunge de două ori. Două incidente ne-au învățat cealaltă jumătate.

## Eșec după eșec

O sincronizare a eșuat iar și iar. Nu într-o buclă strânsă: o dată pe interval al planificatorului, rulare după rulare, cu același mesaj de fiecare dată, că un id personalizat nu poate conține două puncte. Rularea nu a ajuns niciodată la destinație. Murea în timp ce era pusă în coadă, înainte ca vreun executor să o vadă, așa că o alertă bazată pe executor nu a avut niciodată pe ce să se bazeze.

Nimic nu urmărea seria. Asta e toată constatarea.

Remedierea este un disjunctor. După fiecare eșec înregistrat, citește ultimele cinci rulări încheiate ale sincronizării de la ultima ei modificare. Dacă toate cinci sunt erori, pune sincronizarea pe pauză, scrie un rând de audit cu motivul `circuit_breaker_tripped` și declanșează o alertă critică. Seria este derivată din rulările stocate, nu dintr-un contor din worker. Contează un eșec înregistrat pe orice cale, inclusiv eșecul de punere în coadă care a cauzat incidentul. Comentariul din cod spune că ar fi oprit acel incident la a cincea rulare. Un singur succes resetează seria. Scoaterea de pe pauză rearmează disjunctorul în loc să îl declanșeze din nou pe baza rândurilor vechi. [Ghidul conectorului Shopify](https://tajo.io/ro/docs/ecommerce-platforms/shopify/) spune același lucru într-un rând: după cinci rulări eșuate consecutive, sincronizarea se pune singură pe pauză, iar pagina ei arată ultima eroare.

Ce nu face disjunctorul este să repare ceva. Crusoe înlocuiește nodul și repornește jobul fără să întrebe. Tajo se oprește și întreabă: o sincronizare pusă pe pauză rămâne pe pauză până când o persoană remediază cauza și [o publică din nou](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#pause). Această setare prudentă implicită este deliberată: o reîncercare automată a unei sincronizări care scrie în înregistrările clienților este ea însăși o scriere.

## Tăcerea pe care n-a văzut-o nimeni

Obiecția este corectă și sună așa: „Un disjunctor care pune pe pauză după cinci eșecuri ar fi prins și al doilea incident. De ce să construiești un al doilea paznic?” Pentru că al doilea incident nu arăta a eșec. Pentru o perioadă lungă, un spațiu de lucru a avut o sincronizare activă, o grămadă tot mai mare de rânduri de eroare și niciun succes, niciodată, și nimic nu a dat alarma. Fiecare semnal existent se baza pe activitate: o rulare a eșuat, a sosit un webhook, a fost depășit un buget. Zero succese nu este un eveniment. Este absența unuia, iar un disjunctor rulează doar când se înregistrează un eșec. Un planificator mort, o coadă blocată, un worker care nu pornește niciodată: niciunul nu înregistrează nimic, iar un disjunctor nu se trezește niciodată.

Dispozitivul de om mort al unei locomotive funcționează invers. Mecanicul trebuie să îl țină apăsat în continuu, iar tăcerea oprește trenul. Versiunea pentru sincronizare [rulează o dată pe oră](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check), la minutul treisprezece. Pentru fiecare spațiu de lucru cu o sincronizare activă pune o singură întrebare: a reușit vreo rulare în ultimele douăzeci și patru de ore? Un spațiu de lucru a cărui cea mai veche sincronizare activă a fost activată acum mai puțin de o zi este lăsat în pace; nu a avut încă o zi la dispoziție ca să reușească. Unul mai vechi și tăcut primește o alertă critică. Alerta spune despre ce tăcere este vorba: rulări înregistrate, dar niciuna reușită, sau nicio rulare înregistrată. Se declanșează o singură dată pe incident. Un marcaj în Redis o ține închisă până la prima rulare reușită, apoi se șterge, astfel încât următorul incident declanșează din nou o alertă.

Ambii paznici au ajuns într-un singur commit, după fapt. Comentariul disjunctorului spune că ar fi oprit primul incident la a cincea rulare. Cel al dispozitivului de om mort spune că o sincronizare activată de mult cu zero rulări trebuie să declanșeze o alertă. Niciunul nu exista când a fost nevoie de el. I-am scris ulterior, cu ambele incidente consemnate în antetul fișierului, ca nimeni să nu uite de ce.

## Ce este construit și ce nu

Construit, la momentul scrierii:

- Cursorul este salvat la finalul fiecărui lot fără erori și încă o dată la o cădere.
- Cheia de livrare a fiecărei înregistrări este derivată din cursorul paginii și din poziția ei și este verificată într-un [registru de șapte zile](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger) înainte de fiecare apel către destinație.
- O singură [concesiune temporară](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#lease) pe sincronizare, cu o durată de viață de cincisprezece minute.
- Cinci [încercări](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#retries) pe rulare, cu așteptare crescătoare pornind de la șaizeci de secunde.
- Un [disjunctor](https://tajo.io/ro/resources/help/getting-started/understanding-data-sync/) care pune sincronizarea pe pauză după cinci eșecuri consecutive și înregistrează motivul.
- O [alertă orară](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check) după douăzeci și patru de ore fără niciun succes.

Neconstruit, și bine de știut înainte să te bazezi pe el:

- Dispozitivul de om mort urmărește spațiul de lucru, nu sincronizarea. O sincronizare sănătoasă ascunde o soră tăcută din același spațiu de lucru.
- Alerta lui [ajunge la operatorii Tajo](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check): întotdeauna un rând de log și, unde sunt configurate, Sentry, un webhook sau un email. Nu apare pe pagina sincronizării. Pauza disjunctorului, da.
- Nimic nu repornește o sincronizare pusă pe pauză. O face o persoană.
- Recuperarea după o oprire brutală nu este rapidă. Concesiunea temporară se poate menține cincisprezece minute, iar [verificarea periodică așteaptă o oră](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#stuck-runs).
- Ambele praguri, cinci eșecuri și douăzeci și patru de ore, sunt [setări ale implementării](https://tajo.io/ro/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#limits). Nu le poți seta pentru fiecare sincronizare în parte.

[Un lanț lung de pași aproape perfecți tot eșuează](https://tajo.io/ro/blog/almost-perfect-steps-unreliable-chain/); ieșirea este să definești starea finală și să o verifici. Acest articol este jumătatea operațională a acestei idei. Definește ce lasă în urmă o rulare moartă și verifică nimicul pe care îl lasă în urmă tăcerea.

Fraza de încheiere a celor de la Crusoe a fost că „[eșecurile sunt inevitabile](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=955s)”. A noastră merge cu un pas mai departe. Căderea era jumătatea ușoară, pentru că lăsa rânduri. Tăcerea era jumătatea pe care a trebuit să o căutăm.

## Întrebări Frecvente

**Ce se întâmplă cu o sincronizare în curs când workerul moare în mijlocul unui lot?**

Cursorul indică în continuare începutul lotului întrerupt, pentru că Tajo îl mută doar după ce un lot ajunge fără erori. Următoarea rulare citește din nou aceeași pagină. Fiecare înregistrare poartă o cheie de livrare derivată din cursorul paginii și din poziția ei, iar un registru păstrează fiecare scriere finalizată timp de șapte zile, așa că înregistrările deja scrise sunt reluate din registru în loc să fie trimise a doua oară către destinație.

**De ce o sincronizare reluată nu scrie de două ori același contact?**

Înainte de fiecare apel către destinație, rularea verifică cheia de livrare a înregistrării într-un registru. Cheia este un hash al sincronizării, al sursei, al cursorului paginii, al poziției pe pagină și al înregistrării însăși, așa că o cădere, o reîncercare un minut mai târziu și o rulare programată a doua zi derivă aceeași cheie pentru aceeași înregistrare. O cheie deja marcată ca finalizată în fereastra de șapte zile nu este trimisă din nou.

**Ce este o alertă de tip om mort pentru o sincronizare?**

O verificare care se declanșează la o absență, nu la un eșec. O dată pe oră, Tajo verifică fiecare spațiu de lucru cu o sincronizare activă și trimite o alertă când nicio rulare nu a reușit în ultimele douăzeci și patru de ore, inclusiv în cazul în care nu a fost înregistrată nicio rulare. Se declanșează o singură dată pe incident și se rearmează după prima rulare reușită. Există pentru că o alertă de eșec poate vedea doar eșecurile care au fost înregistrate.

## Articole similare

### [Șase reguli pentru o sincronizare care rulează când nu se uită nimeni](https://tajo.io/ro/blog/six-rules-unattended-sync/)

6 nov. 2026 · 8 min de citit

7 secțiuni

### [Fluxul de lucru dintre casete](https://tajo.io/ro/blog/the-workflow-between-the-boxes/)

8 oct. 2026 · 4 min de citit

Înregistrare în magazin → Corecție a operatorului → Destinație de email

### [Integrări Brevo: alege o conexiune pe care o poți verifica](https://tajo.io/ro/blog/brevo-connector-guide/)

19 aug. 2026 · 4 min de citit

6 secțiuni
