[хочу странного] How to extend xid to bigint

qwwq
Дата: 02.04.2015 12:37:06
http://www.postgresql.org/docs/9.4/static/functions-info.html
The internal transaction ID type (xid) is 32 bits wide and wraps around every 4 billion transactions. However, these functions export a 64-bit format that is extended with an "epoch" counter so it will not wrap around during the life of an installation. The data type used by these functions, txid_snapshot, stores information about transaction ID visibility at a particular moment in time.


-- хочу вот этого вот -- "export [xid] a 64-bit format that is extended with an "epoch" counter so it will not wrap around during the life of an installation"
для xid-ов из pg_stat_activity


------------------
контекст:
-- нужен "естественный" генератор тиков в БД.
текущий txid негоден -- коммиты идут в другом порядке.
Есть желание поюзать
min(F(transactionid)) FROM pg_locks [WHERE database ...]
-- нужен {F} -- этот самый способ "extend" ... so it will not wrap around during the life of an installation".

PS: если задача в текущей постановке не решается -- есть ли другой подход к ней в том же контексте.
qwwq
Дата: 02.04.2015 13:08:13
Инфо к :

разница меж :
txid_current()
,( SELECT (transactionid)  FROM pg_locks WHERE pid =pg_backend_pid() AND transactionid IS NOT NULL LIMIT 1  )::text::bigint
константна в большом диапазоне времен. 0 -- для свежих базёнок. и , судя по всему , что-то похожее на N*[2^32::bigint]

SELECT
txid_current()
,( SELECT (transactionid)  FROM pg_locks WHERE pid =pg_backend_pid() AND transactionid IS NOT NULL LIMIT 1  )::text::bigint

,txid_current()
- ( SELECT (transactionid)  FROM pg_locks WHERE pid =pg_backend_pid() AND transactionid IS NOT NULL LIMIT 1  )::text::bigint
AS delta
, (2^32)::bigint
,(txid_current()
- ( SELECT (transactionid)  FROM pg_locks WHERE pid =pg_backend_pid() AND transactionid IS NOT NULL LIMIT 1  )::text::bigint
)/ ( (2^32)::bigint) AS delta_N
,( (2^32)::bigint)*5= 21474836480 AS check;
-------------------
23126819906;1651983426;21474836480;4294967296;5;t

-- итак -- где валяется это самое N ??? (или delta)
[как его поймать косвенно -- уже понятно -- вопрос, как не промахнуться в моменте]
Maxim Boguk
Дата: 02.04.2015 13:22:10
qwwq
http://www.postgresql.org/docs/9.4/static/functions-info.html
The internal transaction ID type (xid) is 32 bits wide and wraps around every 4 billion transactions. However, these functions export a 64-bit format that is extended with an "epoch" counter so it will not wrap around during the life of an installation. The data type used by these functions, txid_snapshot, stores information about transaction ID visibility at a particular moment in time.


-- хочу вот этого вот -- "export [xid] a 64-bit format that is extended with an "epoch" counter so it will not wrap around during the life of an installation"
для xid-ов из pg_stat_activity


------------------
контекст:
-- нужен "естественный" генератор тиков в БД.
текущий txid негоден -- коммиты идут в другом порядке.
Есть желание поюзать
min(F(transactionid)) FROM pg_locks [WHERE database ...]
-- нужен {F} -- этот самый способ "extend" ... so it will not wrap around during the life of an installation".

PS: если задача в текущей постановке не решается -- есть ли другой подход к ней в том же контексте.


А transactionid тоже вообще то идут не в порядке коммитов.
А в порядке begin ов (а реально даже сложнее).
Используйте nextval() из sequence и вам на всю жизнь хватит, не стоит привязываться к внутренним деталям базы.

--Maxim Boguk
www.postgresql-consulting.ru
qwwq
Дата: 02.04.2015 14:00:19
Maxim Boguk
А transactionid тоже вообще то идут не в порядке коммитов.
А в порядке begin ов (а реально даже сложнее).
Используйте nextval() из sequence и вам на всю жизнь хватит, не стоит привязываться к внутренним деталям базы.

--Maxim Boguk
www.postgresql-consulting.ru
господин КО не заметил, что я именно от этого и стартую и именно от этого (генератора чего бы то ни было) хочу уйти.

[то, что отслеживаемые во времени min(transactionid) |с поправкой на wraparround -- монотонны -- надеюсь не ускользнуло от КО ?]


но видимо таки господин КО прав. нужно привязаться к какому то sequence, [даже, вероятно не просто сиквенсу, но уложенному в табличку завершенным коммитом].

уж больно долго получается ловить это дело снаружи:
+
SELECT
	l1.transactionid::text::bigint
		+(txid_current()
			- ( SELECT (transactionid)  FROM pg_locks WHERE pid =pg_backend_pid() AND transactionid IS NOT NULL LIMIT 1  )::text::bigint
		) 
		-- текущий может иметь шифт больше самого старого на  2^32::bigint
		- CASE WHEN txid_current() < l1.transactionid::text::bigint
		+(txid_current()
			- ( SELECT (transactionid)  FROM pg_locks WHERE pid =pg_backend_pid() AND transactionid IS NOT NULL LIMIT 1  )::text::bigint
		) THEN 2^32::bigint ELSE 0 END
FROM pg_locks l1
WHERE  transactionid IS NOT NULL 
ORDER BY age(l1.transactionid) DESC -- olderst

LIMIT 1;
-------------------------------------
"Limit  (cost=88.15..88.15 rows=1 width=4) (actual time=7.024..7.024 rows=1 loops=1)"
"  InitPlan 1 (returns $0)"
"    ->  Limit  (cost=0.00..3.00 rows=1 width=4) (actual time=2.222..2.222 rows=1 loops=1)"
"          ->  Function Scan on pg_lock_status l_1  (cost=0.00..15.00 rows=5 width=4) (actual time=2.220..2.220 rows=1 loops=1)"
"                Filter: ((transactionid IS NOT NULL) AND (pid = pg_backend_pid()))"
"                Rows Removed by Filter: 1916"
"  InitPlan 2 (returns $1)"
"    ->  Limit  (cost=0.00..3.00 rows=1 width=4) (actual time=2.293..2.293 rows=1 loops=1)"
"          ->  Function Scan on pg_lock_status l_2  (cost=0.00..15.00 rows=5 width=4) (actual time=2.291..2.291 rows=1 loops=1)"
"                Filter: ((transactionid IS NOT NULL) AND (pid = pg_backend_pid()))"
"                Rows Removed by Filter: 2122"
"  ->  Sort  (cost=82.14..84.63 rows=995 width=4) (actual time=7.022..7.022 rows=1 loops=1)"
"        Sort Key: (age(l.transactionid))"
"        Sort Method: top-N heapsort  Memory: 25kB"
"        ->  Function Scan on pg_lock_status l  (cost=0.00..77.17 rows=995 width=4) (actual time=6.896..7.011 rows=5 loops=1)"
"              Filter: (transactionid IS NOT NULL)"
"              Rows Removed by Filter: 2369"
"Total runtime: 7.283 ms"

--предполагается, что интересуемся всегда из пишущей транзакции. т.е. мн-во (transactionid IS NOT NULL) не пусто

-- надо-бы как-то изнутри достучаться
qwwq
Дата: 02.04.2015 20:26:20
qwwq
[то, что отслеживаемые во времени min(transactionid) |с поправкой на wraparround -- монотонны -- надеюсь не ускользнуло от КО ?]
-- утверждение неверное, основано на неявной ошибочной посылке, что locks пополнятеся transactionid в порядке возбуждения транзакций

мои извинения КО
qwwq
Дата: 03.04.2015 12:00:48
Продолжаю хотеть странного:

теперь хочу увидеть последние закоммиченные (полностью) данные.
смотрю изнутри транзакции, "закоммиченные" коей данные хочу отбросить

т.е.
SELECT max(...) FROM tbl WHERE tbl.xmin<>F2(txid_current())

т.е. нужна F2(bigint)

подходы:
1. могу смотреть на себя через dblink. накладно (поднимать соединение в каждой такой сессии)
1.1. на себя через fdw -- ещё накладнее (как правило -- по соединению на каждый вызов --т.е. вообще куча соединений)
2. выяснять шифт между txid_current() и txid через pg_locks несколько накладно (см. выше), да и надо обеспечить непустоту pg_locks по своему pid на момент опроса
2.1. то же делается вставкой в любую, хоть времянку, с прямым опросом только что вставленного xmin (тоже дорого, хотя и дешевле хитровывернутого п.2.)

-- но наличие нормальной ф-ии возвертающей либо xid[==xmin] либо (txid_current()-xid::text::bigint) -- было бы премного удобней. Оно где-то есть ? пусть и неподоканное ? Или его таки нет ? (pg_proc навскидку ничего похожего не содержит)

разом нас, велосипедистов, багато:
http://www.sql.ru/forum/1120740/txid-current-xmin?mid=16698801&hl=xmin#16698801
и много ещё т.п. (включая лондайст и pgq)
Misha Tyurin
Дата: 03.04.2015 15:30:54
qwwq,

> нужен "естественный" генератор тиков в БД

зачем? что вы делаете? нету в базе никаких "тиков"
qwwq
Дата: 03.04.2015 16:29:44
Misha Tyurin
qwwq,

> нужен "естественный" генератор тиков в БД

зачем? что вы делаете? нету в базе никаких "тиков"

это отпавшая ветка хотения.


хочу простую вещь -- ф-ю, пусть волатильную, в моменте отображающую txid в xid. или обратно.
т.е. исчислять вот эту вот циклическую разницу, в несколько 2^32.

просто -- хочу, и не понимаю, почему её нет. наверное я не там ищу.

а делать я собираюсь всё то же самое, что нужно делать например в лондайсте и т.п. штуковинах -- выстравиать ивенты таблиц в порядке их коммитов. не зная момента коммита в момент записи ивента.
-- т.е. решать некорректную задачу в каком-то приближении. (какой-то из порядков полагая неважным, но не все).
теперь я просто хочу устанавливать хоть что-то о конкурентах. и смотрю, что для этого у меня есть в наличии. т.е. теперь мне захотелось почитать немного закоммиченных конкурентами данных[, за вычетом "закоммиченных" в текущей транзакции]
qwwq
Дата: 03.04.2015 16:47:36
qwwq,

поздравьте меня, я болван
SELECT (txid_current() % ((2^32)::bigint)) ::text::xid, txid_current() / ((2^32)::bigint)

бггггггггггггггг.
pavel2214444
Дата: 06.04.2015 12:04:49
<a href="http://ololo-alala.livejournal.com/">Бгг</a> интересно тут у вас