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
di kolom TIMESTAMP
, lalu tulis stempel waktu sebagai bagian dari setiap transaksi.
Ringkasan
Stempel waktu commit, berdasarkan teknologi TrueTime, adalah waktu ketika transaksi di-commit dalam database. Opsi kolom allow_commit_timestamp
memungkinkan Anda menyimpan stempel waktu commit ke dalam kolom secara atomik.
Dengan menggunakan stempel waktu commit yang disimpan dalam tabel, Anda dapat menentukan
urutan mutasi yang tepat dan fitur build seperti log perubahan.
Untuk menyisipkan stempel waktu commit ke database Anda, 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 pada kolom stempel waktu commit. Anda juga dapat menggunakan konstanta stempel waktu commit yang disediakan oleh library klien. Misalnya, konstanta pada klien Java ini adalahValue.COMMIT_TIMESTAMP
.
Saat Spanner meng-commit transaksi menggunakan placeholder ini sebagai nilai kolom, stempel waktu commit yang sebenarnya akan ditulis ke kolom yang ditentukan (Misalnya: kolom LastUpdateTime
). Anda kemudian dapat menggunakan nilai kolom ini
untuk membuat riwayat pembaruan pada tabel.
Nilai stempel waktu commit tidak dijamin akan 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 yang unik.
Stempel waktu commit Spanner memiliki perincian mikrodetik,
dan dikonversi menjadi nanodetik saat disimpan dalam TIMESTAMP
kolom.
Membuat dan menghapus kolom stempel waktu commit
Gunakan opsi kolom allow_commit_timestamp
untuk menambahkan dan menghapus dukungan bagi
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) - Tombol menaik ideal untuk menjawab kueri dari waktu tertentu ke depan.DESC
- Kunci menurun menyimpan baris terbaru di bagian atas tabel. Dasbor ini memberikan akses cepat ke data terbaru.
Opsi allow_commit_timestamp
harus konsisten di seluruh kunci utama tabel induk dan turunan. Jika opsi ini tidak konsisten di seluruh kunci utama, Spanner akan menampilkan error. Satu-satunya situasi ketika opsi
menjadi tidak konsisten adalah saat Anda membuat atau memperbarui skema.
Menggunakan stempel waktu commit dalam skenario berikut akan membuat hotspot yang mengurangi performa data:
Jalankan 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 dari 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 update. - Kolom hanya boleh berisi nilai pada masa lalu. Untuk mengetahui 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 sudah 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 melakukan hal ini memerlukan Spanner untuk memvalidasi bahwa nilai stempel waktu yang ada berada di masa lalu. 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 kolom masih
merupakan stempel waktu. Mengubah opsi ini tidak akan mengubah karakteristik lain dari kolom, seperti jenis atau nullability (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 commit transaksi.
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 dianotasikan dengan opsi allow_commit_timestamp=true
.
Jika memiliki mutasi pada baris dalam beberapa tabel, Anda harus menentukan spanner.commit_timestamp()
(atau konstanta library klien) untuk kolom stempel waktu commit di setiap tabel.
Mengkueri kolom stempel waktu commit
Contoh berikut mengkueri kolom stempel waktu commit dalam 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, dan 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
menampilkan error FailedPrecondition
jika stempel waktu yang akan datang ditentukan.
Membuat {i>changelog<i}
Anggaplah Anda ingin membuat log perubahan untuk setiap mutasi yang terjadi pada tabel, lalu menggunakan log perubahan tersebut untuk mengaudit. Contohnya adalah tabel yang menyimpan riwayat perubahan pada dokumen pengolahan kata. Stempel waktu commit mempermudah pembuatan log perubahan, karena stempel waktu dapat memberlakukan pengurutan entri log perubahan. Anda dapat membuat log perubahan yang menyimpan histori perubahan pada dokumen tertentu menggunakan skema seperti dalam 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 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
. Menggabungkan
tabel DocumentsHistory
dengan tabel Documents
akan memungkinkan lokalitas
data serta penyisipan dan pembaruan yang lebih efisien. Namun, cara ini juga menambahkan batasan sehingga baris induk dan turunan harus dihapus bersama. Untuk mempertahankan baris di DocumentHistory
setelah baris
di Documents
dihapus, jangan menyisipkan tabel.
Mengoptimalkan kueri data terbaru dengan stempel waktu commit
Commit stempel waktu mengaktifkan 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 konstan: literal, parameter, atau fungsi yang argumennya sendiri dievaluasi ke konstanta.
Bandingkan apakah stempel waktu commit lebih baru daripada waktu tertentu, melalui operator
>
atau>=
.Secara opsional, tambahkan pembatasan lebih lanjut ke klausa
WHERE
denganAND
. Memperluas klausa denganOR
akan mendiskualifikasi kueri dari pengoptimalan ini.
Misalnya, perhatikan 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 yang 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 yang lebih besar dari stempel waktu commit dan fungsi yang semua argumennya dievaluasi ke 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.