Bagaimana cara membandingkan xmin dan txid_current () setelah pembungkus ID transaksi?

12

Selain kolom regulernya, tabel Postgres juga memiliki berbagai kolom sistem . Salah satunya,, xminmenyimpan ID transaksi yang digunakan untuk membuat baris. Tipe datanya adalah xid, integer empat byte yang membungkus di beberapa titik (yaitu belum tentu unik). Fungsi txid_current()pada gilirannya mengembalikan ID transaksi saat ini, tetapi sebagai bigint, karena "diperpanjang dengan penghitung" zaman "sehingga tidak akan membungkus selama masa instalasi" (mengutip manual ).

Jika penyelesaian transaksi belum terjadi, kedua nilai tersebut tampaknya cocok:

# CREATE TABLE test (label text);
CREATE TABLE
# INSERT INTO test VALUES ('test') RETURNING txid_current();
 txid_current 
--------------
   674500
(1 row)
INSERT 0 1
# SELECT xmin FROM test;
  xmin  
--------
 674500
(1 row)

Tetapi saya bertanya-tanya: apakah kedua nilai ini selalu sebanding? Sejauh yang saya mengerti, txid_current()akan terus memberikan nilai-nilai unik setelah penyelesaian ID transaksi (paling banyak 2 ^ 32 transaksi) dan xminakan mulai dari nol. Ini berarti keduanya mulai mengembalikan nilai yang berbeda pada saat itu?

Dan jika ini benar, apakah ada cara untuk mengekstrak rutin xiddari txid_current()hasil sehingga akan cocok xminentri dalam tabel (misalnya pengecoran txid_current()ke integer)?

Sunting : Jelaskan bahwa saya peduli tentang apa yang terjadi setelah penyelesaian ID transaksi, yang sangat mungkin terjadi jauh sebelum 2 ^ 32 transaksi. Terima kasih kepada Daniel Vérité karena mencatat ini di komentar.

Tomka
sumber
1
Anda mengabaikan fakta bahwa sistem akan VACUUM FREEZEdan menimpa xminbaris pada jauh sebelum sampul 2 ^ 32. Lihat Membekukan Tuples Anda Mati untuk gambaran umum tentang subjek.
Daniel Vérité
Benar, saya mengabaikan fakta ini, terima kasih telah menunjukkannya. Dan memang pembekuan akan terjadi jauh sebelum 2 ^ 32. Namun, bahkan dengan yang lama xminmenjadi beku pertanyaannya masih berdiri bagaimana baru (biasa) xmindibandingkan dengan yang kemudian dieksekusi txid_current().
tomka
1
Perlu dicatat bahwa PostgreSQL akan ditutup jika ada kurang dari 1 juta transaksi yang tersisa sampai sampulnya .
user103153

Jawaban:

5

Anda dapat menghapus zaman ditambahkan untuk mencocokkan nilai dalam xmin, yaitu mengekstrak 4-byte integerdari bigint. Karena xmintipe xiddan bukan (ditandatangani!) integer, Kami membandingkan textrepresentasi:

SELECT * FROM test
WHERE  xmin::text = (txid_current() % (2^32)::bigint)::text;

Penjelasan detail:

Erwin Brandstetter
sumber