ermitteln was ein Apache-Prozess macht

mkr

Registered User
Hallo!

Auf einem Server mit ca. 300 Domains und vielen PHP-Scripts bin ich nach der Suche nach den Top 10 der Ressourcenfresser. Der Load ist permanent über 10, es sind immer ca. 5 Apache2-Prozesse am arbeiten (über 10% CPU-Load). Da aber viele weitere Seiten ausgeliefert werden, ist die Suche nach den langsamen Scripts nicht so einfach.

Hat jemand einen guten Tipp, wie ich schauen könnte, welches Script der Prozess mit 60% CPU-Load gerade am abarbeiten ist?

Vielen Dank für Eure Hilfe!
 
Das Problem ist, dass die Anfrage schon abgearbeitet wurde, bis ich lsof mit der richtigen PID gestartet habe. Habe jetzt mal das Slow Query Log von MySQL aktiviert, vielleicht finde ich dort etwas.
 
Du kannst Dich mit [man]strace[/man] an den laufenden (Haupt-)Prozess des Webservers hängen.
Code:
strace -f -o /tmp/apachecalls.log -tt -p [I]1234[/I]
Ggfs. muss Du das Paket strace Deiner Distribution noch nachinstallieren.
Achtung: Das Logfile wird schnell ziemlich groß (also nicht ewig laufen lassen, und mit Strg-C abbrechen); aber darin findest Du u.A. Zeitstempel und welche Dateien wie geöffnet wurden. Alles in allem sind das sehr viele Informationen, die man dann eben filtern und analysieren muss ;)
 
Last edited by a moderator:
An strace habe ich auch gedacht, die Idee aber wieder verworfen, weil ich dachte, das gäbe zu viel Output. Werde ich aber mal probieren.

Habe gerade folgendes im Slow Query Log gefunden:

Code:
# Time: 080313  9:23:25
# Query_time: 233  Lock_time: 0  Rows_sent: 9  Rows_examined: 1059678
select distinct(ink_product.id) as art, ink_product.* from ink_product, ink_product_by_set p_b_s  where ((ink_product.id=p_b_s.product and p_b_s.product_set=1) or ink_product.webmaster_id=2) and ink_product.`group`='Rechner' and ink_product.`brand`='Peach' order by ink_product.search_string, art;

Es gibt einige solcher Einträge, die Query Time geht dabei bis auf 1000 Sekunden hoch.

Jetzt ist die Frage: Fehlt einer Tabelle ein Index (also sollte Rows_examined kleiner sein), oder hatte MySQL so lange, weil Apache die CPU ausgelastet hat?
 
Ja stimmt eigentlich... Kann die DB ja mal dumpen und auf einem anderen Rechner anschauen. Der Server ist so ausgelastet, dass ich darauf nicht sehen kann, ob MySQL zu wenig CPU-Zeit bekommt oder die DB schlecht designt ist.
 
Hat jemand einen guten Tipp, wie ich schauen könnte, welches Script der Prozess mit 60% CPU-Load gerade am abarbeiten ist?
Apache bringt selber etwas dazu mit: mod_status
Und natürlich sollte man noch "ExtendedStatus On" setzten.
Dann siehst Du die Prozessauslastung für jede aktive Verbindung und welches (PHP-)Script dran hängt.

Es gibt einige solcher Einträge, die Query Time geht dabei bis auf 1000 Sekunden hoch.
Gib mal ein "describe ink_product;" und "describe ink_product_by_set;".

oder hatte MySQL so lange, weil Apache die CPU ausgelastet hat?
Beides... :)

huschi.
 
Apache bringt selber etwas dazu mit: mod_status
Und natürlich sollte man noch "ExtendedStatus On" setzten.
Dann siehst Du die Prozessauslastung für jede aktive Verbindung und welches (PHP-)Script dran hängt.

Da hätte ich auch selbst drauf kommen können... Danke! mod_status habe ich schon aktiviert für munin, aber den ExtendedStatus habe ich vergessen.


Gib mal ein "describe ink_product;" und "describe ink_product_by_set;".

Code:
mysql> describe ink_product;
+-------------------+---------------+------+-----+---------+-------+
| Field             | Type          | Null | Key | Default | Extra |
+-------------------+---------------+------+-----+---------+-------+
| id                | varchar(12)   | NO   | PRI | 0       |       |
| name              | text          | YES  |     | NULL    |       |
| description       | text          | YES  |     | NULL    |       |
| short_description | text          | YES  |     | NULL    |       |
| contents          | text          | YES  |     | NULL    |       |
| price             | decimal(10,2) | YES  |     | NULL    |       |
| group             | varchar(255)  | NO   | PRI |         |       |
| brand             | varchar(255)  | YES  |     | NULL    |       |
| oemid             | varchar(50)   | YES  |     | NULL    |       |
| oem_price         | decimal(11,2) | YES  |     | NULL    |       |
| yield             | varchar(20)   | YES  |     | NULL    |       |
| ink_content       | varchar(20)   | YES  |     | NULL    |       |
| search_string     | text          | YES  |     | NULL    |       |
| price_euro        | decimal(11,2) | YES  |     | NULL    |       |
| webmaster_id      | int(11)       | NO   |     | 0       |       |
+-------------------+---------------+------+-----+---------+-------+

mysql> describe ink_product_by_set;
+-------------+------------------+------+-----+---------+----------------+
| Field       | Type             | Null | Key | Default | Extra          |
+-------------+------------------+------+-----+---------+----------------+
| id          | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| product_set | int(11)          | NO   |     | 0       |                |
| product     | varchar(12)      | YES  |     | NULL    |                |
+-------------+------------------+------+-----+---------+----------------+

Wären Keys auf webmaster_id, group und brand sinnvoll?
 
Ok, werd ich machen, vielen Dank! Wenn ich Zeit habe, lese ich auch endlich das MySQL Buch, dann muss ich solche Grundlagen nicht mehr fragen.

Im Moment ist aber das Problem mit qmail dringender (siehe anderen Thread)... Mühsam...
 
Back
Top