3fc5c9ff7a
- Datenbank auf utf8mb4_unicode_ci migriert (migrate_to_utf8mb4.sh) - beos: Spalte 'role' (kommagetrennte Rollen: guide, admin, key, deleted) - BEO-Auswahl im Formular filtert nur noch role='guide' - logbuch_objekte: ObjektName-Spalte entfernt, stattdessen JOIN auf objekte - lib/db.ts: charset utf8mb4 in Connection-Pool - Session und Auth um role-Feld erweitert - compose.yml: phpMyAdmin mit Traefik unter /myadmin - compose.yml: MySQL auf 127.0.0.1:3336 für SSH-Tunnel (lokale Entwicklung) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
148 lines
6.6 KiB
Bash
Executable File
148 lines
6.6 KiB
Bash
Executable File
#!/bin/bash
|
|
# Migriert die Datenbank von latin1 auf utf8mb4.
|
|
# Läuft auf dem Server im Verzeichnis der compose.yml.
|
|
# Voraussetzung: iconv installiert (apt install libc-bin)
|
|
|
|
set -e
|
|
|
|
CONTAINER="logbuch_mysql"
|
|
DB="sternwarte"
|
|
DUMP_LATIN1="/tmp/sternwarte_latin1.sql"
|
|
DUMP_UTF8="/tmp/sternwarte_utf8mb4.sql"
|
|
|
|
# Root-Passwort aus .env lesen
|
|
ROOT_PASS=$(grep DB_ROOT_PASS .env | cut -d= -f2)
|
|
if [ -z "$ROOT_PASS" ]; then
|
|
echo "FEHLER: DB_ROOT_PASS nicht in .env gefunden." >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "══════════════════════════════════════════════════════"
|
|
echo " latin1 → utf8mb4 Migration: $DB"
|
|
echo "══════════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
# ── Sicherheits-Backup ───────────────────────────────────────────────────────
|
|
BACKUP="/tmp/sternwarte_backup_$(date +%Y%m%d_%H%M%S).sql"
|
|
echo ">>> Erstelle Backup: $BACKUP"
|
|
docker exec "$CONTAINER" mysqldump \
|
|
-u root -p"$ROOT_PASS" \
|
|
--default-character-set=latin1 \
|
|
--single-transaction \
|
|
--no-tablespaces \
|
|
--set-gtid-purged=OFF \
|
|
"$DB" > "$BACKUP"
|
|
echo " Backup gespeichert: $BACKUP"
|
|
echo ""
|
|
|
|
# ── Dump als latin1 exportieren ──────────────────────────────────────────────
|
|
echo ">>> Exportiere Daten mit latin1-Zeichensatz..."
|
|
docker exec "$CONTAINER" mysqldump \
|
|
-u root -p"$ROOT_PASS" \
|
|
--default-character-set=latin1 \
|
|
--single-transaction \
|
|
--no-tablespaces \
|
|
--skip-set-charset \
|
|
--set-gtid-purged=OFF \
|
|
"$DB" > "$DUMP_LATIN1"
|
|
echo " Dump: $DUMP_LATIN1"
|
|
echo ""
|
|
|
|
# ── Bytes latin1 → utf8 konvertieren ────────────────────────────────────────
|
|
echo ">>> Konvertiere Bytes: latin1 → utf8..."
|
|
iconv -f latin1 -t utf8 "$DUMP_LATIN1" > "$DUMP_UTF8"
|
|
|
|
# Charset-Deklarationen im SQL ersetzen
|
|
sed -i \
|
|
-e 's/DEFAULT CHARSET=latin1/DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci/g' \
|
|
-e 's/COLLATE=latin1_swedish_ci//g' \
|
|
-e 's/CHARACTER SET latin1/CHARACTER SET utf8mb4/g' \
|
|
-e 's/COLLATE latin1_swedish_ci/COLLATE utf8mb4_unicode_ci/g' \
|
|
"$DUMP_UTF8"
|
|
|
|
echo " Konvertiert: $DUMP_UTF8"
|
|
echo ""
|
|
|
|
# ── Zeilenzähler vor Migration ───────────────────────────────────────────────
|
|
echo ">>> Zeilenzähler vor Migration:"
|
|
for TABLE in beos objekte logbuch logbuch_beos logbuch_objekte; do
|
|
COUNT=$(docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -sN \
|
|
-e "SELECT COUNT(*) FROM $TABLE;" "$DB" 2>/dev/null || echo "n/a")
|
|
printf " %-25s %5s Zeilen\n" "$TABLE" "$COUNT"
|
|
done
|
|
echo ""
|
|
|
|
# ── Zieldatenbank anlegen ────────────────────────────────────────────────────
|
|
echo ">>> Lege Zieldatenbank an (utf8mb4)..."
|
|
docker exec -i "$CONTAINER" mysql -u root -p"$ROOT_PASS" <<EOF
|
|
DROP DATABASE IF EXISTS ${DB}_new;
|
|
CREATE DATABASE ${DB}_new CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
|
EOF
|
|
|
|
# ── utf8mb4-Dump importieren ─────────────────────────────────────────────────
|
|
echo ">>> Importiere utf8mb4-Daten..."
|
|
docker exec -i "$CONTAINER" mysql \
|
|
-u root -p"$ROOT_PASS" \
|
|
--default-character-set=utf8mb4 \
|
|
"${DB}_new" < "$DUMP_UTF8"
|
|
|
|
# ── Zeilenzähler nach Migration ──────────────────────────────────────────────
|
|
echo ""
|
|
echo ">>> Zeilenzähler nach Migration:"
|
|
ALL_OK=true
|
|
for TABLE in beos objekte logbuch logbuch_beos logbuch_objekte; do
|
|
BEFORE=$(docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -sN \
|
|
-e "SELECT COUNT(*) FROM $TABLE;" "${DB}" 2>/dev/null || echo "?")
|
|
AFTER=$(docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -sN \
|
|
-e "SELECT COUNT(*) FROM $TABLE;" "${DB}_new" 2>/dev/null || echo "?")
|
|
STATUS="✓"
|
|
[ "$BEFORE" != "$AFTER" ] && STATUS="✗ ABWEICHUNG" && ALL_OK=false
|
|
printf " %-25s %5s → %5s %s\n" "$TABLE" "$BEFORE" "$AFTER" "$STATUS"
|
|
done
|
|
echo ""
|
|
|
|
if [ "$ALL_OK" = false ]; then
|
|
echo "FEHLER: Zeilenzähler stimmen nicht überein!" >&2
|
|
echo "Datenbank '${DB}_new' bleibt zur manuellen Prüfung erhalten." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── Swap: sternwarte → sternwarte_old, sternwarte_new → sternwarte ───────────
|
|
echo ">>> Alle Zeilenzähler stimmen — tausche Datenbanken..."
|
|
|
|
TABLES=$(docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -sN \
|
|
-e "SHOW TABLES;" "${DB}_new")
|
|
|
|
# Alte DB umbenennen (Tabellen nach sternwarte_old verschieben)
|
|
docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -e \
|
|
"CREATE DATABASE IF NOT EXISTS ${DB}_old CHARACTER SET latin1;"
|
|
for TABLE in $TABLES; do
|
|
docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -e \
|
|
"RENAME TABLE \`${DB}\`.\`$TABLE\` TO \`${DB}_old\`.\`$TABLE\`;"
|
|
done
|
|
|
|
# Neue DB nach sternwarte verschieben
|
|
docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -e \
|
|
"ALTER DATABASE ${DB} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
|
|
for TABLE in $TABLES; do
|
|
docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -e \
|
|
"RENAME TABLE \`${DB}_new\`.\`$TABLE\` TO \`${DB}\`.\`$TABLE\`;"
|
|
done
|
|
|
|
docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -e \
|
|
"DROP DATABASE ${DB}_new; DROP DATABASE ${DB}_old;"
|
|
|
|
# ── Kollation bestätigen ─────────────────────────────────────────────────────
|
|
echo ""
|
|
echo ">>> Kollation der Tabellen:"
|
|
docker exec "$CONTAINER" mysql -u root -p"$ROOT_PASS" -e \
|
|
"SELECT TABLE_NAME, TABLE_COLLATION FROM information_schema.TABLES
|
|
WHERE TABLE_SCHEMA = '$DB' ORDER BY TABLE_NAME;" 2>/dev/null
|
|
|
|
echo ""
|
|
echo "══════════════════════════════════════════════════════"
|
|
echo " Migration erfolgreich abgeschlossen!"
|
|
echo " Backup: $BACKUP"
|
|
echo " App neu starten: docker compose up -d logbuch_app"
|
|
echo "══════════════════════════════════════════════════════"
|