Datenbank-Replikation mit MySQL

Aus HackerWiki

Contents

Datenbank-Replikation mit MySQL

Bitmuncher 13:47, 13. Jun 2006 (CEST)

Im folgenden werde ich beschreiben, wie man eine Datenbank-Replikation mit MySQL einrichtet. Ich gehe dabei davon aus, dass 2 Server genutzt werden, wobei einer davon der Master-Server und einer der Slave-Server ist. Ziel dieses Howtos ist es nicht, zu erklären wie Replikation im Einzelnen funktioniert, sondern lediglich, wie man eine Replikation mit MySQL einrichet.

Diese Anleitung ist nur für Linux- und Unix-Systeme gültig. Grundkenntnisse in SQL und im Umgang mit Linux/Unix setze ich einfach mal voraus.

Installation der Software

Natürlich benötigen wir auf beiden Servern zuerst einmal eine MySQL-Datenbank. Hier wollen wir die aktuelle MySQL 4.1.x benutzen. Wir laden uns also die Quelltexte runter und entpacken sie nach /usr/src/. Danach wechseln wir nach /usr/src/mysql-4.1.x und konfigurieren die Quelltexte.

bash# cd /usr/src/mysql-4.1.x
bash# ./configure --prefix=/usr/local/mysql --with-ndbcluster \
--with-blackhole-storage-engine --with-csv-storage-engine \
--with-archive-storage-engine --with-berkeley-db --with-isam --with-big-tables \
--with-openssl --with-vio --with-mysqlfs --with-mysqld-user=mysql --with-gnu-ld \
--enable-assembler --enable-local-infile --enable-thread-safe-client \
--enable-dependency-tracking --datadir=/home/mysql --sysconfdir=/etc

Nun kompilieren und installieren wir MySQL

bash# make
bash# make install

Jetzt müssen wir nur noch die Rechte setzen und das Start-Skript an die richtige Stelle kopieren. Ausserdem benötigen wir die Default-Datenbanken 'mysql' und 'test'.

bash# cp support-files/mysql.server /etc/init.d/
bash# chmod ug+x /etc/init.d/mysql.server
bash# cd /usr/local/mysql
bash# mkdir data
bash# groupadd mysql
bash# useradd -g mysql mysql
bash# passwd mysql
bash# chown -R mysql:root ./
bash# chown -R mysql:mysql data
bash# cd /usr/src/mysql-4.1.x
bash# scripts/mysql_install_db --user=mysql --datadir=/usr/local/mysql/data

Diese Prozedur müssen wir auf beiden Servern durchführen!

Konfiguration des Master-Servers

Nachdem wir auf beiden Servern die Software installiert haben, können wir uns nun der Konfiguration des Master zuwenden. Hierzu legen wir uns in /etc/ die Datei my.cnf an, die wir mit folgendem Inhalt füllen (natürlich müssen Datenbank-Namen, IPs sowie Usernamen und Passwörter an die gegebenen Bedingungen angepasst werden).

[client]
# hier koennen wir die Default-Werte nutzen

[mysqld]
datadir=/usr/local/mysql/data
set-variable    = key_buffer=128M
set-variable    = max_allowed_packet=1M
set-variable    = table_cache=512
set-variable    = sort_buffer=2M
set-variable    = record_buffer=2M
set-variable    = thread_cache=4

# replication stuff
# we're using bin-logs
log-bin
binlog-do-db=replication1
# this is our master
server-id       = 1

[safe_mysqld]
err-log=/usr/local/mysql/data/mysqld.log

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[isamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M

[myisamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

Die Speichergrössen sollte man natürlich dem Server entsprechend anpassen. Nachdem wir das Ganze gespeichert haben, können wir nun unseren Master mit

/etc/init.d/mysql.server start

starten. Sollte es Probleme geben, sollte man die Error-Logs in /usr/local/mysql/data/ durchschauen und den Fehler entsprechend beheben.

Zu guter Letzt setzen wir noch ein Root-Passwort und legen einen User für unseren Slave-Server an. Damit wir nicht jedes Mal den kompletten Pfad zu den MySQL-Binaries angeben müssen, tragen wir entweder /usr/local/mysql/bin in unsere PATH-Umgebungsvariable ein oder verlinken sie (wie im folgenden) nach /usr/local/bin/, das eigentlich bei den meisten Systemen im PATH stehen sollte.

bash# ln -s /usr/local/mysql/bin/* /usr/local/bin/
bash# mysqladmin -u root password 'secret'
bash# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 30 to server version: 4.1.18-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CREATE DATABASE replication1;
mysql> GRANT REPLICATION SLAVE ON *.* TO 'slave_user'@'%' IDENTIFIED BY '<some_password>';
mysql> FLUSH PRIVILEGES;

Damit ist die Einrichtung des Master-Servers abgeschlossen.

Konfiguration des Slave-Server

Auch auf dem Slave-Server benötigen wir im Verzeichnis /etc/ die Datei my.cnf. Allerdings sieht diese etwas anders aus.

[client]
# hier koennen wir die Default-Werte nutzen

[mysqld]
datadir=/usr/local/mysql/data
set-variable    = key_buffer=128M
set-variable    = max_allowed_packet=1M
set-variable    = table_cache=512
set-variable    = sort_buffer=2M
set-variable    = record_buffer=2M
set-variable    = thread_cache=4

# replication stuff
# we're using bin-logs
log-bin
# this is our slave
server-id       = 2
master-host=<IP des Master-Servers>
master-user=slave_user
master-password=<Passwort von slave_user>
master-connect-retry=60
replicate-do-db=replication1

[safe_mysqld]
err-log=/usr/local/mysql/data/mysqld.log

[mysqldump]
quick
max_allowed_packet = 16M

[mysql]
no-auto-rehash
# Remove the next comment character if you are not familiar with SQL
#safe-updates

[isamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M

[myisamchk]
key_buffer = 20M
sort_buffer_size = 20M
read_buffer = 2M
write_buffer = 2M

[mysqlhotcopy]
interactive-timeout

Nun können wir auch unseren Slave-Server starten.

bash# /etc/init.d/mysql.server start

Sollten hierbei Fehler auftauchen, helfen uns wieder die Log-Dateien aus /usr/local/mysql/data/ weiter. Wie auch auf dem Master müssen wir natürlich auch hier wieder ein Passwort für root setzen und die Datenbank anlegen, die wir replizieren wollen.

bash# ln -s /usr/local/mysql/bin/* /usr/local/bin/
bash# mysqladmin -u root password 'secret'
bash# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 30 to server version: 4.1.18-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> CREATE DATABASE replication1;

Sollten sich auf dem Master-Server schon Daten in der Datenbank befinden, sollten diese nun per Dump auf den Slave-Server übertragen werden.

Achtung: Auf dem Master-Server sollten während der Konfiguration des Slave keine Schreibzugriffe auf die zu replizierende(n) Datenbank(en) stattfinden!

Nun legen wir für den Slave-Server fest, wie er auf das Binlog des Master zugreifen kann. Dazu müssen wir aber wissen, an welcher Stelle der Master im Binlog ist. Wir loggen uns also zuerst nochmal im Master ein.

bash# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 30 to server version: 4.1.18-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> SHOW MASTER STATUS;
+----------------------+----------+------------------------+------------------+
| File                 | Position | Binlog_Do_DB           | Binlog_Ignore_DB |
+----------------------+----------+------------------------+------------------+
| master-bin.000005    |      758 | replication1           |                  |
+----------------------+----------+------------------------+------------------+
1 row in set (0.00 sec)

mysql>

Wir wissen nun, an welcher Position sich der Master im Binlog befindet und welche Binlog er gerade nutzt und können dies entsprechend unserem Slave-Server bekannt geben, dazu wechseln wir also wieder auf den Slave-Server.

bash# mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 30 to server version: 4.1.18-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> SLAVE STOP;
mysql> CHANGE MASTER TO MASTER_HOST='<IP des Master>', MASTER_USER='slave_user',
  > MASTER_PASSWORD='<Password von slave_user>', 
  > MASTER_LOG_FILE='master-bin.000005', MASTER_LOG_POS=758; 
mysql> START SLAVE;

Und damit ist unsere Einrichtung einer replizierten Datenbank auch schon abgeschlossen. Die Datenbank 'replication1' sollte in Zukunft auf beiden Servern immer identisch sein. Dies kann man sehr einfach überprüfen, indem man einfach mal auf dem Master in der Datenbank 'replication1' eine Tabelle anlegt und diese mit ein paar Daten füllt. Normalerweise sollten die Daten dann auch sofort auf dem Slave-Server erscheinen. Ist dies nicht der Fall, helfen die Logdateien von Master und Slave bei der Fehleranalyse.

Nachwort

Dieses kleine Howto soll nicht darüber hinwegtäuschen, dass es sich bei Datenbank-Replikationen um eine komplexe Sache handelt. Hier soll lediglich einmal der Grundablauf für die Neueinrichtung einer Replikation mit MySQL aufgezeigt werden. Für weitere Informationen sollte das MySQL-Replikations-Handbuch zu Rate gezogen werden.

Persönliche Werkzeuge