MySQL Master-Slave replikáció
MySQL adatbáziskezelő szerver esetén lehetőségünk van replikikációra, azaz az adatokst módosító (beszúrás, update, törlés, stb.) szinte azonnali továbbítására kerülnek egy távoli szerverre is, így az adatokon végzett módosítások ott is végrehajtásra kerülnek.
A megoldás ugyan elég távol áll egy terhelés-eolsztásos clustertől (A master node-ot írni és olvasni is tudjuk, de a slave-et csak olvasni), de ettől haszna még bőven akad:
Egyszerű failover megoldásnak tekinthető: Ha a master szerver elhasal, az adatok gyakorlatilag real time ott vannak a slave-en, csak meg kell neki mondani, hogy Ő mostantól nem slave.
Ha túl sok, vagy túl nagy adatbázisaink vannak, akkor a mysqldump-os megoldás problémás lehet a nagy erőforrásigény, a hosszú mentési idő, és a még hosszabb visszaállítási idő miatt. Ilyen esetben célszerű az adatfájlok közvetlen mentése. Tekintettel arra, hogy a MySQL szerver működése során memóriába pufferel adatokat, ha egy futó MySQL szerver alól kimentjük az adatfájlokat, korántsem biztos hogy minden adat a fájlban lesz, illetve hogy az adatfájl egyáltalán használható lesz egy visszaállítás után. Kézenfekvő a megoldás: slave szerverre replikáljuk az adatokat, majd mentés előtt a slave szervert leállítjuk. Szolgáltatásunk működését ez nem befolyásolja, hisz a kliensek továbbra is a master szerverrel kommunikálnak, a master pedig a binlogban gyűjti, azokat az utasításokat, amelyeket a slave-nek végre kell hajtania, hogy újra az aktuális állapotot tükrözze. A leállított slave adatfájljait ezután gond nélkül menthetjük, majd a mentés végzetével a slave adatbázis szerver ujraindításával minden megy tovább.
A master – slave replikáció megvalósítása:
Tekintettel arra, hogy a replikáció TCP kapcsolaton keresztül megy, így ha a mysql szerverünk úgy van beállítva, hogy csak unix socketeket használjon, konfiguráljuk tcp/ip használatra (my.cnf bind-address = 0.0.0.0), továbbá a tűzfalunkon engedélyezzük a master és slave szerverek közötti kommunikációt a 3306-os porton.
A replikáció működéséhez a “replication slave” jogosultság szükséges. Természetesen a jogosultságot úgy kell felvenni, hogy a slave szerver IP címéről, vagy hostjáról érkező felhasználónak is megfelelő jogosultsága legyen.
Példáinkban feltételezzük, hogy a master szerver IP címe: 192.168.1.100, a slave szerver IP címe pedig 192.168.1.200.
Az első feladatunk, hogy létrehozzunk egy felhasználót a master szerveren, amely rendelkezik a fennt említett “repliaction slave” jogosultsággal.
Csatlakozzunk a master MySQL szerverhez, és hozzuk létre a megfelelő jogosultságú felhasználót:
# mysql -u root -p mysql> grant replication slave on *.* TO repl@"192.168.1.200" identified by 'jelszo'; mysql> quit
Bátrak, és az egyszerű utat kedvelők, természetesen phpMyAdmin segítségével összekattintgathatják a felhasználót.
Következő lépéskét konfiguráljuk a mysql szervert úgy, hogy a modosítást végrehajtó lekérdezésekről készítson ún. binlogot.
Nyissuk meg szövegszerkesztővel a mysql konfigurációs állományát (általában /etc/my.cnf vagy /etc/mysql/my.cnf), és a [mysqld] bejegyzés után ellenőrizzük az alábbi sorok meglétét, illetve ha szükséges, hozzuk létre őket:
log-bin=mysql-bin server-id=1 binlog-ignore-db="mysql"
Ha módosítanunk kellett a konfigurációs állományon, indítsuk újra a MySQL szervert:
/etc/init.d/mysql restart
A replikáció elindításához mind a master, mind a slave adatbázisnak ugyanazokat az adatokat kell tartalmaznia, teljes mértékben meg kell egyzniük.
Ehhez zároljuk a master adatbázist:
flush tables with read lock
és a mysqldump parancs használatával mentsük el a master adatbázis adatait.
mysqldump --all-databases --lock-all-tables >dbdump.db
a dbdump.db-t juttassuk át a slave szerverre és adjuk hozzá a slave mysql szerverhez:
mysql -u root -p < dbdump.sql
Természetesen, ha nem az összes adatbázis replikálását tervezzük, akkor elegendő csak a replikálni kívánt adatbázisok szinkronba hozása, illetve ha nagyon nagyok az adatbázisok, vagy speciális karakterkódolásokat használunk, akkor az adatfájlok átvitelével is megoldhatjuk a kezdeti szinkronizálást. (Ehhez persze a master adatbázist le kell állítanunk!)
Miután a két adatbázis szinkronban van, meg kell tundunk a master adatbázis binlog pozícióját.
A master szerverre bejelentkezve adjuk ki a
show master status
parancsot.
A parancs kimenet valami ilyesmi lesz:
+------------------+--------------------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+--------------------------+------------------+ | mysql-bin.000112 | 79 | | mysql | +------------------+--------------------------+------------------+ 1 row in set (0.00 sec)
Jegyezzük fel a File és a Position mezők értékét. NAGYON fontos, hogy a binlog azt az állapotot tükrözze, amelyet átvittünk a slave-re. Azaz, az adatok átmásolása után azonnal jegyezzük fel a binlog pozícióját, mielőtt bármilyen módosítást végző lekérdezsé lefutna.
Ezzel a master szerveren végzendő módosításokkal megvagyunk, nyissuk meg a slave szerver my.cnf állományát, és a mysqld bejegyzés alatt adjuk hozzá a következő sorokat:
server-id=2 master-host = [MASTER Szerver IP] master-user = [REPLIKACIO USER] master-password = [REPLIKACIO JELSZO] master-port = 3306
A master szerver címe értelemszerű,példánkban 192.168.1.100, a master-user az a felhasználónév, aminek a replication slave jogosultságot megadtuk, a jelszó pedig amit a grant parancsban az identified by után írtunk.
Indítsuk újra a slave szervert, majd jelentkezzünk be, állítsuk be a master szerver binlog fájl nevét, és pozícióját.
# mysql -u root -p mysql> CHANGE MASTER TO MASTER_LOG_FILE='[binlog fajl, korabban leirtuk]', MASTER_LOG_POS=[binlog pos, korabban leirtuk]; mysql> START SLAVE; mysql> SHOW SLAVE STATUS;
A binlog fájl, és a master log pos helyére azokat az értékeket írjuk, amelyeket a show master status parancs kimenetéből lejegyeztünk.
Ha minden sikerült, akkor a show slave status parancs kimenetében a Slave_Io_Status mező értékének Waiting for master to send event-nek kell lennie.
Amennyiben azt látjuk, hogy connecting, vagy egyéb más üzenetet, a syslogból, vagy a mysql log-ból tájékozódhatunk a hiba jellegéről. (többnyire jogosultság probléma).
Kedves Kovix!
Érdekesnek találtam a leírást, viszont pár kérdés felmerült bennem. Elvileg lehet-e több slave szervert is létrehozni vagy csak egyet? Természetesen a master-en létre lennének hozva a felhasználók, külön-külön. Ha csak egy adatbázist akarok szinkronizálni akkor -ha jól értem – a slave szerveren csak azt az adatbázis kell feltöltenem, és utána csak azt szinkronizálja.
Válaszod előre is köszönöm
Szia!
több slave szervered is lehet, az egyetlen megkötés, hogy a server-id-nek a my.cnf-ben mindenhol különböznie kell. (Igazából több master is lehet, de az megér egy külön misét, pl. hogyan lehet elkerülni az autoincrement mezők ütközését, stb.)
Külön felhasználót sem kell feltétlenül létrehozni. Ha azonos privát alhálóban vannak, akkor egy grant replication slave on *.* TO repl@”192.168.1.%” identified by ‘jelszo’; azt jelenti hogy a 192.168.1.0/24-ből bárhonnan jöhet a slave.
Ha csak egy adatbázist szeretnél szinkronizálni, akkor egyrészt elég csak a kérdéses adatbázist szinkronba hozni az elején, másrészt, “meg kell mondani” a mysql szervernek, hogy csak az adott adatbázisra vonatkozó információkat tárolja. (A master küld mindent ész nélkül, kivéve amit a binlog-igonre-db-ben megadunk neki.) Cserébe a binlog_do_db=valami csak a valamiben lévő változásokat írja a binlogba.
A
server-id=2
master-host = [MASTER Szerver IP]
master-user = [REPLIKACIO USER]
master-password = [REPLIKACIO JELSZO]
master-port = 3306
részt egészítsd ki ezzel:
replicate-do-db = valami
és a slave pedig csak azzokkal fog foglalkozni amik a valami.adatbázisra vonatkoznak.
Fontos, hogy a replikáció szempontjából az USE parancs által kijelölt adatbázis a mérvadó.
azaz, ha a replicate-do-db=valami
akkor a
USE valami;
update TABLA1 SET mezo=’xxx’;
replikálódik
de a
USE masikvalami;
update valami.TABLA1 set mezo=’xxx’;
már nem.
erre a replicate-wild-do-table=valami.% való.
Ha nagyon kell, tábla szintre is le lehet menni (replicate-do-table)
Kb ennyi, remélem tudtam segíteni, vagy legalább egy kicsit gondolatébreszteni…
Üdv: KoviX
Szia!
Köszönöm, ez nekem mindenképpen segítség. Még végiggondolom, hogy hogyan lenne a legjobb, aztán nekiugrok
Hálás Köszönettel