[Postgresql] Duza transakcja
Piotr Gasidlo - 11-05-2007 12:32
[Postgresql] Duza transakcja
Witam,
Stworzyłem sobie funkcję w plperl do generowania losowych stringów o prototypie:
common.random_string(chars varchar, length integer) returns varchar;
Ogolnie, jak chce wygenerować sobie 32 znakowe losowy string zawierający tylko znaki '1234567890abcdef' to robie:
select common.random_string('1234567890abcdef', 32);
random_string ---------------------------------- 6e5a552653b815e287e355584cead8f3 (1 row)
Teraz problem. Mam tabelę z 150k rekordami. Baza jest aktywnie używana. I chce dodać do kazdego rekordu wlasnie taką losową zmienną. Tj.
alter table users.users add random_code varchar(32); alter table users.users alter random_code set default common.random_string('1234567890abcdef', 32);
No i teraz (jeszcze tego nie wykonuje ;-)
begin; update users.users set random_code = (select common.random_string('1234567890abcdef', 32) where id > 0) where random_code is null; commit;
To where id > 0 dopisałem, bo stwierdziłem, ze bez tego postgresql evaluuje common.random_string() tylko jednokrotnie i wszystkim przypisuje to samo random_string.
Problem polega na tym, ze chce update zrobić w taki sposób aby nie blokować bazy. Czy da się to zrobić w ramach jednej transakcji (tylko testowo, aby pozniej zobaczyć na wyniki i zrobić ew. commit/rollback)?
Docelowo nie potrzebuje nawet transakcji, lecz z moich obserwacji wynika, ze postgresql i tak zrobic update w jednej transakcji (dobra, PostgreSQL realizuje dobrze ACID w końcu) a tym samym istnieje mozliwosc nagłego przyblokowania bazy.
Czy jest możliwość zapistania tego update jako kilku updateów, nie koniecznie w ramach begin; ..; commit; Tak aby wykonanie tego zapytania trwało krótko i nie blokowało na długo bazy danych? Myśle o jakimś triku.
Ostatecznie skłaniam się do napisania skryptu z kodem:
update users.users set random_code = (select common.random_string('1234567890abcdef', 32) where id > 0) where random_code is null and id < 1000; update users.users set random_code = (select common.random_string('1234567890abcdef', 32) where id > 0) where random_code is null and id < 2000; ....
lecz pytam, czy istnieje mozliwosc zrealizowania tego w ramach jednego zapytania?
-- Piotr 'QuakeR' Gasidło, BOFH @ pandora.barbara.eu.org ############## sending lusers to /dev/null since 1998 ##### Waiting for tomorrow, for a little ray of light ### Waiting for tomorrow just to see your smile again
cienki_bolek - 11-05-2007 12:32
Piotr Gasidlo napisał(a): > Witam, > > Stworzyłem sobie funkcję w plperl do generowania losowych stringów > o prototypie: > > begin; > update users.users set random_code = (select common.random_string('1234567890abcdef', 32) where id > 0) where random_code is null; > commit; > > lecz pytam, czy istnieje mozliwosc zrealizowania tego w ramach jednego > zapytania? >
a w 2 moze byc? zrobic dodatkowa tabelke z id userow i tam wygenerowac te stringi. potem tylko update na users.users lub troche zabawy z limit, offset
cb
=?ISO-8859-2?Q?Micha=B3_Zaborowski?= - 11-05-2007 12:32
Dnia 2007-04-26 15:23, Użytkownik Piotr Gasidlo napisał :
[...] > > lecz pytam, czy istnieje mozliwosc zrealizowania tego w ramach jednego > zapytania? > Pytanie brzmi - czy jest to konieczne? Chodzi o to, że w PG procedury działają w kontekście transakcji, a locki istnieją do końca transakcji... Proponuję rozbić to na bloki po 1000 i odpalać kawałkami. Skoro chodzi o nadanie losowego stringa, to można zrobić - "daj kolejne 1000 idów i nadaj im losowy string". To w transakcję i takie coś należałoby odpalać do końca - naszego lub ich :)
-- Pozdrawiam, Michał Zaborowski (TeXXaS)
zanotowane.pldoc.pisz.plpdf.pisz.pleffulla.pev.pl
|
[PostgreSQL] - jak =?ISO-8859-2?Q?zabezpieczy=E6_interesy_tw?==?ISO-8859-2?Q?=F3rcy_systemu_=3F=3F=3F?=
postgresql - int/int
postgresql Select count(*) czy raczej Select count(ID)
[PostgreSQL] jak =?ISO-8859-2?Q?pobra=E6_warto=B6=E6_zwracan?==?ISO-8859-2?Q?=B1_przez_funkcj=EA=3F?=
[postgresql] INSERT OR UPDATE - jak =?ISO-8859-2?Q?b=EAdzie_na?==?ISO-8859-2?Q?jlepiej=3F?=
[postgresql] kilka =?ISO-8859-2?Q?rekord=F3w_subquery_jako_?==?ISO-8859-2?Q?string?=
[PostgreSQL] Jak =?ISO-8859-2?Q?po=B3=B1czy=E6_funkcje_z_w?==?ISO-8859-2?Q?idokiem?=
Postgres - replikcja master-master
Dopasowanie do "najlepszego" dopasowania :) [ PostgreSQL]
Problemy z =?ISO-8859-2?Q?instalacj=B1_PostgreSQL_na_syste?==?ISO-8859-2?Q?mach_Windows?=
zanotowane.pldoc.pisz.plpdf.pisz.plnocnerozmowy.xlx.pl
Cytat
Decede mihi sole - nie zasłaniaj mi słonca. Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści Hoc fac - tak czyń. A tergo - od tyłu; z tyłu. I czarne włosy posiwieją. Safona |
|