Bermigrasi dari PostgreSQL ke Spanner (dialek GoogleSQL)

Halaman ini memberikan panduan tentang memigrasikan database PostgreSQL open source ke Spanner.

Migrasi melibatkan tugas-tugas berikut:

  • Memetakan skema PostgreSQL ke skema Spanner.
  • Membuat instance, database, dan skema Spanner.
  • Memfaktorkan ulang aplikasi agar berfungsi dengan database Spanner Anda.
  • Memigrasikan data.
  • Memverifikasi sistem baru dan memindahkannya ke status produksi.

Halaman ini juga memberikan beberapa contoh skema menggunakan tabel dari database PostgreSQL MusicBrainz.

Memetakan skema PostgreSQL ke Spanner

Langkah pertama Anda dalam memindahkan database dari PostgreSQL ke Spanner adalah menentukan perubahan skema yang harus dilakukan. Gunakan pg_dump untuk membuat pernyataan Data Definition Language (DDL) yang menentukan objek dalam database PostgreSQL Anda, lalu ubah pernyataan tersebut seperti yang dijelaskan di bagian berikut. Setelah Anda memperbarui pernyataan DDL, gunakan pernyataan tersebut untuk membuat database di instance Spanner.

Jenis data

Tabel berikut menjelaskan cara jenis data PostgreSQL dipetakan ke jenis data Spanner. Perbarui jenis data dalam pernyataan DDL Anda dari jenis data PostgreSQL menjadi jenis data Spanner.

PostgreSQL Spanner
Bigint

int8

INT64
Bigserial

serial8

INT64
bit [ (n) ] ARRAY<BOOL>
bit varying [ (n) ]

varbit [ (n) ]

ARRAY<BOOL>
Boolean

bool

BOOL
box ARRAY<FLOAT64>
bytea BYTES
character [ (n) ]

char [ (n) ]

STRING
character varying [ (n) ]

varchar [ (n) ]

STRING
cidr STRING, menggunakan notasi CIDR standar.
circle ARRAY<FLOAT64>
date DATE
double precision

float8

FLOAT64
inet STRING
Integer

int

int4

INT64
interval[ fields ] [ (p) ] INT64 jika menyimpan nilai dalam milidetik, atau STRING jika menyimpan nilai dalam format interval yang ditentukan aplikasi.
json STRING
jsonb JSON
line ARRAY<FLOAT64>
lseg ARRAY<FLOAT64>
macaddr STRING, menggunakan notasi alamat MAC standar.
money INT64, atau STRING untuk angka presisi arbitrer.
numeric [ (p, s) ]

decimal [ (p, s) ]

Di PostgreSQL, jenis data NUMERIC dan DECIMAL mendukung hingga 217 digit presisi dan skala 214-1, seperti yang ditentukan dalam deklarasi kolom.

Jenis data NUMERIC Spanner mendukung hingga 38 digit presisi dan 9 digit desimal.

Jika Anda memerlukan presisi yang lebih baik, lihat Menyimpan data numerik presisi arbitrer untuk mekanisme alternatif.
path ARRAY<FLOAT64>
pg_lsn Jenis data ini khusus PostgreSQL, sehingga tidak ada padanan Spanner.
point ARRAY<FLOAT64>
polygon ARRAY<FLOAT64>
Real

float4

FLOAT64
Smallint

int2

INT64
Smallserial

serial2

INT64
Serial

serial4

INT64
text STRING
time [ (p) ] [ without time zone ] STRING, menggunakan notasi HH:MM:SS.sss.
time [ (p) ] with time zone

timetz

STRING, menggunakan notasi HH:MM:SS.sss+ZZZZ. Atau, kolom ini dapat dibagi menjadi dua kolom, salah satu dari jenis TIMESTAMP dan satu lagi yang berisi zona waktu.
timestamp [ (p) ] [ without time zone ] Tidak ada ekuivalen. Anda dapat menyimpan sebagai STRING atau TIMESTAMP sesuai pertimbangan Anda.
timestamp [ (p) ] with time zone

timestamptz

TIMESTAMP
tsquery Tidak ada ekuivalen. Sebagai gantinya, tentukan mekanisme penyimpanan dalam aplikasi Anda.
tsvector Tidak ada ekuivalen. Sebagai gantinya, tentukan mekanisme penyimpanan dalam aplikasi Anda.
txid_snapshot Tidak ada ekuivalen. Sebagai gantinya, tentukan mekanisme penyimpanan dalam aplikasi Anda.
uuid STRING atau BYTES
xml STRING

Kunci utama

Untuk tabel dalam database Spanner yang sering Anda tambahkan, hindari penggunaan kunci utama yang meningkat atau menurun secara monoton, karena pendekatan ini akan menyebabkan hotspot selama operasi tulis. Sebagai gantinya, ubah pernyataan CREATE TABLE DDL sehingga menggunakan strategi kunci utama yang didukung. Jika Anda menggunakan fitur PostgreSQL seperti fungsi atau jenis data UUID, jenis data SERIAL, kolom IDENTITY, atau urutan, Anda dapat menggunakan strategi migrasi utama yang dibuat secara otomatis yang kami rekomendasikan.

Perhatikan bahwa setelah menentukan kunci utama, Anda tidak dapat menambahkan atau menghapus kolom kunci utama, atau mengubah nilai kunci utama nanti tanpa menghapus dan membuat ulang tabel. Untuk mengetahui informasi selengkapnya tentang cara menetapkan kunci utama, lihat Model data dan skema - kunci utama.

Selama migrasi, Anda mungkin perlu menyimpan beberapa kunci bilangan bulat yang meningkat secara monoton. Jika perlu menyimpan jenis kunci ini pada tabel yang sering diperbarui dengan banyak operasi pada kunci ini, Anda dapat menghindari pembuatan hotspot dengan memberi awalan pada kunci yang ada dengan angka pseudo-random. Teknik ini menyebabkan Spanner mendistribusikan ulang baris. Lihat Hal yang perlu diketahui DBA tentang Spanner, bagian 1: Kunci dan indeks untuk mengetahui informasi selengkapnya tentang penggunaan pendekatan ini.

{i>Foreign key<i} dan integritas referensial

Pelajari dukungan kunci asing di Spanner.

Indeks

Indeks b-tree PostgreSQL mirip dengan indeks sekunder di Spanner. Dalam database Spanner, Anda menggunakan indeks sekunder untuk mengindeks kolom yang sering ditelusuri guna mendapatkan performa yang lebih baik, dan untuk mengganti batasan UNIQUE yang ditentukan dalam tabel Anda. Misalnya, jika DDL PostgreSQL Anda memiliki pernyataan ini:

 CREATE TABLE customer (
    id CHAR (5) PRIMARY KEY,
    first_name VARCHAR (50),
    last_name VARCHAR (50),
    email VARCHAR (50) UNIQUE
 );

Anda akan menggunakan pernyataan ini di DDL Spanner:

CREATE TABLE customer (
   id STRING(5),
   first_name STRING(50),
   last_name STRING(50),
   email STRING(50)
   ) PRIMARY KEY (id);

CREATE UNIQUE INDEX customer_emails ON customer(email);

Anda dapat menemukan indeks untuk setiap tabel PostgreSQL dengan menjalankan perintah meta \di di psql.

Setelah menentukan indeks yang diperlukan, tambahkan pernyataan CREATE INDEX untuk membuatnya. Ikuti panduan di bagian Membuat indeks.

Spanner menerapkan indeks sebagai tabel, sehingga mengindeks kolom secara monoton (seperti yang berisi data TIMESTAMP) dapat menyebabkan hotspot. Lihat Yang perlu diketahui DBA tentang Spanner, bagian 1: Kunci dan indeks untuk mengetahui informasi selengkapnya tentang metode menghindari hotspot.

Memeriksa batasan

Pelajari dukungan batasan CHECK di Spanner.

Objek database lainnya

Anda harus membuat fungsi objek berikut dalam logika aplikasi:

  • Tabel Virtual
  • Triggers
  • Prosedur tersimpan
  • Fungsi yang ditentukan pengguna (UDF)
  • Kolom yang menggunakan jenis data serial sebagai generator urutan

Perhatikan tips berikut saat memigrasikan fungsi ini ke dalam logika aplikasi:

  • Anda harus memigrasikan pernyataan SQL apa pun yang digunakan dari dialek SQL PostgreSQL ke dialek GoogleSQL.
  • Jika menggunakan cursors, Anda dapat mengerjakan ulang kueri untuk menggunakan offset dan batas.

Membuat instance Spanner

Setelah memperbarui pernyataan DDL agar sesuai dengan persyaratan skema Spanner, gunakan pernyataan tersebut untuk membuat database di Spanner.

  1. Buat instance Spanner. Ikuti panduan di Instance untuk menentukan konfigurasi regional dan kapasitas komputasi yang benar untuk mendukung sasaran performa Anda.

  2. Buat database menggunakan Konsol Google Cloud atau alat command line gcloud:

Konsol

  1. Buka halaman instance
  2. Klik nama instance tempat Anda ingin membuat contoh database untuk membuka halaman Instance details.
  3. Klik Create database.
  4. Ketik nama untuk database, lalu klik Continue.
  5. Di bagian Tentukan skema database Anda, aktifkan kontrol Edit sebagai teks.
  6. Salin dan tempel pernyataan DDL Anda ke kolom Pernyataan DDL.
  7. Klik Create.

gcloud

  1. Instal gcloud CLI.
  2. Gunakan perintah gcloud spanner databases create untuk membuat database:
    gcloud spanner databases create DATABASE_NAME --instance=INSTANCE_NAME
    --ddl='DDL1' --ddl='DDL2'
    
  • DATABASE_NAME adalah nama database Anda.
  • INSTANCE_NAME adalah instance Spanner yang Anda buat.
  • DDLn adalah pernyataan DDL Anda yang dimodifikasi.

Setelah membuat database, ikuti petunjuk di Menerapkan peran IAM untuk membuat akun pengguna dan memberikan izin ke instance dan database Spanner.

Memfaktorkan ulang lapisan akses data dan aplikasi

Selain kode yang diperlukan untuk mengganti objek database sebelumnya, Anda harus menambahkan logika aplikasi untuk menangani fungsi berikut:

  • Melakukan hashing pada kunci utama untuk penulisan, untuk tabel yang memiliki kecepatan operasi tulis yang tinggi ke kunci berurutan.
  • Memvalidasi data, belum dicakup oleh batasan CHECK.
  • Pemeriksaan integritas referensial yang belum dicakup oleh kunci asing, tabel interleaving, atau logika aplikasi, termasuk fungsi yang ditangani oleh pemicu dalam skema PostgreSQL.

Sebaiknya gunakan proses berikut saat memfaktorkan ulang:

  1. Temukan semua kode aplikasi Anda yang mengakses database, dan faktorkan ulang menjadi satu modul atau library. Dengan begitu, Anda akan mengetahui secara pasti kode yang diakses ke database, sehingga kode apa yang perlu dimodifikasi.
  2. Menulis kode yang melakukan pembacaan dan penulisan di instance Spanner, memberikan fungsi paralel dengan kode asli yang membaca dan menulis ke PostgreSQL. Selama operasi tulis, perbarui seluruh baris, bukan hanya kolom yang telah diubah, untuk memastikan data di Spanner identik dengan data di PostgreSQL.
  3. Tulis kode yang menggantikan fungsi objek dan fungsi database yang tidak tersedia di Spanner.

Migrasikan data

Setelah membuat database Spanner dan memfaktorkan ulang kode aplikasi, Anda dapat memigrasikan data ke Spanner.

  1. Gunakan perintah PostgreSQL COPY untuk membuang data ke file .csv.
  2. Upload file .csv ke Cloud Storage.

    1. Buat bucket Cloud Storage.
    2. Di konsol Cloud Storage, klik nama bucket untuk membuka browser bucket.
    3. Klik Upload File.
    4. Arahkan ke direktori yang berisi file .csv dan pilih file tersebut.
    5. Klik Buka.
  3. Buat aplikasi untuk mengimpor data ke Spanner. Aplikasi ini dapat menggunakan Dataflow atau menggunakan library klien secara langsung. Pastikan untuk mengikuti panduan di Praktik terbaik pemuatan data massal untuk mendapatkan performa terbaik.

Pengujian

Uji semua fungsi aplikasi terhadap instance Spanner untuk memverifikasi bahwa fungsi tersebut berfungsi seperti yang diharapkan. Jalankan workload tingkat produksi untuk memastikan performanya memenuhi kebutuhan Anda. Perbarui kapasitas komputasi sesuai kebutuhan untuk memenuhi sasaran performa Anda.

Berpindah ke sistem baru

Setelah Anda menyelesaikan pengujian aplikasi awal, aktifkan sistem baru menggunakan salah satu proses berikut. Migrasi offline adalah cara termudah untuk bermigrasi. Akan tetapi, pendekatan ini akan membuat aplikasi Anda tidak tersedia selama jangka waktu tertentu, dan tidak menyediakan jalur rollback jika Anda menemukan masalah data di kemudian hari. Untuk melakukan migrasi offline:

  1. Hapus semua data di database Spanner.
  2. Matikan aplikasi yang menargetkan database PostgreSQL.
  3. Ekspor semua data dari database PostgreSQL dan impor ke dalam database Spanner seperti yang dijelaskan dalam Memigrasikan data.
  4. Mulai aplikasi yang menargetkan database Spanner.

    Aliran data migrasi offline.

Migrasi langsung dapat dilakukan dan memerlukan perubahan ekstensif pada aplikasi Anda untuk mendukung migrasi.

Contoh migrasi skema

Contoh ini menunjukkan pernyataan CREATE TABLE untuk beberapa tabel dalam skema database PostgreSQL MusicBrainz. Setiap contoh menyertakan skema PostgreSQL dan skema Spanner.

tabel kredit_artis

Versi PostgreSQL:

CREATE TABLE artist_credit (
  id SERIAL,
  name VARCHAR NOT NULL,
  artist_count SMALLINT NOT NULL,
  ref_count INTEGER DEFAULT 0,
  created TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

Versi Spanner:

CREATE TABLE artist_credit (
  hashed_id STRING(4),
  id INT64,
  name STRING(MAX) NOT NULL,
  artist_count INT64 NOT NULL,
  ref_count INT64,
  created TIMESTAMP OPTIONS (
     allow_commit_timestamp = true
  ),
) PRIMARY KEY(hashed_id, id);

tabel rekaman

Versi PostgreSQL:

CREATE TABLE recording (
  id SERIAL,
  gid UUID NOT NULL,
  name VARCHAR NOT NULL,
  artist_credit INTEGER NOT NULL, -- references artist_credit.id
  length INTEGER CHECK (length IS NULL OR length > 0),
  comment VARCHAR(255) NOT NULL DEFAULT '',
  edits_pending INTEGER NOT NULL DEFAULT 0 CHECK (edits_pending >= 0),
  last_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  video BOOLEAN NOT NULL DEFAULT FALSE
);

Versi Spanner:

CREATE TABLE recording (
  hashed_id STRING(36),
  id INT64,
  gid STRING(36) NOT NULL,
  name STRING(MAX) NOT NULL,
  artist_credit_hid STRING(36) NOT NULL,
  artist_credit_id INT64 NOT NULL,
  length INT64,
  comment STRING(255) NOT NULL,
  edits_pending INT64 NOT NULL,
  last_updated TIMESTAMP OPTIONS (
     allow_commit_timestamp = true
  ),
  video BOOL NOT NULL,
) PRIMARY KEY(hashed_id, id);

tabel alias-rekaman

Versi PostgreSQL:

CREATE TABLE recording_alias (
  id SERIAL, --PK
  recording INTEGER NOT NULL, -- references recording.id
  name VARCHAR NOT NULL,
  locale TEXT,
  edits_pending INTEGER NOT NULL DEFAULT 0 CHECK (edits_pending >=0),
  last_updated TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  type INTEGER, -- references recording_alias_type.id
  sort_name VARCHAR NOT NULL,
  begin_date_year SMALLINT,
  begin_date_month SMALLINT,
  begin_date_day SMALLINT,
  end_date_year SMALLINT,
  end_date_month SMALLINT,
  end_date_day SMALLINT,
  primary_for_locale BOOLEAN NOT NULL DEFAULT false,
  ended BOOLEAN NOT NULL DEFAULT FALSE
  -- CHECK constraint skipped for brevity
);

Versi Spanner:

CREATE TABLE recording_alias (
  hashed_id STRING(36)  NOT NULL,
  id INT64  NOT NULL,
  alias_id INT64,
  name STRING(MAX)  NOT NULL,
  locale STRING(MAX),
  edits_pending INT64  NOT NULL,
  last_updated TIMESTAMP NOT NULL OPTIONS (
     allow_commit_timestamp = true
  ),
  type INT64,
  sort_name STRING(MAX)  NOT NULL,
  begin_date_year INT64,
  begin_date_month INT64,
  begin_date_day INT64,
  end_date_year INT64,
  end_date_month INT64,
  end_date_day INT64,
  primary_for_locale BOOL NOT NULL,
  ended BOOL NOT NULL,
) PRIMARY KEY(hashed_id, id, alias_id),
 INTERLEAVE IN PARENT recording ON DELETE NO ACTION;