[ Tyler Durden @ 07.10.2009. 10:38 ] @
Treba da se prebacim neku bazu sa 3.x na 5.x verziju MySQL-a. Samo prebacivanje podataka je prošlo iznenađujuće lako. Ali problem je sa aplikacijom koja koristi tu bazu a gdje neki upiti ne rade kako treba, odnosno vraćaju manje podataka nego isti upit na 3.x verziji.

Npr.
Code:

SELECT k.*, t6.naziv as dnaziv, t4.tip as tip_text, t3.brzina as paket, t2.kod_centrale, t5.naziv as naziv, t5.pozivni, t5.telefon FROM tabela1 t1, tabela t2, tabela3 t3, tabela4 t4, tabela5 t5, tabela6 t6 WHERE t1.tip=t2.id AND t1.paket=t3.id AND t1.cent=t4.id AND t1.d_id=t5.id AND (t1.id=t6.korisnik_id OR (t1.pl=0 AND t6.id=32))


Mozda je ovaj upit malo konfuzan jer sam promjenio stvarne nazive tabela i aliasa ali u suštini to je to. Dakle, ovaj isti upit na verziji 3.x vrati puno više rekorda nego u verziji 5.x
I što je najbitinije, meni treba da vrati ovoliko podataka koliko vrati verzija 3.x
[ djoka_l @ 07.10.2009. 11:24 ] @
Meni padaju na pamet dve stvari:

1. Migracija nije baš bila tako laka i uspešna kao što si pomislio.
2. Postoji problem sa operatorom "=". Od verzije 3.23 postoji i "null safe" verzija operatora ( <=> ).

Sada, nisam neki stručnjak sa MySQL i ne znam šta je operator = vraćao pre verzije 3.23 ako je neki (ili oba) od izraza bio null.

Ono što bih ja uradio je da nađem slog koji se dobija u verziji 3.x , a ne dobija se u verziji 5.x pa bih onda dalje "secirao" upit...
[ Tyler Durden @ 07.10.2009. 11:55 ] @
Što se tiče samog prebacivanja, napravljen je dump fajl na starom serveru i učitan je na novi. Potrebno je bilo na 2 mjesta da se izmjeni nešto vrlo sitno u dump fajlu kako bi prošlo učitavanje na novi server. Zaista ne vjerujem da je do podataka.

Razlika u broju rezultata je velika. Konkretno, na novom serveru ovaj upit vrati 217 slogova, dok je na staroj verziji vrati 10179.
[ djoka_l @ 07.10.2009. 12:18 ] @
Prvo proveri da li je u pitanju komparacija null sa null:

Promeni svaku AND klauzulu sa:

t1.nekopolje = tx.nekodrugopolje
na
(t1.nekopolje = tx.nekodrugopolje or (t1.nekopolje is null and tx.nekodrugopolje is null))

(ja bih na ORACLE stavio NVL(t1.nekopolje,'{null}') = NVL(tx.nekodrugopolje,'{null}'), ali ne znam da li MySQL ima sličnu funkciju)

Edit: može da se izmeni i
t1.nekopolje = tx.nekodrugopolje
na
t1.nekopolje <=> tx.nekodrugopolje
[ djoka_l @ 07.10.2009. 12:36 ] @
Setio sam se još jedne kvake - ako su polja sa leve i desne strane jednakosti različita po tipu, onda se primenjuje implicitna konverzija, a ona može da se razlikuje od verzije do verzije baze. Znači, u svakom slučaju kada se porede dva polja različitih tipova staviti eksplicitnu funkciju konverzije na jednu stranu...
[ bogdan.kecman @ 07.10.2009. 13:11 ] @
Citat:

Code:

SELECT k.*, t6.naziv as dnaziv, t4.tip as tip_text, t3.brzina as paket, t2.kod_centrale, t5.naziv as naziv, t5.pozivni, t5.telefon FROM tabela1 t1, tabela t2, tabela3 t3, tabela4 t4, tabela5 t5, tabela6 t6 WHERE t1.tip=t2.id AND t1.paket=t3.id AND t1.cent=t4.id AND t1.d_id=t5.id AND (t1.id=t6.korisnik_id OR (t1.pl=0 AND t6.id=32))



mnooooooooogo incompatible promena ima izmedju 3.x i 5.x ... uglavnom po tome sto 3.x gomilu stvari nije radio po sql-u a 5.x sada radi

prva stvar koju bi te zamolio da probas je da izbacis OR (t1.pl=0 AND t6.id=32) pa da probas na obe masine .. dakle:

Code:

SELECT count(*) FROM tabela1 t1, tabela t2, tabela3 t3, tabela4 t4, tabela5 t5, tabela6 t6 WHERE t1.tip=t2.id AND t1.paket=t3.id AND t1.cent=t4.id AND t1.d_id=t5.id AND t1.id=t6.korisnik_id ;


to puknes na oba pa vidis dal ce vratiti isti broj.

fora je sto je na 3.22 A=0 isto sto i na 5.1 A=0 or ISNULL(A);

generalno je ista prica i sa ostalim poljima ali ovo je prvo sto se bas vidi ..
sta je cim, 0 == NULL, '' == NULL na 3.22, na 5.1 to nije isto. tako da ovo sto ti je djoka_i rekao pije vodu.

[ Tyler Durden @ 09.10.2009. 09:42 ] @
Našao sam problem.
Kod jedne kolone u glavnoj tabeli t1 koja se spaja sa svim ostalima, za 99% rekorda bio je upisan pogrešan podatak. t1.id_u_t2 za njih je bio setovan u nepostojeći id u tabeli t2.
Konkretno, t1.id_u_t2 je bio setovan u "--" za sve te rekorde. U 3.x to nije pravilo problem, u 5.x pravi.

Izgleda da ima još takvih "situacija", samo će sada biti teže da ih nađem, ostalo ih je malo...
[ Tyler Durden @ 09.10.2009. 10:26 ] @
Hmmmm, the plot thickens...

Kad uradim dump na starom serveru on ovako generiše za jednu tabelu
Code:
CREATE TABLE t2 (
  id bigint(20) NOT NULL auto_increment,
  naziv varchar(80) NOT NULL default '',
  kod varchar(50) NOT NULL default '',
  PRIMARY KEY  (id)
) ENGINE=MyISAM;


i radi insert na sljedeći način
Code:
INSERT INTO t2 VALUES (1,'nesto1','NST1');
INSERT INTO t2 VALUES (2,'nesto2','NST2');
INSERT INTO t2 VALUES (3,'nesto3,'NST3');
INSERT INTO t2 VALUES (4,'nesto4','NST4');
INSERT INTO t2 VALUES (0,'--','');
INSERT INTO t2 VALUES (6,'nesto5','NST5');
......


ali u 5.x verziji kada ovo učitam ovaj id 0 pređe u id 5
Zašto??
[ misk0 @ 09.10.2009. 11:09 ] @
Kako zasto? Pa kolona je autoincrement.

Citat:

id bigint(20) NOT NULL auto_increment,


A ti ubacujes 0, sto je manja vrijednost od trenutne tj od sledece 'increment' vrijednosti.

[ Tyler Durden @ 09.10.2009. 12:28 ] @
A zašto ga onda mysqldump "napopako" generiše? Zašto ne generiše raspored od najmanjeg ka najvećem?
[ bogdan.kecman @ 09.10.2009. 18:18 ] @
nemam nigde 3.23 da ga overim, ali se secam da je bilo extra zezanja sa njegovim mysqldump-om.... probaj da se okacis mysqldump-om od 5.1 na 3.xx server - mozda i radi :D ...

sada imas na mysqldump-u --order-by-primary, sto je super fora ali nemam pojma kada je to uvedeno tj da li radi na 3.xx

sve u svemu, najbolje ti je da probas da se okacis sa novog servera koristeci novi mysqldump na stari server preko tcpipa... to ce ti verovatno resiti 99% problema :D
[ bogdan.kecman @ 09.10.2009. 18:31 ] @
--compatible=mysql323

probaj sa tim parametrom iz 5.1 mysqldump'a
[ Goran Rakić @ 09.10.2009. 18:50 ] @
... ili awk-om sortiraj izlaz... može biti znatno brže do rezultata.
[ bogdan.kecman @ 09.10.2009. 21:37 ] @
Citat:
Goran Rakić: ... ili awk-om sortiraj izlaz... može biti znatno brže do rezultata.


mmmmmmmmmmmmm awk ... koliko godina nisam to koristio .... mocna alatka ... elem .. --order-by-primary ne bi trebalo da uspori ni myisam ni innodb ..

mene iskreno super zanima kako ce da se ponasa mysqldump iz 5.1 pri kacenju na 3.23 server ...
[ Tyler Durden @ 10.10.2009. 21:04 ] @
Izgleda da radi dobro. Više nego dobro.
--order-by-primary je na prvi pogled uradio posao kako treba, ali vidjeću u pondeljak na poslu kad se detaljnije pozabavim time, je li sve kako treba.
Jedina greška koja se javila prilikom dumpovanja jeste
Code:
mysqldump: Error: 'You have an error in your SQL syntax near 'SELECT DISTINCT LOGFILE_GROUP_NAME FROM INFORMATION_SCHEMA
.FILES WHERE FILE_TYPE' at line 1' when trying to dump tablespaces


Radi se o tome da information_schema baza ne postoji na starom serveru. Da li to može da predstavlja problem?
[ bogdan.kecman @ 10.10.2009. 22:27 ] @
information_schema je nova fora na mysql-u da stvari koje si ranije morao preko show ovo ono sada mozes sa select ovo ono from information_schema ..

mislim da to sto mysqldump vadi iz information_schema ne bi trebalo da ima veze sa podacima (to ni ne postoji nista u 3.x) ...

reci mi samo, jesi probao sa i bez --compatible=mysql323 .. nisam 1000% siguran kakva ce biti razlika
[ Tyler Durden @ 11.10.2009. 08:26 ] @
Probao sam samo sa --compatible=mysql323.
[ bogdan.kecman @ 11.10.2009. 18:20 ] @
pitam zato sto me mrzelo da proverim (--help) :) .. kreten ..

elem, --compatible u stvari sluzi samo da generise dump koji je kompatibilan sa ovim ili onim, dakle ako ces da ga pucas na 5.1 uopste ti ne treba --compatible posto bez njega on generise dump koji je ok za 5.1 a to je ono sto ti treba :) ... sorry za pogresan savet ... za sada ti ocigledno treba samo --order-by-primary
[ Tyler Durden @ 11.10.2009. 20:05 ] @
Heh, kad se malo razmisli to je i logicno za zakljuciti... :)
[ bogdan.kecman @ 11.10.2009. 21:41 ] @
da, da .. razmisli ... da, da :D ... nekad je to suvise komplikovan proces