Topik ini menjelaskan cara menulis stempel waktu commit untuk setiap operasi penyisipan dan pembaruan
yang Anda lakukan dengan Spanner. Untuk menggunakan fitur ini, tetapkan
opsi allow_commit_timestamp
pada kolom TIMESTAMP
, lalu tulis
stempel waktu sebagai bagian dari setiap transaksi.
Ringkasan
Stempel waktu commit, berdasarkan teknologi TrueTime, adalah waktu saat transaksi di-commit di database. Opsi kolom allow_commit_timestamp
memungkinkan Anda menyimpan stempel waktu commit secara atomik ke dalam kolom.
Dengan menggunakan stempel waktu commit yang disimpan dalam tabel, Anda dapat menentukan urutan
mutasi yang tepat dan membuat fitur seperti log perubahan.
Untuk menyisipkan stempel waktu commit di database, selesaikan langkah-langkah berikut:
Buat kolom dengan jenis
TIMESTAMP
dengan opsi kolomallow_commit_timestamp
ditetapkan ketrue
dalam definisi skema. Misalnya:CREATE TABLE Performances ( ... LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true) ... ) PRIMARY KEY (...);
Jika Anda melakukan penyisipan atau pembaruan dengan DML, gunakan fungsi
PENDING_COMMIT_TIMESTAMP
untuk menulis stempel waktu commit.Jika Anda melakukan penyisipan atau pembaruan dengan mutasi, gunakan string placeholder
spanner.commit_timestamp()
pada penyisipan atau pembaruan ke kolom stempel waktu commit. Anda juga dapat menggunakan konstanta stempel waktu commit yang disediakan oleh library klien. Misalnya, konstanta ini di klien Java adalahValue.COMMIT_TIMESTAMP
.
Saat Spanner melakukan commit transaksi menggunakan placeholder ini sebagai nilai
kolom, stempel waktu commit yang sebenarnya akan ditulis ke kolom yang ditentukan (Misalnya: kolom LastUpdateTime
). Kemudian, Anda dapat menggunakan nilai kolom ini
untuk membuat histori pembaruan pada tabel.
Nilai stempel waktu commit tidak dijamin unik. Transaksi yang menulis ke kumpulan kolom yang tidak tumpang-tindih mungkin memiliki stempel waktu yang sama. Transaksi yang menulis ke kumpulan kolom yang tumpang-tindih memiliki stempel waktu unik.
Stempel waktu commit Spanner memiliki perincian mikrodetik,
dan dikonversi menjadi nanodetik saat disimpan di kolom TIMESTAMP
.
Membuat dan menghapus kolom stempel waktu commit
Gunakan opsi kolom allow_commit_timestamp
untuk menambahkan dan menghapus dukungan untuk stempel waktu commit:
- Saat membuat tabel baru untuk menentukan bahwa kolom mendukung stempel waktu commit.
- Saat mengubah tabel yang ada:
- untuk menambahkan kolom baru yang mendukung stempel waktu commit,
- untuk mengubah kolom
TIMESTAMP
yang ada guna mendukung stempel waktu commit, - untuk mengubah kolom
TIMESTAMP
yang ada guna menghapus dukungan stempel waktu commit
Kunci dan indeks
Anda dapat menggunakan kolom stempel waktu commit sebagai kolom kunci utama atau sebagai kolom
non-kunci. Kunci utama dapat ditentukan sebagai ASC
atau DESC
.
ASC
(default) - Kunci menaik ideal untuk menjawab kueri dari waktu tertentu dan seterusnya.DESC
- Tombol menurun menyimpan baris terbaru di bagian atas tabel. Laporan ini memberikan akses cepat ke data terbaru.
Opsi allow_commit_timestamp
harus konsisten di seluruh kunci utama tabel induk dan turunan. Jika opsi tidak konsisten di seluruh
kunci utama, Spanner akan menampilkan error. Satu-satunya saat opsi ini
dapat menjadi tidak konsisten adalah saat Anda membuat atau memperbarui skema.
Menggunakan stempel waktu commit dalam skenario berikut akan membuat hotspot yang mengurangi performa data:
Buat kolom stempel waktu sebagai bagian pertama kunci utama tabel:
CREATE TABLE Users ( LastAccess TIMESTAMP NOT NULL, UserId INT64 NOT NULL, ... ) PRIMARY KEY (LastAccess, UserId);
Bagian pertama kunci utama indeks sekunder:
CREATE INDEX UsersByLastAccess ON Users(LastAccess)
atau
CREATE INDEX UsersByLastAccessAndName ON Users(LastAccess, FirstName)
Hotspot mengurangi performa data, bahkan dengan kecepatan tulis yang rendah. Tidak ada overhead performa jika stempel waktu commit diaktifkan pada kolom non-kunci yang tidak diindeks.
Membuat kolom stempel waktu commit
DDL berikut membuat tabel dengan kolom yang mendukung stempel waktu commit.
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate Date,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate),
INTERLEAVE IN PARENT Singers ON DELETE CASCADE
Menambahkan opsi akan mengubah kolom stempel waktu sebagai berikut:
- Anda dapat menggunakan string placeholder
spanner.commit_timestamp()
(atau konstanta yang disediakan oleh library klien) untuk penyisipan dan pembaruan. - Kolom hanya dapat berisi nilai di masa lalu. Untuk informasi selengkapnya, lihat Memberikan nilai Anda sendiri untuk stempel waktu.
Opsi allow_commit_timestamp
peka huruf besar/kecil.
Menambahkan kolom stempel waktu commit ke tabel yang ada
Untuk menambahkan kolom stempel waktu commit ke tabel yang ada, gunakan pernyataan ALTER TABLE
. Misalnya, untuk menambahkan kolom LastUpdateTime
ke tabel Performances
, gunakan pernyataan berikut:
ALTER TABLE Performances ADD COLUMN LastUpdateTime TIMESTAMP
NOT NULL OPTIONS (allow_commit_timestamp=true)
Mengonversi kolom stempel waktu menjadi kolom stempel waktu commit
Anda dapat mengonversi kolom stempel waktu yang ada menjadi kolom stempel waktu commit, tetapi tindakan ini mengharuskan Spanner memvalidasi bahwa nilai stempel waktu yang ada sudah berlalu. Contoh:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=true)
Anda tidak dapat mengubah jenis data atau anotasi NULL
kolom dalam
pernyataan ALTER TABLE
yang menyertakan SET OPTIONS
. Untuk mengetahui detailnya, lihat
Bahasa Definisi Data.
Menghapus opsi stempel waktu commit
Jika Anda ingin menghapus dukungan stempel waktu commit dari kolom, gunakan opsi
allow_commit_timestamp=null
dalam pernyataan
ALTER TABLE
. Perilaku stempel waktu commit dihapus, tetapi kolomnya masih
stempel waktu. Mengubah opsi tidak akan mengubah karakteristik lain dari kolom, seperti jenis atau nullable (NOT NULL
). Misalnya:
ALTER TABLE Performances ALTER COLUMN LastUpdateTime
SET OPTIONS (allow_commit_timestamp=null)
Menulis stempel waktu commit menggunakan pernyataan DML
Anda menggunakan fungsi PENDING_COMMIT_TIMESTAMP
untuk menulis stempel waktu commit dalam pernyataan DML. Spanner memilih stempel waktu commit saat transaksi
di-commit.
Pernyataan DML berikut memperbarui kolom LastUpdateTime
di
tabel Performances
dengan stempel waktu commit:
UPDATE Performances SET LastUpdateTime = PENDING_COMMIT_TIMESTAMP()
WHERE SingerId=1 AND VenueId=2 AND EventDate="2015-10-21"
Contoh kode berikut menggunakan fungsi PENDING_COMMIT_TIMESTAMP
untuk menulis stempel waktu commit di kolom LastUpdateTime
.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Ruby
Stempel waktu commit hanya dapat ditulis ke kolom yang dianotasi dengan
opsi allow_commit_timestamp=true
.
Jika memiliki mutasi pada baris di beberapa tabel, Anda harus menentukan
spanner.commit_timestamp()
(atau konstanta library klien) untuk kolom stempel waktu commit di setiap tabel.
Membuat kueri kolom stempel waktu commit
Contoh berikut membuat kueri kolom stempel waktu commit tabel.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Berikan nilai Anda sendiri untuk kolom stempel waktu commit
Anda dapat memberikan nilai Anda sendiri untuk kolom stempel waktu commit, bukan
meneruskan spanner.commit_timestamp()
(atau konstanta library klien) sebagai
nilai kolom. Nilai harus berupa stempel waktu di masa lalu. Batasan ini
memastikan bahwa penulisan stempel waktu adalah operasi yang murah dan cepat. Server akan menampilkan error FailedPrecondition
jika stempel waktu mendatang ditentukan.
Membuat log perubahan
Misalkan Anda ingin membuat log perubahan dari setiap mutasi yang terjadi pada tabel, lalu menggunakan log perubahan tersebut untuk audit. Contohnya adalah tabel yang menyimpan histori perubahan pada dokumen pengolah kata. Stempel waktu commit mempermudah pembuatan log perubahan, karena stempel waktu dapat menerapkan pengurutan entri log perubahan. Anda dapat membuat log perubahan yang menyimpan histori perubahan pada dokumen tertentu menggunakan skema seperti contoh berikut:
CREATE TABLE Documents (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Contents STRING(MAX) NOT NULL,
) PRIMARY KEY (UserId, DocumentId);
CREATE TABLE DocumentHistory (
UserId INT64 NOT NULL,
DocumentId INT64 NOT NULL,
Ts TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true),
Delta STRING(MAX),
) PRIMARY KEY (UserId, DocumentId, Ts),
INTERLEAVE IN PARENT Documents ON DELETE NO ACTION;
Untuk membuat log perubahan, sisipkan baris baru di DocumentHistory
dalam transaksi
yang sama dengan tempat Anda menyisipkan atau memperbarui baris di Document
. Dalam penyisipan
baris baru di DocumentHistory
, gunakan placeholder
spanner.commit_timestamp()
(atau konstanta library klien) untuk memberi tahu
Spanner agar menulis stempel waktu commit ke kolom Ts
. Menyisipkan
tabel DocumentsHistory
dengan tabel Documents
akan memungkinkan lokalitas
data serta penyisipan dan pembaruan yang lebih efisien. Namun, hal ini juga menambahkan
batasan bahwa baris induk dan turunan
harus dihapus bersama. Untuk mempertahankan baris di DocumentHistory
setelah baris di Documents
dihapus, jangan tumpang-tindih tabel.
Mengoptimalkan kueri data terbaru dengan stempel waktu commit
Stempel waktu commit memungkinkan pengoptimalan Spanner yang dapat mengurangi I/O kueri saat mengambil data yang ditulis setelah waktu tertentu.
Untuk mengaktifkan pengoptimalan ini, klausa WHERE
kueri harus menyertakan perbandingan antara kolom stempel waktu commit tabel dan waktu tertentu yang Anda berikan, dengan atribut berikut:
Berikan waktu tertentu sebagai ekspresi konstanta: literal, parameter, atau fungsi yang argumennya sendiri dievaluasi menjadi konstanta.
Bandingkan apakah stempel waktu commit lebih baru dari waktu yang ditentukan, melalui operator
>
atau>=
.Secara opsional, tambahkan batasan lebih lanjut ke klausa
WHERE
denganAND
. Memperluas klausul denganOR
akan mendiskualifikasi kueri dari pengoptimalan ini.
Misalnya, pertimbangkan tabel Performances
berikut, yang menyertakan
kolom stempel waktu commit:
CREATE TABLE Performances (
SingerId INT64 NOT NULL,
VenueId INT64 NOT NULL,
EventDate DATE,
Revenue INT64,
LastUpdateTime TIMESTAMP NOT NULL OPTIONS (allow_commit_timestamp=true)
) PRIMARY KEY (SingerId, VenueId, EventDate);
Kueri ini mendapatkan manfaat dari pengoptimalan stempel waktu commit yang dijelaskan sebelumnya, karena memiliki perbandingan lebih besar dari atau sama dengan antara kolom stempel waktu commit tabel dan ekspresi konstan—dalam hal ini, literal:
SELECT * FROM Performances WHERE LastUpdateTime >= "2022-05-01";
Kueri berikut juga memenuhi syarat untuk pengoptimalan, karena memiliki perbandingan lebih besar dari antara stempel waktu commit dan fungsi yang semua argumennya dievaluasi menjadi konstanta selama eksekusi kueri:
SELECT * FROM Performances
WHERE LastUpdateTime > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
Langkah selanjutnya
- Gunakan stempel waktu commit untuk membuat log perubahan dengan Go.