---
title: "Worker-nya mati. Sinkronisasinya tidak."
description: "Matikan worker di tengah batch dan ikuti satu kontak: kursor mana yang tersimpan, mengapa penulisan yang diputar ulang tidak tercatat dua kali, dan siapa yang memegang sinkronisasi selama dimulai ulang. Lalu dua insiden yang menunjukkan bahwa pemulihan baru separuh pekerjaan."
url: https://tajo.io/in/blog/worker-died-sync-didnt/
markdown: https://tajo.io/in/blog/worker-died-sync-didnt.md
lang: id-ID
author: "Set Noa"
author_url: https://tajo.io/in/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, 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, 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}
---

[Sinkronisasi Data](https://tajo.io/in/blog/?category=data-sync)

# Worker-nya mati. Sinkronisasinya tidak.

Matikan worker di tengah batch dan ikuti satu kontak: kursor mana yang tersimpan, mengapa penulisan yang diputar ulang tidak tercatat dua kali, dan siapa yang memegang sinkronisasi selama dimulai ulang. Lalu dua insiden yang menunjukkan bahwa pemulihan baru separuh pekerjaan.

pemulihan kegagalan sinkronisasi data

Apa yang terjadi pada sinkronisasi yang sedang berjalan ketika worker mati di tengah sebuah batch?

Kursor hanya maju di akhir batch yang bersih, sehingga worker yang dimatikan di tengah batch membiarkannya di awal batch tersebut dan eksekusi berikutnya membaca halaman yang sama. Kunci pengiriman setiap record diturunkan dari kursor halaman dan posisinya, dan ledger tujuh hari berisi penulisan yang selesai mencegah replay tercatat dua kali. Satu lease per sinkronisasi mencegah dua eksekusi bekerja bersamaan. Itu separuh yang mudah. Satu sinkronisasi terus gagal, eksekusi demi eksekusi, sebelum ada yang menjedanya, dan sebuah ruang kerja diam dengan error dan tanpa satu pun keberhasilan sebelum ada yang menyadarinya. Jadi kini ada pemutus yang menjeda setelah lima kegagalan berturut-turut dan peringatan per jam untuk dua puluh empat jam tanpa keberhasilan.

[Pelajari selengkapnya](https://tajo.io/in/blog/worker-died-sync-didnt/#ikuti-satu-kontak)

Dalam sebuah [talk yang diterbitkan pada 3 Oktober 2026 oleh AI Engineer](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=701s), seorang developer advocate Crusoe menjalankan job pelatihan PyTorch di dua node A100. Lalu ia memberi tahu sistem pemantauan milik demo itu sendiri bahwa satu GPU telah memunculkan error XID 79. Node ditandai mati dan job dibatalkan. Prosesnya menerima SIGTERM dan “[hingga dua menit untuk menangani SIGTERM itu, entah untuk menyimpan checkpoint Anda atau mem-flush log Anda](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=633s)”. Sebuah node cadangan masuk, dan “[job slurm akan dimulai ulang. Job itu akan memuat checkpoint dan melanjutkan pelatihan dari titik terakhirnya](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=769s)”. Sedikit di bawah lima belas menit dari awal hingga akhir. Tidak ada yang dipanggil.

Sinkronisasi adalah makhluk yang jauh lebih kecil daripada eksekusi pelatihan. Pertanyaannya sama. Apa yang dibutuhkan sebuah eksekusi agar mematikan worker hanya memakan waktu beberapa menit dan tanpa duplikat?

Inilah jawabannya untuk [runner sinkronisasi milik Tajo sendiri](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/), dibaca dari kode, bukan dari brosur. [Reverse ETL](https://tajo.io/in/blog/what-is-reverse-etl/) menjelaskan bentuk pekerjaannya. Artikel ini menjelaskan apa yang terjadi ketika pekerjaan itu mati.

## Ikuti satu kontak

Sebuah eksekusi membaca sumber satu halaman demi satu halaman, mulai dari kursor yang tersimpan. Sebut kursor halaman itu `c3`, dan kontak kita adalah record ke-212 di halaman tersebut. Ada tiga hal yang benar tentang kontak itu sebelum apa pun ditulis.

Pertama, kontak itu memiliki kunci pengiriman. Kunci itu adalah hash dari id sinkronisasi, sumber, kursor halaman, posisi di halaman, dan record itu sendiri. Kursor dan record masuk ke dalam hash dan tidak pernah disematkan di dalam kunci, sehingga kunci [tidak membawa alamat email apa pun](https://tajo.io/in/resources/help/getting-started/understanding-data-sync/).

Kedua, penulisan melewati sebuah [ledger](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger), tidak langsung ke tujuan. Sebelum tujuan dipanggil, kunci diklaim dengan status tertunda. Saat penulisan berhasil, baris itu ditandai selesai dan disimpan selama tujuh hari.

Ketiga, kursor belum bergerak. Kursor hanya bergerak di akhir batch, hanya jika setiap record dalam batch itu telah mendarat, dan hanya setelah eksekusi membuktikan bahwa ia masih memegang sinkronisasi tersebut.

Sekarang matikan worker di antara penulisan dan checkpoint.

Saat menerima SIGTERM, setiap worker antrean dikosongkan dalam satu tenggat bersama lima belas detik, dan proses keluar setelah dua puluh lima detik apa pun yang masih berjalan; systemd memberinya empat puluh lima detik sebelum mematikannya paksa. Eksekusi yang tidak selesai dalam jendela itu tetap ditandai sedang berjalan, dan worker berikutnya mengambilnya melalui pemulihan job macet milik antrean. Pada hard kill tidak ada pengosongan sama sekali. Bagaimanapun juga, dua fakta yang sama tetap berlaku. Tujuan sudah memiliki kontak kita. [Kursor](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#cursor) kita masih menunjukkan `c3`.

## Replay

Eksekusi berikutnya dimulai di `c3`, membaca halaman yang sama, menurunkan kunci yang sama untuk record ke-212, dan bertanya kepada ledger. Ledger menjawab: selesai. Tujuan tidak dipanggil; hasil yang tersimpan diputar ulang dan eksekusi berlanjut. Pada jalur bulk, tempat endpoint impor Brevo menerima satu halaman penuh dalam satu panggilan, pemeriksaan yang sama dijalankan untuk setiap kunci sebelum permintaan dibangun. Halaman yang semua kuncinya sudah selesai tidak mengirim apa pun.

Itulah seluruh triknya, dan penting untuk menjelaskan mengapa trik ini berhasil. Kunci diturunkan dari kursor halaman di awal batch, bukan dari eksekusi yang kebetulan sedang berjalan. Crash, percobaan ulang enam puluh detik kemudian, dan eksekusi terjadwal besok semuanya [menurunkan kunci yang sama](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger) untuk record yang sama. Ledger tidak peduli siapa di antara mereka yang bertanya.

Sekarang biayanya. [Ledger lupa setelah tujuh hari](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger). Komentar di kode itu sendiri mengatakan bahwa tujuh hari mencakup percobaan ulang yang tertunda dan gangguan singkat, dan hanya itu yang diklaimnya. Replay dari kursor yang lebih tua dari itu akan menulis lagi. Dan eksekusi yang terputus secara paksa bisa harus menunggu. Lease milik eksekusi yang mati bertahan hingga lima belas menit, dan pada sinkronisasi terjadwal, eksekusi yang lease-nya sudah bebas [baru disapu dan dijadwalkan ulang jika sudah dimulai lebih dari satu jam yang lalu](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#stuck-runs). Demo Crusoe [pulih dalam waktu kurang dari lima belas menit](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=753s). Milik kami tidak selalu.

## Siapa yang memegang sinkronisasi selama dimulai ulang

Satu sinkronisasi hanya dipegang oleh satu eksekusi pada satu waktu. Eksekusi mengambil [lease](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#lease) di Redis dengan tokennya sendiri, masa berlaku lima belas menit, dan perpanjangan setiap lima menit. Sebelum setiap checkpoint, eksekusi memastikan bahwa ia masih memegang lease itu. Jika tidak, ia berhenti. Eksekusi itu dicatat dengan [kalimat sederhana yang akan dibaca orang](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures): “The run lost its slot part-way through and stopped to avoid writing twice.” (Eksekusi kehilangan slotnya di tengah jalan dan berhenti agar tidak menulis dua kali.) Eksekusi kedua yang bertabrakan dengan pemegang yang masih aktif tidak dicoba ulang. Eksekusi itu [berakhir dengan](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) “Another run of this sync was already in progress” (Eksekusi lain dari sinkronisasi ini sudah berjalan), dan eksekusi terjadwal berikutnya dimulai seperti biasa.

Siapa yang bertanggung jawab memperbaiki juga dituliskan. Setiap [kode kegagalan](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) dipetakan ke satu kalimat tentang apa yang terjadi, satu kalimat tentang langkah selanjutnya, dan seorang pemilik: Anda atau Tajo. Tujuan yang menolak setiap record karena pemetaannya salah adalah tanggung jawab Anda. [Lease yang hilang adalah tanggung jawab kami](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures). Halaman eksekusi menunjukkan langkah berikutnya; [panduan pemulihan sinkronisasi](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#failures) mencantumkan yang mana.

Sejauh ini ini adalah separuh yang mudah. Sebuah crash memakan satu replay dan tidak ada yang tercatat dua kali. Dua insiden mengajarkan separuh lainnya.

## Gagal demi gagal

Satu sinkronisasi gagal berulang kali. Bukan dalam loop yang rapat: sekali per interval penjadwal, eksekusi demi eksekusi, dengan pesan yang sama setiap kali, yaitu bahwa id kustom tidak boleh mengandung titik dua. Eksekusi itu tidak pernah mencapai tujuan. Ia mati saat dimasukkan ke antrean, sebelum runner mana pun melihatnya, sehingga peringatan yang dikaitkan dengan runner tidak pernah punya apa pun untuk dikaitkan.

Tidak ada yang mengawasi rentetan itu. Itulah seluruh temuannya.

Perbaikannya adalah sebuah pemutus. Setelah setiap kegagalan yang tercatat, pemutus membaca lima eksekusi terakhir sinkronisasi yang telah selesai sejak sinkronisasi itu terakhir diubah. Jika kelimanya error, pemutus menjeda sinkronisasi, menulis satu baris audit dengan alasan `circuit_breaker_tripped`, dan membunyikan satu peringatan kritis. Rentetan itu diturunkan dari eksekusi yang tersimpan, bukan dari penghitung di dalam worker. Kegagalan yang dicatat lewat jalur mana pun ikut dihitung, termasuk kegagalan saat masuk antrean yang menyebabkan insiden itu. Komentar di kode mengatakan bahwa pemutus ini akan menghentikan insiden itu pada eksekusi kelima. Satu keberhasilan mengatur ulang rentetan. Mengakhiri jeda akan mengaktifkan kembali pemutus alih-alih membuatnya terpicu lagi oleh baris-baris lama. [Panduan konektor Shopify](https://tajo.io/in/docs/ecommerce-platforms/shopify/) mengatakan hal yang sama dalam satu baris: setelah lima eksekusi gagal berturut-turut, sinkronisasi menjeda dirinya sendiri dan halamannya menampilkan error terakhir.

Yang tidak dilakukan pemutus adalah memperbaiki apa pun. Crusoe mengganti node dan memulai ulang job tanpa bertanya. Tajo berhenti dan bertanya: sinkronisasi yang dijeda tetap dijeda sampai seseorang memperbaiki penyebabnya dan [menerbitkannya lagi](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#pause). Bawaan yang hati-hati ini disengaja: percobaan ulang otomatis untuk sinkronisasi yang menulis ke record pelanggan itu sendiri adalah sebuah penulisan.

## Keheningan yang tidak dilihat siapa pun

Keberatannya wajar, dan bunyinya begini: “Pemutus yang menjeda setelah lima kegagalan juga akan menangkap insiden kedua. Mengapa membangun pengawas kedua?” Karena insiden kedua tidak terlihat seperti kegagalan. Untuk waktu yang lama, sebuah ruang kerja memiliki sinkronisasi aktif, tumpukan baris error yang terus bertambah, dan tidak satu pun keberhasilan, sama sekali, dan tidak ada yang memberi peringatan. Setiap sinyal yang ada dikaitkan dengan aktivitas: eksekusi gagal, webhook datang, anggaran terlampaui. Nol keberhasilan bukanlah sebuah peristiwa. Itu adalah ketiadaan peristiwa, dan pemutus hanya berjalan ketika sebuah kegagalan tercatat. Penjadwal yang mati, antrean yang macet, worker yang tidak pernah menyala: semua itu tidak mencatat apa pun, dan pemutus tidak pernah terbangun.

Dead man’s handle pada lokomotif bekerja sebaliknya. Masinis harus terus menekannya, dan keheningan menghentikan kereta. Versi sinkronisasinya [berjalan sekali setiap jam](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check), pada menit ketiga belas. Untuk setiap ruang kerja yang memiliki sinkronisasi aktif, ia mengajukan satu pertanyaan: adakah eksekusi yang berhasil dalam dua puluh empat jam terakhir? Ruang kerja yang sinkronisasi aktif tertuanya diaktifkan kurang dari sehari yang lalu dibiarkan; ruang kerja itu belum punya waktu sehari untuk berhasil. Ruang kerja yang lebih tua dan diam mendapat satu peringatan kritis. Peringatan itu menyebutkan jenis keheningannya: ada eksekusi yang tercatat tetapi tidak ada yang berhasil, atau tidak ada eksekusi yang tercatat sama sekali. Peringatan berbunyi sekali per insiden. Sebuah penanda di Redis menahannya tetap tertutup sampai eksekusi pertama yang berhasil, lalu dihapus, sehingga insiden berikutnya memicu peringatan lagi.

Kedua pengawas itu masuk dalam satu commit, setelah kejadian. Komentar pemutus mengatakan bahwa ia akan menghentikan insiden pertama pada eksekusi kelima. Komentar dead man mengatakan bahwa sinkronisasi yang sudah lama diaktifkan dengan nol eksekusi wajib memicu peringatan. Keduanya belum ada ketika dibutuhkan. Kami menulisnya kemudian, dengan kedua insiden dicatat di header file agar tidak ada yang lupa alasannya.

## Apa yang sudah dibangun, dan apa yang belum

Sudah dibangun, per tulisan ini dibuat:

- Kursor disimpan di akhir setiap batch yang bersih, dan sekali lagi saat crash.
- Kunci pengiriman setiap record diturunkan dari kursor halaman dan posisinya, lalu diperiksa terhadap [ledger tujuh hari](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#ledger) sebelum setiap panggilan ke tujuan.
- Satu [lease](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#lease) per sinkronisasi, dengan masa berlaku lima belas menit.
- Lima [percobaan](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#retries) per eksekusi, dengan jeda yang dimulai dari enam puluh detik.
- [Pemutus](https://tajo.io/in/resources/help/getting-started/understanding-data-sync/) yang menjeda sinkronisasi setelah lima kegagalan berturut-turut dan mencatat alasannya.
- [Peringatan per jam](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check) untuk dua puluh empat jam tanpa keberhasilan.

Belum dibangun, dan perlu Anda ketahui sebelum mengandalkannya:

- Dead man mengawasi ruang kerja, bukan sinkronisasi. Satu sinkronisasi yang sehat menyembunyikan saudaranya yang diam di ruang kerja yang sama.
- Peringatannya [sampai ke operator Tajo](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#hourly-check): selalu berupa baris log, dan Sentry, webhook, atau email jika dikonfigurasi. Peringatan itu tidak muncul di halaman sinkronisasi. Jeda dari pemutus muncul di sana.
- Tidak ada yang memulai ulang sinkronisasi yang dijeda. Seseoranglah yang melakukannya.
- Pemulihan setelah hard kill tidak cepat. Lease bisa bertahan lima belas menit dan [penyapuan menunggu satu jam](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#stuck-runs).
- Kedua ambang batas, lima kegagalan dan dua puluh empat jam, adalah [pengaturan deployment](https://tajo.io/in/resources/help/troubleshooting/recover-a-stuck-or-failed-sync/#limits). Anda tidak dapat mengaturnya per sinkronisasi.

[Rangkaian panjang langkah yang nyaris sempurna tetap bisa gagal](https://tajo.io/in/blog/almost-perfect-steps-unreliable-chain/); jalan keluarnya adalah menetapkan keadaan akhir dan memeriksanya. Artikel ini adalah separuh operasionalnya. Tetapkan apa yang ditinggalkan eksekusi yang mati, dan periksa ketiadaan yang ditinggalkan oleh keheningan.

Kalimat penutup Crusoe adalah bahwa “[kegagalan tidak terhindarkan](https://www.youtube.com/watch?v=bRGyYaE0lxI&t=955s)”. Kalimat kami selangkah lebih jauh. Crash adalah separuh yang mudah, karena ia meninggalkan baris. Keheningan adalah separuh yang harus kami cari.

## Pertanyaan yang sering diajukan

**Apa yang terjadi pada sinkronisasi yang sedang berjalan ketika worker mati di tengah sebuah batch?**

Kursor masih menunjuk ke awal batch yang terputus, karena Tajo hanya memajukannya setelah sebuah batch mendarat dengan bersih. Eksekusi berikutnya membaca halaman yang sama lagi. Setiap record membawa kunci pengiriman yang diturunkan dari kursor halaman dan posisinya, dan sebuah ledger menyimpan setiap penulisan yang selesai selama tujuh hari, sehingga record yang sudah ditulis diputar ulang dari ledger alih-alih dikirim ke tujuan untuk kedua kalinya.

**Mengapa sinkronisasi yang diputar ulang tidak menulis kontak yang sama dua kali?**

Sebelum setiap panggilan ke tujuan, eksekusi memeriksa kunci pengiriman record terhadap sebuah ledger. Kunci itu adalah hash dari sinkronisasi, sumber, kursor halaman, posisi di halaman, dan record itu sendiri, sehingga crash, percobaan ulang semenit kemudian, dan eksekusi terjadwal keesokan harinya menurunkan kunci yang sama untuk record yang sama. Kunci yang sudah ditandai selesai dalam jendela tujuh hari tidak dikirim lagi.

**Apa itu dead man alert untuk sinkronisasi?**

Pemeriksaan yang berbunyi karena ketiadaan, bukan karena kegagalan. Sekali setiap jam, Tajo memeriksa setiap ruang kerja yang memiliki sinkronisasi aktif dan memberi peringatan jika tidak ada eksekusi yang berhasil dalam dua puluh empat jam terakhir, termasuk ketika tidak ada eksekusi yang tercatat sama sekali. Peringatan berbunyi sekali per insiden dan aktif kembali setelah eksekusi pertama yang berhasil. Pemeriksaan ini ada karena peringatan kegagalan hanya dapat melihat kegagalan yang tercatat.

## Artikel terkait

### [Enam aturan untuk sinkronisasi yang berjalan saat tidak ada yang mengawasi](https://tajo.io/in/blog/six-rules-unattended-sync/)

6 Nov 2026 · 7 menit baca

7 bagian

### [Alur kerja yang tersembunyi di antara kotak](https://tajo.io/in/blog/the-workflow-between-the-boxes/)

8 Okt 2026 · 4 menit baca

Catatan toko → Koreksi operator → Sistem email

### [Integrasi Brevo: pilih koneksi yang dapat Anda verifikasi](https://tajo.io/in/blog/brevo-connector-guide/)

19 Agu 2026 · 4 menit baca

6 bagian
