0

CDC (Change Data Capture) dengan go-mysql-replication pada MySQL 8.0.36

CDC atau Change Data Capture adalah metode untuk menangkap/mencatat semua perubahan data pada database, baik itu data UPDATE, DELETE termasuk juga INSERT.

Ada beberapa metode CDC:

  • CDC dengan MySQL trigger
  • CDC dengan Timestamp
  • CDC dengan Binary log

Disini kita akan belajar bagaimana melakukan CDC dengan binary log pada MySQL 8.0.36.

Alur CDC

Contoh CDC dengan binary log, misalkan ada INSERT data baru pada database, maka data INSERT tersebut akan ditangkap/capture/disimpan kedalam log MySQL, yang disebut binary log. Kemudian binary log tersebut dikonsumsi oleh go-mysql-replication (istilahnya pipeline), lalu datanya dikirim ke data warehouse untuk kebutuhan analytics.

Jadi setelah binary log terbuat, go-mysql-replication akan mengkonsumsi / membaca isi file binary log (yang mana berisi statement INSERT, UPDATE dan DELETE). Setelah dibaca, data akan dikirim ke data warehouse.

Namun, disini kita hanya akan belajar sampai go-mysql-replication saja (tidak sampai kirim data ke data warehouse). Di go-mysql-replication kita akan belajar bagaimana membaca isi file binary log menggunakan bahasa pemrograman golang.

Prerequisites

  • MySQL 8.0.36
  • go versi 1.22.1
  • go-mysql-replication versi 1.7.0
  • Ubuntu 22.04

Setup binary log di MySQL

Untuk mengaktifkan binary log, kita harus setup dulu konfigurasinya. Buka file mysqld.conf. Disini saya menggunakan Ubuntu 22.04.

vi /etc/mysql/mysql.conf.d/mysqld.cnf

Lalu tambahkan konfigurasi berikut dibaris paling akhir mysqld.conf

server-id              		= 1
log_bin                        	= /var/log/mysql/mysql-bin.log
binlog_expire_logs_seconds    	= 2592000
max_binlog_size   		= 100M
binlog_row_image		= FULL
binlog_row_metadata		= FULL
binlog_format			= ROW

Penjelasan:

  • server-id, ID unik untuk server MySQL. Diperlukan ketika mengaktifkan binary log.
  • log_bin, dimana file binary log disimpan. Dalam contoh ini, akan disimpan di /var/log/mysql/mysql-bin.log. Maksud dari mysql-bin.log, artinya akan terbuat file dengan incremental number yaitu mysql-bin.000001, mysql-bin.000002, dst.
  • binlog_expire_logs_seconds, berapa lama file binary log disimpan. 259200 seconds artinya hanya 3 hari file binary log akan disimpan. Jika lebih dari itu, maka file lamanya akan dihapus secara otomatis.
  • max_binlog_size, ukuran maksimal pada masing-masing file binary log. Contoh diset 100M, maka file mysql-bin.000001 berukuran maksimal sebesar 100M, mysql-bin.000002 sebesar 100M juga, dst.
  • binlog_row_image, diset FULL agar data sebelum dan sesudah UPDATE disimpan juga ke binary log. Contoh, misal data ‘ABCD’ di UPDATE menjadi ‘DCBA’. Maka ABCD dan DCBA akan tersimpan semua di binary log.

    Kira-kira seperti ini lognya:

  • binlog_row_metadata, diset FULL agar metadata tersimpan juga di binary log. Contoh metadata yang akan tersimpan adalah nama kolom pada database.
  • binlog_format, diset ROW agar semua perubahan per ROW tercapture. Misal kita melakukan UPDATE yang berefek mengubah beberapa rows, dimana kolom class A terdapat 2 rows:
    UPDATE tb_test SET column2='SAMA' WHERE class='A';

    Maka di binary log akan tertulis sebanyak 2 log:


Setelah itu restart mysql

service mysql restart

Cek di MySQL, seharusnya binary log sudah mulai tergenerate:

SHOW MASTER STATUS;
cdc change data capture dengan go-mysql-replication

Contoh diatas, posisi binary log berada pada file mysql-bin.000055 dan posisi (byte) ke 157.

Kita juga bisa lihat di folder /var/log/mysql akan ada file mysql-bin.000055 disana:

binary log d


Download go-mysql-replication

Pastikan go sudah terinstall dulu di komputer kalian. Go yang saya gunakan versi 1.22.1.

Setelah go terinstall, kita siapkan dulu workspace projectnya. Saya akan taruh projectnya di /home/<user>/my_go_project.

cd /home/moko/
mkdir my_go_project
cd my_go_project

Lalu init dulu go projectnya. Saya beri nama projectnya go-mysql-replication

go mod init go-mysql-replication

Download go-mysql-replication versi 1.7.0

go get github.com/go-mysql-org/go-mysql@v1.7.0
install go-mysql-replication

Test go-mysql-replication

Sekarang lanjut ke codingan. Contoh codingannya sudah ada digithub officialnya disini.

Kita buat 1 file dengan nama main.go. Lalu masukkan script dibawah ini. Yang diblock tebal harap sesuaikan dengan credential mysql kalian. ServerID=100 adalah ID server untuk go-mysql-replication, kalian bisa ubah IDnya sesuka kalian (kecuali ID 1, karena sudah dipakai diatas).

Kemudian set posisi binary lognya ke mysql-bin.000055 dan 157 sesuai yang diatas.

main.go

package main

import (
	"github.com/go-mysql-org/go-mysql/replication"
	"os"
	"github.com/go-mysql-org/go-mysql/mysql"
	"context"
	"time"
)


func main() {
	// Create a binlog syncer with a unique server id, the server id must be different from other MySQL's. 
	// flavor is mysql or mariadb
	cfg := replication.BinlogSyncerConfig {
		ServerID: 100,
		Flavor:   "mysql",
		Host:     "127.0.0.1",
		Port:     3306,
		User:     "root",
		Password: "abcd",
	}
	syncer := replication.NewBinlogSyncer(cfg)

	// Start sync with specified binlog file and position
	streamer, _ := syncer.StartSync(mysql.Position{"mysql-bin.000055", 157})

	// or you can start a gtid replication like
	// streamer, _ := syncer.StartSyncGTID(gtidSet)
	// the mysql GTID set likes this "de278ad0-2106-11e4-9f8e-6edd0ca20947:1-2"
	// the mariadb GTID set likes this "0-1-100"

	for {
		ev, _ := streamer.GetEvent(context.Background())
		// Dump event
		ev.Dump(os.Stdout)
	}

	// or we can use a timeout context
	for {
		ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
		ev, err := streamer.GetEvent(ctx)
		cancel()

		if err == context.DeadlineExceeded {
			// meet timeout
			continue
		}

		ev.Dump(os.Stdout)
	}
}

Kemudian jalankan:

go mod tidy
go run main.go

Jika berhasil, maka akan tampil seperti ini:

Change data capture, CDC . go-mysql-replication

Jika kita test INSERT data baru, misal seperti ini:

Maka diterminal akan ada data baru:

Test update data:

Di terminal akan ada data updatenya:

Change data capture row based replication , go-mysql-replication UPDATE stamement, before and after

Test delete data:

change data capture, delete data row based replication, go mysql replication

Kesimpulan

  • Insert data akan tercapture dengan event: WriteRowsEventV2
  • Update data, event: UpdateRowsEventV2
  • Delete data, event: DeleteRowsEventV2


Ditutorial selanjutnya kita akan belajar cara mengextract data dari event WriteRowsEventV2, UpdateRowsEventV2, dan DeleteRowsEventV2. Akan saya update linknya disini.

Ambar Hasbiyatmoko

Hello, I'm web developer. Passionate about programming, web server, and networking.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload the CAPTCHA.