mysql_mit_replikation
Unterschiede
Hier werden die Unterschiede zwischen zwei Versionen angezeigt.
| Beide Seiten der vorigen RevisionVorhergehende ÜberarbeitungNächste Überarbeitung | Vorhergehende Überarbeitung | ||
| mysql_mit_replikation [2017-10-20 20:22:14] – [Probleme] manfred | mysql_mit_replikation [2019-04-12 09:22:48] (aktuell) – manfred | ||
|---|---|---|---|
| Zeile 1: | Zeile 1: | ||
| + | ====== MySQL mit Replikation ====== | ||
| + | |||
| + | Dieses Beispiel wird auf einem //Ubuntu 10.04 LTS Server// und //MySQL 5.1.41-3ubuntu12.1// | ||
| + | |||
| + | * **5.1** | ||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | * **5.7** | ||
| + | * [[http:// | ||
| + | |||
| + | **ACHTUNG!** | ||
| + | - Die **server_id** muss immer eindeutig sein! | ||
| + | - In aktuellen Versionen von MySQL und MariaDB wird das Passwort für den Replikations-User nicht mehr aus einer CNF-Datei ausgelesen, sondern muss per SQL-Aufruf eingetütet werden. | ||
| + | - z.Z. (MySQL 5.1) braucht MySQL für einen Master-Master-Betrieb die Option '' | ||
| + | |||
| + | Zum Beispiel so: | ||
| + | # echo " | ||
| + | |||
| + | |||
| + | == Master und Slave jetzt verbinden == | ||
| + | |||
| + | #!/bin/bash | ||
| + | | ||
| + | MASTER_HOST=" | ||
| + | | ||
| + | BENUTZER=" | ||
| + | PASSWORT=" | ||
| + | | ||
| + | MASTER_USER=" | ||
| + | MASTER_PASSWORD=" | ||
| + | | ||
| + | if [ -n " | ||
| + | MASTERSTATUS=" | ||
| + | | ||
| + | BINLOG=" | ||
| + | LOGPOS=" | ||
| + | | ||
| + | echo "' | ||
| + | | ||
| + | echo " | ||
| + | STOP SLAVE; | ||
| + | CHANGE | ||
| + | MASTER_HOST=' | ||
| + | MASTER_USER=' | ||
| + | MASTER_PASSWORD=' | ||
| + | MASTER_LOG_FILE=' | ||
| + | MASTER_LOG_POS=${LOGPOS} \ | ||
| + | ; | ||
| + | START SLAVE; | ||
| + | " | mysql -u${BENUTZER} -p${PASSWORT} | ||
| + | else | ||
| + | echo "${0} [MySQL-Master]" | ||
| + | fi | ||
| + | |||
| + | |||
| + | ===== DB-Host neu initialisieren ===== | ||
| + | |||
| + | # / | ||
| + | # aptitude update && aptitude safe-upgrade && aptitude autoclean || exit 1 | ||
| + | # aptitude -y install mysql-server || exit 1 | ||
| + | # / | ||
| + | # sed -i ' | ||
| + | # rm -fr / | ||
| + | # dpkg-reconfigure --force $(dpkg -l | awk '/ | ||
| + | |||
| + | |||
| + | ===== Replikation einrichten ===== | ||
| + | |||
| + | - // | ||
| + | - // | ||
| + | |||
| + | |||
| + | ==== my.cnf ==== | ||
| + | |||
| + | Alle Dateien, die im Verzeichnis /// | ||
| + | |||
| + | # ls -l / | ||
| + | |||
| + | |||
| + | === Master + Slave === | ||
| + | |||
| + | # echo "GRANT ALL PRIVILEGES ON *.* TO ' | ||
| + | |||
| + | # vi / | ||
| + | | ||
| + | [mysqld] | ||
| + | pid_file | ||
| + | log_bin | ||
| + | # | ||
| + | relay_log | ||
| + | relay_log_space_limit | ||
| + | | ||
| + | [server] | ||
| + | sql-mode="" | ||
| + | |||
| + | |||
| + | Status des Slave: | ||
| + | # echo "SHOW SLAVE STATUS \G;" | mysql -u root -p | ||
| + | |||
| + | |||
| + | === db01 (Master) === | ||
| + | |||
| + | Konfigurieren Sie ein Konto auf dem Master-Server, | ||
| + | |||
| + | **__Nicht__ empfohlen dagegen ist soetwas:** | ||
| + | # echo "GRANT REPLICATION SLAVE ON *.* TO ' | ||
| + | |||
| + | Besser ist soetwas: | ||
| + | # echo " | ||
| + | |||
| + | # vi / | ||
| + | | ||
| + | [mysqld] | ||
| + | server_id | ||
| + | innodb_flush_log_at_trx_commit=1 | ||
| + | sync_binlog | ||
| + | log_slave_updates | ||
| + | expire_logs_days | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | |||
| + | Die **server_id** muss auf jeden MySQL-Rechner eindeutig sein! | ||
| + | |||
| + | |||
| + | Status des Master: | ||
| + | # echo "SHOW MASTER STATUS;" | ||
| + | File Position | ||
| + | mysql-bin.000003 | ||
| + | |||
| + | Ob der Slave sich mit dem Master verbunden hat, kann man das so abfragen: | ||
| + | # echo "SHOW SLAVE HOSTS;" | ||
| + | Server_id | ||
| + | 20 vdb02 | ||
| + | |||
| + | Slave-Mode auf dem Master deaktivieren: | ||
| + | # echo "STOP SLAVE; | ||
| + | |||
| + | |||
| + | === db02 (Slave) === | ||
| + | |||
| + | # vi / | ||
| + | | ||
| + | [mysqld] | ||
| + | server_id | ||
| + | innodb_flush_log_at_trx_commit=1 | ||
| + | sync_binlog | ||
| + | log_slave_updates | ||
| + | master_host | ||
| + | master_user | ||
| + | master_password | ||
| + | master_port | ||
| + | master_connect_retry | ||
| + | report_host | ||
| + | expire_logs_days | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | # | ||
| + | |||
| + | Die **server_id** muss auf jeden MySQL-Rechner eindeutig sein! | ||
| + | |||
| + | Damit der MySQL-Server sich nach dem Start nicht mit der falschen Maschine verbindet, | ||
| + | muss diese Datei gelöscht werden: | ||
| + | rm / | ||
| + | |||
| + | |||
| + | === Master und Slave verbinden === | ||
| + | |||
| + | * [[http:// | ||
| + | |||
| + | Log-Position des Master auslesen: | ||
| + | # echo "SHOW MASTER STATUS \G;" | mysql -t -uroot -p -h db01 | ||
| + | *************************** 1. row *************************** | ||
| + | File: mysql-bin.000205 | ||
| + | Position: 52225615 | ||
| + | Binlog_Do_DB: | ||
| + | Binlog_Ignore_DB: | ||
| + | |||
| + | Slave in die richtige Log-Position des Master einhängen: | ||
| + | # echo "STOP SLAVE; | ||
| + | |||
| + | |||
| + | == db_master-dump.sh == | ||
| + | |||
| + | #!/bin/bash | ||
| + | | ||
| + | ### Dieses Skript erstellt einen Master-Dump | ||
| + | | ||
| + | MASTER_HOST="" | ||
| + | MASTER_USER=" | ||
| + | MASTER_PASSWD=" | ||
| + | | ||
| + | while [ " | ||
| + | case " | ||
| + | -mh) | ||
| + | MASTER_HOST=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -mu) | ||
| + | MASTER_USER=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -mp) | ||
| + | MASTER_PASSWD=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -h) | ||
| + | echo " | ||
| + | HILFE: | ||
| + | ${0} [Option] | ||
| + | -mh [master host] | ||
| + | -mu [master user] | ||
| + | -mp [master passwd] | ||
| + | " | ||
| + | exit 1 | ||
| + | ;; | ||
| + | *) | ||
| + | if [ " | ||
| + | echo "Der Parameter ' | ||
| + | fi | ||
| + | shift | ||
| + | ;; | ||
| + | esac | ||
| + | done | ||
| + | | ||
| + | # | ||
| + | | ||
| + | HOSTTEST=" | ||
| + | if [ -z " | ||
| + | | ||
| + | echo " | ||
| + | ${0} -mh [MASTER_HOST] | ||
| + | ${0} -mh [MASTER_HOST] -mu [MASTER_USER] -mp [master_passwd] | ||
| + | zum Beispiel | ||
| + | ${0} db01 | ||
| + | " | ||
| + | | ||
| + | else | ||
| + | | ||
| + | ZUFALL=" | ||
| + | | ||
| + | ### auf dem MASETER | ||
| + | echo "FLUSH TABLES WITH READ LOCK;" | mysql -h${MASTER_HOST} -t -u${MASTER_USER} -p${MASTER_PASSWD} | ||
| + | MASTERSTATUS=" | ||
| + | recorded_log_file_name=" | ||
| + | recorded_log_position=" | ||
| + | | ||
| + | time mysqldump -u${MASTER_USER} -p${MASTER_PASSWD} -h${MASTER_HOST} --opt -Ac --master-data=2 > / | ||
| + | echo " | ||
| + | | ||
| + | echo "' | ||
| + | ssh ${MASTER_HOST} 'cat / | ||
| + | ls -lh / | ||
| + | | ||
| + | # | ||
| + | | ||
| + | fi | ||
| + | |||
| + | |||
| + | == db_master-slave_repli_on.sh == | ||
| + | |||
| + | #!/bin/bash | ||
| + | | ||
| + | ### Dieses Skript spielt den Master-Dump ein und aktiviert die Replikation | ||
| + | | ||
| + | MASTER_DUMP="" | ||
| + | SLAVE_HOST="" | ||
| + | SLAVE_USER=" | ||
| + | SLAVE_PASSWD=" | ||
| + | REPLI_USER=" | ||
| + | REPLI_PASSWD=" | ||
| + | | ||
| + | while [ " | ||
| + | case " | ||
| + | -sh) | ||
| + | SLAVE_HOST=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -su) | ||
| + | SLAVE_USER=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -sp) | ||
| + | SLAVE_PASSWD=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -ru) | ||
| + | REPLI_USER=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -rp) | ||
| + | REPLI_PASSWD=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -ms) | ||
| + | MASTER_DEBIAN=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -md) | ||
| + | MASTER_DUMP=${2} | ||
| + | shift | ||
| + | ;; | ||
| + | -h) | ||
| + | echo " | ||
| + | HILFE: | ||
| + | ${0} [Option] | ||
| + | -md [master dump Dateiname] | ||
| + | -sh [slave host] | ||
| + | -su [slave user] | ||
| + | -sp [slave passwd] | ||
| + | -ru [repli user] | ||
| + | -rp [repli passwd] | ||
| + | " | ||
| + | exit 1 | ||
| + | ;; | ||
| + | *) | ||
| + | if [ " | ||
| + | echo "Der Parameter ' | ||
| + | fi | ||
| + | shift | ||
| + | ;; | ||
| + | esac | ||
| + | done | ||
| + | | ||
| + | # | ||
| + | | ||
| + | HOSTTEST=" | ||
| + | if [ -z " | ||
| + | | ||
| + | echo " | ||
| + | ${0} -sh [SLAVE_HOST] -md [MASTER_DUMP] | ||
| + | ${0} -sh [SLAVE_HOST] -su [SLAVE_USER] -sp [SLAVE_PASSWD] -ru [REPLI_USER] -rp [REPLI_PASSWD] -md [MASTER_DUMP] | ||
| + | zum Beispiel | ||
| + | ${0} -sh db02 -ms / | ||
| + | " | ||
| + | | ||
| + | else | ||
| + | | ||
| + | ### auf dem SLAVE | ||
| + | if [ -r " | ||
| + | recorded_log_file_name=" | ||
| + | recorded_log_position=" | ||
| + | | ||
| + | echo "STOP SLAVE;" | ||
| + | time mysql -h${SLAVE_HOST} -u${SLAVE_USER} -p${SLAVE_PASSWD} < ${MASTER_DUMP} | ||
| + | echo " | ||
| + | echo "START SLAVE;" | ||
| + | if [ -r " | ||
| + | md-test=" | ||
| + | ms-test=" | ||
| + | if [ " | ||
| + | cat ${MASTER_DEBIAN} | ssh ${MASTER_HOST} 'cat > / | ||
| + | else | ||
| + | echo " | ||
| + | fi | ||
| + | fi | ||
| + | ssh ${SLAVE_HOST} '/ | ||
| + | fi | ||
| + | | ||
| + | # | ||
| + | | ||
| + | fi | ||
| + | |||
| + | |||
| + | == Access denied for user ' | ||
| + | |||
| + | Sollte auf dem //Slave// diese Fehlermeldung erscheinen, dann muss das Passwort aus der Datei /// | ||
| + | |||
| + | # / | ||
| + | * Starting MariaDB database server mysqld | ||
| + | * Checking for corrupt, not cleanly closed and upgrade needing tables. | ||
| + | ERROR 1045 (28000): Access denied for user ' | ||
| + | |||
| + | oder man überträgt einfach die ganze Datei vom Master zum Slave: | ||
| + | # ssh root@db01 'cat / | ||
| + | |||
| + | |||
| + | ===== MySQL Bin-Log' | ||
| + | |||
| + | In diesem Beispiel lege ich das neue Bin-Log-Verzeichnis in ein LVM. | ||
| + | |||
| + | LVM anlegen: | ||
| + | # fdisk /dev/sda | ||
| + | # pvcreate /dev/sda2 | ||
| + | # vgcreate system /dev/sda2 | ||
| + | |||
| + | LV anlegen und formatieren: | ||
| + | # lvcreate -L 100G -n mysqlbinlog system | ||
| + | # mkfs -t ext4 -L mysqlbinlog / | ||
| + | |||
| + | LV mounten: | ||
| + | # mkdir / | ||
| + | # echo " | ||
| + | # mount / | ||
| + | |||
| + | Apparmor anpassen: | ||
| + | # vi / | ||
| + | | ||
| + | ... | ||
| + | / | ||
| + | } | ||
| + | |||
| + | # / | ||
| + | |||
| + | MySQL-Konfiguration anpassen, hier muss der Variable //'' | ||
| + | # vi / | ||
| + | | ||
| + | [mysqld] | ||
| + | pid_file | ||
| + | log_bin | ||
| + | relay_log | ||
| + | relay_log_space_limit | ||
| + | expire_logs_days | ||
| + | ... | ||
| + | |||
| + | |||
| + | ===== MySQL DB in eine separate Partition schreiben ===== | ||
| + | |||
| + | # mkdir /mysqldb | ||
| + | # echo " | ||
| + | # mount /mysqldb | ||
| + | # mkdir / | ||
| + | # chown -R mysql:mysql /mysqldb | ||
| + | |||
| + | MySQL-Konfiguration anpassen, hier muss der Variable //'' | ||
| + | # vi / | ||
| + | | ||
| + | [mysqld] | ||
| + | datadir | ||
| + | ... | ||
| + | |||
| + | |||
| + | Apparmor anpassen: | ||
| + | # vi / | ||
| + | | ||
| + | ... | ||
| + | /mysqldb/** rw, | ||
| + | / | ||
| + | } | ||
| + | |||
| + | # / | ||
| + | |||
| + | |||
| + | ===== MySQL Bin-Log' | ||
| + | |||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | * [[http:// | ||
| + | |||
| + | |||
| + | ==== MySQL Bin-Log' | ||
| + | |||
| + | # du -shc / | ||
| + | # echo "SHOW BINARY LOGS;" | mysql -t -u root -pgeheim | ||
| + | # echo "SHOW MASTER STATUS;" | ||
| + | # mysqlbinlog --base64-output=decode-rows --verbose / | ||
| + | # echo "SHOW BINLOG EVENTS IN ' | ||
| + | |||
| + | Restore der letzten Bin Log Sicherung „mtebosql01.victorvox.net:/ | ||
| + | # mysqlbinlog --start-position=120 / | ||
| + | # zcat / | ||
| + | |||
| + | |||
| + | ==== überflüssige MySQL Bin-Log' | ||
| + | |||
| + | #!/bin/bash | ||
| + | | ||
| + | DBPASSWD=" | ||
| + | DBMASTER=" | ||
| + | | ||
| + | if [ -z " | ||
| + | echo "${0} [DB-Master-Host]" | ||
| + | exit 1 | ||
| + | fi | ||
| + | | ||
| + | | ||
| + | DBSLAVES=" | ||
| + | BINLOGNR=" | ||
| + | | ||
| + | for i in ${DBSLAVES} | ||
| + | do | ||
| + | BINLOGNR=" | ||
| + | $(echo "SHOW SLAVE STATUS \G;" | mysql -uroot -p${DBPASSWD} -h${i} | awk '/^[ ]*Master_Log_File:/ | ||
| + | done | ||
| + | | ||
| + | MAXBINLOG=" | ||
| + | BINLOGDEL=" | ||
| + | | ||
| + | ### hier wird tatsaechlich geloescht!!! | ||
| + | echo " | ||
| + | |||
| + | |||
| + | ===== Probleme ===== | ||
| + | |||
| + | MySQL-Replikation hat gegenüber einer Lösung mit einer MySQL-DB auf zwei per DRBD gespiegelten Rechnern zwei bedeutende Nachteile: | ||
| + | - Ein automatischer Schwenk zwischen den beiden MySQL-DB' | ||
| + | - Wenn beim Schwenk auch nur ein einziges SQL-Kommando auf dem Slave nicht ausgeführt wird, sind (unter Umständen) die beiden DB's nicht mehr (automatisch) synchron zu bekommen. Dann steht zwar die Verbindung zwischen Master und Slave, aber der Slave snchronisiert sich nicht mehr... | ||
| + | |||
| + | Aus diesem Grund ist die Replikation einer MySQL-DB nur sinnvoll, wenn man: | ||
| + | - eine oder mehrere DBD's als " | ||
| + | - viele Lesezugriffe auf mehrere MySQL-Systeme verteilen möchte | ||
| + | |||
| + | |||
| + | === ERROR 1794 === | ||
| + | |||
| + | ERROR 1794 (HY000) at line 1: Slave is not configured or failed to initialize properly. You must at least set --server-id to enable either a master or a slave. Additional error messages can be found in the MySQL error log. | ||
| + | |||
| + | Wenn es mit diesen Einstellungen zum Fehler "ERROR 1794" kommt: | ||
| + | relay_log | ||
| + | relay_log_info_repository | ||
| + | relay_log_recovery | ||
| + | sync_relay_log_info | ||
| + | relay_log_space_limit | ||
| + | |||
| + | ... dann muss man nur einen Parameter entfernen: | ||
| + | # | ||
| + | relay_log_info_repository | ||
| + | relay_log_recovery | ||
| + | sync_relay_log_info | ||
| + | relay_log_space_limit | ||
| + | |||
| + | ... und schon geht es nach dem Restart. | ||
| + | |||
| + | |||
| + | ===== MySQL-BIN-LOG lesen ===== | ||
| + | |||
| + | <file bash ~/ | ||
| + | #!/bin/bash | ||
| + | |||
| + | |||
| + | if [ -z " | ||
| + | echo "${0} / | ||
| + | echo "less / | ||
| + | echo | ||
| + | echo "${0} / | ||
| + | echo "less / | ||
| + | exit 1; | ||
| + | else | ||
| + | if [ -r " | ||
| + | MASTER_LOG_FILE=" | ||
| + | BIN_LOG_OUT=" | ||
| + | |||
| + | if [ -n " | ||
| + | READ_MASTER_LOG_POS=" | ||
| + | MASTER_LOG_POSITION=" | ||
| + | BIN_LOG_OUT=" | ||
| + | fi | ||
| + | else | ||
| + | echo "Die BIN-LOG-Datei konnte nicht gelesen bzw. gefunden werden."; | ||
| + | exit 1; | ||
| + | fi | ||
| + | fi | ||
| + | |||
| + | # mysqlbinlog --base64-output=DECODE-ROWS -v -j 1013 / | ||
| + | mysqlbinlog --base64-output=DECODE-ROWS -v ${MASTER_LOG_POSITION} ${MASTER_LOG_FILE} > ${BIN_LOG_OUT}.txt | ||
| + | ls -l ${BIN_LOG_OUT}.txt | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== aktuelle Position in der Replikation überspringen ===== | ||
| + | |||
| + | <file bash ~/ | ||
| + | #!/bin/bash | ||
| + | |||
| + | |||
| + | echo " | ||
| + | STOP SLAVE; | ||
| + | SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; | ||
| + | START SLAVE; | ||
| + | SHOW SLAVE STATUS \G; | ||
| + | " | mysql | ||
| + | </ | ||
| + | |||
