본문 바로가기
Node.js

[Node.js] bin log(바이너리 로그) 도입기 BUT FAIL

by yonikim 2021. 4. 22.
728x90

검색서비스 도입을 위해서 커뮤니티 게시물, 댓글 등 테이블의 변경 내역을 Elasitcsearch 에 반영해야 하는데,

매번 ETL 용 Lambda 함수를 돌리기엔 실시간 반영도 어렵고 비효율적이라 판단되었기 때문에 바이너리 로그를 이용하기로 했다.


※ 바이너리 로그란?

MySQL 서버에서 CREATE, DROP, ALTER 같은 DDL 과 INSERT, UPDATE, DELETE 같은 DML 을 통해 데이터에 변화 이벤트가 발생했을 경우, 해당 이벤트를 기록하는 이진 파일이 있는데 이를 바이너리 로그라 한다.
바이너리 로그에는 두가지 중요한 용도가 있는데, 1. 복제 구성에서 사용 2. 특정 시점 복구에 사용 이다.

 

우리의 경우 AWS RDS 를 사용하기 때문에 설정 파일을 건드릴 필요 없지만, 나는 친절하니까

 

※ 바이너리 로그 설정 방법

1. 터미널에서 mysqld_safe 로 시작

$ mysql_safe --defaults-file=/etc/my.conf --user=mysql --log-bin=mysql-bin

 

2. my.conf 설정

$ vi /etc/my.conf

 

 log-bin=mysql-bin # bin log 파일명
 binlog_cache_size=2M # 바이너리 로그 캐시 사이즈
 max_binlog_size=512M # 바이너리 로그 최대 사이즈
 expire_logs_days=10 # 보관기간

 


bin log 서비스 만들기 

(with. Connection Error)


감사하게도 MySql의 이벤트들을 추적할 수 있는 라이브러리를 누군가 만들어놨다.

$ npm install @rodrigogs/mysql-events

 

▷ app.js

const mysql = require('mysql');
const MySQLEvents = require('@rodrigogs/mysql-events');

const program = async () => {
  const connection = mysql.createConnection({
    host: 'localhost',
    user: 'mysql',
    password: 'password',
  });

  const instance = new MySQLEvents(connection, {
    startAtEnd: true,
    excludedSchemas: {
      mysql: true,
    },
  });
  
  await instance.start();
  
  instance.addTrigger({
  	name: 'BinLog',
    expression: '*',
    statement: MySQLEvents.STATEMENTS.ALL,
    onEvent: (event) => {
      console.log(JSON.stringify(event));
      const affectedRows = event.affectedRows;
      const type = event.type;
      const table = event.table;
      
      if (type === 'INSERT') {
      	const row = affectRow.after;
        // Occurred INSERT event...
      }
      if (type === 'UPDATE') {
      	const row = affectRow.after;
        // Occurred UPDATE event...
      }
      if (type === 'DELETE') {
      	const row = affectRow.before;
      	// Occurred DELETE event...
      }
    },
  });
  
  instance.on(MySQLEvents.EVENTS.CONNECTION_ERROR, console.error);
  instance.on(MySQLEvents.EVENTS.ZONGJI_ERROR, console.error);
};

program()
  .then(() => console.log('Start BinLog service'))
  .catch(console.error);


{"error":{"fatal":true,"code":"PROTOCOL_CONNECTION_LOST"},"level":"error","message":"uncaughtException: Connection lost: The server closed the connection.\nError: Connection lost: The server closed the connection.\n at Protocol.end (/opt/node_modules/mysql/lib/protocol/Protocol.js:112:13)\n at Socket. ..." ... }
{"error":{"code":"PROTOCOL_ENQUEUE_AFTER_FATAL_ERROR","fatal":false},"level":"error","message":"uncaughtException: Cannot enqueue Query after fatal error.\nError: Cannot enqueue Query after fatal error. ..." ... }
{"error":{"errno":"ECONNRESET","code":"ECONNRESET","syscall":"read","fatal":true},"level":"error","message":"uncaughtException: read ECONNRESET\nError: read ECONNRESET\n at TCP.onStreamRead (internal/stream_base_commons.js:209:20)" ... }

ERROR 3연타를 맞으며 서비스가 다운됐다. 해결을 위해 열심히 구글링 해봤으나 실패 

728x90