Spanner memungkinkan Anda membuat pembaruan skema tanpa periode nonaktif. Anda dapat mengupdate skema database yang ada dengan beberapa cara:
Di konsol Google Cloud
Kirim perintah
ALTER TABLE
di halaman Spanner Studio.Untuk mengakses halaman Spanner Studio, klik Spanner Studio dari halaman Ringkasan database atau Ringkasan tabel.
Menggunakan alat command line
gcloud spanner
Kirim perintah
ALTER TABLE
dengan menggunakan perintah gcloud spanner database ddl update.Menggunakan library klien
Menggunakan REST API
projects.instances.databases.updateDdl
Menggunakan RPC API
UpdateDatabaseDdl
Update skema yang didukung
Spanner mendukung pembaruan skema berikut dari database yang sudah ada:
- Buat tabel baru. Kolom dalam tabel baru bisa
NOT NULL
. - Hapus sebuah tabel jika tidak ada tabel lain yang disisipi di dalamnya, dan tabel tersebut tidak memiliki indeks sekunder.
- Membuat atau menghapus tabel dengan {i>foreign key<i}.
- Menambahkan atau menghapus {i>foreign key<i} dari tabel yang ada.
- Tambahkan kolom non-kunci ke tabel mana pun. Kolom non-kunci baru tidak boleh berupa
NOT NULL
. - Lepaskan kolom non-kunci dari tabel mana pun, kecuali jika digunakan oleh indeks sekunder, kunci asing, kolom hasil yang disimpan, atau batasan pemeriksaan.
- Tambahkan
NOT NULL
ke kolom non-kunci, kecualiARRAY
kolom. - Hapus
NOT NULL
dari kolom non-kunci. - Ubah kolom
STRING
menjadi kolomBYTES
atau kolomBYTES
menjadi kolomSTRING
. - Menambah atau mengurangi batas panjang untuk jenis
STRING
atauBYTES
(termasuk hinggaMAX
), kecuali jika kolom kunci utama yang diwarisi oleh satu atau beberapa tabel turunan. - Aktifkan atau nonaktifkan stempel waktu commit di kolom nilai dan kunci utama.
- Menambahkan atau menghapus indeks sekunder.
- Tambahkan atau hapus batasan pemeriksaan dari tabel yang ada.
- Menambahkan atau menghapus kolom tersimpan yang dihasilkan dari tabel yang ada.
- Buat paket statistik pengoptimal yang baru.
Performa update skema
Pembaruan skema di Spanner tidak memerlukan periode nonaktif. Saat mengeluarkan sekumpulan pernyataan DDL ke database Spanner, Anda dapat terus menulis dan membaca dari database tanpa gangguan sementara Spanner menerapkan update sebagai operasi yang berjalan lama.
Waktu yang diperlukan untuk mengeksekusi pernyataan DDL bergantung pada apakah update
memerlukan validasi data yang ada atau pengisian ulang data apa pun. Misalnya,
jika Anda menambahkan anotasi NOT NULL
ke kolom yang ada, Spanner harus
membaca semua nilai dalam kolom tersebut untuk memastikan kolom tersebut tidak berisi
nilai NULL
. Langkah ini dapat memerlukan waktu lama jika ada banyak data yang harus divalidasi. Contoh lainnya adalah jika Anda menambahkan indeks ke database: Spanner mengisi ulang indeks menggunakan data yang ada, dan proses tersebut dapat memerlukan waktu lama, bergantung pada definisi indeks dan ukuran tabel dasar yang terkait. Namun, jika Anda menambahkan kolom baru ke tabel, tidak ada
data yang ada untuk divalidasi, sehingga Spanner dapat melakukan pembaruan dengan
lebih cepat.
Singkatnya, pembaruan skema yang tidak memerlukan Spanner untuk memvalidasi data yang ada dapat terjadi dalam hitungan menit. Pembaruan skema yang memerlukan validasi dapat memerlukan waktu lebih lama, bergantung pada jumlah data yang ada yang perlu divalidasi, tetapi validasi data terjadi di latar belakang pada prioritas yang lebih rendah daripada traffic produksi. Pembaruan skema yang memerlukan validasi data dibahas secara lebih mendetail di bagian berikutnya.
Update skema yang divalidasi terhadap definisi tampilan
Saat Anda membuat pembaruan skema, Spanner memvalidasi bahwa pembaruan tersebut tidak akan membatalkan kueri yang digunakan untuk menentukan tampilan yang sudah ada. Jika validasi berhasil, update skema akan berhasil. Jika validasi tidak berhasil, pembaruan skema akan gagal. Lihat Praktik terbaik saat membuat tampilan untuk mengetahui detailnya.
Pembaruan skema yang memerlukan validasi data
Anda dapat membuat pembaruan skema yang memerlukan validasi bahwa data yang ada memenuhi batasan baru. Saat pembaruan skema memerlukan validasi data, Spanner tidak akan mengizinkan pembaruan skema yang bertentangan untuk entitas skema yang terpengaruh dan memvalidasi data di latar belakang. Jika validasi berhasil, pembaruan skema akan berhasil. Jika validasi tidak berhasil, pembaruan skema tidak akan berhasil. Operasi validasi dijalankan sebagai operasi yang berjalan lama. Anda dapat memeriksa status operasi ini untuk menentukan apakah operasi berhasil atau gagal.
Misalnya, Anda telah menentukan tabel Songwriters
dalam skema:
GoogleSQL
CREATE TABLE Songwriters (
Id INT64 NOT NULL,
FirstName STRING(1024),
LastName STRING(1024),
Nickname STRING(MAX),
OpaqueData BYTES(MAX),
) PRIMARY KEY (Id);
Pembaruan skema berikut diizinkan, tetapi memerlukan validasi dan mungkin memerlukan waktu lebih lama untuk diselesaikan, bergantung pada jumlah data yang ada:
Menambahkan anotasi
NOT NULL
ke kolom non-kunci. Contoh:ALTER TABLE Songwriters ALTER COLUMN Nickname STRING(MAX) NOT NULL;
Mengurangi panjang kolom. Contoh:
ALTER TABLE Songwriters ALTER COLUMN FirstName STRING(10);
Mengubah dari
BYTES
menjadiSTRING
. Contoh:ALTER TABLE Songwriters ALTER COLUMN OpaqueData STRING(MAX);
Mengaktifkan stempel waktu commit pada kolom
TIMESTAMP
yang sudah ada. Contoh:ALTER TABLE Albums ALTER COLUMN LastUpdateTime SET OPTIONS (allow_commit_timestamp = true);
Menambahkan batasan pemeriksaan ke tabel yang ada.
Menambahkan kolom tersimpan yang dihasilkan ke tabel yang ada.
Membuat tabel baru dengan {i>foreign key<i}.
Menambahkan {i>foreign key<i} ke tabel yang ada.
Update skema ini akan gagal jika data yang mendasarinya tidak memenuhi batasan
baru. Misalnya, pernyataan ALTER TABLE Songwriters ALTER COLUMN Nickname
STRING(MAX) NOT NULL
di atas akan gagal jika ada nilai dalam kolom Nickname
adalah NULL
, karena data yang ada tidak memenuhi batasan NOT NULL
dari definisi yang baru.
Validasi data bisa memakan waktu beberapa menit hingga beberapa jam. Waktu untuk menyelesaikan validasi data bergantung pada:
- Ukuran {i>dataset<i}
- Kapasitas komputasi instance
- Beban pada instance
Beberapa update skema dapat mengubah perilaku permintaan ke database sebelum update skema selesai. Misalnya, jika Anda menambahkan NOT NULL
ke kolom, Spanner akan segera mulai menolak operasi tulis untuk permintaan baru yang menggunakan NULL
untuk kolom tersebut. Jika update skema baru pada akhirnya gagal untuk validasi data, akan ada periode waktu saat operasi tulis diblokir, meskipun penulisan tersebut telah diterima oleh skema lama.
Anda dapat membatalkan operasi validasi data yang berjalan lama menggunakan metode projects.instances.databases.operations.cancel
atau gcloud spanner operations
.
Urutan eksekusi pernyataan dalam batch
Jika menggunakan Google Cloud CLI, REST API, atau RPC API, Anda dapat menerbitkan batch
yang berisi satu atau beberapa pernyataan CREATE
, ALTER
, atau DROP
.
Spanner menerapkan pernyataan dari batch yang sama secara berurutan, dan berhenti di error pertama. Jika penerapan pernyataan menghasilkan error, pernyataan tersebut akan di-roll back. Hasil dari pernyataan yang diterapkan sebelumnya dalam batch tidak di-roll back.
Spanner dapat menggabungkan dan menyusun ulang pernyataan dari batch yang berbeda, yang berpotensi mencampur pernyataan dari batch yang berbeda menjadi satu perubahan atomik yang diterapkan pada database. Dalam setiap perubahan atomik, pernyataan dari batch yang berbeda terjadi dalam urutan arbitrer. Misalnya, jika satu batch pernyataan
berisi ALTER TABLE MyTable ALTER COLUMN MyColumn STRING(50)
dan
batch pernyataan lainnya berisi ALTER TABLE MyTable ALTER COLUMN MyColumn
STRING(20)
, Spanner akan membiarkan kolom tersebut dalam salah satu dari dua status tersebut,
tetapi tidak ditentukan.
Versi skema yang dibuat selama update skema
Spanner menggunakan pembuatan versi skema sehingga tidak ada periode nonaktif selama update skema ke database yang besar. Spanner mempertahankan versi skema lama untuk mendukung pembacaan saat update skema diproses. Spanner kemudian membuat satu atau beberapa versi baru skema untuk memproses pembaruan skema. Setiap versi berisi hasil dari kumpulan pernyataan dalam satu perubahan atomik, seperti yang dijelaskan di atas.
Versi skema tidak harus terkait one-to-one dengan batch pernyataan DDL atau pernyataan DDL individual. Beberapa pernyataan DDL individual, seperti pembuatan indeks untuk tabel dasar yang sudah ada atau pernyataan yang memerlukan validasi data, akan menghasilkan beberapa versi skema. Dalam kasus lain, beberapa pernyataan DDL dapat dikelompokkan bersama dalam satu versi. Versi skema lama dapat menggunakan resource server dan penyimpanan yang signifikan, dan akan dipertahankan sampai masa berlakunya habis (tidak lagi diperlukan untuk menayangkan pembacaan data versi yang lebih lama).
Tabel berikut menunjukkan waktu yang dibutuhkan Spanner untuk memperbarui skema.
Operasi skema | Perkiraan durasi |
---|---|
CREATE TABLE |
Menit |
CREATE INDEX |
Menit hingga jam, jika tabel dasar dibuat sebelum indeks. Menit, jika pernyataan dieksekusi bersamaan dengan pernyataan |
DROP TABLE |
Menit |
DROP INDEX |
Menit |
ALTER TABLE ... ADD COLUMN |
Menit |
ALTER TABLE ... ALTER COLUMN |
Menit hingga jam, jika validasi latar belakang diperlukan. Menit, jika validasi latar belakang tidak diperlukan. |
ALTER TABLE ... DROP COLUMN |
Menit |
ANALYZE |
Menit hingga jam, bergantung pada ukuran database. |
Perubahan jenis data dan aliran data
Jika Anda mengubah jenis data kolom yang diamati oleh aliran
perubahan, kolom column_types
dari data aliran data
perubahan berikutnya
yang relevan akan mencerminkan jenis barunya, seperti halnya data JSON old_values
dalam
kolom mods
kumpulan data.
new_values
dari kolom mods
catatan aliran data selalu cocok dengan
jenis kolom saat ini. Mengubah jenis data kolom yang dipantau tidak akan
memengaruhi data aliran data perubahan sebelum perubahan tersebut.
Dalam kasus khusus perubahan BYTES
-ke-STRING
,
Spanner memvalidasi nilai lama
kolom sebagai bagian dari pembaruan skema.
Hasilnya, Spanner telah mendekode nilai jenis BYTES
lama dengan aman menjadi string pada saat Spanner menulis data aliran perubahan berikutnya.
Praktik terbaik untuk pembaruan skema
Bagian berikut menjelaskan praktik terbaik untuk memperbarui skema.
Prosedur sebelum Anda mengeluarkan pembaruan skema
Sebelum Anda mengeluarkan pembaruan skema:
Pastikan semua data yang ada dalam database yang Anda ubah memenuhi batasan yang diterapkan oleh update skema. Keberhasilan beberapa jenis update skema bergantung pada data dalam database dan bukan hanya skemanya saat ini. Oleh karena itu, update skema database pengujian yang berhasil tidak menjamin keberhasilan update skema database produksi. Berikut adalah beberapa contoh umumnya:
- Jika Anda menambahkan anotasi
NOT NULL
ke kolom yang ada, pastikan kolom tersebut tidak berisi nilaiNULL
yang ada. - Jika Anda mempersingkat panjang kolom
STRING
atauBYTES
yang diizinkan, pastikan semua nilai yang ada di kolom tersebut memenuhi batasan panjang yang diinginkan.
- Jika Anda menambahkan anotasi
Jika Anda menulis ke kolom, tabel, atau indeks yang mengalami pembaruan skema, pastikan nilai yang Anda tulis memenuhi batasan baru.
Jika Anda memindahkan kolom, tabel, atau indeks, pastikan Anda tidak masih menulis ke atau membaca dari kolom, tabel, atau indeks tersebut.
Membatasi frekuensi pembaruan skema
Jika Anda melakukan terlalu banyak pembaruan skema dalam waktu singkat, Spanner
dapat throttle
memproses pembaruan skema dalam antrean. Ini karena Spanner membatasi
jumlah ruang untuk menyimpan versi skema. Pembaruan skema Anda dapat dibatasi
jika ada terlalu banyak versi skema lama dalam periode retensi. Laju perubahan skema maksimum 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 sederhana (lebih sedikit jika perubahan skema memerlukan beberapa versi) dalam periode retensi data. 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 pengelompokan pernyataan DDL Anda, dan urutannya dalam setiap batch, dapat memengaruhi jumlah versi skema yang dihasilkan. Untuk memaksimalkan jumlah update skema yang dapat dilakukan selama periode waktu tertentu, Anda harus menggunakan batch yang meminimalkan jumlah versi skema. Beberapa aturan praktis dijelaskan dalam update besar.
Seperti yang dijelaskan dalam versi skema, beberapa pernyataan DDL akan membuat beberapa versi skema, dan versi ini penting saat mempertimbangkan pengelompokan dan urutan dalam setiap batch. Ada dua jenis pernyataan utama yang dapat membuat beberapa versi skema:
- Pernyataan yang mungkin perlu mengisi ulang data indeks, seperti
CREATE INDEX
- Pernyataan yang mungkin perlu memvalidasi data yang ada, seperti menambahkan
NOT NULL
Namun, jenis pernyataan ini selalu tidak membuat beberapa versi skema. Spanner akan mencoba mendeteksi kapan jenis pernyataan ini dapat dioptimalkan untuk menghindari penggunaan beberapa versi skema, yang bergantung pada pengelompokan.
Misalnya, pernyataan CREATE INDEX
yang muncul dalam batch yang sama dengan pernyataan CREATE TABLE
untuk tabel dasar indeks, tanpa pernyataan intervensi untuk tabel lain, dapat menghindari pengisian 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 tidak dapat mengelompokkan pernyataan DDL untuk menghindari pembuatan banyak versi skema, Anda harus membatasi jumlah pembaruan skema hanya untuk skema satu database dalam periode retensinya. Tingkatkan periode waktu saat Anda melakukan pembaruan skema agar Spanner dapat menghapus skema versi lama sebelum versi baru dibuat.
- Untuk beberapa sistem manajemen database relasional, ada paket software yang membuat serangkaian pembaruan skema upgrade dan downgrade pada database pada setiap deployment produksi. Jenis proses ini tidak direkomendasikan untuk Spanner.
- Spanner dioptimalkan untuk menggunakan kunci utama guna mempartisi data untuk solusi multitenancy. Solusi multitenancy yang menggunakan tabel terpisah untuk setiap pelanggan dapat mengakibatkan backlog besar operasi pembaruan skema yang memerlukan waktu lama untuk diselesaikan.
- Update skema yang memerlukan validasi atau pengisian ulang indeks menggunakan lebih banyak resource server karena setiap pernyataan membuat beberapa versi skema secara internal.
Opsi untuk update skema berukuran besar
Cara terbaik untuk membuat tabel dan sejumlah besar indeks pada tabel tersebut adalah dengan membuat semuanya secara bersamaan, sehingga hanya akan ada satu versi skema yang dibuat. Praktik terbaiknya adalah membuat indeks tepat setelah tabel dalam daftar pernyataan DDL. Anda dapat membuat tabel dan indeksnya saat membuat database, atau dalam satu batch besar pernyataan. Jika 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 ketika semua pernyataan dapat dijalankan bersama menggunakan satu versi skema.
Jika suatu pernyataan memerlukan pengisian ulang data indeks atau melakukan validasi data, pernyataan tidak dapat dijalankan 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 mengharuskan tidak ada lebih
dari 10 pernyataan seperti itu dalam satu batch. Pembuatan indeks yang memerlukan pengisian ulang, secara khusus, menggunakan beberapa versi skema per indeks. Oleh karena itu, merupakan aturan praktis untuk membuat tidak lebih dari 3 indeks baru yang memerlukan pengisian ulang per hari (terlepas dari cara pengelompokannya, 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 yang memaksa semua indeks berikut juga memerlukan pengisian ulang (meskipun keduanya 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.
Menunggu 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), untuk menunggu
setiap permintaan selesai sebelum memulai permintaan baru. Dengan menunggu setiap permintaan selesai diproses, aplikasi Anda dapat melacak progres update skema. Hal ini juga mempertahankan backlog update skema yang tertunda ke ukuran
yang dapat dikelola.
Pemuatan massal
Jika Anda memuat data secara massal ke dalam tabel setelah dibuat, biasanya akan lebih efisien untuk membuat indeks setelah data dimuat. Jika Anda menambahkan beberapa indeks, membuat database dengan semua tabel dan indeks dalam skema awal mungkin akan lebih efisien, seperti yang dijelaskan dalam opsi untuk update besar.