MySQL¶
Inhalt¶
- MySQL 8.0 über
databases/mysql80-server - aktueller Portstand:
8.0.44auf2026Q1,8.0.45auflatest - InnoDB als primäre Engine
- Basishärtung mit
mysql_secure_installation - Zugangsdaten mit
mysql_config_editor - logische Backups mit
mysqldump - optionale GTID-/Binlog-Basis für spätere Replikation
Einleitung¶
Dieses HowTo beschreibt die Installation und Konfiguration von MySQL auf FreeBSD 15+.
Dieses HowTo verwendet bewusst databases/mysql80-server für bestehende 8.0-Bestandsumgebungen. Stand heute liegt der Port im FreeBSD-Quarterly-Zweig 2026Q1 bei 8.0.44 und im latest-Zweig bei 8.0.45. Gleichzeitig ist wichtig: MySQL 8.0 erreicht im April 2026 EoL. Für neue Installationen solltest du deshalb prüfen, ob MySQL 8.4 LTS die bessere Wahl ist. (freshports.org)
Dieses HowTo konzentriert sich auf InnoDB als primäre Engine. GTID ist hier bewusst nicht standardmäßig aktiv, sondern wird weiter unten als optionale Produktionsfunktion getrennt behandelt. Das ist Absicht, weil GTID in MySQL explizit konfiguriert werden muss und nicht zur Standardinstallation gehört. (dev.mysql.com)
Voraussetzungen¶
Zu den Voraussetzungen für dieses HowTo siehe bitte: Hosting System
Vorbereitungen¶
DNS Records¶
Für dieses HowTo sind keine zusätzlichen DNS-Records erforderlich.
Gruppen / Benutzer / Passwörter¶
Für dieses HowTo müssen keine zusätzlichen Systemgruppen oder Systembenutzer manuell angelegt werden.
Der Dienst verwendet den Systembenutzer mysql. (GitHub)
Verzeichnisse / Dateien¶
Für dieses HowTo müssen vor der Installation keine zusätzlichen Verzeichnisse oder Dateien manuell angelegt werden.
Der Port bringt bereits die Beispieldatei my.cnf.sample unter /usr/local/etc/mysql/ sowie das FreeBSD-Service-Skript mysql-server mit. (freshports.org)
Installation¶
Wir installieren databases/mysql80-server und dessen Abhängigkeiten.¶
mkdir -p /var/db/ports/comms_hidapi
cat <<'EOF' > /var/db/ports/comms_hidapi/options
_OPTIONS_READ=hidapi-0.15.0
_FILE_COMPLETE_OPTIONS_LIST=DOCS
OPTIONS_FILE_UNSET+=DOCS
EOF
mkdir -p /var/db/ports/security_libfido2
cat <<'EOF' > /var/db/ports/security_libfido2/options
_OPTIONS_READ=libfido2-1.16.0
_FILE_COMPLETE_OPTIONS_LIST=DOCS
OPTIONS_FILE_UNSET+=DOCS
EOF
mkdir -p /var/db/ports/textproc_groff
cat <<'EOF' > /var/db/ports/textproc_groff/options
_OPTIONS_READ=groff-1.24.1
_FILE_COMPLETE_OPTIONS_LIST=DOCS EXAMPLES UCHARDET
OPTIONS_FILE_UNSET+=DOCS
OPTIONS_FILE_UNSET+=EXAMPLES
OPTIONS_FILE_SET+=UCHARDET
EOF
mkdir -p /var/db/ports/print_gsfonts
cat <<'EOF' > /var/db/ports/print_gsfonts/options
_OPTIONS_READ=gsfonts-8.11
_FILE_COMPLETE_OPTIONS_LIST=DOCS
OPTIONS_FILE_UNSET+=DOCS
EOF
mkdir -p /var/db/ports/databases_mysql80-client
cat <<'EOF' > /var/db/ports/databases_mysql80-client/options
_OPTIONS_READ=mysql80-client-8.0.45
_FILE_COMPLETE_OPTIONS_LIST= SASLCLIENT
OPTIONS_FILE_UNSET+=SASLCLIENT
EOF
mkdir -p /var/db/ports/databases_mysql80-server
cat <<'EOF' > /var/db/ports/databases_mysql80-server/options
_OPTIONS_READ=mysql80-server-8.0.45
_FILE_COMPLETE_OPTIONS_LIST= ARCHIVE BLACKHOLE EXAMPLE FEDERATED INNOBASE PARTITION PERFSCHEMA PERFSCHM
OPTIONS_FILE_UNSET+=ARCHIVE
OPTIONS_FILE_UNSET+=BLACKHOLE
OPTIONS_FILE_UNSET+=EXAMPLE
OPTIONS_FILE_UNSET+=FEDERATED
OPTIONS_FILE_UNSET+=INNOBASE
OPTIONS_FILE_UNSET+=PARTITION
OPTIONS_FILE_UNSET+=PERFSCHEMA
OPTIONS_FILE_SET+=PERFSCHM
EOF
portmaster -w -B -g -U --force-config databases/mysql80-server -n
Dienst in rc.conf eintragen¶
Der Dienst wird mittels sysrc in der rc.conf eingetragen und dadurch beim Systemstart automatisch gestartet.
Das FreeBSD-rc-Skript unterstützt hier unter anderem mysql_enable, mysql_dbdir und mysql_optfile. Es initialisiert ein noch leeres Datenverzeichnis beim ersten Start außerdem automatisch mit mysqld --initialize-insecure. (GitHub)
Konfiguration¶
Verzeichnisse anlegen¶
Für Passwortdateien und Backups legen wir die benötigten Verzeichnisse jetzt an.
Konfigurationsdatei¶
MySQL sollte dauerhaft über eine Option-Datei konfiguriert werden. Das rc-Skript verwendet standardmäßig /usr/local/etc/mysql/my.cnf, wenn dort eine Datei vorhanden ist; alternativ sucht es im Datenverzeichnis. Der Port liefert dafür bereits my.cnf.sample mit. (GitHub)
cat <<'EOF' > /usr/local/etc/mysql/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock
[mysqld]
user = mysql
port = 3306
socket = /tmp/mysql.sock
bind_address = 127.0.0.1,::1
basedir = /usr/local
datadir = /var/db/mysql
tmpdir = /var/db/mysql_tmpdir
replica-load-tmpdir = /var/db/mysql_tmpdir
secure_file_priv = /var/db/mysql_secure
default_password_lifetime = 0
explicit-defaults-for-timestamp = 1
log_bin = mysql-bin
server_id = 1
sync_binlog = 1
binlog_cache_size = 256K
binlog_expire_logs_seconds = 604800
binlog_stmt_cache_size = 256K
log_output = FILE
slow_query_log = OFF
slow_query_log_file = slow-query.log
long_query_time = 0.05
# log_queries_not_using_indexes = ON
max_connections = 101
net_retry_count = 16384
open_files_limit = 32768
table_open_cache = 8192
table_definition_cache = 4096
key_buffer_size = 256M
join_buffer_size = 512K
sort_buffer_size = 2M
read_buffer_size = 256K
read_rnd_buffer_size = 512K
max_heap_table_size = 256M
tmp_table_size = 256M
innodb_thread_concurrency = 8
innodb_buffer_pool_size = 2G
innodb_buffer_pool_instances = 2
innodb_data_home_dir = /var/db/mysql
innodb_log_group_home_dir = /var/db/mysql
innodb_data_file_path = ibdata1:1G;ibdata2:1G;ibdata3:128M:autoextend
innodb_temp_data_file_path = ibtmp1:128M:autoextend
innodb_flush_method = O_DIRECT
innodb_redo_log_capacity = 512M
innodb_sort_buffer_size = 2M
# innodb_force_recovery = 1
lower_case_table_names = 1
# myisam_recover_options = FORCE,BACKUP
# relay_log_recovery = ON
# sync_relay_log = 1
# enforce_gtid_consistency = ON
# gtid_mode = ON
mysqlx = OFF
mysqlx_port = 33060
mysqlx_socket = /tmp/mysqlx.sock
mysqlx_bind_address = 127.0.0.1,::1
EOF
Falls deine my.cnf selbst eine datadir-Direktive enthält, muss sie zur rc.conf-Einstellung mysql_dbdir="/var/db/mysql" passen. Das rc-Skript übergibt den Datenpfad explizit an mysqld_safe. (GitHub)
Server zum ersten Mal starten¶
Wenn das Datenverzeichnis noch nicht initialisiert ist, erzeugt das FreeBSD-rc-Skript es beim ersten Start mit --initialize-insecure. Danach existiert der initiale root-Account ohne Passwort, bis du es selbst setzt. Genau dafür ist der erste Start hier absichtlich getrennt vom nächsten Schritt. (GitHub)
Erster Funktionstest:
Root-Passwort sauber setzen¶
Nach einer Initialisierung mit --initialize-insecure setzt du das Root-Passwort sauber mit ALTER USER. Für MySQL 8.0 ist caching_sha2_password der moderne Standard-Mechanismus; Legacy-Authentifizierung mit mysql_native_password solltest du nur noch für nachweislich alte Clients überhaupt in Betracht ziehen. In MySQL 8.4 ist mysql_native_password bereits nicht mehr standardmäßig aktiviert. (dev.mysql.com)
# Passwort für den MySQL-Superuser "root" erzeugen und
# in /var/db/passwords/mysql_superuser_root speichern
install -b -m 0600 -o mysql -g mysql /dev/null /var/db/passwords/mysql_superuser_root
openssl rand -hex 64 | openssl passwd -5 -stdin | tr -cd '[[:print:]]' | \
cut -c 2-17 | tee /var/db/passwords/mysql_superuser_root | xargs -I % \
mysql --protocol=socket --user=root --skip-password -e "ALTER USER 'root'@'localhost' IDENTIFIED BY \"%\";"
cat /var/db/passwords/mysql_superuser_root
Zusätzliche Basishärtung¶
mysql_secure_installation ist im Port enthalten und hilft bei den üblichen Basishärtungen. Für dieses Setup ist sinnvoll:
- optional
validate_passwordaktivieren - anonyme Benutzer entfernen
- Remote-Login für
rootverbieten - Test-Datenbank entfernen
- Privilegien neu laden
Das Root-Passwort ist in diesem HowTo bereits gesetzt. In mysql_secure_installation überspringst du die Passwortänderung deshalb an dieser Stelle und nutzt das Tool nur noch für die restlichen Härtungsschritte. (freshports.org)
Zugangsdaten mit mysql_config_editor speichern¶
Ein Login-Path in .mylogin.cnf kann nur einen Satz aus host, user, password, port und socket speichern. Genau diese Felder schreibt mysql_config_editor. Auf Unix verwendet localhost ohne explizites TCP-Protokoll standardmäßig den Unix-Socket. Für lokale Root-Administration reicht deshalb zuerst ein einzelner Socket-Login-Path. (dev.mysql.com)
mysql_config_editor set \
--login-path=root-local \
--socket=/tmp/mysql.sock \
--user=root \
--password
Falls dein my.cnf einen anderen Socket-Pfad setzt, musst du hier denselben Pfad verwenden. (dev.mysql.com)
Konfiguration prüfen¶
Eine klassische configtest-Funktion wie bei manchen anderen Diensten gibt es hier nicht. Für die Prüfung ist deshalb sinnvoll, sich zuerst die aus Option-Dateien gelesenen Werte anzeigen zu lassen und anschließend die Erreichbarkeit des laufenden Dienstes zu testen. my_print_defaults ist genau für das Auslesen solcher Optionen vorgesehen. (dev.mysql.com)
Optionale Produktionsfunktion: Binärlog und GTID¶
GTID ist in dieser Anleitung absichtlich nicht standardmäßig aktiv. Für GTID-basierte Replikation muss die Konfiguration bewusst vorbereitet werden. Oracle dokumentiert dafür insbesondere: Binary Logging muss aktiv sein, enforce_gtid_consistency muss gesetzt werden und gtid_mode=ON ist nicht der Default. Das hier ist nur die Grundrichtung, keine vollständige Replikationsanleitung. (dev.mysql.com)
[mysqld]
# log_bin = mysql-bin
# server_id = 1
# binlog_expire_logs_seconds = 604800
# enforce_gtid_consistency = ON
# gtid_mode = ON
Datenbanken¶
MySQL-Benutzer admin anlegen¶
MySQL-Konten sind immer an Benutzer + Host gebunden. Für dieses HowTo legen wir deshalb drei lokale Administrationskonten an: für Socket, IPv4 und IPv6. Das passt sauber zu den späteren Login-Paths. (dev.mysql.com)
# Passwort für den MySQL-Benutzer "admin" erzeugen und
# in /var/db/passwords/mysql_user_admin speichern
install -b -m 0600 -o mysql -g mysql /dev/null /var/db/passwords/mysql_user_admin
openssl rand -hex 64 | openssl passwd -5 -stdin | tr -cd '[[:print:]]' | \
cut -c 2-17 | tee /var/db/passwords/mysql_user_admin | xargs -I % \
mysql --login-path=root-local -e "\
DROP USER IF EXISTS 'admin'@'localhost'; \
DROP USER IF EXISTS 'admin'@'127.0.0.1'; \
DROP USER IF EXISTS 'admin'@'::1'; \
CREATE USER 'admin'@'localhost' IDENTIFIED BY '%'; \
CREATE USER 'admin'@'127.0.0.1' IDENTIFIED BY '%'; \
CREATE USER 'admin'@'::1' IDENTIFIED BY '%'; \
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION; \
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'127.0.0.1' WITH GRANT OPTION; \
GRANT ALL PRIVILEGES ON *.* TO 'admin'@'::1' WITH GRANT OPTION; \
FLUSH PRIVILEGES;"
cat /var/db/passwords/mysql_user_admin
Passende Login-Paths:
mysql_config_editor set \
--login-path=admin-local \
--socket=/tmp/mysql.sock \
--user=admin \
--password
mysql_config_editor set \
--login-path=admin-tcp4 \
--host=127.0.0.1 \
--port=3306 \
--user=admin \
--password
mysql_config_editor set \
--login-path=admin-tcp6 \
--host=::1 \
--port=3306 \
--user=admin \
--password
MySQL-Datenbank test_db für admin anlegen¶
MySQL 8.0 verwendet utf8mb4 als Standardzeichensatzlinie. Für neue Datenbanken ist das die richtige Basis. Dieses Beispiel bleibt bewusst bei InnoDB. (dev.mysql.com)
cat <<'EOF' > /tmp/test_db.sql
DROP DATABASE IF EXISTS test_db;
CREATE DATABASE test_db CHARACTER SET utf8mb4;
GRANT ALL PRIVILEGES ON test_db.* TO 'admin'@'localhost';
GRANT ALL PRIVILEGES ON test_db.* TO 'admin'@'127.0.0.1';
GRANT ALL PRIVILEGES ON test_db.* TO 'admin'@'::1';
FLUSH PRIVILEGES;
USE test_db;
CREATE TABLE kunden (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
UNIQUE KEY uq_kunden_email (email)
) ENGINE=InnoDB;
EOF
mysql --login-path=admin-local < /tmp/test_db.sql
Einfacher Funktionstest:
mysql --login-path=admin-local -e "SHOW DATABASES;"
mysql --login-path=admin-local -e "USE test_db; SHOW TABLES;"
mysql --login-path=admin-tcp4 -e "SELECT CURRENT_USER(), @@hostname;"
Einzelne Datenbank sichern¶
Für InnoDB ist mysqldump --single-transaction die richtige logische Backup-Basis, weil dabei ein konsistenter Snapshot für transaktionale Tabellen erzeugt wird, ohne normale Lese-/Schreibvorgänge unnötig hart zu blockieren. mysqlpump solltest du für neue Setups nicht mehr einplanen; es ist seit 8.0.34 deprecated. (dev.mysql.com)
mysqldump \
--login-path=admin-local \
--single-transaction \
--routines \
--events \
--triggers \
test_db > /var/db/backups/mysql/test_db-$(date +%F).sql
Wiederherstellung:
mysql --login-path=admin-local -e "CREATE DATABASE test_db_restore CHARACTER SET utf8mb4;"
mysql --login-path=admin-local test_db_restore < /var/db/backups/mysql/test_db-2026-03-21.sql
Einzelne Tabelle sichern¶
mysqldump \
--login-path=admin-local \
--single-transaction \
test_db kunden > /var/db/backups/mysql/test_db-kunden-$(date +%F).sql
Wiederherstellung:
mysql --login-path=admin-local test_db_restore < /var/db/backups/mysql/test_db-kunden-2026-03-21.sql
Alle Datenbanken logisch sichern¶
mysqldump \
--login-path=admin-local \
--single-transaction \
--routines \
--events \
--triggers \
--all-databases > /var/db/backups/mysql/all-databases-$(date +%F).sql
Wiederherstellung:
Zusatzsoftware¶
Mögliche Zusatzsoftware wird hier installiert und konfiguriert.
Für dieses HowTo ist keine zusätzliche Software erforderlich.
Aufräumen¶
Überflüssige oder temporäre Verzeichnisse und Dateien entsorgen.
Zusatzsoftware Installation¶
Nicht erforderlich.
Zusatzsoftware Konfiguration¶
Nicht erforderlich.
Temporäre Testdatei entfernen:
Abschluss¶
Abschließend den Dienst einmal sauber neu starten und die Erreichbarkeit prüfen:
Für spätere Änderungen:
Für Updates gilt: erst Backup, dann Update. Seit MySQL 8.0.16 übernimmt der Server die Upgrade-Arbeiten, die früher mysql_upgrade erledigt hat; das Tool ist deshalb deprecated und in 8.4 bereits entfernt. Bei Major-Upgrades, insbesondere 8.0 → 8.4, solltest du dem dokumentierten Upgrade-Pfad folgen und nicht blind nur den Port austauschen. (freshports.org)
Referenzen¶
- FreeBSD Handbook: Ports und Diensteverwaltung
- FreshPorts:
databases/mysql80-server - MySQL Reference Manual: Initializing the Data Directory
- MySQL Reference Manual: Securing the Initial MySQL Account
- MySQL Reference Manual:
mysql_secure_installation - MySQL Reference Manual:
mysql_config_editor - MySQL Reference Manual: Connection Transport Protocols
- MySQL Reference Manual:
mysqldump - MySQL Reference Manual: GTID / Replication
- MySQL Product Support EOL Announcements