README.md aktualisiert

This commit is contained in:
2025-12-12 17:55:35 +01:00
parent 1f1144ac5a
commit 76cbbfb10e

175
README.md
View File

@@ -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