Praktik terbaik pembaruan skema

Dokumen ini menjelaskan praktik terbaik untuk memperbarui skema.

Prosedur sebelum Anda memulai pembaruan skema

Sebelum Anda mengeluarkan pembaruan skema:

  • Pastikan semua data yang ada dalam database mematuhi batasan yang diperkenalkan oleh update skema. Karena beberapa update skema bergantung pada data sebenarnya, bukan hanya skema saat ini, update yang berhasil dalam database pengujian tidak menjamin keberhasilan dalam database produksi. Berikut beberapa contoh umumnya:

    • Jika Anda menambahkan anotasi NOT NULL ke kolom yang ada, periksa bahwa kolom tersebut tidak berisi nilai NULL yang ada.
    • Jika Anda memperpendek panjang yang diizinkan untuk kolom STRING atau BYTES, periksa apakah semua nilai yang ada dalam kolom tersebut memenuhi batasan panjang.
  • Jika Anda menulis ke kolom, tabel, atau indeks yang sedang menjalani pembaruan skema, pastikan nilai yang Anda tulis memenuhi batasan baru.

  • Pastikan Anda tidak sedang menulis atau membaca dari kolom, tabel, atau indeks jika ingin menghapusnya.

Membatasi frekuensi pembaruan skema

Jika Anda melakukan terlalu banyak pembaruan skema dalam jangka waktu yang singkat, Spanner dapat throttle pemrosesan pembaruan skema yang diantrekan. Hal ini karena Spanner membatasi jumlah ruang untuk menyimpan versi skema. Pembaruan skema Anda mungkin dibatasi jika ada terlalu banyak versi skema lama dalam periode retensi. Kecepatan maksimum perubahan skema bergantung pada banyak faktor, salah satunya adalah jumlah total kolom dalam database. Misalnya, database dengan 2.000 kolom (sekitar 2.000 baris di INFORMATION_SCHEMA.COLUMNS) dapat melakukan maksimal 1.500 perubahan skema (lebih sedikit jika perubahan skema memerlukan beberapa versi) dalam periode retensi. Untuk melihat status update skema yang sedang berlangsung, gunakan perintah gcloud spanner operations list dan filter menurut operasi jenis DATABASE_UPDATE_DDL. Untuk membatalkan update skema yang sedang berlangsung, gunakan perintah gcloud spanner operations cancel dan tentukan ID operasi.

Cara pernyataan DDL Anda dikelompokkan, dan urutannya dalam setiap batch, dapat memengaruhi jumlah versi skema yang dihasilkan. Untuk memaksimalkan jumlah update skema yang dapat Anda lakukan selama jangka waktu tertentu, Anda harus menggunakan batching yang meminimalkan jumlah versi skema. Beberapa panduan dijelaskan dalam update besar.

Seperti yang dijelaskan dalam versi skema, beberapa pernyataan DDL akan membuat beberapa versi skema, dan hal ini penting saat mempertimbangkan pengelompokan dan urutan dalam setiap batch. Ada dua jenis utama pernyataan yang dapat membuat beberapa versi skema:

  • Pernyataan yang mungkin perlu mengisi ulang data indeks, seperti CREATE INDEX.
  • Pernyataan yang memaksa Spanner memvalidasi data yang ada, seperti menambahkan NOT NULL atau batasan panjang.

Jenis pernyataan ini tidak selalu membuat beberapa versi skema. Spanner akan mencoba mendeteksi kapan jenis pernyataan ini dapat dioptimalkan untuk menghindari penggunaan beberapa versi skema, yang bergantung pada batching. Misalnya, pernyataan CREATE INDEX yang terjadi dalam batch yang sama dengan pernyataan CREATE TABLE untuk tabel dasar indeks, tanpa ada pernyataan yang menyisipi untuk tabel lain, dapat menghindari kebutuhan untuk mengisi ulang data indeks karena Spanner dapat menjamin bahwa tabel dasar kosong pada saat indeks dibuat. Bagian pembaruan besar menjelaskan cara menggunakan properti ini untuk membuat banyak indeks secara efisien.

Jika Anda tidak dapat mengelompokkan pernyataan DDL untuk menghindari pembuatan banyak versi skema, Anda harus membatasi jumlah pembaruan skema ke skema satu database dalam periode retensinya. Perpanjang jangka waktu saat Anda membuat pembaruan skema agar Spanner dapat menghapus versi skema sebelumnya sebelum versi baru dibuat.

  • Untuk beberapa sistem manajemen database relasional, ada paket software yang membuat serangkaian panjang update skema upgrade dan downgrade ke database pada setiap deployment produksi. Jenis proses ini tidak direkomendasikan untuk Spanner.
  • Spanner dioptimalkan untuk menggunakan kunci utama guna mempartisi data untuk solusi multi-tenant. Jika Anda menggunakan solusi multi-tenancy yang menggunakan tabel terpisah untuk setiap pelanggan, perlu diketahui bahwa pembaruan skema untuk banyak pelanggan sekaligus dapat menghasilkan backlog besar terkait operasi pembaruan skema yang memerlukan waktu lama untuk diselesaikan.
  • Pembaruan skema yang memerlukan validasi atau pengisian ulang indeks menggunakan lebih banyak resource server karena setiap pernyataan membuat beberapa versi skema secara internal.

Urutan eksekusi pernyataan dalam batch

Jika menggunakan Google Cloud CLI, REST API, atau RPC API, Anda dapat mengeluarkan batch dari satu atau beberapa pernyataan CREATE, ALTER, atau DROP.

Spanner menerapkan pernyataan dari batch yang sama secara berurutan, dan berhenti pada error pertama. Jika penerapan pernyataan menghasilkan error, pernyataan tersebut akan di-roll back. Hasil pernyataan yang diterapkan sebelumnya dalam batch tidak di-rollback. Penerapan pernyataan berurutan ini berarti bahwa jika Anda ingin pernyataan yang memerlukan pengisian ulang yang tidak dapat dihindari berjalan secara paralel (seperti membuat beberapa indeks pada tabel besar yang sudah ada), Anda harus mengirimkan pernyataan tersebut dalam batch terpisah, karena setiap pengisian ulang dapat memakan waktu yang lama. Jika Anda membuat tabel baru dengan indeks, di sisi lain, praktik terbaiknya adalah menempatkannya bersama-sama (CREATE TABLE diikuti dengan CREATE INDEX) dalam satu batch untuk menghindari pengisian ulang sepenuhnya.

Spanner dapat menggabungkan dan mengurutkan ulang pernyataan dari batch yang berbeda, yang berpotensi mencampur pernyataan dari batch yang berbeda ke dalam satu perubahan atomik yang diterapkan ke database. Dalam setiap perubahan atomik, pernyataan dari batch yang berbeda terjadi dalam urutan yang arbitrer. Misalnya, jika satu batch pernyataan berisi ALTER TABLE table_name ALTER COLUMN column_name STRING(50) dan batch pernyataan lainnya berisi ALTER TABLE table_name ALTER COLUMN column_name STRING(20), Spanner akan membiarkan kolom tersebut dalam salah satu dari kedua status tersebut, tetapi status yang ditinggalkan tidak deterministik.

Opsi untuk pembaruan skema besar

Cara terbaik untuk membuat tabel dan sejumlah besar indeks pada tabel tersebut adalah dengan membuat semuanya secara bersamaan, sehingga hanya ada satu versi skema yang dibuat. Praktik terbaik adalah membuat indeks segera setelah tabel dalam daftar pernyataan DDL. Anda dapat membuat tabel dan indeksnya saat membuat database, atau dalam satu batch besar pernyataan. Jika Anda perlu membuat banyak tabel, masing-masing dengan banyak indeks, Anda dapat menyertakan semua pernyataan dalam satu batch. Anda dapat menyertakan beberapa ribu pernyataan dalam satu batch jika semua pernyataan dapat dieksekusi bersama menggunakan satu versi skema.

Jika pernyataan memerlukan pengisian ulang data indeks atau melakukan validasi data, pernyataan tersebut tidak dapat dieksekusi dalam satu versi skema. Hal ini terjadi untuk pernyataan CREATE INDEX saat tabel dasar indeks sudah ada (baik karena dibuat dalam batch pernyataan DDL sebelumnya, atau karena ada pernyataan dalam batch antara pernyataan CREATE TABLE dan CREATE INDEX yang memerlukan beberapa versi skema). Spanner mewajibkan tidak lebih dari 10 pernyataan tersebut dalam satu batch. Pembuatan indeks yang memerlukan pengisian ulang, khususnya, menggunakan beberapa versi skema per indeks, dan oleh karena itu, sebaiknya buat tidak lebih dari 3 indeks baru yang memerlukan pengisian ulang per hari (tidak peduli bagaimana indeks tersebut dikelompokkan, kecuali jika pengelompokan tersebut dapat menghindari pengisian ulang).

Misalnya, batch pernyataan ini akan menggunakan satu versi skema:

GoogleSQL

CREATE TABLE Singers (
SingerId   INT64 NOT NULL,
FirstName  STRING(1024),
LastName   STRING(1024),
) PRIMARY KEY (SingerId);

CREATE INDEX SingersByFirstName ON Singers(FirstName);

CREATE INDEX SingersByLastName ON Singers(LastName);

CREATE TABLE Albums (
SingerId   INT64 NOT NULL,
AlbumId    INT64 NOT NULL,
AlbumTitle STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId);

CREATE INDEX AlbumsByTitle ON Albums(AlbumTitle);

Sebaliknya, batch ini akan menggunakan banyak versi skema, karena UnrelatedIndex memerlukan pengisian ulang (karena tabel dasarnya harus sudah ada), dan hal tersebut memaksa semua indeks berikut juga memerlukan pengisian ulang (meskipun indeks tersebut berada dalam batch yang sama dengan tabel dasarnya):

GoogleSQL

CREATE TABLE Singers (
SingerId   INT64 NOT NULL,
FirstName  STRING(1024),
LastName   STRING(1024),
) PRIMARY KEY (SingerId);

CREATE TABLE Albums (
SingerId   INT64 NOT NULL,
AlbumId    INT64 NOT NULL,
AlbumTitle STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId);

CREATE INDEX UnrelatedIndex ON UnrelatedTable(UnrelatedIndexKey);

CREATE INDEX SingersByFirstName ON Singers(FirstName);

CREATE INDEX SingersByLastName ON Singers(LastName);

CREATE INDEX AlbumsByTitle ON Albums(AlbumTitle);

Sebaiknya pindahkan pembuatan UnrelatedIndex ke akhir batch, atau ke batch lain, untuk meminimalkan versi skema.

Tunggu hingga permintaan API selesai

Saat membuat permintaan projects.instances.databases.updateDdl (REST API) atau UpdateDatabaseDdl (RPC API), gunakan projects.instances.databases.operations.get (REST API) atau GetOperation (RPC API), masing-masing, untuk menunggu setiap permintaan selesai sebelum memulai permintaan baru. Menunggu setiap permintaan selesai memungkinkan aplikasi Anda melacak progres update skema. Proses ini juga menjaga backlog pembaruan skema yang tertunda agar ukurannya tetap dapat dikelola.

Pemuatan massal

Saat memuat data secara massal ke tabel baru, Anda dapat membuat indeks sekunder sebelum atau setelah memuat data. Memuat data lebih cepat jika Anda membuat indeks setelah memuat, tetapi ini berarti indeks harus diisi ulang.

Jika Anda memuat data terlebih dahulu, lalu membuat indeks, penyerapan data akan lebih cepat karena hanya tabel yang ditulis, dan pengisian ulang indeks selanjutnya dapat menulis data indeks dalam batch yang dioptimalkan yang lebih efisien daripada menulis data indeks bersama dengan data tabel. Namun, pengisian ulang indeks memerlukan beberapa versi skema dan memiliki batasan; seperti yang disebutkan dalam opsi untuk update besar, Anda tidak boleh membuat lebih dari 10 indeks yang memerlukan pengisian ulang dalam satu batch, dan sebaiknya tidak membuat lebih dari 3 indeks tersebut per hari.

Atau, Anda dapat membuat tabel dan indeks dalam batch yang sama, seperti yang dijelaskan dalam opsi untuk update besar. Cara ini menghindari pengisian ulang indeks, tetapi pemuatan data massal akan lebih lambat karena setiap indeks harus diperbarui saat data dimuat.

Pilihan mana yang lebih baik dalam situasi tertentu bergantung pada seberapa banyak data yang akan dimuat, kunci tabel dan indeks tertentu, jumlah indeks yang diperlukan, dan seberapa sering operasi pemuatan massal akan diperlukan dalam database yang sama. Aturan umumnya adalah lebih baik membuat indeks secara terpisah jika sejumlah besar data perlu dimuat ke dalam setiap tabel dan hanya beberapa indeks yang diperlukan.