weniger Verbindungen, gezielter Read/Write-Split, mehr Kontrolle
Tausende gleichzeitige Anwendungsverbindungen überfordern MySQL schneller als die eigentliche Abfragelast. ProxySQL sitzt zwischen Anwendung und Datenbank, bündelt Verbindungen über Connection-Pooling und verteilt Lese- und Schreibzugriffe per Query-Routing-Regeln auf die passenden Server, ohne dass die Anwendung davon etwas merkt.
Inhaltsverzeichnis
- 1. Warum ein Proxy zwischen Anwendung und MySQL
- 2. Architektur: Threads, Backends und Admin-Interface
- 3. Installation und Grundkonfiguration
- 4. Connection Pooling und Multiplexing verstehen
- 5. Query-Routing-Regeln für Read/Write-Split
- 6. Hostgroups und Replikations-Erkennung
- 7. Monitoring und Statistiken in ProxySQL
- 8. Failover-Verhalten und Health Checks
- 9. Performance-Vergleich mit und ohne ProxySQL
- 10. Zusammenfassung
- 11. FAQ
1. Warum ein Proxy zwischen Anwendung und MySQL
ProxySQL löst ein Problem, das mit wachsender Anwendungslandschaft fast immer entsteht: zu viele gleichzeitig offene Verbindungen zur Datenbank. Jede PHP-FPM-Instanz, jeder Kubernetes-Pod und jeder Cronjob öffnet eigene Verbindungen, und MySQL muss für jede davon einen eigenen Thread mit eigenem Speicherbereich vorhalten. Bei mehreren hundert Anwendungsservern summiert sich das schnell auf tausende Verbindungen, obwohl die tatsächliche Abfragelast dafür gar nicht nötig wäre.
ProxySQL setzt sich als eigenständiger Layer zwischen Anwendung und Datenbank und spricht das MySQL-Protokoll auf beiden Seiten, sodass weder die Anwendung noch der Datenbankserver eine Anpassung benötigen. Die Anwendung verbindet sich wie gewohnt per MySQL-Client-Bibliothek zu ProxySQL, und ProxySQL entscheidet dahinter, über welche Verbindung und an welchen Server eine Abfrage tatsächlich weitergereicht wird. Damit wird ProxySQL zum zentralen Kontrollpunkt für Connection-Pooling, Query-Routing und Lastverteilung in einem produktiven MySQL-Setup.
2. Architektur: Threads, Backends und Admin-Interface
Intern besteht ProxySQL aus mehreren Worker-Threads, die eingehende Client-Verbindungen entgegennehmen, sowie einem separaten Pool von Backend-Verbindungen zu den eigentlichen MySQL-Servern. Diese Trennung ist der Kern des Connection-Poolings: Client-Verbindungen und Backend-Verbindungen sind zwei unterschiedliche Ressourcen, die ProxySQL unabhängig voneinander skaliert. Ein Query-Processing-Layer zwischen beiden Seiten wertet jede eingehende Abfrage anhand konfigurierbarer Regeln aus, bevor sie an ein Backend weitergereicht wird.
Konfiguriert wird ProxySQL nicht über eine klassische Konfigurationsdatei, sondern über ein eigenes SQL-Admin-Interface auf Port 6032, das MySQL-Syntax versteht und Tabellen wie mysql_servers, mysql_users und mysql_query_rules bereitstellt. Änderungen werden zunächst in eine Runtime-Konfiguration geladen und erst nach Bestätigung dauerhaft in eine SQLite-Datenbank persistiert, was Testen ohne Risiko für die laufende Konfiguration ermöglicht.
# ProxySQL installieren und Dienst starten (Debian/Ubuntu)
wget https://repo.proxysql.com/ProxySQL/proxysql-2.6.x/apt/proxysql_2.6.0-debian12_amd64.deb
apt install -y ./proxysql_2.6.0-debian12_amd64.deb
systemctl enable --now proxysql
# Offene Ports pruefen: 6033 Datenverkehr, 6032 Admin-Interface
ss -tlnp | grep proxysql
# Aktuellen Konfigurationsstatus im Admin-Interface pruefen
mysql -u admin -p -h 127.0.0.1 -P 6032 -e "SELECT * FROM runtime_mysql_servers;"
3. Installation und Grundkonfiguration
Die Installation von ProxySQL erfolgt über die offiziellen Pakete für Debian, Ubuntu oder RHEL und startet einen Systemdienst, der sofort zwei Ports öffnet: einen für den eigentlichen Datenverkehr, meist 6033, und einen für das Admin-Interface auf 6032. Nach der Installation verbindet man sich mit einem MySQL-Client gegen das Admin-Interface und legt zunächst die Backend-Server in der Tabelle mysql_servers an, gefolgt von den Anwendungs-Zugangsdaten in mysql_users.
Wichtig ist, nach jeder Änderung an einer Runtime-Tabelle den passenden LOAD ... TO RUNTIME-Befehl auszuführen, da ProxySQL sonst weiterhin die zuvor geladene Konfiguration verwendet. Erst SAVE ... TO DISK macht die Änderung über einen Neustart hinweg dauerhaft. Dieser zweistufige Mechanismus aus Runtime und Disk ist ein häufiger Stolperstein für Einsteiger, aber essenziell, um Fehlkonfigurationen kontrolliert testen zu können, bevor sie dauerhaft aktiv werden.
-- Verbindung zum ProxySQL Admin-Interface
-- mysql -u admin -p -h 127.0.0.1 -P 6032
-- Backend-Server registrieren: Writer und zwei Reader
INSERT INTO mysql_servers (hostgroup_id, hostname, port, weight)
VALUES (10, 'db-writer.internal', 3306, 1000),
(20, 'db-reader-1.internal', 3306, 900),
(20, 'db-reader-2.internal', 3306, 900);
-- Anwendungs-User anlegen und der Standard-Hostgroup zuweisen
INSERT INTO mysql_users (username, password, default_hostgroup)
VALUES ('shop_app', 'strong_password_here', 10);
-- Konfiguration aktiv schalten und dauerhaft speichern
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;
4. Connection Pooling und Multiplexing verstehen
Der zentrale Vorteil von ProxySQL ist Connection Multiplexing: mehrere Client-Verbindungen teilen sich eine deutlich kleinere Anzahl an Backend-Verbindungen zum eigentlichen MySQL-Server. Solange keine Transaktion oder gesperrte Session-Variable eine feste Zuordnung erzwingt, kann ProxySQL nach jeder Abfrage die Backend-Verbindung wieder freigeben und für die nächste Anfrage eines anderen Clients wiederverwenden. Das reduziert die Anzahl gleichzeitig offener MySQL-Verbindungen oft um eine Größenordnung.
Diese Wiederverwendung spart nicht nur Speicher auf dem Datenbankserver, sondern auch den Overhead beim Verbindungsaufbau selbst, der bei TLS-verschlüsselten Verbindungen mit vollem Handshake spürbar ins Gewicht fällt. Multiplexing wird automatisch deaktiviert, sobald eine Session in eine Transaktion eintritt oder SET-Befehle mit Session-Scope ausführt, weil in diesem Fall der Zustand der Verbindung an genau diese eine Client-Session gebunden bleiben muss, bis die Transaktion abgeschlossen ist.
5. Query-Routing-Regeln für Read/Write-Split
Die Tabelle mysql_query_rules ist das Herzstück des Query-Routings in ProxySQL: jede eingehende Abfrage wird nacheinander gegen die definierten Regeln geprüft, meist per regulärem Ausdruck auf den SQL-Text. Eine typische Regel leitet alle Abfragen, die mit SELECT beginnen, auf die Read-Hostgroup mit den Replikaten um, während INSERT, UPDATE und DELETE automatisch auf der Write-Hostgroup mit dem primären Server landen, ganz ohne Änderung am Anwendungscode.
Für komplexere Fälle lassen sich Regeln mit Prioritäten und einer apply-Flag-Kette kombinieren, etwa um SELECT-Abfragen mit dem Kommentar /* force_master */ gezielt trotzdem auf den Writer zu leiten, wenn eine Anwendung unmittelbar nach einem Schreibzugriff konsistent lesen muss. Diese Flexibilität macht Query-Routing in ProxySQL deutlich mächtiger als ein statischer Read/Write-Split allein in der Anwendungsschicht.
-- Query-Regeln für Read/Write-Split anlegen
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES
(100, 1, '^SELECT.*FOR UPDATE', 10, 1), -- Schreibende Selects zum Writer
(200, 1, '^SELECT.*/\\*force_master\\*/', 10, 1), -- Explizit erzwungene Writer-Reads
(300, 1, '^SELECT', 20, 1), -- Alle übrigen Selects zu den Readern
(400, 1, '^(INSERT|UPDATE|DELETE|REPLACE)', 10, 1); -- Schreibbefehle zum Writer
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
6. Hostgroups und Replikations-Erkennung
Hostgroups sind logische Gruppen von Backend-Servern, denen ProxySQL unabhängige Rollen zuweist, typischerweise eine Writer-Hostgroup mit dem primären Server und eine Reader-Hostgroup mit allen Replikaten. Ueber das Modul mysql_replication_hostgroups kann ProxySQL den Replikationsstatus jedes Servers automatisch per SHOW SLAVE STATUS überwachen und Server bei Bedarf selbstständig zwischen Writer- und Reader-Hostgroup verschieben, etwa nach einem manuellen Failover.
Diese automatische Erkennung reduziert manuelle Eingriffe erheblich: fällt der bisherige Writer aus und ein Replikat wird zum neuen primären Server befördert, erkennt ProxySQL die geänderte Replikationstopologie und passt die Hostgroup-Zugehörigkeit selbstständig an, ohne dass die Query-Routing-Regeln selbst verändert werden müssen. Die Regeln bleiben stabil, nur die Zuordnung der Server zu den Hostgroups ändert sich im Hintergrund.
7. Monitoring und Statistiken in ProxySQL
Neben dem Admin-Interface stellt ProxySQL eine eigene Statistik-Datenbank bereit, erreichbar über dieselbe Verbindung mit USE stats;. Tabellen wie stats_mysql_query_digest zeigen aggregierte Ausführungszeiten pro Query-Muster, stats_mysql_connection_pool den aktuellen Zustand jeder Backend-Verbindung inklusive der Anzahl aktiver, freier und fehlgeschlagener Verbindungen je Hostgroup.
Diese eingebauten Statistiken machen ProxySQL zu einem wertvollen Beobachtungspunkt für die gesamte Datenbanklast, weil hier bereits vor der eigentlichen Datenbank sichtbar wird, welche Query-Muster am häufigsten ausgeführt werden und wie lange sie im Schnitt dauern. In Kombination mit Prometheus-Exportern, die ProxySQL nativ unterstützt, lassen sich diese Werte direkt in bestehende Monitoring-Dashboards integrieren, ohne zusätzliche Agenten auf den Datenbankservern selbst zu benötigen.
-- Verbindungsstatus je Backend-Server pruefen
SELECT hostgroup, srv_host, status, ConnUsed, ConnFree, ConnOK, ConnERR
FROM stats_mysql_connection_pool
ORDER BY hostgroup;
-- Die zehn langsamsten Query-Muster der letzten Stunde
SELECT digest_text, count_star, sum_time, sum_time / count_star AS avg_time_us
FROM stats_mysql_query_digest
ORDER BY sum_time DESC
LIMIT 10;
8. Failover-Verhalten und Health Checks
ProxySQL überwacht jeden Backend-Server kontinuierlich mit konfigurierbaren Health Checks: einem einfachen Verbindungstest, einer Prüfung auf schreibgeschützten Zustand über read_only und optional benutzerdefinierten Skripten für komplexere Zustandsprüfungen. Fällt ein Server aus oder antwortet nicht mehr innerhalb der konfigurierten Zeitgrenze, markiert ProxySQL ihn automatisch als OFFLINE_SOFT oder OFFLINE_HARD und leitet neue Abfragen an die verbleibenden Server der Hostgroup um.
Der entscheidende Vorteil gegenüber einem Failover ausschließlich auf Anwendungsebene ist, dass laufende Verbindungen aus dem Client-Pool erhalten bleiben, während nur die Backend-Zuordnung dahinter wechselt. Die Anwendung selbst bemerkt im Idealfall lediglich eine kurze erhöhte Latenz während des Umschaltens, aber keinen vollständigen Verbindungsabbruch, was besonders bei lang laufenden Anwendungsprozessen die Fehlerrate spürbar senkt.
-- Health-Check-Intervalle und Zeitgrenzen konfigurieren
SET mysql-monitor_connect_interval = 2000;
SET mysql-monitor_ping_interval = 3000;
SET mysql-monitor_read_only_interval = 1500;
SET mysql-shun_on_failures = 3;
LOAD MYSQL VARIABLES TO RUNTIME;
-- Aktuellen Serverstatus nach einem simulierten Ausfall pruefen
SELECT hostgroup_id, hostname, status
FROM mysql_servers
WHERE status != 'ONLINE';
9. Performance-Vergleich mit und ohne ProxySQL
Der Performance-Effekt von ProxySQL hängt stark vom Verbindungsverhalten der Anwendung ab. Bei kurzlebigen Verbindungen, wie sie klassische PHP-Anwendungen ohne Persistent-Connections erzeugen, zeigt sich der größte Gewinn: statt für jeden Request eine neue TCP- und TLS-Verbindung zum Datenbankserver aufzubauen, nutzt die Anwendung eine bereits offene Verbindung zu ProxySQL, während ProxySQL selbst deutlich weniger, aber länger offene Backend-Verbindungen unterhält.
Die folgende Tabelle fasst zusammen, wie sich typische Kennzahlen zwischen einer direkten Verbindung und einer Verbindung über ProxySQL unterscheiden, basierend auf Erfahrungswerten aus produktiven Setups mit mehreren hundert Anwendungsinstanzen.
| Kennzahl | Direkte Verbindung | Mit ProxySQL |
|---|---|---|
| Aktive MySQL-Backend-Verbindungen | Eine pro Anwendungsprozess | Gebündelt, oft 5 bis 10 Prozent der Client-Zahl |
| Verbindungsaufbau pro Request | Voller TCP/TLS-Handshake | Wiederverwendung bestehender Backend-Verbindung |
| Read/Write-Split | Manuell im Anwendungscode | Zentral über Query-Regeln, ohne Code-Änderung |
| Failover-Sichtbarkeit für Anwendung | Vollständiger Verbindungsabbruch | Kurze Latenzspitze, Verbindung bleibt bestehen |
| Zusätzliche Latenz pro Query | Keine | Meist unter 1 Millisekunde durch den Proxy-Hop |
Mironsoft
MySQL-Skalierung, Connection-Management und Query-Routing für Produktionslast
Zu viele MySQL-Verbindungen, ungenutzte Replikate?
Wir konzipieren und betreiben ProxySQL-Setups für eure Anwendungslandschaft, richten Query-Routing-Regeln für sauberen Read/Write-Split ein und binden Monitoring an bestehende Dashboards an.
ProxySQL-Einführung
Installation, Hostgroups und Connection-Pooling passend zur bestehenden Replikationstopologie
Query-Routing-Regeln
Read/Write-Split ohne Anwendungscode-Änderung, inklusive Sonderfälle wie erzwungene Writer-Reads
Monitoring-Integration
ProxySQL-Statistiken in bestehende Prometheus- und Grafana-Dashboards einbinden
10. Zusammenfassung
ProxySQL löst zwei Probleme gleichzeitig: die Zahl echter MySQL-Verbindungen sinkt durch Connection Multiplexing drastisch, und Lese- sowie Schreibzugriffe lassen sich über Query-Regeln zentral und ohne Anwendungscode-Änderung auf die passenden Server verteilen. Die zweistufige Konfiguration aus Runtime und Disk erlaubt risikoarmes Testen neuer Regeln, bevor sie dauerhaft aktiv werden.
Der größte Nutzen zeigt sich in Umgebungen mit vielen kurzlebigen Anwendungsverbindungen und mehreren Lesereplikaten, wo ProxySQL sowohl die Backend-Last reduziert als auch Failover für die Anwendung nahezu unsichtbar macht. Wer ProxySQL einführt, sollte Query-Regeln schrittweise ausrollen und die eingebauten Statistiktabellen von Anfang an in ein bestehendes Monitoring einbinden.
ProxySQL für Connection-Pooling und Query-Routing: Das Wichtigste auf einen Blick
Connection Pooling
Multiplexing bündelt viele Client-Verbindungen auf wenige Backend-Verbindungen und spart Speicher sowie Handshake-Overhead.
Query-Routing
Regex-basierte Regeln in mysql_query_rules verteilen SELECT und schreibende Befehle automatisch auf die richtige Hostgroup.
Hostgroups
Automatische Replikations-Erkennung passt Writer- und Reader-Zuordnung nach einem Failover selbstständig an.
Konfiguration
Immer LOAD TO RUNTIME und SAVE TO DISK trennen, um Änderungen erst risikofrei zu testen.