이 문서에서는 소스 데이터베이스 테이블에서 Spanner로 기본 키를 마이그레이션하는 방법을 안내합니다. 기본 키 마이그레이션 개요에 나와 있는 정보를 숙지해야 합니다.
시작하기 전에
-
기본 키를 Spanner로 마이그레이션하는 데 필요한 권한을 얻으려면 관리자에게 인스턴스에 대한 Cloud Spanner 데이터베이스 관리자(
roles/spanner.databaseAdmin
) IAM 역할을 부여해 달라고 요청하세요.
자동 생성된 순차적 키 마이그레이션
MySQL의 AUTO_INCREMENT
, PostgreSQL의 SERIAL
, SQL Server 또는 Oracle의 표준 IDENTITY
유형과 같이 순차적 단조 키를 사용하는 데이터베이스에서 마이그레이션하는 경우 다음과 같은 대략적인 마이그레이션 전략을 고려하세요.
- Spanner에서 정수 기본 키를 사용하여 소스 데이터베이스의 테이블 구조를 복제합니다.
- 순차 값이 포함된 Spanner의 각 열에 대해 시퀀스를 만들고
GET_NEXT_SEQUENCE_VALUE
(GoogleSQL, PostgreSQL) 함수를 열의 기본값으로 할당합니다. - 원본 키가 있는 기존 데이터를 소스 데이터베이스에서 Spanner로 마이그레이션합니다. Spanner 마이그레이션 도구 또는 Dataflow 템플릿을 사용하는 것이 좋습니다.
- 필요한 경우 종속 테이블에 외래 키 제약조건을 설정할 수 있습니다.
- 새 데이터를 삽입하기 전에 Spanner 시퀀스를 조정하여 기존 키 값 범위를 건너뜁니다.
- 시퀀스가 고유 키를 자동으로 생성할 수 있도록 새 데이터를 삽입합니다.
샘플 마이그레이션 워크플로
다음 코드는 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_id
가 SERIAL
유형이라고 가정해 보겠습니다. 다음 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로 마이그레이션하기 위한 다음과 같은 대략적인 전략을 고려해 보세요.
- 기본 표현식이 있는 문자열 열을 사용하여 Spanner에서 UUID 키를 정의합니다.
GENERATE_UUID()
함수(GoogleSQL, PostgreSQL)를 사용합니다. - UUID 키를 문자열로 직렬화하여 소스 시스템에서 데이터를 내보냅니다.
- 기본 키를 Spanner로 가져옵니다.
- 선택사항: 외래 키를 사용 설정합니다.
다음은 샘플 마이그레이션 워크플로입니다.
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) );