Joomla.it Forum
Non solo Joomla... => Database => : bigham 15 Oct 2014, 12:31:54
-
Ciao a tutti.
Da un po' di tempo su un sito che sto seguendo compaiono errori del tipo in oggetto ed il sito risulta parecchio più lento.
Il sito è su server linux e si basa su una versione joomla 2.5 (aggiornata all'ultima release) e include un forum kunena.
Per completezza inserisco uno degli ultimi dump di errore:
Query execution was interrupted SQL=SELECT a.id, a.title, a.alias, a.title_alias, a.introtext, a.language, a.checked_out, a.checked_out_time,
a.catid, a.created, a.created_by, a.created_by_alias, CASE WHEN a.modified = 0 THEN a.created ELSE a.modified END as modified,
a.modified_by, uam.name as modified_by_name,CASE WHEN a.publish_up = 0 THEN a.created ELSE a.publish_up END as
publish_up,a.publish_down, a.images, a.urls, a.attribs, a.metadata, a.metakey, a.metadesc, a.access, a.hits, a.xreference, a.featured,
LENGTH(a.fulltext) AS readmore,CASE WHEN badcats.id is not null THEN 0 ELSE a.state END AS state,c.title AS category_title, c.path AS
category_route, c.access AS category_access, c.alias AS category_alias,CASE WHEN a.created_by_alias > ' ' THEN a.created_by_alias ELSE
ua.name END AS author,ua.email AS author_email,( SELECT MAX(contact.id) AS id FROM jjj_contact_details AS contact WHERE
contact.published = 1 AND contact.user_id = a.created_by) as contactid,parent.title as parent_title, parent.id as parent_id, parent.path as
parent_route, parent.alias as parent_alias,ROUND(v.rating_sum / v.rating_count, 0) AS rating, v.rating_count as rating_count,c.published, CASE
WHEN badcats.id is null THEN c.published ELSE 0 END AS parents_published FROM jjj_content AS a LEFT JOIN jjj_categories AS c ON c.id =
a.catid LEFT JOIN jjj_users AS ua ON ua.id = a.created_by LEFT JOIN jjj_users AS uam ON uam.id = a.modified_by LEFT JOIN jjj_categories as
parent ON parent.id = c.parent_id LEFT JOIN jjj_content_rating AS v ON a.id = v.content_id LEFT OUTER JOIN (SELECT cat.id as id FROM
jjj_categories AS cat JOIN jjj_categories AS parent ON cat.lft BETWEEN parent.lft AND parent.rgt WHERE parent.extension = 'com_content'
AND parent.published != 1 GROUP BY cat.id ) AS badcats ON badcats.id = c.id INNER JOIN jjj_content_frontpage AS fp ON fp.content_id = a.id
WHERE a.access IN (1,1) AND c.access IN (1,1) AND CASE WHEN badcats.id is null THEN a.state ELSE 0 END = 1 AND (a.publish_up = '0000-
00-00 00:00:00' OR a.publish_up <= '2014-09-25 19:01:00') AND (a.publish_down = '0000-00-00 00:00:00' OR a.publish_down >= '2014-09-
25 19:01:00') ORDER BY a.featured DESC, fp.ordering, a.created DESC
Errore nel caricamento del modulo MySQL server has gone away SQL=SELECT m.id, m.title, m.module, m.position, m.content, m.showtitle,
m.params, mm.menuid FROM jjj_modules AS m LEFT JOIN jjj_modules_menu AS mm ON mm.moduleid = m.id LEFT JOIN jjj_extensions AS e
ON e.element = m.module AND e.client_id = m.client_id WHERE m.published = 1 AND e.enabled = 1 AND (m.publish_up = '0000-00-00
00:00:00' OR m.publish_up <= '2014-09-25 19:01:00') AND (m.publish_down = '0000-00-00 00:00:00' OR m.publish_down >= '2014-09-25
19:01:00') AND m.access IN (1,1) AND m.client_id = 0 AND (mm.menuid = 1169 OR mm.menuid <= 0) ORDER BY m.position, m.ordering
Kunena COM_KUNENA_INTERNAL_ERROR
Errore nel caricamento del componente: com_contact, 1
Errori di questo tipo sono dovuti alla momentanea indisponibilità del server MySql cosa che accade abbastanza di frequente se il sito è su server condivisi. Quindi il dubbio non è sul perchè ciò accade, ne sono perfettamente cosciente.
Spesso la causa principale è quella di un numero considerevole di accessi concorreti alle risorse del server (non solo dal sito in questione, ma anche da tutti gli altri siti ospitati sul web server che utilizzano lo stesso db server).
Un dubbio ce l'ho sull'interpretazione del dump di errore: dal momento che viene visualizzato il nome del componente com_kunena la query che viene interrotta è relativa a questo componente?
Perchè in questo caso la prima cosa da fare sarebbe quella di disattivare il componente e vedere se gli errori continuano.
Volevo monitorare la frequenza di generazione di questi errori, che vengono visualizzati dall'utente nella pagina che sta visitando, ma non trovo un plugin che faccia al caso mio.
Ho cercato nella JED un plugin che mi aiutasse ad intercettare gli errori MySQL ma ho trovato solo due plugin, tipo questo ottimo (http://extensions.joomla.org/extensions/miscellaneous/development/25493) che intercettano gli errori php. In realtà tiene traccia anche delle query eseguite ma a me servirebbero solo gli errori mysql e in modalità background.
Qualcuno conosce un plugin (o un altro sistema) che in background permetta di tracciare questo tipo di errore?
Ovviamente è un problema da risolvere con il servizio di hosting ma so già che la prima risposta che daranno sarà: avete troppi accessi, dovete passare ad un server dedicato.
Grazie
-
chi si rivede :) :)
tutto ok?
non mi pare che la query sia relativa a kunema, io direi piuttosto un modulo relativo agli articoli di joomla:
SELECT a.id,
a.title,
a.alias,
a.title_alias,
a.introtext,
a.language,
a.checked_out,
a.checked_out_time,
a.catid,
a.created,
a.created_by,
a.created_by_alias,
CASE
WHEN a.modified = 0 THEN a.created
ELSE a.modified
END AS modified,
a.modified_by,
uam.name AS modified_by_name,
CASE
WHEN a.publish_up = 0 THEN a.created
ELSE a.publish_up
END AS publish_up,
a.publish_down,
a.images,
a.urls,
a.attribs,
a.metadata,
a.metakey,
a.metadesc,
a.access,
a.hits,
a.xreference,
a.featured,
LENGTH(a.fulltext) AS readmore,
CASE
WHEN badcats.id IS NOT NULL THEN 0
ELSE a.state
END AS STATE,
c.title AS category_title,
c.path AS category_route,
c.access AS category_access,
c.alias AS category_alias,
CASE
WHEN a.created_by_alias > ' ' THEN a.created_by_alias
ELSE ua.name
END AS author,
ua.email AS author_email,
(SELECT MAX(contact.id) AS id
FROM jjj_contact_details AS contact
WHERE contact.published = 1
AND contact.user_id = a.created_by) AS contactid,
parent.title AS parent_title,
parent.id AS parent_id,
parent.path AS parent_route,
parent.alias AS parent_alias,
ROUND(v.rating_sum / v.rating_count, 0) AS rating,
v.rating_count AS rating_count,
c.published,
CASE
WHEN badcats.id IS NULL THEN c.published
ELSE 0
END AS parents_published
FROM jjj_content AS a
LEFT JOIN jjj_categories AS c ON c.id = a.catid
LEFT JOIN jjj_users AS ua ON ua.id = a.created_by
LEFT JOIN jjj_users AS uam ON uam.id = a.modified_by
LEFT JOIN jjj_categories AS parent ON parent.id = c.parent_id
LEFT JOIN jjj_content_rating AS v ON a.id = v.content_id
LEFT OUTER JOIN
(SELECT cat.id AS id
FROM jjj_categories AS cat
JOIN jjj_categories AS parent ON cat.lft BETWEEN parent.lft AND parent.rgt
WHERE parent.extension = 'com_content'
AND parent.published != 1
GROUP BY cat.id) AS badcats ON badcats.id = c.id
INNER JOIN jjj_content_frontpage AS fp ON fp.content_id = a.id
WHERE a.access IN (1,
1)
AND c.access IN (1,
1)
AND CASE
WHEN badcats.id IS NULL THEN a.STATE
ELSE 0
END = 1
AND (a.publish_up = '0000-00-00 00:00:00'
OR a.publish_up <= '2014-09-25 19:01:00')
AND (a.publish_down = '0000-00-00 00:00:00'
OR a.publish_down >= '2014-09-25 19:01:00')
ORDER BY a.featured DESC,
fp.ordering,
a.created DESC
visto il numero di LEFT e di sub queries io ipotizzerei una slow query, più che un alto numero di accessi, al limite entrambi.
la prima soluzione che puoi tentare è far girare la query con un explain davanti e aggiungere gli eventuali indici necessari, la seconda è trovare il codice incriminato (cerca badcats) e cassarlo.
ciao,
marco
-
Ciao mmleoni.
Tutto bene grazie :D Spero altrettanto.
Credo che la query sia generata dal file \components\com_content\models\articles.php riga 157 e succ. (quindi non è un'estensione di terze parti a generarla) e facendo una ricerca col termine badcats con google ho visto che il problema delle slow query è abbastanza frequente, su stackoverflow ci sono un paio di pagine con la stessa query ;)
A questo punto non credo si possa cassare piuttosto si può cercare di ottimizzare la query e credo che questo plugin (http://extensions.joomla.org/extensions/style-a-design/templating/15611) dovrebbe dare una mano a non toccare il codice del core.
Il numero di accessi al sito è effettivamente alto e se a questo sommiamo la lentezza della query e il traffico generato da altri siti verso lo stesso db server facciamo una bella frittata.
Certo, forse un server dedicato risolverebbe...
Ora vediamo cosa mi dice explain di questa query.
Intanto grazie per la risposta.
Ciaoooooo
-
sì, bene anche io.
il fatto che sia usato un model di com_content non esclude che sia una estensione di terze parti a farlo.
propendo ancora di più per un modulo, visto che hai detto che l'errore avviene in kunema, ma potrebbe anche essere un plugin di tipo content che tenta di legare i contenuti di kumena a qualche articolo (kunema usa sue tabelle per i post, vero?)
non mi stupirei di trovare nella dir dei moduli o dei plugin qualcososa di simile:
JModelLegacy::getInstance('Articles', 'ContentModel', [...])
o
JModelLegacy::getInstance('Articles', 'ContentModel', [...])
magari cercalo anche nelle dirs di kunema.
explain resta la scelta da sistemista quale tu sei...
ciao,
marco
-
Credo di poter escludere che ci siano estensioni di terze parti che eseguono quella query.
Ho fatto una ricerca su tutti i files php del sito della stringa JModelLegacy::getInstance('Articles', 'ContentModel' e la trovo solo su parti del core di joomla, poi ho usato una copia del sito in locale e disattivato tutti i moduli visualizzati in home page e tutti i plugin possibili. Il risultato è che prima e dopo la "cura" il plugin di debug mi riporta sempre l'esecuzione della stessa query (quella incriminata). In effetti è la query che crea la lista di articoli in evidenza in home page.
Un qualche aiuto nella velocità di esecuzione della query l'ho ottenuto modificando la where finale da
WHERE a.access IN (1,
1)
AND c.access IN (1,
1)
AND CASE
WHEN badcats.id IS NULL THEN a.STATE
ELSE 0
END = 1
AND (a.publish_up = '0000-00-00 00:00:00'
OR a.publish_up <= '2014-10-16 19:01:00')
AND (a.publish_down = '0000-00-00 00:00:00'
OR a.publish_down >= '2014-10-16 19:01:00')
diventa
a.access IN (1,1) AND
badcats.id IS NULL AND
a.state = 1 AND
a.publish_up <= '2014-10-16 19:01:00' AND
(a.publish_down = '0000-00-00 00:00:00' OR a.publish_down >= '2014-10-16 19:01:00')
(Soluzione trovata su stackoverflow)
Ho analizzato la query con explain e la prima cosa che salta all'occhio è che seleziona quasi 6000 (senza usare indici) righe e lo fa dalla tabella _content_frontpage. Ovvero ci sono 6000 articoli in evidenza!
il join INNER JOIN jjj_content_frontpage AS fp ON fp.content_id = a.id mette in relazione esattamente 5994 articoli nella tabella content_frontpage con altrettnti nella tabella conten.
Ora mi chiedo: ma che bisogno c'è di fare una select di 6000 record solo visualizzando la home page dove si vedono poi solo 7 articoli? Solo perchè in fondo alla pagina si devono vedere i numerini della paginazione?
Secondo me la soluzione è più semplice: ridurre drasticamente gli articoli "in evidenza"
-
truncate jjj_content_frontpage;
;D ;D ;D
-
Siiiiiiiiiiiiiiiiiiiiii ;D ;D ;D
Intanto riducendo il numero di articoli "in evidenza" da5944 a 1548 il tempo di esecuzione della query è passato da 0,57s a 0,376s
Come sempre la soluzione sta nel mezzo ;D
Grazie Marco