README.md aktualisiert
This commit is contained in:
175
README.md
175
README.md
@@ -1,6 +1,6 @@
|
||||
# JTL-Shop MariaDB Optimization
|
||||
|
||||
Automatisierte Index-Optimierung und FULLTEXT-Suche für JTL-Shop-Datenbanken auf Multi-Shop-Servern.
|
||||
Automatisierte Index-Optimierung, FULLTEXT-Suche und MariaDB-Konfiguration für JTL-Shop-Datenbanken auf Multi-Shop-Servern.
|
||||
|
||||
## 🎯 Problemstellung
|
||||
|
||||
@@ -73,7 +73,7 @@ Das Skript `mariadb-optimization.py` behebt diese Probleme automatisiert:
|
||||
| **2** | Standard-Indizes | Erstellt 4 fehlende Index-Typen |
|
||||
| **3** | FULLTEXT-Index | Erstellt FULLTEXT-Index auf `tartikel` |
|
||||
| **4** | Einstellung aktivieren | Setzt `suche_fulltext = 'Y'` |
|
||||
| **5** | Rollback-Skript | Generiert Rollback für Notfälle |
|
||||
| **5** | MariaDB-Config | Erstellt optimierte Konfiguration & Restart |
|
||||
|
||||
### Erstellte Indizes
|
||||
|
||||
@@ -95,6 +95,81 @@ CREATE FULLTEXT INDEX idx_tartikel_fulltext ON tartikel
|
||||
(cName, cSeo, cSuchbegriffe, cArtNr, cKurzBeschreibung, cBeschreibung, cBarcode, cISBN, cHAN);
|
||||
```
|
||||
|
||||
### MariaDB-Konfiguration (Phase 5)
|
||||
|
||||
Das Skript erstellt automatisch eine optimierte Konfiguration unter:
|
||||
```
|
||||
/etc/mysql/conf.d/ZZ-ztl-final-override.cnf
|
||||
```
|
||||
|
||||
**Dynamische Buffer Pool Berechnung:**
|
||||
- Ermittelt Gesamtgröße aller Datenbanken
|
||||
- Berechnet: `DB-Größe × 1.2`, aufgerundet auf ganze GB
|
||||
- Beispiel: 18.74 GB × 1.2 = **23 GB** Buffer Pool
|
||||
|
||||
**Konfigurationsinhalt:**
|
||||
|
||||
```ini
|
||||
[mysqld]
|
||||
# InnoDB Buffer Pool (dynamisch berechnet)
|
||||
innodb_buffer_pool_size = XXG
|
||||
innodb_buffer_pool_instances = 16
|
||||
innodb_buffer_pool_dump_at_shutdown = 1
|
||||
innodb_buffer_pool_load_at_startup = 1
|
||||
innodb_log_file_size = 512M
|
||||
innodb_log_buffer_size = 64M
|
||||
innodb_flush_log_at_trx_commit = 2
|
||||
|
||||
# InnoDB Performance
|
||||
innodb_flush_method = O_DIRECT
|
||||
innodb_file_per_table = 1
|
||||
innodb_io_capacity = 2000
|
||||
innodb_io_capacity_max = 4000
|
||||
innodb_read_io_threads = 16
|
||||
innodb_write_io_threads = 16
|
||||
|
||||
# Query Cache deaktiviert (bei MariaDB 10.1.7+ empfohlen)
|
||||
query_cache_type = 0
|
||||
query_cache_size = 0
|
||||
|
||||
# Table Cache für viele Shops
|
||||
table_definition_cache = 20000
|
||||
table_open_cache = 15000
|
||||
open_files_limit = 30000
|
||||
|
||||
# Performance
|
||||
skip_name_resolve = 1
|
||||
optimizer_search_depth = 0
|
||||
key_buffer_size = 64M
|
||||
|
||||
# Slow Query Log
|
||||
slow_query_log = 1
|
||||
slow_query_log_file = /var/log/mysql/slow.log
|
||||
long_query_time = 1.0
|
||||
log_queries_not_using_indexes = 0
|
||||
|
||||
# Connections
|
||||
max_connections = 400
|
||||
thread_cache_size = 100
|
||||
wait_timeout = 120
|
||||
|
||||
# Buffer für JTL-Queries
|
||||
join_buffer_size = 4M
|
||||
sort_buffer_size = 4M
|
||||
read_buffer_size = 2M
|
||||
read_rnd_buffer_size = 2M
|
||||
```
|
||||
|
||||
**Wichtige Einstellungen erklärt:**
|
||||
|
||||
| Parameter | Wert | Funktion |
|
||||
|-----------|------|----------|
|
||||
| `innodb_buffer_pool_dump/load` | 1 | Buffer Pool bleibt nach Restart "warm" |
|
||||
| `skip_name_resolve` | 1 | Schnellere Verbindungen (kein DNS-Lookup) |
|
||||
| `optimizer_search_depth` | 0 | Auto-Optimierung für JOINs |
|
||||
| `key_buffer_size` | 64M | Reduziert (nur für MyISAM, JTL nutzt InnoDB) |
|
||||
| `query_cache` | OFF | Bei write-heavy Workloads kontraproduktiv |
|
||||
|
||||
## 🚀 Installation & Verwendung
|
||||
|
||||
### Voraussetzungen
|
||||
@@ -124,7 +199,7 @@ python3 mariadb-optimization.py
|
||||
|
||||
⚠️ **Zu Zeiten geringer Last ausführen** (nachts/früh morgens)
|
||||
|
||||
Der FULLTEXT-Index auf großen Shops (z.B. 468.000 Artikel) kann mehrere Minuten dauern und erhöht kurzzeitig die Server-Last.
|
||||
Der FULLTEXT-Index auf großen Shops (z.B. 468.000 Artikel) kann mehrere Minuten dauern und erhöht kurzzeitig die Server-Last. Am Ende wird MariaDB automatisch neugestartet.
|
||||
|
||||
## 📁 Ausgabe-Dateien
|
||||
|
||||
@@ -133,7 +208,8 @@ Nach der Ausführung werden folgende Dateien erstellt:
|
||||
| Datei | Zweck |
|
||||
|-------|-------|
|
||||
| `/root/jtl_search_backup_TIMESTAMP.json` | Backup aller Sucheinstellungen |
|
||||
| `/root/jtl_search_rollback_TIMESTAMP.py` | Rollback-Skript |
|
||||
| `/root/jtl_search_rollback_TIMESTAMP.py` | Rollback-Skript für Sucheinstellungen |
|
||||
| `/root/mariadb_config_backup_TIMESTAMP.cnf` | Backup der vorherigen MariaDB-Config |
|
||||
| `/root/jtl_index_log_TIMESTAMP.txt` | Vollständiges Ausführungs-Log |
|
||||
|
||||
## 🔄 Rollback bei Problemen
|
||||
@@ -143,6 +219,10 @@ Falls nach der Optimierung Probleme auftreten:
|
||||
```bash
|
||||
# Rollback der Sucheinstellungen (setzt suche_fulltext auf vorherigen Wert)
|
||||
python3 /root/jtl_search_rollback_TIMESTAMP.py
|
||||
|
||||
# Rollback der MariaDB-Konfiguration
|
||||
cp /root/mariadb_config_backup_TIMESTAMP.cnf /etc/mysql/conf.d/ZZ-ztl-final-override.cnf
|
||||
systemctl restart mariadb
|
||||
```
|
||||
|
||||
**Hinweis:** Die erstellten Indizes müssen nicht zurückgerollt werden – sie haben keine negative Auswirkung und können bei Bedarf manuell entfernt werden.
|
||||
@@ -180,6 +260,22 @@ Typische Gründe:
|
||||
2. Updates erstellen keine Indizes nachträglich
|
||||
3. Die Tabellen waren ursprünglich klein
|
||||
|
||||
### Wie wird der Buffer Pool berechnet?
|
||||
|
||||
```
|
||||
Buffer Pool = Gesamtgröße aller Datenbanken × 1.2 (aufgerundet)
|
||||
```
|
||||
|
||||
Beispiel: 18.74 GB × 1.2 = 22.49 GB → **23 GB**
|
||||
|
||||
### Warum ist Query Cache deaktiviert?
|
||||
|
||||
Bei Multi-Shop-Servern mit vielen Schreiboperationen (Bestellungen, Lagerbestände, etc.) ist der Query Cache kontraproduktiv:
|
||||
|
||||
- Jedes INSERT/UPDATE/DELETE invalidiert den Cache
|
||||
- Lock Contention bei vielen gleichzeitigen Queries
|
||||
- MySQL 8.0 hat den Query Cache komplett entfernt
|
||||
|
||||
### Wie kann ich den Effekt messen?
|
||||
|
||||
**Vorher/Nachher Vergleich:**
|
||||
@@ -219,7 +315,7 @@ pt-query-digest --limit=50 /var/log/mysql/slow.log > /tmp/slow_report.txt
|
||||
|
||||
```bash
|
||||
# Shops ohne FULLTEXT-Index
|
||||
mysql -N -e "SELECT t.table_schema, t.table_rows
|
||||
mysql -N -B -e "SELECT t.table_schema, t.table_rows
|
||||
FROM information_schema.tables t
|
||||
WHERE t.table_name = 'tartikel'
|
||||
AND t.table_schema NOT IN (
|
||||
@@ -230,14 +326,31 @@ AND t.table_schema NOT IN (
|
||||
ORDER BY t.table_rows DESC;"
|
||||
|
||||
# FULLTEXT-Einstellung pro Shop
|
||||
mysql -N -e "SELECT table_schema FROM information_schema.tables
|
||||
mysql -N -B -e "SELECT table_schema FROM information_schema.tables
|
||||
WHERE table_name = 'teinstellungen'" | while read db; do
|
||||
val=$(mysql -N -e "SELECT cWert FROM \`$db\`.teinstellungen
|
||||
val=$(mysql -N -B -e "SELECT cWert FROM \`$db\`.teinstellungen
|
||||
WHERE cName = 'suche_fulltext' LIMIT 1" 2>/dev/null)
|
||||
echo "$db: ${val:-NICHT GESETZT}"
|
||||
done
|
||||
```
|
||||
|
||||
### Datenbankgrößen prüfen
|
||||
|
||||
```bash
|
||||
# Gesamtgröße aller Datenbanken
|
||||
mysql -N -B -e "SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');"
|
||||
|
||||
# Größe pro Datenbank
|
||||
mysql -e "SELECT table_schema AS 'Datenbank',
|
||||
ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Größe (MB)'
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys')
|
||||
GROUP BY table_schema
|
||||
ORDER BY SUM(data_length + index_length) DESC;"
|
||||
```
|
||||
|
||||
### Buffer Pool & Key Metrics
|
||||
|
||||
```bash
|
||||
@@ -247,54 +360,6 @@ mysql -e "SHOW GLOBAL STATUS WHERE Variable_name IN
|
||||
'Threads_running','Questions','Slow_queries','Uptime');"
|
||||
```
|
||||
|
||||
## 📋 Empfohlene MariaDB-Konfiguration
|
||||
|
||||
Basierend auf der Analyse, hier eine optimierte Konfiguration für Multi-Shop-Server:
|
||||
|
||||
```ini
|
||||
[mysqld]
|
||||
# InnoDB Buffer Pool (ca. 70% des verfügbaren RAM)
|
||||
innodb_buffer_pool_size = 32G
|
||||
innodb_buffer_pool_instances = 16
|
||||
innodb_log_file_size = 512M
|
||||
innodb_log_buffer_size = 64M
|
||||
innodb_flush_log_at_trx_commit = 2
|
||||
|
||||
# InnoDB Performance
|
||||
innodb_flush_method = O_DIRECT
|
||||
innodb_file_per_table = 1
|
||||
innodb_io_capacity = 2000
|
||||
innodb_io_capacity_max = 4000
|
||||
innodb_read_io_threads = 16
|
||||
innodb_write_io_threads = 16
|
||||
|
||||
# Query Cache deaktiviert (bei MariaDB 10.1.7+ empfohlen)
|
||||
query_cache_type = 0
|
||||
query_cache_size = 0
|
||||
|
||||
# Table Cache für viele Shops
|
||||
table_definition_cache = 20000
|
||||
table_open_cache = 10000
|
||||
open_files_limit = 30000
|
||||
|
||||
# Slow Query Log
|
||||
slow_query_log = 1
|
||||
slow_query_log_file = /var/log/mysql/slow.log
|
||||
long_query_time = 1.0
|
||||
log_queries_not_using_indexes = 0
|
||||
|
||||
# Connections
|
||||
max_connections = 400
|
||||
thread_cache_size = 100
|
||||
wait_timeout = 120
|
||||
|
||||
# Buffer für JTL-Queries
|
||||
join_buffer_size = 4M
|
||||
sort_buffer_size = 4M
|
||||
read_buffer_size = 2M
|
||||
read_rnd_buffer_size = 2M
|
||||
```
|
||||
|
||||
## 🐛 Bekannte Einschränkungen
|
||||
|
||||
### Nicht durch Indizes lösbar
|
||||
|
||||
Reference in New Issue
Block a user