기본 키 마이그레이션

이 문서에서는 소스 데이터베이스 테이블에서 Spanner로 기본 키를 마이그레이션하는 방법을 안내합니다. 기본 키 마이그레이션 개요에 나와 있는 정보를 숙지해야 합니다.

시작하기 전에

  • 기본 키를 Spanner로 마이그레이션하는 데 필요한 권한을 얻으려면 관리자에게 인스턴스에 대한 Cloud Spanner 데이터베이스 관리자(roles/spanner.databaseAdmin) IAM 역할을 부여해 달라고 요청하세요.

자동 생성된 순차적 키 마이그레이션

MySQL의 AUTO_INCREMENT, PostgreSQL의 SERIAL, SQL Server 또는 Oracle의 표준 IDENTITY 유형과 같이 순차적 단조 키를 사용하는 데이터베이스에서 마이그레이션하는 경우 다음과 같은 대략적인 마이그레이션 전략을 고려하세요.

  1. Spanner에서 정수 기본 키를 사용하여 소스 데이터베이스의 테이블 구조를 복제합니다.
  2. 순차 값이 포함된 Spanner의 각 열에 대해 시퀀스를 만들고 GET_NEXT_SEQUENCE_VALUE(GoogleSQL, PostgreSQL) 함수를 열의 기본값으로 할당합니다.
  3. 원본 키가 있는 기존 데이터를 소스 데이터베이스에서 Spanner로 마이그레이션합니다. Spanner 마이그레이션 도구 또는 Dataflow 템플릿을 사용하는 것이 좋습니다.
  4. 필요한 경우 종속 테이블에 외래 키 제약조건을 설정할 수 있습니다.
  5. 새 데이터를 삽입하기 전에 Spanner 시퀀스를 조정하여 기존 키 값 범위를 건너뜁니다.
  6. 시퀀스가 고유 키를 자동으로 생성할 수 있도록 새 데이터를 삽입합니다.

샘플 마이그레이션 워크플로

다음 코드는 SEQUENCE 객체를 사용하여 Spanner에서 테이블 구조와 관련 시퀀스를 정의하고 객체를 대상 테이블의 기본 기본값으로 설정합니다.

GoogleSQL

CREATE SEQUENCE singer_id_sequence OPTIONS (
     SequenceKind = 'bit_reversed_positive'
  );

CREATE TABLE Singers (
     SingerId INT64 DEFAULT
     (GET_NEXT_SEQUENCE_VALUE(SEQUENCE SingerIdSequence)),
     Name STRING(1024),
     Biography STRING(MAX),
  ) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
     AlbumId INT64,
     SingerId INT64,
     AlbumName STRING(1024),
     SongList STRING(MAX),
     CONSTRAINT FK_singer_album
     FOREIGN KEY (SingerId)
       REFERENCES Singers (SingerId)
  ) PRIMARY KEY (AlbumId);

PostgreSQL

CREATE SEQUENCE SingerIdSequence BIT_REVERSED_POSITIVE;

CREATE TABLE Singers (
  SingerId BIGINT DEFAULT nextval('SingerIdSequence') PRIMARY KEY,
  Name VARCHAR(1024) NOT NULL,
  Biography TEXT
);

CREATE TABLE Albums (
  AlbumId BIGINT PRIMARY KEY,
  SingerId BIGINT,
  AlbumName VARCHAR(1024),
  SongList TEXT,
  CONSTRAINT FK_singer_album FOREIGN KEY (SingerId) REFERENCES Singers (SingerId)
);

bit_reversed_positive 옵션은 시퀀스에서 생성된 값이 INT64 유형이고 0보다 크며 순차적이지 않음을 나타냅니다.

소스 데이터베이스에서 Spanner로 기존 행을 마이그레이션할 때 기본 키는 변경되지 않습니다.

기본 키를 지정하지 않는 새 삽입의 경우 Spanner는 GET_NEXT_SEQUENCE_VALUE()(GoogleSQL 또는 PostgreSQL) 함수를 호출하여 새 값을 자동으로 검색합니다.

이러한 값은 [1, 263] 범위에 균등하게 분포되며 기존 키와 충돌이 발생할 수 있습니다. 이를 방지하려면 ALTER_SEQUENCE(GoogleSQL 또는 PostgreSQL)를 사용하여 시퀀스를 구성하여 기존 키에 포함된 값 범위를 건너뛸 수 있습니다.

singers 테이블이 PostgreSQL에서 마이그레이션되었으며 기본 키 singer_idSERIAL 유형이라고 가정해 보겠습니다. 다음 PostgreSQL에는 소스 데이터베이스 DDL이 표시됩니다.

PostgreSQL

CREATE TABLE Singers (
SingerId SERIAL PRIMARY KEY,
Name varchar(1024),
Biography varchar
);

기본 키 값은 단조롭게 증가합니다. 마이그레이션 후 Spanner에서 기본 키 singer_id의 최댓값을 가져올 수 있습니다. Spanner에서 다음 코드를 사용합니다.

GoogleSQL

SELECT MAX(SingerId) FROM Singers;

PostgreSQL

SELECT MAX(SingerId) FROM Singers;

반환된 값이 20,000이라고 가정합니다. Spanner 시퀀스를 구성하여 [1, 21000] 범위를 건너뛸 수 있습니다. 추가 1,000은 초기 마이그레이션 후 소스 데이터베이스에 대한 쓰기를 수용하는 버퍼 역할을 합니다. Spanner에서 생성된 새 키는 소스 PostgreSQL 데이터베이스에서 생성된 기본 키 범위와 충돌하지 않습니다. Spanner에서 다음 코드를 사용합니다.

GoogleSQL

ALTER SEQUENCE SingerIdSequence SET OPTIONS (
skip_range_min = 1,
skip_range_max = 21000
);

PostgreSQL

ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 21000;

Spanner 및 소스 데이터베이스 사용

범위 건너뛰기 개념을 사용하여 Spanner 또는 소스 데이터베이스에서 기본 키를 생성하는 시나리오를 지원할 수 있습니다. 예를 들어 마이그레이션 컷오버 중에 재해 복구를 위해 양방향으로 복제를 사용 설정할 수 있습니다.

이를 지원하기 위해 두 데이터베이스 모두 기본 키를 생성하고 데이터가 두 데이터베이스 간에 동기화됩니다. 겹치지 않는 키 범위에서 기본 키를 만들도록 각 데이터베이스를 구성할 수 있습니다. 소스 데이터베이스의 범위를 정의할 때 Spanner 시퀀스를 구성하여 해당 범위를 건너뛸 수 있습니다.

예를 들어 음악 트랙 애플리케이션을 마이그레이션한 후 PostgreSQL에서 Spanner로 데이터를 복제하여 컷오버에 걸리는 시간을 줄입니다.

Spanner에서 애플리케이션을 업데이트하고 테스트한 후에는 소스 PostgreSQL 데이터베이스 사용을 중지하고 Spanner를 사용하여 업데이트 및 새 기본 키의 레코드 시스템으로 만들 수 있습니다. Spanner가 인계되면 데이터베이스 간의 데이터 흐름을 PostgreSQL 인스턴스로 역전시킬 수 있습니다.

소스 PostgreSQL 데이터베이스가 32비트 부호 있는 정수인 SERIAL 기본 키를 사용한다고 가정해 보겠습니다. Spanner 기본 키는 더 큰 64비트 숫자입니다. PostgreSQL에서 기본 키 열을 64비트 열 또는 bigint로 변경합니다. 소스 PostgreSQL 데이터베이스에서 다음 코드를 사용합니다.

PostgreSQL

ALTER TABLE Singers ALTER COLUMN SingerId TYPE bigint;

소스 PostgreSQL 데이터베이스의 테이블에 CHECK 제약조건을 설정하여 SingerId 기본 키 값이 항상 231-1보다 작거나 같은지 확인할 수 있습니다. 소스 PostgreSQL 데이터베이스에서 다음 코드를 사용합니다.

PostgreSQL

ALTER TABLE Singers ADD CHECK (SingerId <= 2147483647);

Spanner에서는 시퀀스를 변경하여 [1, 231-1] 범위를 건너뛸 수 있습니다. Spanner에서 다음 코드를 사용합니다.

GoogleSQL

ALTER SEQUENCE SingerIdSequence SET OPTIONS (
skip_range_min = 1,
skip_range_max = 2147483647 -- 231-1
);

PostgreSQL

ALTER SEQUENCE SingerIdSequence SKIP RANGE 1 2147483648;

소스 PostgreSQL 데이터베이스는 항상 32비트 정수 공간에서 키를 생성하는 반면 Spanner 키는 모든 32비트 정수 값보다 큰 64비트 정수 공간으로 제한됩니다. 이렇게 하면 두 데이터베이스 모두 충돌하지 않는 기본 키를 독립적으로 생성할 수 있습니다.

UUID 키 열 마이그레이션

UUIDv4 키는 생성된 위치에 관계없이 고유합니다. 다른 곳에서 생성된 UUID 키는 Spanner에서 생성된 새 UUID 키와 통합됩니다.

UUID 키를 Spanner로 마이그레이션하기 위한 다음과 같은 대략적인 전략을 고려해 보세요.

  1. 기본 표현식이 있는 문자열 열을 사용하여 Spanner에서 UUID 키를 정의합니다. GENERATE_UUID() 함수(GoogleSQL, PostgreSQL)를 사용합니다.
  2. UUID 키를 문자열로 직렬화하여 소스 시스템에서 데이터를 내보냅니다.
  3. 기본 키를 Spanner로 가져옵니다.
  4. 선택사항: 외래 키를 사용 설정합니다.

다음은 샘플 마이그레이션 워크플로입니다.

Spanner에서 UUID 기본 키 열을 STRING 또는 TEXT 유형으로 정의하고 GENERATE_UUID()(GoogleSQL 또는 PostgreSQL)를 기본값으로 할당합니다. 소스 데이터베이스에서 Spanner로 모든 데이터를 마이그레이션합니다. 마이그레이션 후 새 행이 삽입될 때 Spanner는 GENERATE_UUID()를 호출하여 기본 키의 새 UUID 값을 생성합니다. 예를 들어 테이블 FanClubs에 새 행이 삽입되면 기본 키 FanClubId가 UUIDv4 값을 가져옵니다. Spanner에서 다음 코드를 사용합니다.

GoogleSQL

CREATE TABLE Fanclubs (
FanClubId STRING(36) DEFAULT (GENERATE_UUID()),
ClubName STRING(1024),
) PRIMARY KEY (FanClubId);

INSERT INTO FanClubs (ClubName) VALUES ("SwiftFanClub");

PostgreSQL

CREATE TABLE FanClubs (
  FanClubId TEXT DEFAULT spanner.generate_uuid() PRIMARY KEY,
  ClubName VARCHAR(1024)
);

INSERT INTO FanClubs (ClubName) VALUES ('SwiftFanClub');

자체 기본 키 마이그레이션

애플리케이션이 기본 키 순서를 사용하여 데이터의 최신성을 확인하거나 새로 생성된 데이터를 정렬할 수 있습니다. Spanner에서 외부에서 생성된 순차적 키를 사용하려면 해시와 같이 균일하게 분포된 값을 첫 번째 구성요소로, 순차적 키를 두 번째 구성요소로 조합하는 복합 키를 만들면 됩니다. 이렇게 하면 대규모 핫스팟을 만들지 않고도 순차적 키 값을 보존할 수 있습니다. 다음과 같은 마이그레이션 워크플로를 고려하세요.

AUTO_INCREMENT 기본 키가 있는 MySQL 테이블 students를 Spanner로 마이그레이션해야 한다고 가정해 보겠습니다. 소스 MySQL 데이터베이스에서 다음 코드를 사용합니다.

MySQL

CREATE TABLE Students (
StudentId INT NOT NULL AUTO_INCREMENT,
Info VARCHAR(2048),
PRIMARY KEY (StudentId)
);

Spanner에서는 StudentId 열의 해시를 만들어 생성된 열 StudentIdHash를 추가할 수 있습니다. 예를 들면 다음과 같습니다.

  StudentIdHash = FARM_FINGERPRINT(CAST(StudentId AS STRING))

Spanner에서 다음 코드를 사용할 수 있습니다.

GoogleSQL

CREATE TABLE student (
  StudentIdHash INT64 AS (FARM_FINGERPRINT(cast(StudentId as string))) STORED,
  StudentId INT64 NOT NULL,
  Info STRING(2048),
) PRIMARY KEY(StudentIdHash, StudentId);

PostgreSQL

CREATE TABLE Student (
  StudentIdHash bigint GENERATED ALWAYS AS
  (FARM_FINGERPRINT(cast(StudentId AS varchar))) STORED,
  StudentId bigint NOT NULL,
  Info varchar(2048),
  PRIMARY KEY (StudentIdHash, StudentId)
);

다음 단계