mysql caching

wall < "mysql und Caching"

Broadcast message from spillerm@unixe.de (pts/1) (Mi Jul 14 14:22:33 2010):
4
Diesen Beitrag schrieb ich vor 8 Jahren. Behalte das beim Lesen bitte im Hinterkopf.

Wozu eigentlich den MySQL-Query-Cache aktivieren? Nun — er speichert zweierlei, nämlich

  • zum einen die SELECT-Anweisung und
  • zum anderen das zu der Anweisung gehörige Ergebnis, das dem Client übermittelt wurde.

Wird hernach die selbe Anweisung erneut empfangen, so wird das SELECT-Statement nicht erneut ausgeführt, sondern das Ergebnis aus dem Cache gegriffen und übermittelt. Dies spart natürlich Ressourcen — was sich beispielsweise bei gut besuchten Webseiten doch deutlich bemerkbar macht. Und wer nun skeptisch ist, der sei beruhigt: der MySQL-Query-Cache liefert keine veralteten Daten zurück — werden Tabellen modifiziert, wird auch der Cache synchronisiert.

Doch wie prüfe ich nun, ob das Caching auf meinem Server aktiviert ist — beziehungsweise wie aktiviere ich es? Melde dich per mysql -u root -p an deinem MySQL-Server an und schau nach:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 634
Server version: 5.0.83-0ubuntu3 (Ubuntu)
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql> show variables like '%cache%';
+------------------------------+----------------------+
| Variable_name                | Value                |
+------------------------------+----------------------+
| binlog_cache_size            | 32768                | 
| have_query_cache             | YES                  | 
| key_cache_age_threshold      | 300                  | 
| key_cache_block_size         | 1024                 | 
| key_cache_division_limit     | 100                  | 
| max_binlog_cache_size        | 18446744073709547520 | 
| ndb_cache_check_time         | 0                    | 
| query_cache_limit            | 1048576              |
| query_cache_min_res_unit     | 4096                 | 
| query_cache_size             | 0                    |
| query_cache_type             | ON                   |
| query_cache_wlock_invalidate | OFF                  | 
| table_cache                  | 64                   | 
| thread_cache_size            | 0                    | 
+------------------------------+----------------------+
14 rows in set (0.00 sec)

have_query_cache gibt hierbei an, ob die Caching-Funktionalität prinzipiell vorhanden ist; ein YES sagt jedoch an dieser Stelle nur aus, dass sie da ist — nicht aber, dass sie auch aktiv ist! query_cache_limit gibt die maximale Grösse einer Anfrage an, die im Cache vorgehalten werden kann; der Default hierfür ist 1MB (1048576). Daneben bezeichnet query_cache_size die Grösse des Speichers, der insgesamt für zwischengespeicherte Anfragen zur Verfügung steht. Der Default hierfür lautet 0, und das ist gleichbedeutend mit »abgeschaltetem Caching«. Um den Wert nun (global) auf 256MB zu erhöhen und das Caching somit anzuschalten, kann man beispielsweise wie folgt vorgehen:

$ echo "256*1024*1024" | bc
268435456
mysql> set global query_cache_size = 268435456;
Query OK, 0 rows affected (0.00 sec)

Das setzt den Wert im laufenden Betrieb des Servers auf den angegebenen Wert; bereits bestehende Verbindungen (Sessions) sind hiervon aber gegebenenfalls nicht betroffen! Wird bei SHOW VARIABLES weder GLOBAL noch SESSION angeben, gibt MySQL immer den SESSION-Wert zurück — das ist ebenfalls wichtig zu wissen. Nun kann man den Cache manuell initialisieren, was eine Defragmentierung des Caches bewirkt und auch zur Optimierung eingesetzt werden kann (hierbei werden keine hinterlegten Abfragen gelöscht):

mysql> FLUSH QUERY CACHE;

Ebenso lassen sich alle gespeicherten Ergebnisse manuell aus dem Query-Cache löschen:

mysql> RESET QUERY CACHE;

Natürlich lassen sich die Einstellungen auch in der my.cnf hinterlegen, hier dann (ab MySQL-Version >= 5.0) beispielsweise in der Form

query_cache_limit       = 1M
query_cache_size        = 256M
query_cache_type        = 1

Um Informationen über den aktuellen Status des Caches zu erhalten, kann man beispielsweise folgendermassen vorgehen:

mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| Qcache_free_blocks      | 3559      | 
| Qcache_free_memory      | 242407856 | 
| Qcache_hits             | 1560460   | 
| Qcache_inserts          | 46485     | 
| Qcache_lowmem_prunes    | 0         | 
| Qcache_not_cached       | 31029     | 
| Qcache_queries_in_cache | 13806     | 
| Qcache_total_blocks     | 31344     | 
+-------------------------+-----------+
8 rows in set (0.00 sec)

mysql cachingWichtig: bei einem Restart des Servers (=Prozesses) gehen die zwischengespeicherten Daten (!!! die im RAM vorgehalten werden !!!) natürlich verloren. Insofern sollte man darauf achten, nicht jeglicher Mini-Änderung direkt ein /etc/init.d/mysqld restart folgen zu lassen! Die meisten Settings lassen sich, wie man sieht, mühelos im laufenden Betrieb einstellen.

4