⚡ MySQL → PostgreSQL Migration Tool

Migrasi data besar dengan mapping kolom, checkpoint otomatis, dan real-time progress

{{ i+1 }} {{ s }}
✓ Setting "{{ currentConfigLabel }}" tersimpan {{ savedConfigAt }}
🕘 Koneksi & Setting Migrasi Tersimpan
🐬 {{ conn.mysql.database }} → 🐘 {{ conn.pg.database }} {{ conn.mysql.host }}
📦 {{ cfg.label }} {{ (cfg.tableMappings || []).length }} tabel {{ new Date(cfg.savedAt).toLocaleString('id-ID') }}
🐬 MySQL
{{ connStatus.mysqlMsg }}
🐘 PostgreSQL
{{ connStatus.pgMsg }}
🗺️ Table Mapping
Klik "Refresh Tables" untuk memuat daftar tabel.
→
Filter WHERE WHERE {{ (mapping.whereConditions || []).filter(c=>c.col).map(c => c.op==='IS NULL'||c.op==='IS NOT NULL' ? '`'+c.col+'` '+c.op : '`'+c.col+'` '+c.op+(c.op==='IN'?' ('+c.val+')':' '+c.val)).join(' AND ') }}
🔧 Column Mapping
{{ m.mysqlTable }} → {{ m.pgTable }}
⏳ Memuat kolom...
row per batch
Kolom PostgreSQL Constraints Sumber Value Kolom MySQL / Config (boleh nama berbeda) Transform Value Map (nilai lama → baru)
{{ col.pgCol }} Tidak di MySQL NOT NULL DEFAULT –
≠ nama berbeda: {{ col.mysqlCol }} → {{ col.pgCol }}
Auto NOW() saat insert
Insert NULL
Kolom ini dilewati
-
→
-
📋 Urutan Migrasi Drag & drop untuk mengatur urutan (parent tabel dulu)
  • ⠿
    {{ idx + 1 }}
    {{ srcOf(item) }}
    → {{ dstOf(item) }}
⚡ Run Migration
Tabel yang dijalankan: {{ selectedRunTables.length }}/{{ migrationOrder.length }} terpilih
⚠️ Pilih minimal 1 tabel untuk dijalankan.
Mode Tabel PG: ⚠️ Data di tabel PG akan dihapus!
🌐 Filter Global Diterapkan (AND) ke semua tabel yang punya kolomnya — tabel tanpa kolom otomatis dilewati. Tersimpan otomatis.
`{{ cond.col }}` {{ cond.op }}{{ ['IS NULL','IS NOT NULL'].includes(cond.op) ? '' : (cond.op==='IN' ? ' ('+cond.val+')' : ' '+cond.val) }}
🔗 FK constraint tidak dilepas. Validasi FK dinonaktifkan sementara selama migrasi via session_replication_role = 'replica' (butuh user PG superuser). Jika user bukan superuser, migrasi tetap jalan dengan FK aktif — perhatikan urutan tabel (parent lebih dulu).
⚡ Performa Insert:
baris
Insert dibagi ke {{ concurrency }} koneksi PG sekaligus, {{ insertChunkSize }} baris/transaksi. Checkpoint disimpan per batch ({{ formatNum(batchSize) }} baris).
📍 Checkpoint Terakhir
Tabel Status Rows Migrated Last PK Cek DB (aktual)
{{ srcOf(t) }} → {{ dstOf(t) }} {{ getCheckpointInfo(t).status }} belum ada checkpoint {{ getCheckpointInfo(t) ? formatNum(getCheckpointInfo(t).total_migrated || 0) : '-' }} {{ getCheckpointInfo(t) ? (getCheckpointInfo(t).last_pk_value ?? '-') : '-' }}
Overall Progress {{ doneTablesCount }}/{{ activeRunOrder.length || migrationOrder.length }} tabel
{{ overallPercent }}%
{{ srcOf(tp.table) }} → {{ tp.pgTable }}
{{ tp.status === 'done' ? '✓ Selesai' : tp.status === 'error' ? '✗ Error' : '⏳ Running' }}
{{ tp.percent }}%
{{ formatNum(tp.totalMigrated) }} / {{ formatNum(tp.totalRows) }} rows {{ formatNum(tp.totalInserted || 0) }} inserted {{ formatNum(tp.totalSkipped) }} updated (PK ada) {{ formatNum(tp.rate) }} row/s ETA: {{ formatETA(tp.eta) }} {{ tp.errorCount }} errors
Live Log
{{ log.time }} {{ log.msg }}
✅ Summary Migrasi
{{ doneTablesCount }}
Tabel Selesai
{{ formatNum(totalInsertedRows) }}
Inserted ke PG
{{ formatNum(totalSkippedRows) }}
Updated (PK sudah ada)
{{ formatNum(totalAdjustedRows) }}
Nilai di-suffix "-id"
{{ totalErrors }}
Total Error
Dibaca dari MySQL: {{ formatNum(totalMigratedRows) }} rows = {{ formatNum(totalInsertedRows) }} inserted + {{ formatNum(totalSkippedRows) }} updated + {{ totalErrors }} error. Angka Inserted yang harus cocok dengan COUNT(*) di tabel target (sudah termasuk {{ formatNum(totalAdjustedRows) }} baris yang nilai unique-nya di-suffix -id agar tetap masuk).
📊 Per Tabel
🔴 Error Log ({{ allErrors.length }})
🔄 Retry Error ({{ tablesWithErrors.length }})
MySQL Table PG Table Rows Dibaca Inserted Di-suffix Updated (PK ada) Errors Status
{{ srcOf(tp.table) }} {{ tp.pgTable }} {{ formatNum(tp.totalMigrated) }} {{ formatNum(tp.totalInserted || 0) }} {{ formatNum(tp.totalAdjusted) }} 0 {{ formatNum(tp.totalSkipped) }} 0 {{ tp.errorCount }} 0 {{ tp.status === 'done' ? '✓ Done' : '⏳ Partial' }}
Tidak ada error! 🎉
# Tabel PK Error Message
{{ i + 1 }} {{ srcOf(e.table) }} {{ e.pk }} {{ e.error }}
Menampilkan {{ filteredErrors.length }} dari {{ allErrors.length }} error
Tidak ada tabel yang perlu di-retry! 🎉
Pilih tabel yang ingin dijalankan ulang. Checkpoint tabel terpilih akan direset, lalu migrasi dijalankan ulang dari awal untuk tabel tersebut.
{{ selectedRetryTables.length }} terpilih
MySQL Table PG Table Rows Migrated Errors Status
{{ srcOf(tp.table) }} {{ tp.pgTable }} {{ formatNum(tp.totalMigrated) }} {{ tp.errorCount }} {{ tp.status === 'done' ? '✓ Done' : '⏳ Partial' }}
🗂 Checkpoint Manager
⏳ Memuat checkpoint...
Belum ada checkpoint. File checkpoint dibuat otomatis saat migrasi berjalan.
{{ checkpointTables.length }}
Total Tabel
{{ checkpointTables.filter(t=>t.status==='done').length }}
Done
{{ checkpointTables.filter(t=>t.status==='in_progress').length }}
In Progress
{{ checkpointTables.filter(t=>t.status==='pending').length }}
Pending
Tabel MySQL Status Last PK Value Total Migrated Errors PK Gagal Aksi
📜 History Aksi
⏳ Memuat history...
Belum ada history aksi yang tercatat.
{{ historyItems.length }} aksi tercatat
Waktu Aksi Detail Status
{{ formatHistoryTime(h.timestamp) }} {{ h.action }} {{ h.detail }} {{ h.status }}