MySQL replicatie

Je kan verschillende redenen aanvoeren om serieus gebruik te maken van de replicatie mogelijkheden van MySQL. De belangrijkste reden blijkt in veel gevallen beschikbaarheid en een constante backup te zijn. Maar replicatie kan ook een uitkomst zijn voor performance problemen. In deze stap voor stap handleiding zal ik productie database repliceren op een tweede machine. Alle informatie die ik hier weergeef komt uit de prima online documentatie van MySQl zelf: setup replication.

Replicatie; de concepten.

Om een idee te hebben wat replicatie precies is, het is heel eenvoudig. Je hebt ergens een draaiende database (master), en deze database wordt constant in de gaten gehouden door een tweede database (slave). Wanneer er in de master database een wijziging plaatsvindt, dan wordt dat direct nagedaan op de slave. Dit zorgt ervoor dat er ten alle tijden een exacte kopie van je database beschikbaar is op een tweede machine. Een wijziging is dus elk statement dat fysiek iets wijzigt aan de data die is opgeslagen in je database. Of om het om te keren, alle statements die niet een query zijn worden gedupliceerd naar de slave. Wat we nog meer met deze database kunnen doen, naast het bieden van garantie dat je altijd een volwaardige backup hebt kom ik later over te spreken.

Snapshot nemen en inrichten

Alle begin is moeilijk, en met replicatie blijkt dat ook het geval. Wanneer alles eenmaal draait heb je er zelden omkijken naar, het opzetten kost even iets meer moeite, maar ik denk dat deze moeite zich terugbetaald. Bij de eerstvolgende calamiteit op je database server kan je in ieder geval met een gerust hart denken dat er geen data uit de database verloren is gegaan. We gaan een plan de campagne opstellen, of het verkorte stappenplan. Ik zal voor alles wat we doen de defaults accepteren, verderop zullen we kijken hoe we dit allemaal kunnen verfijnen en controle uitoefenen op wat er wel en wat er niet wordt gerepliceerd. Voorlopig doen we de alles-of-niets methode.

  • Master inrichten
  • Snapshot maken
  • Slave inrichten

Om gebruik te kunnen maken van replicatie is het noodzakelijk dat je binairy logging (mysql-doc) aan hebt staan op de master. Binairy logging is de manier waarop MySQL verkort alle wijzigingen aan de database wegschrijft in een apart bestand. Dit bestand wordt vervolgens door het replicatieproces gebruikt om de wijzigingen ook in de slave database te laten plaatsvinden. De binary logging zet je aan door de database op te starten met de log-bin optie aan. Dit kan door op de command-prompt --log-bin mee te geven, of je neemt

log-bin[=<em>bestandsnaam</em>]
op in je configuratie bestand (my.cnf of mysql.ini). Daarnaast zal je je machine een server-id moeten geven. Ook die schrijven we in ons configuratie bestand:
server-id=1

Je kan nu MySQL herstarten met de nieuwe configuratie, vanaf dan zal elke wijziging aan de database worden weggeschreven in dit bestand (/var/lib/mysql/machinenaam-bin.NNN).
Dan is het zaak om een snapshot te maken. Er bestaan diverse methodes om een snapshot te maken. De methode die hanteer zal de database wel online laten om uit te vragen, maar hij zal op slot staan voor updates. (dat je het maar weet). Vanuit mysql:
flush tables with read lock;

Alle tabellen worden gesloten, en je kan ze niet meer updaten totdat je ze hebt vrijgegeven. Op die manier ben je er zeker van dat de snapshot die je gaat maken geen halve schrijfacties bevat, of verwijzingen naar niet betsaande records. Het snapshot nemen we vanaf de command prompt (linux:)
tar -cvzf /tmp/snapshot.tar.gz /var/lib/mysql

Let op, je neemt nu werkelijk alles mee, dus ook de gebruikers en rechten. Als je dit niet wilt, dan kan je beter de gedetailleerde handleiding voor 'enkele databases' volgen.
Als dit commando klaar is kunnen we in MySQL de tabellen weer vrijgeven, maar eerst en dat is echt belangrijk moet je de master status uitvragen. De uitkomst daarvan heb je straks nodig om de slave te configureren.
mysql> show master status;
+----------------+----------+---------------------------+------------------+
| File           | Position | Binlog_do_db              | Binlog_ignore_db |
+----------------+----------+---------------------------+------------------+
| nazgul-bin.002 | 14599324 |                           |                  |
+----------------+----------+---------------------------+------------------+
1 row in set (0.05 sec)

Zowel de naam van het binaire logbestand als de positie zijn van cruciaal belang straks. Als je dit hebt opgeschreven, of gecopieerd, dan doe je in mysql:
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

Als laatste gaan we een speciaal replicatie account aanmaken op de master database. Deze gebruiker krijgt enkel 'replicatie' rechten en we kunnen netjes zijn proces volgen. Binnen MySQL kan dat in een statement door
mysql> grant replication slave on *.* to shadow@'<em>slave-machine-naam</em>' identified by 'password';

Slave inrichten

Mocht je dat nog niet gedaan hebben, dan is het nu zaak om mysql op de slave stop te zetten. We gaan de zojuist gemaakte database neerzetten en daarna het configuratie bestand klaar maken. Allereerst gaan de snapshot uitpakken:

tar -xzvf /tmp/snapshot.tar.gz

Dan is het zaak om de bestanden die niet op de slave machine horen weg te halen. Dit zijn master.pid en master-bin.*. En dan de configuratie file aanpassen, de minimale toevoegiing is in dit geval een server-id:
server-id=2

Je kan nu MySQL aanzetten. En dan vanuit MySQl de slave verder configureren:
mysql> CHANGE MASTER TO
    ->     MASTER_HOST='[master hostname]',
    ->     MASTER_USER='[replication username]',
    ->     MASTER_PASSWORD='[replication password]',
    ->     MASTER_LOG_FILE='[recorded log file name]',
    ->     MASTER_LOG_POS=[recorded log offset];

Waarbij je dus wel alle waardes moet vervangen door de waardes die bij jou van toepassing zijn. In de situatie zoals die in de voobeelden is gebruikt is dat dus:
mysql> CHANGE MASTER TO
    ->     MASTER_HOST='nazgul',
    ->     MASTER_USER='shadow',
    ->     MASTER_PASSWORD='password',
    ->     MASTER_LOG_FILE='nazgul-bin.002',
    ->     MASTER_LOG_POS=14599324;

En als dat allemaal is gelukt, dan kan je de slave activeren:
mysql> start slave;

Vanaf dat moment zal de slave gaan beginnen om alle veranderingen die op de master hebben plaatsgevonden ook in zijn eigen database toe te passen. Als er een geruime tijd ligt tussen het nemen van de snapshot en en opzetten van de slave, geen probleem. Alleen zal het wat meer tijd in beslag nemen eerdat de slave volledig bij is.

Je hebt nu een volledig replicerende MySQl configuratie gemaakt. In tijden van nood kan je dus altijd terug vallen op een database die een exacte kopie is van de master database. Een geruststellende gedachte lijkt me zo.

Verfijning

Het kan natuurlijk voorkomen dat je niet alle databases gerepliceerd wilt hebben, maar slechts een paar. Hiervoor bestaan twee verschillende opstart parameters voor MySQL. De eerste methode gaat via het noemen van de databases die je gerepliceerd wilt hebben. Dat doe je door binlog-do-db=databasenaam op te nemen in je configuratiebestand voor alle databases die je gerepliceerd wilt hebben. Dus:

binlog-do-db=nucleus
binlog-do-db=rss
...

Vanaf nu zal MySQL enkel die wijzigingen die plaatsvinden in nucleus of rss opnemen in het binlog, en de andere databases negeren.
Wanneer dit rijtje erg lang zou worden en je eigenlijk slechts een of twee databases niet gerepliceerd wilt zien is het eenvoudiger om via uitsluiting te werken. Dan neem je binlog-ignore-db=databasenaam op in je configuratiebestand. Als je dat doet, dan zal MySQL alle wijzigingen opnemen in het binlog, behalve wanneer ze in het rijtje ignore databases staan.
Je kan zien welke databases gelogd worden in je binlog door in mysql de volgende query te draaien:
mysql> show master status;
+----------------+----------+---------------------------+------------------+
| File           | Position | Binlog_do_db              | Binlog_ignore_db |
+----------------+----------+---------------------------+------------------+
| nazgul-bin.002 | 26381187 | nucleus,rss               |                  |
+----------------+----------+---------------------------+------------------+
1 row in set (0.00 sec)

Op de slave bestaan er nog meer opstart parameters om aan te geven wat wel en/of wat niet gerpeliceerd moet worden. Hiervan gebruik maken biedt als voordeel dat je binairy log op de master alle transacties bevat en niet alleen die van de database die je gerepliceerd wilt hebben.
In dat geval gebruik je opstart variabele replicate-do-db of replicate-ignore-db. Je kan hier zelfs nog verder in gaan door slechts enkele tabellen te repliceren. Een compleet overzicht van alle opstart opties voor mysql replicatie vind je in de documentatie.

previous item: next item:
thank you for watching  Creative Commons License