Dokumen 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 TrueTime
teknologi, adalah waktu saat
transaksi di-commit dalam 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
TIMESTAMPdengan opsi kolomallow_commit_timestampyang ditetapkan ketruedalam 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_TIMESTAMPuntuk 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 sebenarnya akan ditulis ke kolom yang ditentukan (Misalnya: kolom LastUpdateTime). Anda kemudian dapat menggunakan nilai kolom ini untuk membuat histori pembaruan ke 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 yang unik.
Stempel waktu commit Spanner memiliki granularitas 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
TIMESTAMPyang ada agar mendukung stempel waktu commit, - untuk mengubah kolom
TIMESTAMPyang 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 naik ideal untuk menjawab kueri dari waktu tertentu ke depan.DESC- Kunci turun menyimpan baris terbaru di bagian atas tabel. Kunci ini memberikan akses cepat ke catatan 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 dapat tidak konsisten adalah saat Anda membuat atau memperbarui skema.
Menggunakan stempel waktu commit dalam skenario berikut akan membuat hotspot yang mengurangi performa data:
Kolom stempel waktu commit sebagai bagian pertama dari 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 pembaruan. - Kolom hanya dapat berisi nilai di 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 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 berada di masa lalu. Misalnya:
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 akan dihapus, tetapi kolom tersebut masih berupa stempel waktu. Mengubah opsi tidak akan mengubah karakteristik kolom lainnya, 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 transaksi di-commit.
Pernyataan DML berikut memperbarui kolom LastUpdateTime dalam 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 Anda 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.
Mengkueri kolom stempel waktu commit
Contoh berikut mengkueri kolom stempel waktu commit dari tabel.
C++
C#
Go
Java
Node.js
PHP
Python
Ruby
Memberikan 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. Pembatasan 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 memudahkan 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 saat 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 dalam kolom Ts. Menyisipkan
tabel DocumentsHistory dengan tabel Documents akan memungkinkan lokalitas
data serta penyisipan dan pembaruan yang lebih efisien. Namun, tindakan ini juga menambahkan batasan bahwa baris induk dan turunan harus dihapus bersama-sama. Untuk menyimpan baris di DocumentHistory setelah baris di Documents dihapus, jangan sisipkan 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 ke konstanta.
Bandingkan apakah stempel waktu commit lebih baru dari waktu yang diberikan, melalui operator
>atau>=.Secara opsional, tambahkan batasan lebih lanjut ke klausa
WHEREdenganAND. Memperluas klausa denganORakan 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 konstanta—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 argumennya semua dievaluasi ke konstanta selama eksekusi kueri:
SELECT * FROM Performances
WHERE LastUpdateTime > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 30 DAY);
Langkah berikutnya
- Gunakan stempel waktu commit untuk membuat log perubahan dengan Go.