datenbanken:galera
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| datenbanken:galera [2023-12-14 09:32:36] – [Aus einem Galera-Cluster sterben spontan einzelne Knoten] manfred | datenbanken:galera [2025-05-19 11:46:15] (aktuell) – [MySQL 8.0] manfred | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| + | ====== Galera ====== | ||
| + | |||
| + | |||
| + | ===== mehrere PXC-Instanzen auf dem selben Rechner betreiben ===== | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | Wenn man auf einem Rechner mehr als eine PXC-Instanz betreiben möchte, ist zu beachten, dass es dann zunehmend den Fall geben kann, | ||
| + | dass eine Instanzen nicht starten kann, weil einer der Ports, die sie öffne muß, bereits belegt ist. | ||
| + | Um das zu verhindern, kann man dem Kernel sagen ('' | ||
| + | |||
| + | <file c / | ||
| + | ### damit Galera alle Ports unterhalb von 40000 frei nutzen kann | ||
| + | ### https:// | ||
| + | # | ||
| + | net.ipv4.ip_local_port_range = 40000 60999 | ||
| + | </ | ||
| + | |||
| + | |||
| + | ==== MySQL 8.0 ==== | ||
| + | |||
| + | Zuerst wird ein globaler ZFS-Pool angelegt, indem dann jede einzelne MySQL-Instanz sein eigenes ZFS-Dataset (Volumen) bekommt. | ||
| + | |||
| + | <code bash ZFS-RAID-10> | ||
| + | > zpool create -m / | ||
| + | > chown -R mysql:mysql / | ||
| + | |||
| + | > zfs get mountpoint, | ||
| + | NAME | ||
| + | mysql_datadir | ||
| + | mysql_datadir | ||
| + | mysql_datadir | ||
| + | </ | ||
| + | |||
| + | <code bash / | ||
| + | [mysqld] | ||
| + | # https:// | ||
| + | # 4. Configure InnoDB for Max Flushing. | ||
| + | # SET GLOBAL innodb_fast_shutdown=0; | ||
| + | innodb_fast_shutdown = 0 | ||
| + | innodb_max_dirty_pages_pct = 0 | ||
| + | innodb_max_dirty_pages_pct_lwm = 0 | ||
| + | innodb_change_buffering = ' | ||
| + | </ | ||
| + | |||
| + | <code bash / | ||
| + | [mysqld] | ||
| + | # | ||
| + | # * SSL | ||
| + | # | ||
| + | # ssl-mode = DISABLED PREFERRED REQUIRED VERIFY_CA VERIFY_IDENTITY | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | #ssl = ON # Deprecated, use --ssl-mode. | ||
| + | ssl-ca = / | ||
| + | ssl-cert = / | ||
| + | ssl-key | ||
| + | # | ||
| + | ### TLS-Version | ||
| + | tls-version = TLSv1.3, | ||
| + | # | ||
| + | ### nur noch verschlüsselte Verbindungen möglich | ||
| + | require_secure_transport = ON | ||
| + | |||
| + | [sst] | ||
| + | # https:// | ||
| + | compressor | ||
| + | decompressor | ||
| + | rebuild | ||
| + | compact | ||
| + | encrypt = 4 | ||
| + | ssl-ca = / | ||
| + | ssl-cert = / | ||
| + | ssl-key | ||
| + | </ | ||
| + | |||
| + | <code bash / | ||
| + | # | ||
| + | |||
| + | VERSION=" | ||
| + | |||
| + | # | ||
| + | ### die unterschiedlichen MySQL-DBMS-Instanz werden auch etwas unterschiedlich konfiguriert | ||
| + | ### hier muß man vorsichtig sein, weil der RAM auch mal ein voll ist... | ||
| + | |||
| + | RICHTIGE_PORT_NUMMER_01=" | ||
| + | RICHTIGE_PORT_NUMMER_02=" | ||
| + | RICHTIGE_PORT_NUMMER_03=" | ||
| + | RICHTIGE_PORT_NUMMER_04=" | ||
| + | RICHTIGE_PORT_NUMMER_05=" | ||
| + | if [ Ja = " | ||
| + | echo " | ||
| + | echo " | ||
| + | elif [ Ja = " | ||
| + | echo " | ||
| + | echo " | ||
| + | elif [ Ja = " | ||
| + | echo " | ||
| + | echo " | ||
| + | elif [ Ja = " | ||
| + | echo " | ||
| + | echo " | ||
| + | elif [ Ja = " | ||
| + | echo " | ||
| + | echo " | ||
| + | else | ||
| + | echo " | ||
| + | echo " | ||
| + | fi >> / | ||
| + | # | ||
| + | </ | ||
| + | |||
| + | <code bash / | ||
| + | #!/bin/bash | ||
| + | |||
| + | # | ||
| + | # | ||
| + | # Mir diesem Skript kann man, mit einem einzigen Kommando, | ||
| + | # eine voll funktionstüchtige MySQL-DBMS-Instanz erstellen. | ||
| + | # | ||
| + | # | ||
| + | |||
| + | # | ||
| + | # | ||
| + | VERSION=" | ||
| + | |||
| + | # | ||
| + | #### Sicherheitsüberprüfungen | ||
| + | |||
| + | # Prüfen, ob die übergebene Option leer ist. | ||
| + | if [ x = " | ||
| + | echo 'Es muß eine Portnummer für die neue MySQL-DBMS-Instanz übergeben werden!' | ||
| + | echo " | ||
| + | echo "zum Beispiel:" | ||
| + | echo " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | # Prüfen, ob die übergebene Option eine Integer-Zahl, | ||
| + | I_FUENF=" | ||
| + | if [ x = " | ||
| + | echo 'Bitte übergeben sie diesem Skript die gewünschte Portnummer.' | ||
| + | echo 'Die übergebene Option muß eine Integer-Zahl, | ||
| + | echo ' | ||
| + | exit 1 | ||
| + | else | ||
| + | PORTNUMMER=" | ||
| + | fi | ||
| + | |||
| + | if [ -e "/ | ||
| + | echo 'Das gesuchte Verzeichnis existiert schon!' | ||
| + | ls -d "/ | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | # | ||
| + | ### Aktion: SystemD-Dateien erstellen | ||
| + | |||
| + | DATEI_01="/ | ||
| + | if [ -e " | ||
| + | echo " | ||
| + | else | ||
| + | echo " | ||
| + | echo " | ||
| + | fi | ||
| + | ls -lha ${DATEI_01} | ||
| + | |||
| + | DATEI_02="/ | ||
| + | if [ -e " | ||
| + | echo " | ||
| + | else | ||
| + | echo " | ||
| + | echo " | ||
| + | fi | ||
| + | ls -lha ${DATEI_02} | ||
| + | |||
| + | ### diese Datei ist nicht speziell für eine Portnummer | ||
| + | ### und gehört deshalb zur Allgemeinen/ | ||
| + | DATEI_03="/ | ||
| + | if [ -x " | ||
| + | echo " | ||
| + | else | ||
| + | cat / | ||
| + | chmod 0755 ${DATEI_03} | ||
| + | fi | ||
| + | ls -lha ${DATEI_03} | ||
| + | |||
| + | ### diese Datei ist nicht speziell für eine Portnummer | ||
| + | ### und gehört deshalb zur Allgemeinen/ | ||
| + | DATEI_04="/ | ||
| + | if [ -x " | ||
| + | echo " | ||
| + | else | ||
| + | cat / | ||
| + | fi | ||
| + | ls -lha ${DATEI_04} | ||
| + | |||
| + | # | ||
| + | ### Aktion: ZFS-Volumen mit Verzeichnissen erstellen | ||
| + | # | ||
| + | # Es wird empfohlen, für DataDir und Log-Bin unterschiedliche ZFS-Volumen (DataSets) | ||
| + | # zu verwenden und das ZFS-Volumen für DataDir mit " | ||
| + | # | ||
| + | |||
| + | zfs create -o mountpoint=/ | ||
| + | chown -R mysql:mysql / | ||
| + | |||
| + | # https:// | ||
| + | # https:// | ||
| + | zfs set compression=lz4 mysql_datadir/ | ||
| + | zfs set recordsize=16K mysql_datadir/ | ||
| + | zfs set logbias=throughput mysql_datadir/ | ||
| + | |||
| + | mkdir -p / | ||
| + | mkdir -p / | ||
| + | mkdir -p / | ||
| + | mkdir -p / | ||
| + | mkdir -p / | ||
| + | mkdir -p / | ||
| + | mkdir -p / | ||
| + | |||
| + | # Insecure configuration for --secure-log-path: | ||
| + | chmod 0750 / | ||
| + | chmod 0777 / | ||
| + | |||
| + | chown -R mysql:mysql / | ||
| + | |||
| + | # | ||
| + | ### Aktion: MySQL-CNF-Dateien erstellen | ||
| + | |||
| + | mkdir -p / | ||
| + | chown mysql:mysql / | ||
| + | |||
| + | # | ||
| + | # my.cnf | ||
| + | echo "# / | ||
| + | !includedir / | ||
| + | !includedir / | ||
| + | " > / | ||
| + | |||
| + | # | ||
| + | # client.cnf | ||
| + | echo "# / | ||
| + | [client] | ||
| + | port = ${PORTNUMMER} | ||
| + | socket | ||
| + | " > / | ||
| + | |||
| + | # | ||
| + | # mysqld.cnf | ||
| + | SERVER_ID=" | ||
| + | REPORTNUMMER=" | ||
| + | REPORTKENNUNG=" | ||
| + | MYSQLX_PORT=" | ||
| + | ADMIN_PORT=" | ||
| + | echo "# / | ||
| + | # | ||
| + | [mysqld] | ||
| + | server_id | ||
| + | report_host | ||
| + | port = ${PORTNUMMER} | ||
| + | mysqlx_port | ||
| + | admin_port | ||
| + | datadir | ||
| + | socket | ||
| + | mysqlx_socket | ||
| + | secure_log_path | ||
| + | log-error | ||
| + | general_log_file | ||
| + | slow_query_log_file | ||
| + | |||
| + | tmpdir | ||
| + | # Binary log expiration period is 604800 seconds, which equals 7 days | ||
| + | binlog_expire_logs_seconds | ||
| + | log_bin | ||
| + | log_bin_index | ||
| + | relay_log | ||
| + | relay_log_index | ||
| + | # The syntax ' | ||
| + | relay_log_info_file | ||
| + | |||
| + | # | ||
| + | # | ||
| + | # innodb_autoinc_lock_mode changes how InnoDB autoincrement locks are managed and is a requirement for Galera | ||
| + | innodb_autoinc_lock_mode | ||
| + | innodb_file_per_table | ||
| + | innodb_flush_log_at_trx_commit | ||
| + | innodb_thread_concurrency | ||
| + | # | ||
| + | # siehe: mysqltuner.pl | ||
| + | # | ||
| + | innodb_log_buffer_size | ||
| + | innodb_redo_log_capacity | ||
| + | innodb_buffer_pool_instances | ||
| + | innodb_buffer_pool_size | ||
| + | binlog_cache_size | ||
| + | # | ||
| + | # siehe: SHOW STATUS LIKE ' | ||
| + | #" > / | ||
| + | |||
| + | . / | ||
| + | |||
| + | # | ||
| + | # mysqld_safe.cnf | ||
| + | echo "# / | ||
| + | # One can use all long options that the program supports. | ||
| + | # Run program with --help to get a list of available options and with | ||
| + | # --print-defaults to see which it would actually understand and use. | ||
| + | # | ||
| + | # For explanations see | ||
| + | # http:// | ||
| + | |||
| + | [mysqld_safe] | ||
| + | pid-file | ||
| + | socket | ||
| + | nice = 0 | ||
| + | " > / | ||
| + | |||
| + | # | ||
| + | # wsrep.cnf | ||
| + | NODE_ADDRESS=" | ||
| + | SST_PORT=" | ||
| + | INTERCOM_PORT=" | ||
| + | echo "# / | ||
| + | [mysqld] | ||
| + | # Path to Galera library | ||
| + | wsrep_provider = / | ||
| + | # | ||
| + | # | ||
| + | |||
| + | # Cluster connection URL contains IPs of nodes | ||
| + | #If no IP is found, this implies that a new cluster needs to be created, | ||
| + | #in order to do that you need to bootstrap this node | ||
| + | ### Standard für InterCom: 4567 -> 33XX7 | ||
| + | wsrep_cluster_address = gcomm:// | ||
| + | # | ||
| + | |||
| + | # Slave thread to use | ||
| + | wsrep_applier_threads = 8 | ||
| + | |||
| + | wsrep_log_conflicts | ||
| + | |||
| + | # Node IP address | ||
| + | # | ||
| + | wsrep_node_address = ${NODE_ADDRESS} | ||
| + | # Cluster name | ||
| + | # | ||
| + | wsrep_cluster_name = pxc-cluster_${REPORTNUMMER} # | ||
| + | |||
| + | #If wsrep_node_name is not specified, | ||
| + | wsrep_node_name = pxc-${REPORTNUMMER}-${REPORTKENNUNG} | ||
| + | |||
| + | # | ||
| + | pxc_strict_mode = ENFORCING | ||
| + | |||
| + | # SST method | ||
| + | wsrep_sst_method = xtrabackup-v2 | ||
| + | |||
| + | # | ||
| + | ### Standard für SST: 4444 -> 33XX4 (das , am Zeilenende muss unbedingt bleiben) | ||
| + | wsrep_sst_donor | ||
| + | |||
| + | ### Standard für IST / replication: | ||
| + | ### Standard für GCache: 128 MB -> 4G | ||
| + | ### IST bezieht seine Daten aus dem GCache, vergleichbar mit der BIN-LOG-Historie bei GTID-Replikation | ||
| + | ### Je größer der GCache ist, desto länger dürfen Wartungsarbeiten sein. | ||
| + | wsrep_provider_options = \" | ||
| + | |||
| + | # | ||
| + | |||
| + | pxc-encrypt-cluster-traffic = OFF | ||
| + | " > / | ||
| + | |||
| + | # | ||
| + | # wsrep_knoten.cnf | ||
| + | echo "# / | ||
| + | [mysqld] | ||
| + | ### Standard für SST: 4444 -> 33XX4 | ||
| + | wsrep_sst_receive_address = ${NODE_ADDRESS}: | ||
| + | # | ||
| + | ### Standard: 4567 (InterCom) -> 33XX7 (Referenzadresse für viele andere Variablen) | ||
| + | wsrep_node_address = ${NODE_ADDRESS}: | ||
| + | " > / | ||
| + | |||
| + | # | ||
| + | ### Aktion: DataDir mit Daten füllen / DBMS initialisieren | ||
| + | |||
| + | # https:// | ||
| + | # Bei der Initialisierung des Datenverzeichnisses sollten Sie keine anderen Optionen als diese angeben: | ||
| + | # --basedir oder --datadir | ||
| + | # --user | ||
| + | # --initialize oder --initialize-insecure | ||
| + | # | ||
| + | # https:// | ||
| + | # | ||
| + | #mysqld --datadir=/ | ||
| + | #grep -F 'A temporary password is generated for root@localhost:' | ||
| + | # | ||
| + | #mysqld --datadir=/ | ||
| + | echo " | ||
| + | mysqld --no-defaults --datadir=/ | ||
| + | echo "rm -f / | ||
| + | rm -f / | ||
| + | |||
| + | # | ||
| + | ### Aktion: DataDir mit Daten füllen / DBMS initialisieren | ||
| + | |||
| + | # Erster Start nach der Initialisierung | ||
| + | # mit ' | ||
| + | echo " | ||
| + | (mysqld --defaults-file=/ | ||
| + | echo | ||
| + | # | ||
| + | # root ein Passwort geben | ||
| + | ls -lha / | ||
| + | PWT=" | ||
| + | if [ x = " | ||
| + | passwortabfrage() | ||
| + | { | ||
| + | echo | ||
| + | echo "Bitte geben Sie das root-Passwort für das neue DBMS ein:" | ||
| + | read PWT1 | ||
| + | echo | ||
| + | echo "Bitte das neue root-Passwort einmal wiederholen:" | ||
| + | read PWT2 | ||
| + | echo | ||
| + | } | ||
| + | passwort_abfrage() | ||
| + | { | ||
| + | passwortabfrage | ||
| + | if [ " | ||
| + | passwort_abfrage | ||
| + | fi | ||
| + | } | ||
| + | passwort_abfrage} | ||
| + | fi | ||
| + | sleep 2 | ||
| + | echo | ||
| + | echo "Kein Passwort eingeben, einfach nur ENTER drücken!" | ||
| + | echo "echo \" | ||
| + | echo "ALTER USER ' | ||
| + | # | ||
| + | # root auf machen | ||
| + | echo "echo \" | ||
| + | echo " | ||
| + | # | ||
| + | # Benutzer anzeigen | ||
| + | #echo " | ||
| + | echo "echo ' | ||
| + | echo ' | ||
| + | # | ||
| + | # einfacher Zugriff per root funktioniert jetzt | ||
| + | echo " | ||
| + | mysqlshow -S / | ||
| + | # | ||
| + | # | ||
| + | # MySQL-Dienst wieder beenden | ||
| + | |||
| + | # | ||
| + | MY_PID_02=" | ||
| + | if [ x != " | ||
| + | echo "kill -15 ${MY_PID_02}" | ||
| + | kill -15 ${MY_PID_02} | ||
| + | sleep 20 | ||
| + | fi | ||
| + | |||
| + | # | ||
| + | # DBMS regulär starten | ||
| + | |||
| + | # ab jetzt kann man diesen MySQL-Dienst auch per SystemD starten und stoppen | ||
| + | rm -f / | ||
| + | service mysql_port@${PORTNUMMER} restart | ||
| + | sleep 1 | ||
| + | |||
| + | # Probeaufruf | ||
| + | echo " | ||
| + | mysqlshow -S / | ||
| + | |||
| + | echo "################################################################################" | ||
| + | grep -F ERROR / | ||
| + | echo "################################################################################" | ||
| + | |||
| + | # | ||
| + | ### Zum guten Schluß gibt es noch ein paar Hinweise. | ||
| + | |||
| + | systemctl daemon-reload | ||
| + | JETZT=" | ||
| + | echo " | ||
| + | # So wird das BDMS behandelt: | ||
| + | |||
| + | > service mysql_port@${PORTNUMMER}.bootstrap start | ||
| + | > service mysql_port@${PORTNUMMER}.bootstrap status | ||
| + | > service mysql_port@${PORTNUMMER}.bootstrap stop | ||
| + | |||
| + | > service mysql_port@${PORTNUMMER} start | ||
| + | > service mysql_port@${PORTNUMMER} status | ||
| + | > service mysql_port@${PORTNUMMER} stop | ||
| + | |||
| + | > mysqlshow -S / | ||
| + | > echo ' | ||
| + | > echo \"SHOW VARIABLES LIKE ' | ||
| + | > echo \"SHOW VARIABLES WHERE variable_name IN (' | ||
| + | > mysqlshow --ssl-ca=/ | ||
| + | |||
| + | zum kompletten und unwiederbringlichen entfernen dieser MySQL-DBMS-Instanz, | ||
| + | ist nur dieses Kommando nötig: | ||
| + | / | ||
| + | " | ||
| + | |||
| + | # | ||
| + | # damit keiner etwas illegales unten anhängen kann | ||
| + | exit | ||
| + | </ | ||
| + | |||
| + | <code bash / | ||
| + | #!/bin/bash | ||
| + | |||
| + | # | ||
| + | # | ||
| + | # Mir diesem Skript kann man, mit einem einzigen Kommando, | ||
| + | # eine komplette MySQL-DBMS-Instanz restlos löschen. | ||
| + | # | ||
| + | # | ||
| + | # https:// | ||
| + | # | ||
| + | |||
| + | # | ||
| + | VERSION=" | ||
| + | |||
| + | # | ||
| + | #### Sicherheitsüberprüfungen | ||
| + | |||
| + | # Prüfen, ob die übergebene Option leer ist. | ||
| + | if [ x = " | ||
| + | echo 'Es muß eine Portnummer für die neue MySQL-DBMS-Instanz übergeben werden!' | ||
| + | echo " | ||
| + | echo "zum Beispiel:" | ||
| + | echo " | ||
| + | echo " | ||
| + | exit 1 | ||
| + | fi | ||
| + | |||
| + | # Prüfen, ob die übergebene Option eine Integer-Zahl, | ||
| + | I_FUENF=" | ||
| + | if [ x = " | ||
| + | echo 'Bitte übergeben sie diesem Skript die gewünschte Portnummer.' | ||
| + | echo 'Die übergebene Option muß eine Integer-Zahl, | ||
| + | echo ' | ||
| + | exit 1 | ||
| + | else | ||
| + | PORTNUMMER=" | ||
| + | fi | ||
| + | |||
| + | # | ||
| + | ### stoppen | ||
| + | |||
| + | STATUS=" | ||
| + | if [ x != " | ||
| + | echo " | ||
| + | service mysql_port@${PORTNUMMER} stop | ||
| + | sleep 2 | ||
| + | fi | ||
| + | STATUS=" | ||
| + | if [ x = " | ||
| + | echo " | ||
| + | service mysql_port@${PORTNUMMER} stop | ||
| + | sleep 2 | ||
| + | fi | ||
| + | if [ -e / | ||
| + | MY_PID_01=" | ||
| + | if [ x != " | ||
| + | echo "kill -9 ${MY_PID_01}" | ||
| + | kill -9 ${MY_PID_01} | ||
| + | sleep 2 | ||
| + | fi | ||
| + | fi | ||
| + | MY_PID_02=" | ||
| + | if [ x != " | ||
| + | echo "kill -9 ${MY_PID_02}" | ||
| + | kill -9 ${MY_PID_02} | ||
| + | sleep 2 | ||
| + | fi | ||
| + | |||
| + | # | ||
| + | ### löschen | ||
| + | |||
| + | # ZFS-Volumen zerstören | ||
| + | echo "zfs destroy -r mysql_datadir/ | ||
| + | zfs destroy -r mysql_datadir/ | ||
| + | |||
| + | # ZFS-Volumen-Mount-Point und zwei spezielle Dateien löschen | ||
| + | echo "rm -fr / | ||
| + | rm -fr / | ||
| + | |||
| + | # SystemD-Start-Stop-Datei-Reload | ||
| + | echo " | ||
| + | systemctl daemon-reload | ||
| + | </ | ||
| + | |||
| + | <code bash 1. / | ||
| + | root@host61: | ||
| + | -rw-r--r-- 1 root root 137 Apr 29 18:00 / | ||
| + | -rw-r--r-- 1 root root 157 Apr 29 18:00 / | ||
| + | / | ||
| + | -rwxr-xr-x 1 root root 12K Apr 28 12:52 / | ||
| + | -rw-r--r-- 1 root root 4.9K Apr 29 18:00 / | ||
| + | mysqld --no-defaults --datadir=/ | ||
| + | 2025-04-29T18: | ||
| + | 2025-04-29T18: | ||
| + | 2025-04-29T18: | ||
| + | 2025-04-29T18: | ||
| + | 2025-04-29T18: | ||
| + | 2025-04-29T18: | ||
| + | 2025-04-29T18: | ||
| + | 2025-04-29T18: | ||
| + | rm -f / | ||
| + | (mysqld --defaults-file=/ | ||
| + | |||
| + | -rw------- 1 root root 259 Apr 29 08:49 / | ||
| + | echo "ALTER USER ' | ||
| + | |||
| + | Kein Passwort eingeben, einfach nur ENTER drücken! | ||
| + | Enter password: | ||
| + | </ | ||
| + | |||
| + | **//Kein Passwort eingeben!!!// | ||
| + | **// | ||
| + | |||
| + | <code bash 2. / | ||
| + | ... | ||
| + | echo " | ||
| + | mysql: [Warning] Using a password on the command line interface can be insecure. | ||
| + | echo ' | ||
| + | mysql: [Warning] Using a password on the command line interface can be insecure. | ||
| + | +-----------+----------------------------+-----------------------+-----------------------+ | ||
| + | | host | user | plugin | ||
| + | +-----------+----------------------------+-----------------------+-----------------------+ | ||
| + | | % | root | caching_sha2_password | 2025-04-30 10: | ||
| + | | localhost | mysql.infoschema | ||
| + | | localhost | mysql.pxc.internal.session | caching_sha2_password | 2025-04-30 10: | ||
| + | | localhost | mysql.pxc.sst.role | ||
| + | | localhost | mysql.session | ||
| + | | localhost | mysql.sys | ||
| + | | localhost | percona.telemetry | ||
| + | +-----------+----------------------------+-----------------------+-----------------------+ | ||
| + | mysqlshow -S / | ||
| + | mysqlshow: [Warning] Using a password on the command line interface can be insecure. | ||
| + | +--------------------+ | ||
| + | | | ||
| + | +--------------------+ | ||
| + | | information_schema | | ||
| + | | mysql | | ||
| + | | performance_schema | | ||
| + | | sys | | ||
| + | +--------------------+ | ||
| + | kill -15 332245 | ||
| + | ################################################################################ | ||
| + | ################################################################################ | ||
| + | |||
| + | # So wird das BDMS behandelt: | ||
| + | |||
| + | > service mysql_port@13307.bootstrap start | ||
| + | > service mysql_port@13307.bootstrap status | ||
| + | > service mysql_port@13307.bootstrap stop | ||
| + | |||
| + | > service mysql_port@13307 start | ||
| + | > service mysql_port@13307 status | ||
| + | > service mysql_port@13307 stop | ||
| + | |||
| + | > mysqlshow -S / | ||
| + | > echo ' | ||
| + | > echo "SHOW VARIABLES LIKE ' | ||
| + | > echo "SHOW VARIABLES WHERE variable_name IN (' | ||
| + | > mysqlshow --ssl-ca=/ | ||
| + | |||
| + | zum kompletten und unwiederbringlichen entfernen dieser MySQL-DBMS-Instanz, | ||
| + | ist nur dieses Kommando nötig: | ||
| + | / | ||
| + | |||
| + | |||
| + | real 0m32.173s | ||
| + | user 0m4.630s | ||
| + | sys 0m1.172s | ||
| + | </ | ||
| + | |||
| + | <code bash / | ||
| + | root@host61: | ||
| + | service mysql_port@13307 stop | ||
| + | zfs destroy mysql_datadir/ | ||
| + | rm -fr / | ||
| + | systemctl daemon-reload | ||
| + | |||
| + | real 0m16.575s | ||
| + | user 0m0.029s | ||
| + | sys 0m0.085s | ||
| + | </ | ||
| + | |||
| + | |||
| + | === ZFS === | ||
| + | |||
| + | [[https:// | ||
| + | |||
| + | <file bash / | ||
| + | 0 1 * * * root / | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | #!/bin/bash | ||
| + | |||
| + | # | ||
| + | # Dieses Skript macht von allen ZFS-Volumen auf diesem Host einen SnapShot. | ||
| + | # | ||
| + | # Es kann maximal EINER pro Stunde angelegt werden, | ||
| + | # sollte für diesen Zeitraum bereits einer existieren, | ||
| + | # dann wird er vorher gelöscht. | ||
| + | # | ||
| + | # zfs snapshot mysql_datadir/ | ||
| + | # zfs list -t snapshot mysql_datadir/ | ||
| + | # zfs destroy mysql_datadir/ | ||
| + | # | ||
| + | # Bedeutung von " | ||
| + | # mysql_datadir - ZFS-Pool (Tank) | ||
| + | # port_13307 | ||
| + | # 4 - 4. Wochentag -> am Donnerstag aufgenommen | ||
| + | # 16 - zwischen 16:00 und 16:59 Uhr aufgenommen | ||
| + | # | ||
| + | |||
| + | SNAP_ZEIT=" | ||
| + | zfs list -Hp | awk '/ | ||
| + | do | ||
| + | echo "################################################################################" | ||
| + | echo " | ||
| + | zfs destroy ${SNAP}@${SNAP_ZEIT} | ||
| + | zfs snapshot ${SNAP}@${SNAP_ZEIT} | ||
| + | done | ||
| + | echo | ||
| + | |||
| + | # alle SnapShots anzeigen | ||
| + | zfs list -t snapshot | ||
| + | </ | ||
| + | |||
| + | * [[https:// | ||
| + | * Beispiele | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * all pools are healthy | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | * '' | ||
| + | |||
| + | |||
| + | ==== MySQL 5.7 ==== | ||
| + | |||
| + | |||
| + | === percona-xtradb-cluster-server-5.7 (5.7.31-31.45-3.focal) === | ||
| + | |||
| + | > echo "SHOW VARIABLES WHERE variable_name IN (' | ||
| + | +--------------------------+-------+ | ||
| + | | Variable_name | ||
| + | +--------------------------+-------+ | ||
| + | | auto_increment_increment | 3 | | ||
| + | | auto_increment_offset | ||
| + | | max_connections | ||
| + | | wsrep_slave_threads | ||
| + | +--------------------------+-------+ | ||
| + | |||
| + | > echo "SHOW STATUS WHERE variable_name IN (' | ||
| + | +----------------------------+----------------------------------------------------------+ | ||
| + | | Variable_name | ||
| + | +----------------------------+----------------------------------------------------------+ | ||
| + | | wsrep_last_committed | ||
| + | | wsrep_local_send_queue_avg | 0.000000 | ||
| + | | wsrep_local_recv_queue_avg | 0.000000 | ||
| + | | wsrep_flow_control_paused | ||
| + | | wsrep_cert_deps_distance | ||
| + | | wsrep_local_state_comment | ||
| + | | wsrep_incoming_addresses | ||
| + | | wsrep_cluster_size | ||
| + | | wsrep_cluster_status | ||
| + | | wsrep_connected | ||
| + | | wsrep_local_bf_aborts | ||
| + | +----------------------------+----------------------------------------------------------+ | ||
| + | |||
| + | [[https:// | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | - '' | ||
| + | |||
| + | |||
| + | === bekannte Probleme mit Percona XtraDB Cluster (PXC) === | ||
| + | |||
| + | |||
| + | == eine von mehreren PXC-Instanzen startet nicht == | ||
| + | |||
| + | Manchmal kommt es vor, dass sich einige Datenbank-Instanzen einfach nicht starten lassen. | ||
| + | Dieses Problem konnte jetzt analysiert und Gegenmaßnahmen erarbeitet werden. | ||
| + | |||
| + | __In diesem Beispiel will der dritte Knoten von dem Cluster DB23348 einfach nicht starten, auch nicht, wenn das DataDir geleert wurde.__ | ||
| + | |||
| + | Datenbank starten: | ||
| + | # / | ||
| + | # / | ||
| + | |||
| + | Log von einem Knoten, bei dem der SST funktioniert hat: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | InnoDB: Progress in percent: 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | |||
| + | Log von diesem Knoten, bei dem der SST abgebrochen ist: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | 2021-07-06T11: | ||
| + | |||
| + | nachsehen, welche Ports offen sind: | ||
| + | # netstat -antp | fgrep ESTABLISHED | fgrep 3348 | ||
| + | tcp 0 0 10.232.0.63: | ||
| + | |||
| + | nachsehen, welcher Prozess den Port offen hält: | ||
| + | # ps alxwww | fgrep 3169001 | ||
| + | 4 112 3169001 3160912 | ||
| + | |||
| + | Zur Überraschung, | ||
| + | Von der DB23320. | ||
| + | |||
| + | Um das Problem zu lösen, restarten wir die DB23320 einmal: | ||
| + | # / | ||
| + | Stopping mysql-iq_23320 (via systemctl): mysql-iq_23320.service. | ||
| + | |||
| + | prüfen, ob der Prozess wirklich beendet wurde: | ||
| + | # ps alxwww | fgrep -v grep | fgrep 3320 | ||
| + | |||
| + | neu starten: | ||
| + | # / | ||
| + | Starting mysql-iq_23320 (via systemctl): mysql-iq_23320.service. | ||
| + | |||
| + | der Port sollte jetzt wieder frei sein: | ||
| + | # netstat -antp | fgrep ESTABLISHED | fgrep 3348 | ||
| + | |||
| + | Und nun startet auch die DB23348: | ||
| + | # / | ||
| + | Starting mysql-iq_23348 (via systemctl): mysql-iq_23348.service. | ||
| + | |||
| + | Und nun ist alles gut! | ||
| + | |||
| + | |||
| + | == einzelne Galera-Cluster-Knoten lassen sich nicht mehr starten == | ||
| + | |||
| + | Wenn alles überprüft wurde und in Ordnung ist und doch diese Galera-Cluster-Knoten einfach nicht starten, dann kann es sein, dass Netzwerkports, | ||
| + | Das kann in seltenen Fällen ein im Hintergrund hängender MySQL-Prozess sein. | ||
| + | In unserem Fall hatte Ceph/RBD diese Ports in Nutzung. | ||
| + | |||
| + | Um dieses Problem zu beheben, muß man Ceph in seiner zu nutzenden Port-Range einschränken. | ||
| + | > sysctl net.ipv4.ip_local_port_range | ||
| + | > echo " | ||
| + | > sysctl -p | ||
| + | > sysctl net.ipv4.ip_local_port_range | ||
| + | |||
| + | |||
| + | == Aus einem Galera-Cluster sterben spontan einzelne Knoten == | ||
| + | |||
| + | __In einer Galera-Datenbank (synchroner DB-Cluster) muß immer mit expliziten Transaktionen gearbeitet werden!__ | ||
| + | |||
| + | Wenn in unregelmäßigen Abständen einzelne Galera-Cluster-Knoten sterben, dann kann es daran liegen, dass die ändernden SQL-Querries nicht in einer __expliziten Transaktion__ ausgeführt werden. Auch **Trigger** und **Events** müssen in __expliziten Transaktionen__ ausgeführt werden. | ||
| + | |||
| + | |||
| + | == The table is full == | ||
| + | |||
| + | > mysqlcheck -o --all-databases | ||
| + | ... | ||
| + | simsysnetwork.IccidEntries | ||
| + | note : Table does not support optimize, doing recreate + analyze instead | ||
| + | error : The table ' | ||
| + | status | ||
| + | ... | ||
| + | |||
| + | Dafür soll es zwei Ursachen bzw. Lösungen geben: | ||
| + | - running the query below with incorrect foreign key: '' | ||
| + | - You seem to have a too low maximum size for your '' | ||
| + | - bis 512MB: '' | ||
| + | - ohne Limit: '' | ||
| + | |||
| + | |||
| + | ==== Konfigurationsdateien ==== | ||
| + | |||
| + | |||
| + | === percona-xtradb-cluster-server-5.7 === | ||
| + | |||
| + | <file bash / | ||
| + | [client] | ||
| + | port = 23321 | ||
| + | socket | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | [mysqld] | ||
| + | innodb_autoinc_lock_mode | ||
| + | innodb_buffer_pool_size | ||
| + | innodb_file_per_table | ||
| + | innodb_flush_log_at_trx_commit | ||
| + | innodb_flush_method | ||
| + | innodb_log_file_size | ||
| + | innodb_log_buffer_size | ||
| + | innodb_thread_concurrency | ||
| + | innodb_use_native_aio | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | [server] | ||
| + | sql_mode | ||
| + | |||
| + | [mysqld] | ||
| + | report_host | ||
| + | report_port | ||
| + | bind_address | ||
| + | socket | ||
| + | datadir | ||
| + | default_storage_engine | ||
| + | pid-file | ||
| + | log_error | ||
| + | # Error messages | ||
| + | # Error and warning messages | ||
| + | # Error, warning, and information messages -> log_error_verbosity = 3 | ||
| + | log_error_verbosity | ||
| + | log_slave_updates | ||
| + | log_syslog | ||
| + | log_syslog_include_pid | ||
| + | log_syslog_tag | ||
| + | # relay_log_recovery=OFF, | ||
| + | # | ||
| + | relay_log | ||
| + | relay_log_index | ||
| + | relay_log_info_repository | ||
| + | relay_log_space_limit | ||
| + | character_set_server | ||
| + | # 1M = 1048576 | ||
| + | collation_server | ||
| + | expire_logs_days | ||
| + | explicit_defaults_for_timestamp | ||
| + | interactive_timeout | ||
| + | master_info_repository | ||
| + | master_verify_checksum | ||
| + | max_allowed_packet | ||
| + | max_binlog_size | ||
| + | max_connect_errors | ||
| + | max_connections | ||
| + | max_relay_log_size | ||
| + | net_read_timeout | ||
| + | net_write_timeout | ||
| + | port = 23321 | ||
| + | query_cache_limit | ||
| + | query_cache_min_res_unit | ||
| + | query_cache_size | ||
| + | query_cache_type | ||
| + | skip_external_locking | ||
| + | skip_name_resolve | ||
| + | sync_binlog | ||
| + | sync_master_info | ||
| + | sync_relay_log_info | ||
| + | ignore-db-dir | ||
| + | log-error | ||
| + | symbolic-links | ||
| + | server-id | ||
| + | |||
| + | log_bin | ||
| + | log_bin_index | ||
| + | |||
| + | # | ||
| + | # | ||
| + | |||
| + | open_files_limit | ||
| + | connect_timeout | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | # | ||
| + | # The Percona XtraDB Cluster 5.7 configuration file. | ||
| + | # | ||
| + | # One can use all long options that the program supports. | ||
| + | # Run program with --help to get a list of available options and with | ||
| + | # --print-defaults to see which it would actually understand and use. | ||
| + | # | ||
| + | # For explanations see | ||
| + | # http:// | ||
| + | |||
| + | [mysqld_safe] | ||
| + | pid-file | ||
| + | socket | ||
| + | nice = 0 | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | [mysqld] | ||
| + | # Path to Galera library | ||
| + | wsrep_provider=/ | ||
| + | |||
| + | # Cluster connection URL contains IPs of nodes | ||
| + | #If no IP is found, this implies that a new cluster needs to be created, | ||
| + | #in order to do that you need to bootstrap this node | ||
| + | # | ||
| + | |||
| + | # In order for Galera to work correctly binlog format should be ROW | ||
| + | binlog_format=ROW | ||
| + | |||
| + | # MyISAM storage engine has only experimental support | ||
| + | default_storage_engine=InnoDB | ||
| + | |||
| + | # Slave thread to use | ||
| + | wsrep_slave_threads= 8 | ||
| + | |||
| + | wsrep_log_conflicts | ||
| + | |||
| + | # This changes how InnoDB autoincrement locks are managed and is a requirement for Galera | ||
| + | innodb_autoinc_lock_mode=2 | ||
| + | |||
| + | # Node IP address | ||
| + | # | ||
| + | # Cluster name | ||
| + | # | ||
| + | |||
| + | #If wsrep_node_name is not specified, | ||
| + | # | ||
| + | |||
| + | # | ||
| + | pxc_strict_mode=ENFORCING | ||
| + | |||
| + | # SST method | ||
| + | # | ||
| + | |||
| + | # | ||
| + | # | ||
| + | |||
| + | # | ||
| + | |||
| + | wsrep_cluster_name | ||
| + | wsrep_sst_method | ||
| + | wsrep_sst_auth | ||
| + | |||
| + | ### Standard für DB: 3306 -> 233XX | ||
| + | port = 23321 | ||
| + | bind-address | ||
| + | |||
| + | ### Standard für SST: 4444 -> 33XX4 (das , am Zeilenende muss unbedingt bleiben) | ||
| + | ### Standard für IST / replication: | ||
| + | wsrep_sst_donor | ||
| + | |||
| + | ### Standard für InterCom: 4567 -> 33XX7 | ||
| + | # | ||
| + | wsrep_cluster_address | ||
| + | |||
| + | ### Standard für GCache: 128 MB -> 4G | ||
| + | ### IST bezieht seine Daten aus dem GCache, vergleichbar mit der BIN-LOG-Historie bei GTID-Replikation | ||
| + | ### Je größer der GCache ist, desto länger dürfen Wartungsarbeiten sein. | ||
| + | wsrep_provider_options | ||
| + | |||
| + | # | ||
| + | </ | ||
| + | |||
| + | <file bash / | ||
| + | [mysqld] | ||
| + | ### Standard für SST: 4444 -> 33XX4 | ||
| + | wsrep_sst_receive_address | ||
| + | # | ||
| + | ### Standard: 4567 (InterCom) -> 33XX7 (Referenzadresse für viele andere Variablen) | ||
| + | wsrep_node_address | ||
| + | </ | ||
| + | ---- | ||
| + | |||
| + | |||
| + | ===== implizite vs. explizite Transaktionen ===== | ||
| + | |||
| + | Wenn man viele DELETE-Kommandos (tausende) in kurzer Folge auf einen Galera-Cluster absetzt, dann kann er komplett abstürzen: | ||
| + | DELETE FROM tabelle WHERE id=120340243; | ||
| + | DELETE FROM tabelle WHERE id=120340244; | ||
| + | DELETE FROM tabelle WHERE id=120340245; | ||
| + | ... | ||
| + | |||
| + | ...wenn diese DELETE-Kommandos nicht explizit in einer Transaktion zusammengefasst werden. | ||
| + | |||
| + | Dabei werden dann im Log die Meldungen "'' | ||
| + | |||
| + | Die Log-Meldung "'' | ||
| + | besagt, dass während der vielen kurz aufeinander folgenden impliziten Transaktionen, | ||
| + | die Tabelle und ihr Index nicht synchron sind. | ||
| + | Das scheint in so einem Fall normal zu sein und muß gezielte durch weitere Maßnahmen verhindert werden. | ||
| + | Im Index stehen dann für kurze Zeit noch ältere Daten drin, als in der Tabelle. | ||
| + | Das verhindert die implizite Transaktion nicht, sondern nur eine explizite Transaktion. | ||
| + | |||
| + | Diese Tatsache führt dann zu dem Folgefehler: | ||
| + | Der Fehler "'' | ||
| + | Daraus schließt Galera, dass der Cluster nicht mehr synchron ist und versucht sich den kompletten Datenbestand per SST von einem anderen Knoten zu holen. | ||
| + | Damit beginnt der Zusammenbruch des Clusters. | ||
| + | |||
| + | Dieses Problem kann durch das gezielte einleiten einer Transaktion verhindert werden: | ||
| + | START TRANSACTION; | ||
| + | DELETE FROM tabelle WHERE id=120340243; | ||
| + | DELETE FROM tabelle WHERE id=120340244; | ||
| + | DELETE FROM tabelle WHERE id=120340245; | ||
| + | ... | ||
| + | COMMIT; | ||
| + | |||
