3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2007 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
14 if (!defined("_ECRIRE_INC_VERSION")) return;
16 // heure de reference pour le garbage collector = 24h auparavant
17 // http://doc.spip.org/@optimiser_base
18 function optimiser_base($attente = 86400) {
19 spip_log ("optimisation de la base");
21 # format = 20060610110141, si on veut forcer une optimisation tout de suite
22 $mydate = date("YmdHis", time() - $attente);
28 if ($GLOBALS['table_prefix']) $table_pref = $GLOBALS['table_prefix']."_";
29 else $table_pref = "";
31 $result = spip_query("SHOW TABLES LIKE '$table_pref%'");
33 // on ne va OPTIMIZE qu'une seule des tables a chaque fois,
34 // pour ne pas vautrer le systeme
35 // lire http://dev.mysql.com/doc/refman/5.0/fr/optimize-table.html
36 while ($row = spip_fetch_array($result,SPIP_NUM
)) $tables[] = $row[0];
39 $table_op = intval($GLOBALS['meta']['optimiser_table']+
1) %
sizeof($tables);
40 ecrire_meta('optimiser_table', $table_op);
42 $query = "OPTIMIZE TABLE ".$tables[$table_op];
45 spip_log("$query : ok");
49 // Les requetes DELETE multi table ne sont pas supportees par mysql<4.0
50 // et ont une syntaxe differente entre 4.0 et 4.1
51 // On passe donc par un SELECT puis DELETE unitaire dans une boucle while
52 // en pariant sur le fait que le nombre d'objets a supprimer est marginal
58 # les articles qui sont dans une id_rubrique inexistante
59 $res = spip_query("SELECT articles.id_article
60 FROM spip_articles AS articles
61 LEFT JOIN spip_rubriques AS rubriques
62 ON articles.id_rubrique=rubriques.id_rubrique
63 WHERE rubriques.id_rubrique IS NULL
64 AND articles.maj < $mydate");
66 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
67 spip_query("DELETE FROM spip_articles
68 WHERE id_article=".$row['id_article']);
70 # les breves qui sont dans une id_rubrique inexistante
71 $res = spip_query("SELECT breves.id_breve
72 FROM spip_breves AS breves
73 LEFT JOIN spip_rubriques AS rubriques
74 ON breves.id_rubrique=rubriques.id_rubrique
75 WHERE rubriques.id_rubrique IS NULL
76 AND breves.maj < $mydate");
78 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
79 spip_query("DELETE FROM spip_breves
80 WHERE id_breve=".$row['id_breve']);
82 # les forums lies a une id_rubrique inexistante
83 $res = spip_query("SELECT forum.id_forum FROM spip_forum AS forum
84 LEFT JOIN spip_rubriques AS rubriques
85 ON forum.id_rubrique=rubriques.id_rubrique
86 WHERE rubriques.id_rubrique IS NULL
87 AND forum.id_rubrique>0");
89 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
90 spip_query("DELETE FROM spip_forum
91 WHERE id_forum=".$row['id_forum']);
93 # les droits d'auteurs sur une id_rubrique inexistante
94 $res = spip_query("SELECT auteurs_rubriques.id_rubrique,auteurs_rubriques.id_auteur
95 FROM spip_auteurs_rubriques AS auteurs_rubriques
96 LEFT JOIN spip_rubriques AS rubriques
97 ON auteurs_rubriques.id_rubrique=rubriques.id_rubrique
98 WHERE rubriques.id_rubrique IS NULL");
100 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
101 spip_query("DELETE FROM spip_auteurs_rubriques
102 WHERE id_auteur=".$row['id_auteur']
103 ." AND id_rubrique=".$row['id_rubrique']);
106 # les liens des documents qui sont dans une id_rubrique inexistante
107 $res = spip_query("SELECT documents_rubriques.id_document,documents_rubriques.id_rubrique
108 FROM spip_documents_rubriques AS documents_rubriques
109 LEFT JOIN spip_rubriques AS rubriques
110 ON documents_rubriques.id_rubrique=rubriques.id_rubrique
111 WHERE rubriques.id_rubrique IS NULL");
113 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
114 spip_query("DELETE FROM spip_documents_rubriques
115 WHERE id_document=".$row['id_document']
116 ." AND id_rubrique=".$row['id_rubrique']);
118 # les liens des mots affectes a une id_rubrique inexistante
119 $res = spip_query("SELECT mots_rubriques.id_mot,mots_rubriques.id_rubrique
120 FROM spip_mots_rubriques AS mots_rubriques
121 LEFT JOIN spip_rubriques AS rubriques
122 ON mots_rubriques.id_rubrique=rubriques.id_rubrique
123 WHERE rubriques.id_rubrique IS NULL");
125 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
126 spip_query("DELETE FROM spip_mots_rubriques
127 WHERE id_mot=".$row['id_mot']
128 ." AND id_rubrique=".$row['id_rubrique']);
135 spip_query("DELETE FROM spip_articles
136 WHERE statut='poubelle' AND maj < $mydate");
139 # les liens d'auteurs d'articles effaces
140 $res = spip_query("SELECT auteurs_articles.id_auteur,auteurs_articles.id_article
141 FROM spip_auteurs_articles AS auteurs_articles
142 LEFT JOIN spip_articles AS articles
143 ON auteurs_articles.id_article=articles.id_article
144 WHERE articles.id_article IS NULL");
146 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
147 spip_query("DELETE FROM spip_auteurs_articles
148 WHERE id_auteur=".$row['id_auteur']
149 ." AND id_article=".$row['id_article']);
151 # les liens de documents d'articles effaces
152 $res = spip_query("SELECT documents_articles.id_document,documents_articles.id_article
153 FROM spip_documents_articles AS documents_articles
154 LEFT JOIN spip_articles AS articles
155 ON documents_articles.id_article=articles.id_article
156 WHERE articles.id_article IS NULL");
158 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
159 spip_query("DELETE FROM spip_documents_articles
160 WHERE id_document=".$row['id_document']
161 ." AND id_article=".$row['id_article']);
163 # les liens de mots affectes a des articles effaces
164 $res = spip_query("SELECT mots_articles.id_mot,mots_articles.id_article
165 FROM spip_mots_articles AS mots_articles
166 LEFT JOIN spip_articles AS articles
167 ON mots_articles.id_article=articles.id_article
168 WHERE articles.id_article IS NULL");
170 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
171 spip_query("DELETE FROM spip_mots_articles
172 WHERE id_mot=".$row['id_mot']
173 ." AND id_article=".$row['id_article']);
175 # les forums lies a des articles effaces
176 $res = spip_query("SELECT forum.id_forum
177 FROM spip_forum AS forum
178 LEFT JOIN spip_articles AS articles
179 ON forum.id_article=articles.id_article
180 WHERE articles.id_article IS NULL
181 AND forum.id_article>0");
183 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
184 spip_query("DELETE FROM spip_forum
185 WHERE id_forum=".$row['id_forum']);
192 spip_query("DELETE FROM spip_breves
193 WHERE statut='refuse' AND maj < $mydate");
196 # les liens de documents sur des breves effacees
197 $res = spip_query("SELECT documents_breves.id_document,documents_breves.id_breve
198 FROM spip_documents_breves AS documents_breves
199 LEFT JOIN spip_breves AS breves
200 ON documents_breves.id_breve=breves.id_breve
201 WHERE breves.id_breve IS NULL");
203 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
204 spip_query("DELETE FROM spip_documents_breves
205 WHERE id_document=".$row['id_document']
206 ." AND id_breve=".$row['id_breve']);
208 # les liens de mots affectes a des breves effacees
209 $res = spip_query("SELECT mots_breves.id_mot,mots_breves.id_breve
210 FROM spip_mots_breves AS mots_breves
211 LEFT JOIN spip_breves AS breves
212 ON mots_breves.id_breve=breves.id_breve
213 WHERE breves.id_breve IS NULL");
215 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
216 spip_query("DELETE FROM spip_mots_breves
217 WHERE id_mot=".$row['id_mot']
218 ." AND id_breve=".$row['id_breve']);
220 # les forums lies a des breves effacees
221 $res = spip_query("SELECT forum.id_forum
222 FROM spip_forum AS forum
223 LEFT JOIN spip_breves AS breves
224 ON forum.id_breve=breves.id_breve
225 WHERE breves.id_breve IS NULL
226 AND forum.id_breve>0");
228 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
229 spip_query("DELETE FROM spip_forum
230 WHERE id_forum=".$row['id_forum']);
237 spip_query("DELETE FROM spip_syndic
238 WHERE maj < $mydate AND statut = 'refuse'");
241 # les articles syndiques appartenant a des sites effaces
242 $res = spip_query("SELECT syndic_articles.id_syndic_article,syndic_articles.id_syndic
243 FROM spip_syndic_articles AS syndic_articles
244 LEFT JOIN spip_syndic AS syndic
245 ON syndic_articles.id_syndic=syndic.id_syndic
246 WHERE syndic.id_syndic IS NULL");
248 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
249 spip_query("DELETE FROM spip_syndic_articles
250 WHERE id_syndic_article=".$row['id_syndic_article']
251 ." AND id_syndic=".$row['id_syndic']);
253 # les liens de mots affectes a des sites effaces
254 $res = spip_query("SELECT mots_syndic.id_mot,mots_syndic.id_syndic
255 FROM spip_mots_syndic AS mots_syndic
256 LEFT JOIN spip_syndic AS syndic
257 ON mots_syndic.id_syndic=syndic.id_syndic
258 WHERE syndic.id_syndic IS NULL");
260 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
261 spip_query("DELETE FROM spip_mots_syndic
262 WHERE id_mot=".$row['id_mot']
263 ." AND id_syndic=".$row['id_syndic']);
265 # les forums lies a des sites effaces
266 $res = spip_query("SELECT forum.id_forum
267 FROM spip_forum AS forum
268 LEFT JOIN spip_syndic AS syndic
269 ON forum.id_syndic=syndic.id_syndic
270 WHERE syndic.id_syndic IS NULL
271 AND forum.id_syndic>0");
273 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
274 spip_query("DELETE FROM spip_forum
275 WHERE id_forum=".$row['id_forum']);
282 # les liens d'articles sur des auteurs effaces
283 $res = spip_query("SELECT auteurs_articles.id_auteur,auteurs_articles.id_article
284 FROM spip_auteurs_articles AS auteurs_articles
285 LEFT JOIN spip_auteurs AS auteurs
286 ON auteurs_articles.id_auteur=auteurs.id_auteur
287 WHERE auteurs.id_auteur IS NULL");
289 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
290 spip_query("DELETE FROM spip_auteurs_articles
291 WHERE id_auteur=".$row['id_auteur']
292 ." AND id_article=".$row['id_article']);
294 # les liens de messages sur des auteurs effaces
295 $res = spip_query("SELECT auteurs_messages.id_auteur,auteurs_messages.id_message
296 FROM spip_auteurs_messages AS auteurs_messages
297 LEFT JOIN spip_auteurs AS auteurs
298 ON auteurs_messages.id_auteur=auteurs.id_auteur
299 WHERE auteurs.id_auteur IS NULL");
301 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
302 spip_query("DELETE FROM spip_auteurs_messages
303 WHERE id_auteur=".$row['id_auteur']
304 ." AND id_message=".$row['id_message']);
306 # les liens de rubriques sur des auteurs effaces
307 $res = spip_query("SELECT auteurs_rubriques.id_auteur,auteurs_rubriques.id_rubrique
308 FROM spip_auteurs_rubriques AS auteurs_rubriques
309 LEFT JOIN spip_rubriques AS rubriques
310 ON auteurs_rubriques.id_rubrique=rubriques.id_rubrique
311 WHERE rubriques.id_rubrique IS NULL");
313 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
314 spip_query("DELETE FROM spip_auteurs_rubriques
315 WHERE id_auteur=".$row['id_auteur']
316 ." AND id_rubrique=".$row['id_rubrique']);
318 # effacer les auteurs poubelle qui ne sont lies a aucun article
319 $res = spip_query("SELECT auteurs.id_auteur
320 FROM spip_auteurs AS auteurs
321 LEFT JOIN spip_auteurs_articles AS auteurs_articles
322 ON auteurs_articles.id_auteur=auteurs.id_auteur
323 WHERE auteurs_articles.id_auteur IS NULL
324 AND auteurs.statut='5poubelle' AND auteurs.maj < $mydate");
326 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
327 spip_query("DELETE FROM spip_auteurs
328 WHERE id_auteur=".$row['id_auteur']);
330 # supprimer les auteurs 'nouveau' qui n'ont jamais donne suite
331 # au mail de confirmation (45 jours pour repondre, ca devrait suffire)
332 spip_query("DELETE FROM spip_auteurs WHERE statut='nouveau' AND maj < ". _q(date('Y-m-d', time()-45*24*3600)));exit;
339 # supprimer les messages lies a un auteur disparu
340 $res = spip_query("SELECT messages.id_message
341 FROM spip_messages AS messages
342 LEFT JOIN spip_auteurs AS auteurs
343 ON auteurs.id_auteur=messages.id_auteur
344 WHERE auteurs.id_auteur IS NULL");
346 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
347 spip_query("DELETE FROM spip_messages
348 WHERE id_message=".$row['id_message']);
355 $result = spip_query("DELETE FROM spip_mots
356 WHERE titre='' AND maj < $mydate");
359 # les liens mots-articles sur des mots effaces
360 $res = spip_query("SELECT mots_articles.id_mot,mots_articles.id_article
361 FROM spip_mots_articles AS mots_articles
362 LEFT JOIN spip_mots AS mots
363 ON mots_articles.id_mot=mots.id_mot
364 WHERE mots.id_mot IS NULL");
366 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
367 spip_query("DELETE FROM spip_mots_articles
368 WHERE id_mot=".$row['id_mot']
369 ." AND id_article=".$row['id_article']);
371 # les liens mots-breves sur des mots effaces
372 $res = spip_query("SELECT mots_breves.id_mot,mots_breves.id_breve
373 FROM spip_mots_breves AS mots_breves
374 LEFT JOIN spip_mots AS mots
375 ON mots_breves.id_mot=mots.id_mot
376 WHERE mots.id_mot IS NULL");
378 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
379 spip_query("DELETE FROM spip_mots_breves
380 WHERE id_mot=".$row['id_mot']
381 ." AND id_breve=".$row['id_breve']);
383 # les liens mots-forum sur des mots effaces
384 $res = spip_query("SELECT mots_forum.id_mot,mots_forum.id_forum
385 FROM spip_mots_forum AS mots_forum
386 LEFT JOIN spip_mots AS mots
387 ON mots_forum.id_mot=mots.id_mot
388 WHERE mots.id_mot IS NULL");
390 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
391 spip_query("DELETE FROM spip_mots_forum
392 WHERE id_mot=".$row['id_mot']
393 ." AND id_forum=".$row['id_forum']);
395 # les liens mots-rubriques sur des mots effaces
396 $res = spip_query("SELECT mots_rubriques.id_mot,mots_rubriques.id_rubrique
397 FROM spip_mots_rubriques AS mots_rubriques
398 LEFT JOIN spip_mots AS mots
399 ON mots_rubriques.id_mot=mots.id_mot
400 WHERE mots.id_mot IS NULL");
402 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
403 spip_query("DELETE FROM spip_mots_rubriques
404 WHERE id_mot=".$row['id_mot']
405 ." AND id_rubrique=".$row['id_rubrique']);
407 # les liens mots-syndic sur des mots effaces
408 $res = spip_query("SELECT mots_syndic.id_mot,mots_syndic.id_syndic
409 FROM spip_mots_syndic AS mots_syndic
410 LEFT JOIN spip_mots AS mots
411 ON mots_syndic.id_mot=mots.id_mot
412 WHERE mots.id_mot IS NULL");
414 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
415 spip_query("DELETE FROM spip_mots_syndic
416 WHERE id_mot=".$row['id_mot']
417 ." AND id_syndic=".$row['id_syndic']);
424 spip_query("DELETE FROM spip_forum
425 WHERE statut='redac' AND maj < $mydate");
428 # les liens mots-forum sur des forums effaces
429 $res = spip_query("SELECT mots_forum.id_mot,mots_forum.id_forum
430 FROM spip_mots_forum AS mots_forum
431 LEFT JOIN spip_forum AS forum
432 ON mots_forum.id_forum=forum.id_forum
433 WHERE forum.id_forum IS NULL");
435 while ($row = spip_fetch_array($res,SPIP_ASSOC
))
436 spip_query("DELETE FROM spip_mots_forum
437 WHERE id_mot=".$row['id_mot']
438 ." AND id_forum=".$row['id_forum']);
444 // les objets inutiles
445 include_spip('inc/indexation');
446 $liste_tables = liste_index_tables();
447 foreach ($liste_tables as $id_table => $table_objet) {
448 $col_id = primary_index_table($table_objet);
449 $critere = critere_optimisation($table_objet);
450 if (strlen($critere)>0)
451 $critere = "AND $critere";
453 spip_query("UPDATE $table_objet SET idx=''
454 WHERE idx<>'non' $critere");
457 $s = spip_query("SELECT $col_id FROM $table_objet
458 WHERE idx='' $critere");
459 while ($t = spip_fetch_array($s,SPIP_NUM
))
461 $s = spip_query("SELECT $col_id FROM $table_objet
463 while ($t = spip_fetch_array($s,SPIP_NUM
))
466 spip_query("DELETE FROM spip_index
467 WHERE id_objet IN (0$suppr) AND id_table=$id_table");
470 spip_log("optimisation terminee");