이 문서에서는 커밋 타임스탬프 기능을 사용하여 데이터베이스 레코드가 변경된 날짜와 시간을 추적하는 방법을 설명합니다. 레코드를 변경하는 트랜잭션이 많은 대규모 데이터베이스가 있고 데이터 세트의 변경사항을 캡처하려는 경우 커밋 타임스탬프 기능으로 이 작업을 간소화할 수 있습니다.
이 문서에서는 일련의 코드 샘플을 통해 기존 데이터 조작 언어(DML)를 다시 작성하여 변경 로그를 만드는 방법을 보여줍니다. 이 문서는 Cloud Spanner 커밋 타임스탬프를 사용하여 Go로 변경 로그 만들기에서 더 나아가 Java 및 JDBC를 사용하는 메서드를 설명합니다. 로직은 Spanner 클라이언트 객체가 아닌 SQL로 표현됩니다.
테이블 작동 방식
msgs
라는 사실 테이블과 msg_history
라는 기록 테이블이 있다고 가정하겠습니다. 사실 테이블이 수정될 때마다 레코드를 msg_history
테이블에 동시에 저장하려고 합니다. 나중에 감사 또는 이벤트 소스와 같은 다른 용도로 기록 테이블의 콘텐츠를 사용할 수 있습니다.
msgs
테이블에는 트랜잭션 ID(id
)와 메시지(msg
)로 표현되는 사실이 포함됩니다. 테이블을 만드는 데 사용되는 데이터 정의 언어(DDL) 문은 다음과 같습니다.
CREATE TABLE msgs (
id INT64,
msg STRING(MAX),
) PRIMARY KEY (id)
msg_history
테이블에는 트랜잭션 기록이 있습니다. 기록 테이블을 만드는 DDL은 다음과 같습니다. ts
열은 커밋 타임스탬프를 저장합니다.
CREATE TABLE msgs_history (
id INT64,
ts TIMESTAMP OPTIONS (allow_commit_timestamp=true),
previous_msg STRING(MAX)
) PRIMARY KEY (ts, id)
예시
사실 테이블에만 기록하지 않고 동일한 트랜잭션의 기록 테이블에 작업을 수행해야 합니다. Spanner의 JDBC 드라이버는 표준 JDBC 작업인 트랜잭션의 시작과 끝 선언을 지원합니다.
1단계: 삽입 작업 재작성
첫 번째 단계는 다음 양식에서 insert
작업을 다시 작성하는 것입니다.
insert into msgs (id, msg) values (1, 'a real msg')
다음과 같이 삽입을 변경합니다.
insert into msgs_history (id, previous_msg, ts) values (1, Null, PENDING_COMMIT_TIMESTAMP()); insert into msgs (id, msg) values (1, 'a real msg');
자바 코드는 다음과 같습니다.
// insert into history stmt.executeUpdate( "insert into msgs_history (id, previous_msg, ts)" + " values (1, Null, PENDING_COMMIT_TIMESTAMP())"); // insert into real table stmt.executeUpdate("insert into msgs (id, msg)" + " values (1, 'a real msg')"); conn.commit();
2단계: 업데이트 작업 재작성
다음으로, 다음 양식에서 update
작업을 다시 작성합니다.
update msgs set msg = 'new message' where id = 1
다음과 같이 업데이트를 변경합니다.
insert msgs_history (id, previous_msg, ts) values ((select id from msgs where id =1 ), (select msg from msgs where id = 1), PENDING_COMMIT_TIMESTAMP()); update msgs set msg = 'new message' where id = 1;
자바 코드는 다음과 같습니다.
// insert into historystmt.executeUpdate( "insert msgs_history (id, previous_msg, ts)" + " values ((select id from msgs where id =1)," + " (select msg from msgs where id = 1), PENDING_COMMIT_TIMESTAMP())"); // update into fact table stmt.executeUpdate("update msgs set msg = 'new message' where id = 1"); conn.commit();
3단계: 삭제 작업 재작성
마지막으로, 다음 양식에서 delete
작업을 다시 작성합니다.
delete from msgs where id = 1
다음과 같이 삭제를 변경합니다.
insert msgs_history (id, previous_msg, ts) values ((select id from msgs where id =1 ), (select msg from msgs where id = 1), PENDING_COMMIT_TIMESTAMP()); delete from msgs where id = 1;
자바 코드는 다음과 같습니다.
// insert into history stmt.executeUpdate( "insert msgs_history (id, previous_msg, ts)" + " values ((select id from msgs where id =1)," + " (select msg from msgs where id = 1), PENDING_COMMIT_TIMESTAMP()) "); // delete from real table stmt.executeUpdate("delete from msgs where id = 1"); conn.commit();
기록 테이블 사용
다음과 같이 변경 내역에 액세스합니다.
select id,msg,current_timestamp() as ts from msgs where id = 1 union all select id,previous_msg, ts as msg from msgs_history where id = 1 order by ts desc
결과는 다음과 유사합니다.
id msg ts 1 new message 2020-02-07T07:44:10.24833726Z 1 a real msg 2020-01-14T10:07:20.137935Z 1 2020-01-14T10:07:20.070374Z
다음 단계
- Spanner 커밋 타임스탬프 기능에 대해 자세히 알아봅니다.
- Spanner 변경 내역에 대해 자세히 알아보기
- Google Cloud에 대한 참조 아키텍처, 다이어그램, 권장사항 살펴보기 Cloud 아키텍처 센터 살펴보기