과거 데이터 복구, 오라클(Oracle)만 가능한 줄 아셨나요?
데이터베이스(DB)를 운영하다 보면 누군가의 실수로 WHERE 조건 없이 UPDATE나 DELETE 문이 실행되는 끔찍한 사고가 종종 발생합니다. 이럴 때 오라클(Oracle) 사용자들은 AS OF TIMESTAMP라는 마법 같은 플래시백(Flashback) 쿼리를 사용해 손쉽게 과거의 데이터를 조회하고 복구하곤 합니다.
그렇다면 MSSQL(SQL Server) 환경에서 이런 실수가 벌어지면 어떻게 해야 할까요? 예전에는 백업 파일(.bak)을 뒤져서 복원해야 하는 험난한 과정을 거쳐야 했고, 이 때문에 많은 개발자가 "과거 데이터 직접 조회는 오라클만 된다"라고 오해하곤 했습니다.
하지만 실망하지 않으셔도 됩니다! SQL Server 2016 버전부터 도입된 'Temporal Tables (시스템 버전 임시 테이블)' 기능을 활용하면 MSSQL에서도 오라클과 사실상 100% 동일하게 특정 과거 시점의 데이터를 콕 집어 조회할 수 있습니다. 오늘은 이 유용한 기능의 사용법과주의사항을 완벽하게 정리해 보겠습니다.
1. 오라클과 MSSQL의 아키텍처 차이점
명령어를 알아보기 전에, 두 DB가 과거 데이터를 다루는 방식의 차이를 먼저 이해해야 합니다.
오라클은 데이터가 변경될 때 기본적으로 언두(Undo) 데이터라는 임시 보관소에 과거 기록을 남겨둡니다. 그래서 별도의 설정 없이도 골든타임(Undo Retention 시간) 내라면 언제든 과거를 조회할 수 있습니다.
반면, MSSQL의 기본 아키텍처는 다릅니다. MSSQL에서 과거 데이터를 조회하려면 DBA나 관리자가 해당 테이블에 미리 Temporal Table(시스템 버전 관리) 기능을 활성화(ON) 해두어야 합니다. 이 기능이 켜져 있는 테이블에 한해서만 변경 이력이 전용 히스토리 테이블에 차곡차곡 쌓이게 되고, 우리는 이 히스토리 테이블을 통해 과거로 시간 여행을 할 수 있게 됩니다.
2. MSSQL 과거 데이터 조회 쿼리문 작성법
기능이 활성화되어 있다는 가정하에, 과거 시점의 데이터를 조회하는 쿼리문은 오라클과 매우 흡사합니다. 오라클이 AS OF TIMESTAMP를 쓴다면, MSSQL은 FOR SYSTEM_TIME AS OF 구문을 사용합니다.
예를 들어, 현재 시점에서 '정확히 50분 전'의 데이터 상태를 확인하고 싶다면 아래와 같이 쿼리를 작성합니다.
| SELECT * FROM TABLE명 FOR SYSTEM_TIME AS OF DATEADD(minute, -50, SYSUTCDATETIME()); |
3. 쿼리 작성 시 반드시 알아야 할 주의사항 (핵심 ⭐)
① 시간 계산 함수: interval 대신 DATEADD 사용
오라클에서는 시간을 뺄 때 interval '50' minute 같은 직관적인 문법을 사용하지만, MSSQL에서는 기본 내장 함수인 DATEADD를 사용해야 합니다.
DATEADD(단위, 더하거나 뺄 숫자, 기준시간) 형태로 작성하며, 50분 전이라면 DATEADD(minute, -50, 현재시간)으로 표기합니다.
② UTC 시간 사용의 함정 (GETDATE() 사용 금지!)
여기가 가장 많은 실무자가 실수하는 부분입니다. MSSQL의 Temporal Table은 데이터를 히스토리에 저장할 때 로컬 시간이 아닌 협정 세계시(UTC)를 기준으로 기록합니다.
따라서 우리가 평소 현재 시간을 구할 때 자주 쓰는 GETDATE() 함수(한국 시간 기준)를 넣어서 50분을 빼버리면, 시스템에 기록된 UTC 시간과 무려 9시간이나 차이가 나기 때문에 데이터가 아예 안 나오거나 엉뚱한 시점의 결과가 나옵니다.
반드시 한국 시간이 아닌 시스템의 UTC 현재 시간을 불러오는 SYSUTCDATETIME() 함수를 사용해야 정확히 50분 전의 과거로 돌아갈 수 있습니다.