Newsgroup: it.comp.os.linux.sys
Titolo: Help con MySQL

Come da ogni primo del mese, mi trovo di fronte ad un problema con MySQL.
Ho 4 tabelle (InnoDB): 3 sono piccole, mentre 1 è gigante (qualche decina di Giga).
Ogni primo del mese, devo esportare e cancellare tutti i dati più vecchi di 6 mesi dalla tabella enorme. Anche se lancio la query con LOW PRIORITY (che non serve con InnoDB) il DB è come se fosse bloccato "a tratti" per ore, con conseguenti disservizi e blocchi.
 
I dati sono su dei dischi locali SAS a 15000 giri in RAID-6.
A parte ottimizzare la query, cosa potrei fare per evitare il comportamento "a strappi"?


Se i dati sono più vecchi di sei mesi immagino che nessuno vada a toccarli proprio
quel giorno lì.
 
Quindi niente ti vieta di esportarli (e cancellarli) a blocchi di un giorno. Così,
ti ritrovi sessanta query più piccole che girano.
 
O potresti farti un ciclo che generi 720 query di select (una per ogni ora), e 720
query di DELETE. Ciascuna dovrebbe durare 1/720 della query grossa.
 
Altrimenti, potresti creare uno statement slave, fare girare la query lì, e poi al
momento buono fai il lavoro sullo slave... dopodiché dopo un "settle time" inverti
tra loro master e slave. E' un po' farraginoso ma dovrebbe funzionare.
 
Un'altra cosa che potrebbe venirti buona sarebbe di partizionare la tabella, anche
se la prima volta ti ritroverai a piangere napalm:
 
ALTER TABLE ...
PARTITION BY RANGE(MONTH(campoData)) (
    PARTITION m01 VALUES LESS THAN (2),
    PARTITION m02 VALUES LESS THAN (3),
    PARTITION m03 VALUES LESS THAN (4),
    PARTITION m04 VALUES LESS THAN (5),
    PARTITION m05 VALUES LESS THAN (6),
    PARTITION m06 VALUES LESS THAN (7),
    PARTITION m07 VALUES LESS THAN (8),
    PARTITION m08 VALUES LESS THAN (9),
    PARTITION m09 VALUES LESS THAN (10),
    PARTITION m10 VALUES LESS THAN (11),
    PARTITION m11 VALUES LESS THAN (12),
    PARTITION m12 VALUES LESS THAN (13)
);
 
E questo DOVREBBE far sì che sia la SELECT di esportazione che la DELETE vadano ad
impattare soltanto un settimo del database. E in ogni momento, solo sei partizioni
saranno piene.
 
Per il DELETE poi puoi usare TRUNCATE PARTITION.
 
http://dev.mysql.com/doc/refman/5.7/en/partitioning-limitations-locking.html
 
 
Leonardo
-- 
 
A terrible beauty is born.
                                     - W. B. Yeats, Easter 1916


cominciare a vedere qual'e' realmente il collo di bottiglia: query, dischi, ram,...?
anche chiedere su un newsgroup dedicato a mysql potrebbe essere una buona idea, magari c'e' qualche parametro di mysql che si puo' variare.
 
Ciao Jack

Il collo di bottiglia è la query che viene eseguita su una tabella enorme.

 
 
Mmmh...L'idea non è male, ma è una macchina di produzione, quindi sarebbe un po' un casino stravolgerla così
 

 "a strappi"?
 
A parte il consiglio di Leonardo, puoi mettere un trigger sulla tabella che
copia il record su di una tabella gemella e cancella l'ultimo inserito sulla
tabella principale. Praticamente non cambi nulla nella struttura principale e
qualsiasi problema lo sposti su quella che è effettivamente una tabella di
manutenzione
 
Enrico

 Il collo di bottiglia è la query che viene eseguita su una tabella enorme.
 
  Quindi bisogna vedere su che cosa la query va in stallo.
Curare senza avere una diagnosi vuol dire andare a caso, potrebbe
andarti bene come potrebbe andarti male, certamente sprechi un sacco di
tempo e difficilmente impari come fare la prossima volta per evitare
l'insorgere di un problema simile.
 
 
  Ciao,
 
 
-- 
Alessandro Selli 
http://alessandro.route-add.net
 
AVVERTENZA: i messaggi inviati a "trappola" non mi arriveranno.
WARNING: messages sent to "trappola" will never reach me.

Mmmh...L'idea non è male, ma è una macchina di produzione, quindi sarebbe un po' un casino stravolgerla così
 
Metti su surrettiziamente un MySQL slave (occhio a intasare il master di binlog), in configurazione
esattamente mirrorata e binlog statement
 
 
https://plusbryan.com/mysql-replication-without-downtime
 
 
...dopo di che, aspetti con pazienza che lo slave sia sincronizzato. Quando lo è, gli partizioni la
tabella. Lo slave uscirà di sincronia di un buon 3000 secondi :-), ma dopo un po' si ripiglia. Puoi
farci su un po' di SELECT per verificare che ci sia tutto e che si comporti bene.
 
A questo punto, in un momento tranquillo, fermi il master, fermi lo slave, li scambi di posto, e li
fai ripartire. Il master essendo fermo, ti consente di farlo ripartire se qualcosa va storto. Tutta
l'operazione non dovrebbe portare via più di un minuto, però il server andrà parecchio piano per il
primo quarto d'ora, quando legge i dati da disco anziché trovarseli già in RAM.
