TTL로 데이터 보관 관리

이 페이지에서는 Spanner 테이블에서 TTL(수명)을 사용하는 방법을 설명합니다. 자세한 내용은 TTL 정보를 참조하세요.

시작하기 전에

시작하기 전에 다음 권장사항을 따르세요.

백업 및 PITR(point-in-time recovery) 사용 설정

TTL을 테이블에 추가하기 전에 Spanner 백업 및 복원을 사용 설정하는 것이 좋습니다. 이에 따라 TTL 정책을 사용하여 데이터를 실수로 삭제한 경우 데이터베이스를 완전히 복원할 수 있습니다.

PITR(point-in-time recovery)을 사용 설정한 경우 구성된 버전 보관 기간 내에 있으면 백업에서 전체 복원을 수행하지 않고도 삭제된 데이터를 보고 복원할 수 있습니다. 과거 데이터 읽기에 대한 자세한 내용은 비활성 읽기 수행을 참조하세요.

이전 데이터 정리

TTL을 처음 사용하고 첫 번째 실행에서 많은 행이 삭제될 것으로 예상되는 경우 먼저 파티션을 나눈 DML을 통해 이전 데이터를 수동으로 삭제하는 것이 좋습니다. 이렇게 하면 리소스 사용량을 TTL 백그라운드 프로세스에 두지 않아도 리소스 사용량을 보다 세부적으로 제어할 수 있습니다. TTL은 낮은 우선순위로 실행되며 증분 정리에 적합합니다. 그러나 Spanner의 내부 작업 스케줄러가 사용자 쿼리와 같은 다른 작업의 우선순위를 두기 때문에 사용량이 많은 데이터베이스의 초기 행 집합을 삭제하는 데 시간이 오래 걸릴 수 있습니다.

조건 확인

GoogleSQL 테이블의 경우 TTL을 사용 설정하기 전에 행 삭제 정책에 영향을 받는 데이터를 확인하려면 동일한 조건을 사용하여 테이블을 쿼리하면 됩니다. 예를 들면 다음과 같습니다.

GoogleSQL

  SELECT COUNT(*)
  FROM CalculatedRoutes
  WHERE TIMESTAMP_ADD(CreatedAt, INTERVAL 30 DAY) < CURRENT_TIMESTAMP();

필수 권한

데이터베이스의 스키마를 변경하려면 spanner.databases.updateDdl 권한이 있어야 합니다. 자세한 내용은 Spanner의 액세스 제어를 참조하세요.

행 삭제 정책 만들기

GoogleSQL

GoogleSQL을 사용하여 행 삭제 정책을 만들려면 새 테이블을 만들 때 ROW DELETION POLICY 절을 정의하거나 기존 테이블에 정책을 추가하면 됩니다. 이 절에는 열과 간격의 표현식이 포함됩니다.

테이블을 만들 때 정책을 추가하려면 다음 안내를 따르세요.

CREATE TABLE MyTable(
Key INT64,
CreatedAt TIMESTAMP,
) PRIMARY KEY (Key),
ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));

각 항목의 의미는 다음과 같습니다.

  • timestamp_columnTIMESTAMP 유형의 기존 열이어야 합니다. 생성된 열과 같이 커밋 타임스탬프가 있는 열이 유효합니다. 하지만 커밋 타임스탬프 열을 참조하는 생성된 열은 지정할 수 없습니다.

  • num_daystimestamp_column에서 행이 삭제로 표시된 타임스탬프 이후의 일 수입니다. 값은 음수가 아닌 정수여야 하며, DAY가 유일하게 지원되는 단위입니다.

기존 테이블에 정책을 추가하려면 ALTER TABLE 문을 사용합니다. 테이블에는 최대 1개의 행 삭제 정책이 있을 수 있습니다. 기존 정책이 있는 테이블에 행 삭제 정책을 추가하면 오류와 함께 실패합니다. 보다 정교한 행 삭제 로직을 지정하려면 생성 열의 TTL을 참조하세요.

ALTER TABLE Albums
ADD ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL num_days DAY));

PostgreSQL

PostgreSQL을 사용하여 행 삭제 정책을 만들려면 새 테이블을 만들 때 TTL INTERVAL 절을 정의하거나 기존 테이블에 정책을 추가하면 됩니다.

테이블을 만들 때 정책을 추가하려면 다음 안내를 따르세요.

CREATE TABLE mytable (
  key bigint NOT NULL,
  timestamp_column_name TIMESTAMPTZ,
  PRIMARY KEY(key)
) TTL INTERVAL interval_spec ON timestamp_column_name;

각 항목의 의미는 다음과 같습니다.

  • timestamp_column_name는 데이터 유형이 TIMESTAMPTZ인 열이어야 합니다. CREATE TABLE 문에서 이 열을 만들어야 합니다. 생성된 열과 같이 커밋 타임스탬프가 있는 열이 유효합니다. 하지만 커밋 타임스탬프 열을 참조하는 생성된 열은 지정할 수 없습니다.

  • interval_spectimestamp_column_name에서 행이 삭제로 표시된 타임스탬프 이후의 일 수입니다. 이 값은 음이 아닌 정수여야 하며, 일 단위로 평가해야 합니다. 예를 들어 '3 days'는 허용되지만 '3 days - 2 minutes'는 오류를 반환합니다.

기존 테이블에 정책을 추가하려면 ALTER TABLE 문을 사용합니다. 테이블에는 최대 TTL 정책이 하나만 포함될 수 있습니다. 기존 정책이 있는 테이블에 TTL 정책을 추가하면 오류가 발생합니다. 보다 정교한 TTL 로직을 지정하려면 생성된 열의 TTL을 참조하세요.

기존 테이블에 정책을 추가하려면 다음을 수행하세요.

ALTER TABLE albums
ADD COLUMN timestampcolumn TIMESTAMPTZ;

ALTER TABLE albums
ADD TTL INTERVAL '5 days' ON timestampcolumn;

제한사항

다음에서는 행 삭제 정책을 만들 수 없습니다.

  • 외래 키로 참조되는 테이블
  • 외래 키로 참조되는 테이블의 상위 요소

다음 예시에서는 행 삭제 정책을 Customers 테이블에 추가할 수 없습니다. Orders 테이블에서 외래 키로 참조되고 고객을 삭제하면 이 제약조건을 위반할 수 있기 때문입니다.

GoogleSQL

CREATE TABLE Customers (
  CustomerID INT64,
  CreatedAt TIMESTAMP
) PRIMARY KEY (CustomerID);

CREATE TABLE Orders (
  OrderID INT64,
  CustomerID INT64,
  CONSTRAINT FK_CustomerOrder FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID)
) PRIMARY KEY (OrderID)

PostgreSQL

CREATE TABLE customers (
  customerid   bigint NOT NULL,
  CreatedAt  timestamptz,
  PRIMARY KEY(customerid)
);

CREATE TABLE orders (
  orderid bigint NOT NULL,
  customerid bigint,
  PRIMARY KEY(orderid),
  CONSTRAINT fk_customerorder FOREIGN KEY (customerid) REFERENCES customers (customerid)
);

기본값이 있는 열의 TTL

행 삭제 정책은 기본값이 포함된 타임스탬프 열을 사용할 수 있습니다. 일반적인 기본값은 CURRENT_TIMESTAMP입니다. 값이 열에 명시적으로 할당되지 않았거나 열이 INSERT 또는 UPDATE 문에 따라 해당 기본값으로 설정된 경우 규칙 계산에 기본값이 사용됩니다.

다음 예시에서 Customers 테이블의 CreatedAt 열에 있는 기본값은 행이 생성된 타임스탬프입니다.

GoogleSQL

CREATE TABLE Customers (
  CustomerID INT64,
  CreatedAt TIMESTAMP DEFAULT (CURRENT_TIMESTAMP())
) PRIMARY KEY (CustomerID);

자세한 내용은 'GoogleSQL 데이터 정의 언어'의 DEFAULT(표현식)를 참조하세요.

PostgreSQL

CREATE TABLE customers (
  customerid bigint NOT NULL,
  createdat timestamptz DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY(customerid)
  );

자세한 내용은 'PostgreSQL 데이터 정의 언어'의 테이블 만들기를 참조하세요.

생성 열의 TTL

행 삭제 정책은 생성된 열을 사용하여 보다 복잡한 규칙을 표현할 수 있습니다. 예를 들어 여러 열의 greatest 타임스탬프(GoogleSQL 또는 PostgreSQL)에 행 삭제 정책을 정의하거나 타임스탬프에 다른 값을 매핑할 수 있습니다.

GoogleSQL

Orders라는 다음 테이블은 영업 주문을 추적합니다. 테이블 소유자는 취소된 주문을 30일 후 삭제하고, 취소되지 않은 주문은 180일 후 삭제하는 행 삭제 정책을 설정하려고 합니다.

Spanner TTL은 테이블당 하나의 행 삭제 정책만 허용합니다 단일 열에서 두 기준을 표현하려면 다음과 같이 IF 문이 있는 생성 열을 사용하면 됩니다.

CREATE TABLE Orders (
  OrderId INT64 NOT NULL,
  OrderStatus STRING(30) NOT NULL,
  LastModifiedDate TIMESTAMP NOT NULL,
  ExpiredDate TIMESTAMP AS (IF(OrderStatus = 'Cancelled',
    TIMESTAMP_ADD(LastModifiedDate, INTERVAL 30 DAY),
    TIMESTAMP_ADD(LastModifiedDate, INTERVAL 180 DAY))) STORED,
) PRIMARY KEY(OrderId),
ROW DELETION POLICY (OLDER_THAN(ExpiredDate, INTERVAL 0 DAY));

이 문은 주문 상태에 따라 LastModifiedDate에 30일 또는 180일을 추가하는 ExpiredDate라는 열을 만듭니다. 그런 후 INTERVAL 0 day를 지정하여 ExpiredDate 열에 저장된 날 행을 만료시키는 행 삭제 정책을 정의합니다.

PostgreSQL

Orders라는 다음 테이블은 영업 주문을 추적합니다. 테이블 소유자가 30일 동안 활동이 없으면 행을 삭제하는 행 삭제 정책을 설정하려고 합니다.

Spanner TTL은 테이블당 하나의 행 삭제 정책만 허용합니다 단일 열에서 두 기준을 표현하려면 생성 열을 만들면 됩니다.

CREATE TABLE orders (
    orderid bigint NOT NULL,
    orderstatus varchar(30) NOT NULL,
    createdate timestamptz NOT NULL,
    lastmodifieddate timestamptz,
    expireddate timestamptz GENERATED ALWAYS AS (GREATEST(createdate, lastmodifieddate)) STORED,
    PRIMARY KEY(orderid)
) TTL INTERVAL '30 days' ON expireddate;

이 문은 두 날짜(LastModifiedDate 또는 CreateDate) 중 최신 날짜를 평가하는 ExpiredDate라는 생성 열을 만듭니다. 그런 다음 주문이 생성되고 30일 후에 행을 만료하도록 행 삭제 정책을 정의하거나 해당 30일 안에 주문이 수정된 경우 삭제 기간을 추가로 30일 연장합니다.

TTL 및 인터리브 처리된 테이블

인터리브 처리된 테이블은 일대다 하위 테이블의 관련 행을 상위 테이블의 행과 연결하는 성능 최적화입니다. 상위 테이블에 행 삭제 정책을 추가하려면 인터리브 처리된 모든 하위 테이블이 ON DELETE CASCADE를 지정해야 합니다. 즉, 하위 행이 상위 행과 함께 원자적으로 삭제됩니다. 이렇게 하면 참조 무결성이 보장되어 상위 테이블 삭제를 통해 동일한 트랜잭션의 관련 하위 행도 삭제할 수 있습니다. Spanner TTL은 ON DELETE NO ACTION를 지원하지 않습니다.

최대 트랜잭션 크기

Spanner에는 트랜잭션 크기 한도가 있습니다. 색인이 생성된 열이 있는 대규모 상위-하위 계층 구조에서 연속 삭제는 이러한 제한을 초과하여 하나 이상의 TTL 작업이 실패할 수 있습니다. 실패한 작업의 경우 TTL은 단일 상위 행까지 더 작은 배치로 다시 시도합니다. 그러나 단일 상위 행에 대해서도 큰 하위 계층 구조가 여전히 변형 한도를 초과할 수 있습니다.

실패한 작업은 TTL 측정항목에 보고됩니다.

단일 행 및 인터리브 처리된 하위 요소가 너무 커서 삭제할 수 없는 경우 상위 테이블의 행뿐만 아니라 하위 테이블에 직접 행 삭제 정책을 연결할 수 있습니다. 하위 테이블의 정책은 상위 행 전에 하위 행이 삭제되도록 구성되어야 합니다.

다음 두 문이 적용될 때 행 삭제 정책을 하위 테이블에 연결할 수 있습니다.

  • 하위 테이블에는 글로벌 색인이 연결되어 있습니다.
  • 상위 행당 100개 이상의 하위 행이 있어야 합니다.

행 삭제 정책 삭제

테이블에서 기존 행 삭제 정책을 삭제할 수 있습니다. 테이블에 기존 행 삭제 정책이 없으면 오류가 반환됩니다.

GoogleSQL

ALTER TABLE MyTable
DROP ROW DELETION POLICY;

PostgreSQL

ALTER TABLE mytable
DROP TTL;

행 삭제 정책을 삭제하면 백그라운드에서 실행되는 TTL 프로세스가 즉시 중단됩니다. 진행 중인 프로세스로 이미 삭제된 행은 삭제된 상태로 유지됩니다.

행 삭제 정책으로 참조되는 열 삭제

Spanner에서는 행 삭제 정책으로 참조되는 열을 삭제할 수 없습니다. 열을 삭제하려면 먼저 행 삭제 정책을 삭제해야 합니다.

테이블의 행 삭제 정책 보기

Spanner 테이블의 행 삭제 정책을 볼 수 있습니다.

GoogleSQL

SELECT TABLE_NAME, ROW_DELETION_POLICY_EXPRESSION
FROM INFORMATION_SCHEMA.TABLES
WHERE ROW_DELETION_POLICY_EXPRESSION IS NOT NULL;

자세한 내용은 GoogleSQL 언어 데이터베이스의 정보 스키마를 참조하세요.

PostgreSQL

SELECT table_name, row_deletion_policy_expression
FROM information_schema.tables
WHERE row_deletion_policy_expression is not null;

자세한 내용은 PostgreSQL 언어 데이터베이스에 대한 정보 스키마를 참조하세요.

행 삭제 정책 수정

기존 행 삭제 정책의 열 또는 간격 표현식을 변경할 수 있습니다. 다음 예시에서는 열을 CreatedAt에서 ModifiedAt로 전환하고 간격을 1 DAY에서 7 DAY로 확장합니다. 테이블에 기존 행 삭제 정책이 없으면 오류가 반환됩니다.

GoogleSQL

ALTER TABLE MyTable
REPLACE ROW DELETION POLICY (OLDER_THAN(ModifiedAt, INTERVAL 7 DAY));

PostgreSQL

ALTER TABLE mytable
ALTER TTL INTERVAL '7 days' ON timestampcolumn;