Inhaltsverzeichnis
MySQL - Server (ab MySQL 5.6.12)
Auf der Produktpräsentation vom 14. Nov. 2012 wurden die Funktionen von MySQL 5.6 vorgestellt. Demnach sollen bei MySQL 5.6 alle Werkzeuge bereits dabei sein, die man für einen Cluster benötigt.
MySQL - Server (ab MySQL 5.6.5)
Installation auf Ubuntu 10.04
verwendete Hostnamen:
- Master: master01
- Slave1: slave01
- Slave2: slave02
1. Installationsschritt
Als erstes muss man das MySQL-5.6-Server-Paket und das MySQL-Workbench-Paket von der Webseite saugen (dazu muss man sich bei MySQL einloggen): http://dev.mysql.com/downloads/mysql/5.6.html / http://www.mysql.com/downloads/workbench/
Paket installieren:
> aptitude install libaio1 libatk1.0-0 libcairo2 libcairomm-1.0-1 libctemplate0 libfontconfig1 libgl1-mesa-glx libgl1 libglibmm-2.4-1c2a libgnome-keyring0 libgtk2.0-0 libgtkmm-2.4-1c2a liblua5.1-0 libpango1.0-0 libpangomm-1.4-1 libzip1 python-paramiko python-pexpect mysql-client python-pysqlite2 > dpkg -i mysql-5.6.8-rc-debian6.0-x86_64.deb > dpkg -i mysql-workbench-gpl-5.2.44-1ubu1004-amd64.deb > echo 'PATH="/opt/mysql/server-5.6/bin:/usr/share/mysql-workbench/python/:$PATH"' > /etc/profile.d/mysql_server-5.6.sh > echo 'export PATH' >> /etc/profile.d/mysql_server-5.6.sh > chmod 0755 /etc/profile.d/mysql_server-5.6.sh > echo 'blacklist ipv6' >> /etc/modprobe.d/blacklist.conf
2. Installationsschritt
Doku lesen:
> less /opt/mysql/server-5.6/INSTALL-BINARY
MySQL-Benutzer anlegen:
> groupadd mysql > useradd -r -g mysql mysql
3. Installationsschritt
Da wir für unsere Zwecke hier nur das InnoDB-Back-End benötigen und auf keinen Fall das MyISAM
gebrauchen können, werden wir das Initialisierungs-Skript anpassen.
In Zeile 672 ändern wir MyISAM in InnoDB:
> vi /opt/mysql/server-5.6/scripts/mysql_install_db
...
"--default-storage-engine=InnoDB",
...
Leider werden aber trotzdem die Systemtabellen vom Typ MyISAM erstellt, weil MySQL als Systemtabellen nichts anderes unterstützt… ⇒ ab Version 5.6.9 ist es aber möglich einen SQL-Dump (mysqldump) mit eingeschaltetem GTID-Mode einzuspielen
beim ersten Mal gab es bei mir einen Fehler
> cd /opt/mysql/server-5.6/ > chown -R mysql . > chgrp -R mysql . > scripts/mysql_install_db --user=mysql ... 121121 11:38:46 [ERROR] InnoDB: os_file_get_status() failed on './ibdata1'. Can't determine file permissions 121121 11:38:46 [ERROR] InnoDB: The system tablespace must be writable! 121121 11:38:46 [ERROR] Plugin 'InnoDB' init function returned error. 121121 11:38:46 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed. 121121 11:38:46 [ERROR] Unknown/unsupported storage engine: InnoDB 121121 11:38:46 [ERROR] Aborting 121121 11:38:46 [Note] Binlog end 121121 11:38:46 [Note] /opt/mysql/server-5.6/bin/mysqld: Shutdown complete
beim zweiten Mal funktionierte es
> cd /opt/mysql/server-5.6/ > chown -R mysql . > chgrp -R mysql . > scripts/mysql_install_db --user=mysql ... 121121 11:39:53 [Note] InnoDB: Using Linux native AIO 121121 11:39:53 [Note] InnoDB: Initializing buffer pool, size = 128.0M 121121 11:39:53 [Note] InnoDB: Completed initialization of buffer pool 121121 11:39:53 [Note] InnoDB: Highest supported file format is Barracuda. 121121 11:39:53 [Note] InnoDB: 128 rollback segment(s) are active. 121121 11:39:53 [Note] InnoDB: Waiting for purge to start 121121 11:39:53 [Note] InnoDB: 1.2.8 started; log sequence number 1625977 121121 11:39:54 [Note] Binlog end 121121 11:39:54 [Note] InnoDB: FTS optimize thread exiting. 121121 11:39:54 [Note] InnoDB: Starting shutdown... 121121 11:39:55 [Note] InnoDB: Shutdown completed; log sequence number 1625987 OK To start mysqld at boot time you have to copy support-files/mysql.server to the right place for your system PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER ! To do so, start the server, then issue the following commands: /opt/mysql/server-5.6/bin/mysqladmin -u root password 'new-password' /opt/mysql/server-5.6/bin/mysqladmin -u root -h slave01 password 'new-password' Alternatively you can run: /opt/mysql/server-5.6/bin/mysql_secure_installation which will also give you the option of removing the test databases and anonymous user created by default. This is strongly recommended for production servers. See the manual for more instructions. You can start the MySQL daemon with: cd /opt/mysql/server-5.6 ; /opt/mysql/server-5.6/bin/mysqld_safe & You can test the MySQL daemon with mysql-test-run.pl cd mysql-test ; perl mysql-test-run.pl Please report any problems with the /opt/mysql/server-5.6/bin/mysqlbug script! The latest information about MySQL is available on the web at http://www.mysql.com Support MySQL by buying support/licenses at http://shop.mysql.com WARNING: Found existing config file /opt/mysql/server-5.6/my.cnf on the system. Because this file might be in use, it was not replaced, but was used in bootstrap (unless you used --defaults-file) and when you later start the server. The new default config file was created as /opt/mysql/server-5.6/my-new.cnf, please compare it with your file and take the changes you need. WARNING: Default config file /etc/mysql/my.cnf exists on the system This file will be read by default by the MySQL server If you do not want to use this, either remove it, or use the --defaults-file argument to mysqld_safe when starting the server
4. Installationsschritt
> chown -R root . > chown -R mysql data > cp support-files/mysql.server /etc/init.d/mysql.server
Konfiguration
Jetzt kann man sich entscheiden, welche my.cnf man verwenden möchte und die andere Datei am besten löschen:
- /etc/mysql/my.cnf
- /opt/mysql/server-5.6/my.cnf
Die "my.cnf" muss die richtigen Rechte haben, sonst startet MySQL nicht:
> chmod 0644 my.cnf
Wenn noch irgendwo ein Eintrag existiert, den MySQL daran hindert auch auf von außen zugängliche Ports zu lauschen, dann müssen die entfernt werden:
> vi my.cnf #bind-address 127.0.0.1
mit diesem Beispiel wurden meine Tests durchgeführt:
> vi .../my.cnf [mysqld] server_id = 1000 report_host = rechnername bind-address = 0.0.0.0 report-port = 3306 report-user = otto basedir = /opt/mysql/server-5.6 datadir = /opt/mysql/server-5.6/data pid_file = mysql.pid log_bin = mysql-bin relay_log = mysql-relay-bin master_info_repository = TABLE relay_log_info_repository = TABLE #gtid_mode = ON #disable_gtid_unsafe_statements = 1 expire_logs_days = 7 sync_binlog = 1 log_slave_updates = 1 auto_increment_offset = 1 auto_increment_increment = 10 default-storage-engine = innodb innodb_file_per_table innodb_flush_log_at_trx_commit = 1 innodb_fast_shutdown = 0 #innodb_read_only = 1 #slave-skip-errors = 1062 # # Tuning # # key buffer bei Bedarf ehoehen # key_buffer_size + (read_buffer_size + sort_buffer_size) * max_connections = K bytes of memory key_buffer = 256M max_connect_errors = 1000 max_connections = 1000 connect_timeout = 10 tmp_table_size = 256M max_heap_table_size = 256M query_cache_limit = 256M query_cache_size = 256M query_cache_type = 1 [server] #sql-mode = ""
auf Master und Slave's werden wir root für den Zugriff aus dem ganzen Netzwerk frei schalten:
> sed -i 's/^disable[_-]gtid[_-]unsafe[_-]statements.*/#&/;s/^gtid[_-]mode.*/#&/' /opt/mysql/server-5.6/my.cnf > /etc/init.d/mysql.server restart root@master01:~# echo "UPDATE user SET HOST='%' WHERE USER='root' AND HOST='master01';" | mysql -t mysql root@slave01:~# echo "UPDATE user SET HOST='%' WHERE USER='root' AND HOST='slave01';" | mysql -t mysql root@slave02:~# echo "UPDATE user SET HOST='%' WHERE USER='root' AND HOST='slave02';" | mysql -t mysql > echo "SELECT Host,User,Password FROM user ;" | mysql -t mysql > sed -i 's/^#disable[_-]gtid[_-]unsafe[_-]statements/disable_gtid_unsafe_statements/;s/^#gtid[_-]mode/gtid_mode/' /opt/mysql/server-5.6/my.cnf > /etc/init.d/mysql.server restart
Master+Slave brauchen einen Replikations-User (in diesem Beispiel: otto):
root@master01:~# echo "CREATE USER otto IDENTIFIED BY 'geheim' ; GRANT REPLICATION SLAVE ON *.* TO 'otto'@'%';" | mysql root@slave01:~# echo "CREATE USER otto IDENTIFIED BY 'geheim' ; GRANT REPLICATION SLAVE ON *.* TO 'otto'@'%';" | mysql root@slave02:~# echo "CREATE USER otto IDENTIFIED BY 'geheim' ; GRANT REPLICATION SLAVE ON *.* TO 'otto'@'%';" | mysql > echo "SELECT Host,User,Password FROM user ;" | mysql -t mysql
Start
- http://dev.mysql.com/doc/refman/5.1/de/innodb.html - InnoDB-Tabellen
- http://dev.mysql.com/doc/refman/5.1/de/using-innodb-tables.html - InnoDB-Tabellen erzeugen
- http://dev.mysql.com/doc/refman/5.1/de/converting-tables-to-innodb.html - MyISAM-Tabellen in InnoDB-Tabellen umwandeln ⇒ Wichtig: Bitte konvertieren Sie keine Systemtabellen von MySQL in der mysql-Datenbank (wie etwa user oder host) in den Typ InnoDB. Diese Operation wird nicht unterstützt. Die Systemtabellen müssen immer den Typ MyISAM haben. ⇒ und daran hat sich in MySQL 5.6 nichts geändert! ⇒ ab Version 5.6.9 ist es aber möglich einen SQL-Dump (mysqldump) mit eingeschaltetem GTID-Mode einzuspielen
- http://www.alexander-langer.de/2012-05-08/mysql-tabellentyp-fur-viele-tabellen-auf-einmal-andern.html - Tabellentyp für viele Tabellen auf einmal ändern
- http://dev.mysql.com/doc/refman/5.1/de/adding-and-removing.html - Hinzufügen und Entfernen von InnoDB-Daten- und -Logdateien
- http://dev.mysql.com/doc/refman/5.1/de/innodb-backup.html - Sichern und Wiederherstellen einer InnoDB-Datenbank
- http://dev.mysql.com/doc/refman/5.1/de/moving.html - Eine InnoDB-Datenbank auf eine andere Maschine verschieben
- http://dev.mysql.com/doc/refman/5.1/de/innodb-tuning.html - Tipps zur Leistungssteigerung
- http://dev.mysql.com/doc/refman/5.1/de/innodb-file-defragmenting.html - Eine Tabelle defragmentieren
- http://dev.mysql.com/doc/refman/5.1/de/innodb-error-handling.html - InnoDB-Fehlerbehandlung
DB-Test:
> cd /opt/mysql/server-5.6/mysql-test && perl mysql-test-run.pl ... Only 325 of 3201 completed. mysql-test-run: *** ERROR: Not all tests completed
DB-Start:
> mkdir /var/log/mysql/ > cd /opt/mysql/server-5.6 && /opt/mysql/server-5.6/bin/mysqld_safe &
oder
> /etc/init.d/mysql.server start
Version zeigen:
> echo "SELECT VERSION();" | mysql -t -uroot -p Enter password: +--------------+ | version() | +--------------+ | 5.6.8-rc-log | +--------------+
Log-Datei:
> less /opt/mysql/server-5.6/data/rechnername.err
dieses Kommando setzt das Passwort nur für "root@localhost":
> /opt/mysql/server-5.6/bin/mysqladmin -u root password 'geheim' > echo "SELECT Host,User,Password FROM user ;" | mysql -t mysql +-----------+------+-------------------------------------------+ | Host | User | Password | +-----------+------+-------------------------------------------+ | localhost | root | *2F7DFE7D02BC942AAA12F3CE1BCFFAD27FAD33CA | | % | root | | | 127.0.0.1 | root | | | ::1 | root | | +-----------+------+-------------------------------------------+
… dann sind aber noch drei root-Zugänge ohne Passwort, deshalb machen wir das lieber mit dem folgenden Skript, das setzt nicht nur alle root-Passwörter, sondern entfernt auch noch den Test-Benutzer und die Test-DB (zur Sicherheit):
> /opt/mysql/server-5.6/bin/mysql_secure_installation
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MySQL
SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY!
In order to log into MySQL to secure it, we'll need the current
password for the root user. If you've just installed MySQL, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.
Enter current password for root (enter for none):
OK, successfully used password, moving on...
Setting the root password ensures that nobody can log into the MySQL
root user without the proper authorisation.
You already have a root password set, so you can safely answer 'n'.
Change the root password? [Y/n]
New password:
Re-enter new password:
Password updated successfully!
Reloading privilege tables..
... Success!
By default, a MySQL installation has an anonymous user, allowing anyone
to log into MySQL without having to have a user account created for
them. This is intended only for testing, and to make the installation
go a bit smoother. You should remove them before moving into a
production environment.
Remove anonymous users? [Y/n]
... Success!
Normally, root should only be allowed to connect from 'localhost'. This
ensures that someone cannot guess at the root password from the network.
Disallow root login remotely? [Y/n] n
... skipping.
By default, MySQL comes with a database named 'test' that anyone can
access. This is also intended only for testing, and should be removed
before moving into a production environment.
Remove test database and access to it? [Y/n]
- Dropping test database...
ERROR 1008 (HY000) at line 1: Can't drop database 'test'; database doesn't exist
... Failed! Not critical, keep moving...
- Removing privileges on test database...
... Success!
Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.
Reload privilege tables now? [Y/n]
... Success!
All done! If you've completed all of the above steps, your MySQL
installation should now be secure.
Thanks for using MySQL!
Cleaning up...
Jetzt sind auch alle root-Zugänge mit Passwort versehen:
> echo "SELECT Host,User,Password FROM user ;" | mysql -t mysql +-----------+------+-------------------------------------------+ | Host | User | Password | +-----------+------+-------------------------------------------+ | localhost | root | *2F7DFE7D02BC942AAA12F3CE1BCFFAD27FAD33CA | | % | root | *2F7DFE7D02BC942AAA12F3CE1BCFFAD27FAD33CA | | 127.0.0.1 | root | *2F7DFE7D02BC942AAA12F3CE1BCFFAD27FAD33CA | | ::1 | root | *2F7DFE7D02BC942AAA12F3CE1BCFFAD27FAD33CA | +-----------+------+-------------------------------------------+
ACHTUNG: Die USER-Tabelle ist vom Type MyISAM
und die können nur verändert werden, wenn die Variablen
disable_gtid_unsafe_statements und gtid_mode abgeschaltet sind.
Somit müssen diese Optionen zwingend abgeschaltet werden,
wenn man ein Passwort oder Benutzerrechte ändern
oder einen Benutzer anlegen oder löschen möchte!
Dabei ist auch zu beachten, dass alle so vorgenommenen
Änderungen nicht an die Slaves repliziert werden! ⇒ http://blog.koehntopp.de/archives/3298-MySQL-5.6.7-RC-GTID-vs.-MyISAM.html → http://dev.mysql.com/doc/refman/5.6/en/replication-gtids-restrictions.html → Aber das wird wohl erst in MySQL 5.7 behoben werden. ⇒ ab Version 5.6.9 ist es aber möglich einen SQL-Dump (mysqldump) mit eingeschaltetem GTID-Mode einzuspielen
Jetzt können wir den GTID-Mode aktivieren:
> sed -i 's/^#disable[_-]gtid[_-]unsafe[_-]statements/disable_gtid_unsafe_statements/;s/^#gtid[_-]mode/gtid_mode/' /opt/mysql/server-5.6/my.cnf > /etc/init.d/mysql.server restart
Login-Datei anlegen;
bisher musste man in der Datei ~/.my.cnf das Passwort im Klartext eingeben,
jetzt gibt es ein Werkzeug um eine verschlüsselte Login-Datei anzulegen:
> mysql_config_editor reset
> mysql_config_editor set -u root -p -h 127.0.0.1
Enter password:
> cat ~/.mylogin.cnf
�<��]��.�dO�>v�����X�
6 ,\�g+��R�rx�{�I���*�Q9�]u� @�w�/��z�'�r�@ĉ�c�DU�Q�FY
Test:
> mysqlshow +--------------------+ | Databases | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ > mysqladmin version mysqladmin Ver 8.42 Distrib 5.6.8-rc, for debian6.0 on x86_64 Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Server version 5.6.8-rc-log Protocol version 10 Connection Localhost via UNIX socket UNIX socket /tmp/mysql.sock Uptime: 1 min 46 sec Threads: 1 Questions: 4 Slow queries: 0 Opens: 70 Flush tables: 1 Open tables: 63 Queries per second avg: 0.142 > mysqladmin variables +----------------------------------+----------------------------------+ | Variable_name | Value | +----------------------------------+----------------------------------+ | auto_increment_increment | 10 | | auto_increment_offset | 1 | | autocommit | ON | | automatic_sp_privileges | ON | | back_log | 230 | | basedir | /opt/mysql/server-5.6 | ...
> echo "SHOW ENGINE INNODB STATUS \G;" | mysql *************************** 1. row *************************** Type: InnoDB Name: Status: ...
mysql_config_editor
Allerdings scheint es so als würde diese Verschlüsselung praktisch für die Füße zu sein. Denn es ist nur eine aes-128-ecb, die man ganz leicht wieder entschlüsseln kann:
> ~/bin/AES_DECRYPT.php [client] user = root password = geheim host = 127.0.0.1
Sollte man also ein Passwort vergessen haben, kann man auch mal eben wieder nachsehen.
Aber es ist auch zu bedenken, dass man soeine Datei nicht bei jedem ins Home-Verzeichnis legen darf!
~/bin/AES_DECRYPT.php
#! /usr/bin/php -q
<?php
$fp = fopen(".mylogin.cnf", "r");
if (!$fp) {
die("Cannot open .mylogin.cnf");
}
# read key
fseek($fp, 4);
$key = fread($fp, 20);
# generate real key
$rkey = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
for ($i = 0; $i < strlen($key); $i++) {
$rkey[$i % 16] = ( $rkey[$i % 16] ^ $key[$i] );
}
# for each line
while ($len = fread($fp, 4)) {
# as integer
$len = unpack("V", $len);
$len = $len[1];
# decrypt
$crypt = fread($fp, $len);
$plain = openssl_decrypt($crypt, 'aes-128-ecb', $rkey, true);
# print
print $plain;
}
Replikation
Asynchrone Replikation
MySQL 5.6:
-
-
-
- http://dev.mysql.com/doc/refman/5.6/en/replication-howto-mysqldump.html ⇒
mysqldump –all-databases –master-data | gzip > dbdump.db.gz
- http://dev.mysql.com/doc/refman/5.6/en/replication-features-auto-increment.html - Replication and AUTO_INCREMENT
- http://dev.mysql.com/doc/refman/5.6/en/alter-table-problems.html - Problems with ALTER TABLE
-
-
MySQL Workbench (die neuen MySQL-Replikations-Werkzeuge):
Die Einstellungen für die MySQL-Replikation haben sich von der MySQL 5.5 zur MySQL 5.6.5 etwas geändert.
Unter anderem wird in MySQL 5.6 an Stelle von MASTER_LOG_FILE und MASTER_LOG_POS der Parameter MASTER_AUTO_POSITION verwendet.
Allerdings muss dafür der GTID_MODE (Globale Transaktions-IDentifikation: gtid-mode=ON) aktiviert sein.
Um einen Rechner zum Master zu machen und an ihm einen oder mehrer Slaves anzuhängen, sind folgende Schritte nötig (Master: master01 / Slave: slave01):
- diese Schritte müssen auf dem (neuen) Master durchgeführt werden:
- damit keine neuen Daten reinlaufen, aber die noch arbeitenden Prozesse weiter laufen, bis sie fertig sind:
STOP SLAVE IO_THREAD; - ob die laufenden Prozesse fertig sind bzw. ob noch Prozesse laufen, das kann man so sehen:
SHOW PROCESSLIST; - wenn keine Prozesse mehr laufen, dann wird der Slave-Dienst angehalten:
STOP SLAVE; - jetzt beenden wir den Slave-Dienst komplett und setzen dabei auch alle Slave-Einstellungen zurück:
RESET SLAVE ALL; - GTID_MODE: wenn der Cluster mit aktiviertem GTID_MODE läuft, sollte man den Master-Dienst nicht restarten ("RESET MASTER" leert die GTIDs), werden allerdings die Datenbanken vom (neuen) Master auf den Slave kopiert, bevor der Slave mit dem Master verbunden wird, dann ist der Master-Dienst zu restarten:
- der Master-Dienst muß auch komplett zurückgesetzt werden, damit die Zählweise ab dem jetzt aktuellen Stand von neuem beginnt:
RESET MASTER;
- diese Schritte müssen auf allen Knoten nacheinander durchgeführt werden:
- damit keine neuen Daten reinlaufen, aber die noch arbeitenden Prozesse weiter laufen, bis sie fertig sind:
STOP SLAVE IO_THREAD; - ob die laufenden Prozesse fertig sind bzw. ob noch Prozesse laufen, das kann man so sehen:
SHOW PROCESSLIST; - wenn keine Prozesse mehr laufen, dann wird der Slave-Dienst angehalten:
STOP SLAVE; - jetzt beenden wir den Slave-Dienst komplett und setzen dabei auch alle Slave-Einstellungen zurück:
RESET SLAVE ALL; - GTID_MODE: wenn der Cluster mit aktiviertem GTID_MODE läuft, sollte man den Master-Dienst nicht restarten ("RESET MASTER" leert die GTIDs), werden allerdings die Datenbanken vom (neuen) Master auf den Slave kopiert, bevor der Slave mit dem Master verbunden wird, dann ist der Master-Dienst zu restarten:
- der Master-Dienst muß auch komplett zurückgesetzt werden, damit die
gtid_purged-Wert gesäubert wird (jedoch nicht sein Session-Wert):RESET MASTER;
- Replikation starten:
mysqlreplicate –master=root:geheim@master01 –slave=root:geheim@slave01:3306 –rpl-user=otto:geheim -b -p -vvv - nachdem die Replikationsverbindung nun steht, braucht man nur noch den SQL-Slave-Dienst zu starten:
START SLAVE SQL_THREAD;
Damit man sich die oben aufgeführte Handarbeit sparen kann, habe ich das Skript db-schwenk.sh geschrieben.
Dieses Skript benötigt das Paket "mysql-workbench-gpl" ab der Version 5.2.44.
Handhabung des Skriptes
/root/bin/db-schwenk.sh -clip …⇒ Es wird ein MASTER definiert und dort alle anderen als SLAVEs angehängt, GTIDs müssen stimmen bzw. zueinander passen, die Daten im Master und in den Slaves bleiben unangetastet!/root/bin/db-schwenk.sh -cp -clip …⇒ Die Daten vom Master werden auf die SLAVEs verteilt, MASTER-Dienste (mit GTIDs) & SLAVE-Dienste werden überall zurückgesetzt!/root/bin/db-schwenk.sh -resync …⇒ Nur die SLAVE-Dienste werden zurückgesetzt, die Einstellungen auf dem Masters bleiben unangetastet und werden auf den Slaves entsprechend gesetzt!
Der -cp-Parameter und der -resync-Parameter können sicht gleichzeitig verwendet werden,
da der -cp-Parameter den -resync-Parameter ausschließt
und der -resync-Parameter den -cp-Parameter einschließt.
Cluster-Schwenk durchführen / Knoten aus einem Cluster in neuer Ordnung verbinden
verbinden von drei DBs, diese müssen folgende Bedingungen erfüllen:
- entweder müssen alle DBMS leer sein;
- oder sie müssen bereits als Cluster verbunden gewesen sein und keine dieser DBs darf nachträglich separat bearbeitet worden sein, dann passen die GTIDs zueinander und man muss sich um nichts weiter kümmern;
> /root/bin/db-schwenk.sh -vu root -vp geheim -ru otto -rp geheim -k master01,slave01,slave02
unabhängige Knoten zu einem Cluster verbinden
Sind die oben genannten Bedingungen nicht erfüllt,
also sind in der (neuen) Master-DB bereits Daten drin,
dann muss man dem Kommando noch zusätzlich den Kopier-Parameter (-cp) übergeben:
> /root/bin/db-schwenk.sh -cp -vu root -vp geheim -ru otto -rp geheim -k master01,slave01,slave02
Der -cp-Parameter bewirkt vor dem verbinden der Knoten, dass evtl. bereits vorhandene DBs auf den (neuen) Slaves gelöscht werden und die bereits vorhandenen gültigen Daten vom (neuen) Master auf die einzelnen Slaves kopiert werden.
Der -cp-Parameter darf nicht verwendet werden, wenn man zu einem bestehenden Cluster einen neuen Slave hinzufühgen möchte!
Dafür gibt es einen anderen Parameter -resync.
einen Knoten zu einem Cluster (wieder) hinzufühgen
Den -resync-Parameter kann man für folgende Zwecke verwenden:
- Um einen neuen Slave zu einem bestehenden Cluster hinzuzufühgen;
- oder einen Slave, der sich im Cluster befindet aber jetzt Asynchron geworden ist und nicht mehr repliziert, wieder sauber mit dem Master zu verbinden;
verschiedene Statusabfragen
> echo "SHOW MASTER STATUS;SHOW SLAVE HOSTS;" | mysql -t -h master01 > echo "SHOW SLAVE STATUS \G;" | mysql -h slave01 > echo "SHOW SLAVE STATUS \G;" | mysql -h slave02 > echo "SELECT @@GTID_MODE;" | mysql -t +-------------+ | @@GTID_MODE | +-------------+ | ON | +-------------+ > echo "show global variables like 'gtid_mode';" | mysql -t +---------------+-------+ | Variable_name | Value | +---------------+-------+ | gtid_mode | ON | +---------------+-------+ root@master01:~# mysqlrpladmin --master=root:geheim@master01:3306:/tmp/mysql.sock --slaves=root:geheim@slave01:3306:/tmp/mysql.sock,root:geheim@slave02:3306:/tmp/mysql.sock health # Checking privileges. # # Replication Topology Health: +----------+-------+---------+--------+------------+------------------------------------+ | host | port | role | state | gtid_mode | health | +----------+-------+---------+--------+------------+------------------------------------+ | master01 | 3306 | MASTER | UP | ON | OK | | slave01 | 3306 | SLAVE | WARN | | Slave is not connected to master. | | slave02 | 3306 | SLAVE | WARN | | Slave is not connected to master. | +----------+-------+---------+--------+------------+------------------------------------+ # ...done. root@slave01:~# mysqlrpladmin --master=root:geheim@master01:3306:/tmp/mysql.sock --slaves=root:geheim@slave01:3306:/tmp/mysql.sock,root:geheim@slave02:3306:/tmp/mysql.sock health # Checking privileges. # # Replication Topology Health: +----------+-------+---------+--------+------------+---------+ | host | port | role | state | gtid_mode | health | +----------+-------+---------+--------+------------+---------+ | master01 | 3306 | MASTER | UP | ON | OK | | slave01 | 3306 | SLAVE | UP | ON | OK | | slave02 | 3306 | SLAVE | UP | ON | OK | +----------+-------+---------+--------+------------+---------+ # ...done. > mysqldiskusage --server=root:geheim@master01:3306:/tmp/mysql.sock --all root@master01:~# mysqlrplcheck --master=root:geheim@master01:3306 --slave=root:geheim@slave01:3306 # master on master01: ... connected. # slave on slave01: ... connected. Test Description Status --------------------------------------------------------------------------- Checking for binary logging on master [pass] Are there binlog exceptions? [pass] Replication user exists? [pass] Checking server_id values [pass] Checking server_uuid values [pass] Is slave connected to master? [pass] Check master information file [WARN] Cannot read master information file from a remote machine. Checking InnoDB compatibility [pass] Checking storage engines compatibility [pass] Checking lower_case_table_names settings [pass] Checking slave delay (seconds behind master) [pass] # ...done. root@slave01:~# mysqlrplcheck --master=root:geheim@master01:3306 --slave=root:geheim@slave01:3306 # master on master01: ... connected. # slave on slave01: ... connected. Test Description Status --------------------------------------------------------------------------- Checking for binary logging on master [pass] Are there binlog exceptions? [pass] Replication user exists? [pass] Checking server_id values [pass] Checking server_uuid values [pass] Is slave connected to master? [pass] Check master information file [pass] Checking InnoDB compatibility [pass] Checking storage engines compatibility [pass] Checking lower_case_table_names settings [pass] Checking slave delay (seconds behind master) [pass] # ...done.
sonstiges
#==============================================================================# ### GTIDs anzeigen > mysqlrpladmin --master=root:geheim@master01:3306 --slaves=root:geheim@slave01:3306,root:geheim@slave02:3306 gtid # Checking privileges. # # UUIDS for all servers: +----------+-------+---------+---------------------------------------+ | host | port | role | uuid | +----------+-------+---------+---------------------------------------+ | master01 | 3306 | MASTER | a30c2309-3b0c-11e2-be93-009d80482043 | | slave01 | 3306 | SLAVE | 0eaadab9-3b0d-11e2-be96-00ba1a989e0f | | slave02 | 3306 | SLAVE | 0f077c3a-3b0d-11e2-be96-00813c630858 | +----------+-------+---------+---------------------------------------+ # # Transactions executed on the server: +----------+-------+---------+---------------------------------------------+ | host | port | role | gtid | +----------+-------+---------+---------------------------------------------+ | master01 | 3306 | MASTER | 0EAADAB9-3B0D-11E2-BE96-00BA1A989E0F:1-49 | | master01 | 3306 | MASTER | A30C2309-3B0C-11E2-BE93-009D80482043:1-155 | | slave01 | 3306 | SLAVE | 0EAADAB9-3B0D-11E2-BE96-00BA1A989E0F:1-49 | | slave01 | 3306 | SLAVE | A30C2309-3B0C-11E2-BE93-009D80482043:1-155 | | slave02 | 3306 | SLAVE | 0EAADAB9-3B0D-11E2-BE96-00BA1A989E0F:1-49 | | slave02 | 3306 | SLAVE | A30C2309-3B0C-11E2-BE93-009D80482043:1-155 | +----------+-------+---------+---------------------------------------------+ # ...done. #==============================================================================# ### Clusterschwenk > mysqlrpladmin --master=root:geheim@master01:3306 --slaves=root:geheim@slave01:3306,root:geheim@slave02:3306 --new-master=root:geheim@slave01:3306 switchover # Checking privileges. # Performing switchover from master at master01:3306 to slave at slave01:3306. # Checking candidate slave prerequisites. Candidate slave is missing replication user. ERROR: Candidate slave is missing replication user. # Errors found. Switchover aborted. # # Replication Topology Health: +----------+-------+---------+--------+------------+---------+ | host | port | role | state | gtid_mode | health | +----------+-------+---------+--------+------------+---------+ | master01 | 3306 | MASTER | UP | ON | OK | | slave01 | 3306 | SLAVE | UP | ON | OK | | slave02 | 3306 | SLAVE | UP | ON | OK | +----------+-------+---------+--------+------------+---------+ # ...done. #==============================================================================# ### Clusterschwenk und den alten Master als Slave einhängen > mysqlrpladmin --master=root:geheim@master01:3306 --slaves=root:geheim@slave01:3306,root:geheim@slave02:3306 --new-master=root:geheim@slave01:3306 --demote-master switchover # Checking privileges. # Performing switchover from master at master01:3306 to slave at slave01:3306. # Checking candidate slave prerequisites. Candidate slave is missing replication user. ERROR: Candidate slave is missing replication user. # Errors found. Switchover aborted. # # Replication Topology Health: +----------+-------+---------+--------+------------+---------+ | host | port | role | state | gtid_mode | health | +----------+-------+---------+--------+------------+---------+ | master01 | 3306 | MASTER | UP | ON | OK | | slave01 | 3306 | SLAVE | UP | ON | OK | | slave02 | 3306 | SLAVE | UP | ON | OK | +----------+-------+---------+--------+------------+---------+ # ...done.
/root/bin/db-schwenk.sh
#!/usr/bin/env bash
#
# http://dev.mysql.com/doc/refman/5.6/en/replication-solutions-switch.html
#
VERSION="2012120717"
#------------------------------------------------------------------------------#
### Abhängigkeiten prüfen
if [ "x$(dpkg -s mysql-workbench-gpl 2>/dev/null)" == "x" ]; then
echo "
Dieses Skript benötigt das Paket 'mysql-workbench-gpl'.
Es wurde mit "mysql-5.6.8-rc-debian6.0-x86_64.deb" und mit
"mysql-workbench-gpl-5.2.44-1ubu1004-amd64.deb" getestet.
http://dev.mysql.com/downloads/mysql/5.6.html
http://www.mysql.com/downloads/workbench/
"
exit 1
else
echo "
VERSION='${VERSION}'
"
fi
#==============================================================================#
# PARAMETERVERARBEITUNG
#------------------------------------------------------------------------------#
### Parameterkontrolle
if [ -z "${10}" ]; then
${0} -h
exit 1
fi
#------------------------------------------------------------------------------#
### Parameter auseinanderpulen
while [ "${#}" -ne "0" ]; do
case "${1}" in
-clip)
CLIP="${2}" # Cluster-IP vom aktiven MASTER
shift
;;
-cp)
KOPIE="Ja" # Daten vom MASTER zum SLAVE kopieren und ALLE IDs zurücksetzen
shift
;;
-resync)
RESYNC="Ja" # Daten vom MASTER zum SLAVE kopieren und dann SLAVE mit MASTER verbinden
shift
;;
-kette)
KETTE="Ja" # Daten vom MASTER zum SLAVE kopieren und dann SLAVE mit MASTER verbinden
shift
;;
-vu)
BENUTZERVERBIND="${2}" # Name des Verbindungs-User
shift
;;
-vp)
PASSWORTVERBIND="${2}" # Passwort des Verbindungs-User
shift
;;
-ru)
BENUTZERREPLI="${2}" # Name des Replikations-User
shift
;;
-rp)
PASSWORTREPLI="${2}" # Passwort des Replikations-User
shift
;;
-k)
KNOTEN="${2}" # der erste Knoten wird zum Master gemacht
shift
;;
-testdb)
TESTDB="${2}" # DB-Name für den automatischen Replikationstest, es darf keine DB mit diesem Namen existieren
shift
;;
-h)
echo "" # Ausgabe einer kurzen Hilfe
echo "${0} -vu [Verbindungs-Benutzer] -vp geheim -ru [Replikations-Benutzer] -rp geheim -k [alle Cluster-Knoten, erster wird zum Master]"
echo "${0} -vu root -vp geheim -ru otto -rp geheim -k knoten1,knoten2,knoten3"
echo "${0} -vu root -vp geheim -ru otto -rp geheim -k knoten1:3306,knoten2:3306,knoten3:3306"
echo ""
shift
exit 1
;;
*)
if [ "$(echo "${1}"|egrep '^-')" ] ; then
echo "Der Parameter '${1}' wird nicht unterstützt!"
fi
shift
;;
esac
done
#==============================================================================#
# PARAMETERABHÄNGIGKEITEN
#------------------------------------------------------------------------------#
### Knotenkontrolle
#
MEHRFACHKNOTEN="$(echo "KNOTEN" | tr -s ',' '\n' | sort | uniq -d)"
if [ "x${MEHRFACHKNOTEN}" != "x" ]; then
echo "
Es darf kein Knoten mehrfach genannt werden: '${MEHRFACHKNOTEN}'
"
exit 1
fi
#------------------------------------------------------------------------------#
### Cluster-IP-Kontrolle
#
if [ "x${RESYNC}" != "x" ] ; then
if [ "x${CLIP}" != "x" ]; then
echo "
Es darf entweder '-clip' oder '-resync' übergeben werden,
aber nicht beide Parameter gleichzeitig!
"
exit 1
fi
if [ "x${KETTE}" != "x" ]; then
echo "
Es darf entweder '-kette' oder '-resync' übergeben werden,
aber nicht beide Parameter gleichzeitig!
"
exit 1
fi
else
if [ "x${CLIP}" != "x" ]; then
echo "
Cluster-IP: '${CLIP}'
"
else
if [ "x${KETTE}" == "x" ]; then
echo "
Die Cluster-IP muss mit übergeben werden!
"
exit 1
fi
fi
fi
#------------------------------------------------------------------------------#
### den ersten übergebenen Knoten als (neuen) Master deklarieren
#
while read MASTER CLUSTERKNOTEN
do
MASTER_P="${MASTER}"
CLMASTER="$(echo "${MASTER}" | sed 's/[:].*//g')"
CLKNOTEN="${CLUSTERKNOTEN}"
done < <(echo "${KNOTEN}" | sed 's/,/ /g')
#==============================================================================#
# FUNKTIONEN
#------------------------------------------------------------------------------#
### den Slave-Dienst stoppen und warten bis sich alle Prozesse beendet haben
#
### DIESE FUNKTION BEWIRKT (normalerweise) AUF DEM ALTEN MASTER NICHTS,
### da dort kein Slave-Dienst laufen sollte.
### Allerdings ist bei einer Kettenreplikation, der erste Slave auch gleichzeitig
### ein Master, in dem Fall wird gnau diese Verbindung zerstört.
#
stopslave()
{
#----------------------------------------------------------------------#
### Replikations-User anlegen
#
echo "echo \"CREATE USER ${BENUTZERREPLI} IDENTIFIED BY '${PASSWORTREPLI}' ; GRANT REPLICATION SLAVE ON *.* TO '${BENUTZERREPLI}'@'%';\" | mysql -t -h ${1} 2>/dev/null"
echo "CREATE USER ${BENUTZERREPLI} IDENTIFIED BY '${PASSWORTREPLI}' ; GRANT REPLICATION SLAVE ON *.* TO '${BENUTZERREPLI}'@'%';" | mysql -t -h ${1} 2>/dev/null
echo "echo 'SELECT Host,User,Password FROM user ;' | mysql -t -h ${1} mysql"
echo 'SELECT Host,User,Password FROM user ;' | mysql -t -h ${1} mysql
#----------------------------------------------------------------------#
### sauberen STOP SLAVE durchführen
#
echo "echo 'STOP SLAVE IO_THREAD;' | mysql -h ${1}"
echo "STOP SLAVE IO_THREAD;" | mysql -h ${1}
SYSTEM_USER="$(echo "SHOW PROCESSLIST;" | mysql -t -h ${1} | fgrep 'system user')"
if [ -n "${SYSTEM_USER}" ] ; then
unset BINFERTIG
while [ -z "${BINFERTIG}" ]
do
sleep 1
BINFERTIG="$(echo "SHOW PROCESSLIST;" | mysql -t -h ${1} | fgrep 'system user' | fgrep 'has read all relay log')"
done
fi
#----------------------------------------------------------------------#
### SLAVE-Dienst zurücksetzen
#
echo "echo 'STOP SLAVE; RESET SLAVE ALL;' | mysql -h ${1}"
echo "STOP SLAVE; RESET SLAVE ALL;" | mysql -h ${1}
echo "echo 'SHOW SLAVE STATUS \G ;' | mysql -h ${1}"
echo "SHOW SLAVE STATUS \G ;" | mysql -h ${1}
}
#------------------------------------------------------------------------------#
### den Slave-Dienst stoppen und warten bis sich alle Prozesse beendet haben
#
resetmaster()
{
#----------------------------------------------------------------------#
### MASTER-Dienst zurücksetzen
#
echo "echo 'RESET MASTER;' | mysql -t -h ${1}"
echo "RESET MASTER;" | mysql -t -h ${1}
echo "echo 'SHOW MASTER STATUS;' | mysql -t -h ${1}"
echo "SHOW MASTER STATUS;" | mysql -t -h ${1}
}
#------------------------------------------------------------------------------#
### zum ermitteln und setzen der korrekten Master-Log-Position
#
masterposition()
{
MASTERPOSITION="$(echo 'SHOW MASTER STATUS \G;' | mysql -h ${1} | egrep 'File[:]|Position[:]' | sed 's/[ ]//g')"
MLOGFILE="$(echo "${MASTERPOSITION}" | fgrep 'File:' | awk -F':' '{print $2}')"
MLOGPOS="$(echo "${MASTERPOSITION}" | fgrep 'Position:' | awk -F':' '{print $2}')"
echo "echo \"STOP SLAVE; CHANGE MASTER TO MASTER_HOST='${1}', MASTER_USER='${3}', MASTER_PASSWORD='${4}', MASTER_PORT=${5}, MASTER_AUTO_POSITION=0, MASTER_LOG_FILE='${MLOGFILE}', MASTER_LOG_POS=${MLOGPOS}; START SLAVE;\" | mysql -h ${2}"
echo "STOP SLAVE; CHANGE MASTER TO MASTER_HOST='${1}', MASTER_USER='${3}', MASTER_PASSWORD='${4}', MASTER_PORT=${5}, MASTER_AUTO_POSITION=0, MASTER_LOG_FILE='${MLOGFILE}', MASTER_LOG_POS=${MLOGPOS}; START SLAVE;" | mysql -h ${2}
}
#==============================================================================#
# BEDINGUNGEN
#------------------------------------------------------------------------------#
### ReSync
###
### Wenn nur ein neuer Rechner zum Cluster hinzugefühgt werden soll
### oder ein Slave kaputtgeschrieben wurde.
#
if [ -n "${RESYNC}" ] ; then
if [ -n "${KOPIE}" ] ; then
#--------------------------------------------------------------#
### KOPIE und RESYNC dürfen nicht zusammen übergeben werden,
### weil das den Anwender in seiner Erwartungshaltung verwirren kann.
#
echo "
KOPIE und RESYNC dürfen nicht zusammen übergeben werden,
weil das den Anwender in seiner Erwartungshaltung verwirren kann.
"
exit 1
else
#--------------------------------------------------------------#
### zum neu Synchronisieren ist auch das Kopieren nötig
#
KOPIE="Ja"
fi
else
if [ "x${KETTE}" == "x" ]; then
#----------------------------------------------------------------------#
### Cluster-IP auf dem _alten_ Master runterfahren
#
echo "
Jetzt muss die Cluster-IP '${CLIP}' auf dem alten Master runtergefahren werden!
"
#----------------------------------------------------------------------#
### Nachdem die IP unten ist, legen wir sicherheitshalber
### eine kurze Wartezeit ein um evtl. noch laufende Prozesse
### die Zeit zu geben, fertig zu werden.
#
sleep 5
fi
echo "
#----------------------------------------------------------------------#
# in Bearbeitung ist der Master: '${MASTER_P}'
"
if [ -n "${KETTE}" ] ; then
#--------------------------------------------------------------#
### sauberen STOP SLAVE durchführen
#
echo "echo 'STOP SLAVE IO_THREAD;' | mysql -h ${CLMASTER}"
echo "STOP SLAVE IO_THREAD;" | mysql -h ${CLMASTER}
#--------------------------------------------------------------#
### zum neu Synchronisieren ist auch das Kopieren nötig
#
KOPIE="Ja"
else
#--------------------------------------------------------------#
### STOP SLAVE
#
stopslave ${CLMASTER}
fi
if [ -n "${KOPIE}" ] ; then
FROMBEGINNING="-b"
resetmaster ${CLMASTER}
fi
fi
#------------------------------------------------------------------------------#
### Test-DB
### DB-Name für den automatischen Replikationstest,
### es darf keine DB mit diesem Namen existieren
#
if [ -n "${TESTDB}" ] ; then
TEST_DB="--test-db=${TESTDB}"
DROPTESTDB="DROP DATABASE ${TESTDB}"
fi
#==============================================================================#
### lock auf dem Master setzen
#
echo "FLUSH TABLES WITH READ LOCK;" | mysql -h ${CLMASTER}
#==============================================================================#
# SLAVES
#------------------------------------------------------------------------------#
### alle Slave's nacheinander bearbeiten
#
for CLK in ${CLKNOTEN}
do
echo "
#----------------------------------------------------------------------#
# in Bearbeitung ist der Slave: '${CLK}'
"
KNOT="$(echo "${CLK}" | awk -F':' '{print $1}')"
KPORT="$(echo "${CLK}" | awk -F':' '{print $2}')"
if [ "x${KOPIE}" != "x" ] ; then
#--------------------------------------------------------------#
### wenn kein Port angegeben wurde, wird 3306 verwendet
#
KPORT="3306"
fi
#----------------------------------------------------------------------#
### Stop IO_THREAD
#
stopslave ${KNOT}
#----------------------------------------------------------------------#
### Daten vom neuen MASTER auf die SLAVEs kopieren
#
if [ "x${KOPIE}" != "x" ] ; then
#--------------------------------------------------------------#
### Daten auf dem Slave löschen
#
for i in $(mysqlshow -h ${KNOT} | egrep '^[|][ ]' | egrep -v '^[|][ ]+Databases|^[|][ ]information_schema|^[|][ ]performance_schema|^[|][ ]mysql' | sed 's/^[|][ ]//;s/[ ]*[|]$//')
do
echo "echo 'DROP DATABASE ${i}' | mysql -h ${KNOT}"
echo "DROP DATABASE ${i}" | mysql -h ${KNOT}
done
#--------------------------------------------------------------#
### Daten vom Master zum Slave kopieren
#
resetmaster ${KNOT}
echo "mysqldbcopy --new-storage-engine=Innodb --default-storage-engine=Innodb --rpl=master --rpl-user=${BENUTZERREPLI}:${PASSWORTREPLI} --source=${BENUTZERVERBIND}:${PASSWORTVERBIND}@${MASTER_P} --destination=${BENUTZERVERBIND}:${PASSWORTVERBIND}@${CLK} -a -f -vvv"
mysqldbcopy --new-storage-engine=Innodb --default-storage-engine=Innodb --rpl=master --rpl-user=${BENUTZERREPLI}:${PASSWORTREPLI} --source=${BENUTZERVERBIND}:${PASSWORTVERBIND}@${MASTER_P} --destination=${BENUTZERVERBIND}:${PASSWORTVERBIND}@${CLK} -a -f -vvv
#--------------------------------------------------------------#
### das manuelle setzen der Master-Position ist nur dann nötig,
### wenn eine Asynchrone Maschine wieder synchronisiert werden soll
#
if [ -n "${RESYNC}" -o -n "${KETTE}" ] ; then
masterposition ${CLMASTER} ${KNOT} ${BENUTZERREPLI} ${PASSWORTREPLI} ${KPORT}
fi
else
#--------------------------------------------------------------#
### Master und Slave verbinden
#
echo "mysqlreplicate ${TEST_DB} --master=${BENUTZERVERBIND}:${PASSWORTVERBIND}@${MASTER_P} --slave=${BENUTZERVERBIND}:${PASSWORTVERBIND}@${CLK} --rpl-user=${BENUTZERREPLI}:${PASSWORTREPLI} ${FROMBEGINNING} -p -vvv"
mysqlreplicate ${TEST_DB} --master=${BENUTZERVERBIND}:${PASSWORTVERBIND}@${MASTER_P} --slave=${BENUTZERVERBIND}:${PASSWORTVERBIND}@${CLK} --rpl-user=${BENUTZERREPLI}:${PASSWORTREPLI} ${FROMBEGINNING} -p -vvv
### leider wird die Test-DB (bei einem Fehler) nicht wieder gelöscht
if [ -n "${DROPTESTDB}" ] ; then
echo "echo '${DROPTESTDB};' | mysql -h ${CLMASTER}"
echo "${DROPTESTDB};" | mysql -h ${CLMASTER}
fi
fi
echo "echo 'START SLAVE SQL_THREAD;' | mysql -h ${KNOT}"
echo "START SLAVE SQL_THREAD;" | mysql -h ${KNOT}
done
#------------------------------------------------------------------------------#
### START SLAVE
#
if [ -n "${KETTE}" ] ; then
echo "echo 'START SLAVE IO_THREAD;' | mysql -h ${CLMASTER}"
echo "START SLAVE IO_THREAD;" | mysql -h ${CLMASTER}
fi
#------------------------------------------------------------------------------#
### Cluster-IP auf dem neuen Master hochfahren
#
if [ -z "${RESYNC}" -o "x${KETTE}" == "x" ] ; then
echo "
Ab jetzt darf man die Cluster-IP '${CLIP}' auf dem neuen Master hochgefahren werden.
"
fi
#==============================================================================#
### lock auf dem Master aufheben
#
echo "UNLOCK TABLES;" | mysql -h ${CLMASTER}
Semi-Synchronous Replication
### Master # echo "INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';" | mysql -uroot -pgeheim -h master01 # echo "SHOW PLUGINS;" | mysql -t -uroot -pgeheim -h master01 # echo "SET GLOBAL rpl_semi_sync_master_enabled = 1;" | mysql -uroot -pgeheim -h master01 # ### Slave # echo "INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';" | mysql -uroot -pgeheim -h slave01 # echo "SHOW PLUGINS;" | mysql -t -uroot -pgeheim -h slave01 # echo "SET GLOBAL rpl_semi_sync_slave_enabled = 1;" | mysql -uroot -pgeheim -h slave01 # echo "STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;" | mysql -uroot -pgeheim -h slave01 # ### Monitor # echo "SHOW VARIABLES LIKE 'rpl_semi_sync%';" | mysql -uroot -pgeheim -h master01 # echo "SHOW STATUS LIKE 'Rpl_semi_sync%';" | mysql -uroot -pgeheim -h master01
Dump mit MyISAM-Tabellen einspielen (MySQL 5.6.5 - 5.6.8)
⇒ ab Version 5.6.9 ist es möglich einen SQL-Dump (mysqldump) mit eingeschaltetem GTID-Mode einzuspielen
Es lässt sich im gtid-mode=on keine MyISAM-Tabelle veändern!
Leider müssen die Systemtabellen in MySQL vom Type MyISAM bleiben (http://dev.mysql.com/doc/refman/5.1/de/converting-tables-to-innodb.html), deshalb muss man zum ändern eines Passwortes oder zum anlegen eines neuen Benutzers oder zum ändern der Rechte eines Benutzers immer der GTID-MODE abgeschaltet werden.
Wenn sich in der DBMS auch MyISAM-Tabellen befinden (und das sind mindestens die Systemtabellen), dann lässt sich ein Dump nur einspielen, wenn die folgenden Punkte gegeben sind:
- die Variable
MASTER_AUTO_POSITIONmuss auf0stehen, damit wir die GTID-Variablen abschalten können; - beide "GTID"-Variablen (
disable_gtid_unsafe_statementsundgtid_mode) müssen deaktiviert sein; - die DB darf nicht im SLAVE-Mode laufen;
… dazu geht man wie folgt vor …
1. Dump vom Master ziehen, zum Beispiel so:
> mysqldump --all-databases --master-data | gzip > dbdump.db.gz
Alle weiteren Schritte werden auf dem Slave ausgeführt, auf dem der Dump eingespielet werden soll.
2. die Variable MASTER_AUTO_POSITION auf 0 setzen:
> echo "STOP SLAVE ; CHANGE MASTER TO MASTER_HOST='master01', MASTER_AUTO_POSITION=0;" | mysql
3. beide "GTID"-Variablen in der my.cnf abstellen:
> sed -i 's/^#disable[_-]gtid[_-]unsafe[_-]statements/disable_gtid_unsafe_statements/;s/^#gtid[_-]mode/gtid_mode/' /opt/mysql/server-5.6/my.cnf
4. die DB restarten, sonst werden die Änderungen nicht aktiviert, denn "gtid-mode" ist leider eine read-only-Variable:
> /etc/init.d/mysql.server restart
5. Dump einspielen:
> echo "STOP SLAVE;" | mysql > zcat dbdump.db.gz | mysql
6. die "GTID"-Variablen in der my.cnf wieder einschalten:
> sed -i 's/^#disable[_-]gtid[_-]unsafe[_-]statements/disable_gtid_unsafe_statements/;s/^#gtid[_-]mode/gtid_mode/' /opt/mysql/server-5.6/my.cnf
7. die DB restarten, sonst werden die Änderungen nicht aktiviert, denn "gtid-mode" ist leider eine read-only-Variable:
> /etc/init.d/mysql.server restart
8. den Slave-Status überprüfen:
> echo "SHOW SLAVE STATUS \G;" | mysql
