MySQL/PostreSQL szerver költöztetése leállás nélkül

Magas SLA-val üzemeltetett rendszereknél előfordulhat, hogy úgy kell adatbázisokat költöztetni két szerver között, hogy egyáltalán ne legyen leállás, vagy legalábbis pár percnél több kiesés semmiképp se fordulhasson elő.

Manapság a sokszorosan redundáns felhős rendszerek világában ez általában nem szokott problémát okozni, de előfordulhat, hogy pl. egy régebbi (fizikai) vasról szeretnénk egy másik, újabb vasra költöztetni adatbázisokat nagy tételben - erre a helyzetre remek megoldás, ha egy ad-hoc replikációt hozunk létre a forrás- és célszerver között.

A MySQL ilyen jellegű konfigurálásáról már számtalan leírás született, így ezt most nem fejteném ki bővebben, itt egy jól összeszedett, lényegre törő HOWTO-t a témában:

https://plusbryan.com/mysql-replication-without-downtime

A replikáció beállítását követően folyamatosan szinkronban lesz a régi (master) és új (slave) szerver, így szabadon időzíthető a migráció, akár napokkal, hetekkel későbbre is be lehet ütemezni.

Ennek a megoldásnak az előnyei:

  • Nem jár leállással – a kezdeti dump-restore-t a master és a slave között csak a táblák lockolásával lehet adatvesztés nélkül megcsinálni – ennél a megoldásnál erre nincs szükség
  • Be lehet állítani meglévő mysql instance-ekre is
  • Ha a slave-en vannak már DB-k, azok érintetlenül maradnak, és tudnak tovább működni read-write módban
  • Replikáció aszinkron módon – ha változás van a masteren, azt nem muszáj azonnal frissíteni a slave-re, ha épp nem elérhető (pl. újraindítás, frissítés vagy akármi más miatt).
  • A szerverek közti adatmigrálást nagyban megkönnyíti – ezzel a megoldással minden DB és user automatikusan tükrözve lesz a slave-re, átálláskor pedig csak le kell állítani a master-t és előléptetni a slave-et, ez másodpercek kérdése

Az átálláskor az alábbi parancsokat kell csak lefuttatni:

MASTER-en:

mysql> FLUSH LOGS;

Ha ez lefutott, le lehet állítani a szervert:

# /etc/init.d/mysql stop

SLAVE-en:

mysql> STOP SLAVE;
mysql> RESET MASTER;
mysql> CHANGE MASTER TO MASTER_HOST='';

# /etc/init.d/mysql restart

És készen is vagyunk! A slave szerver innentől master módban üzemel, így ettől a ponttól read-write módban használhatók a költöztetett adatbázisok.

Ugyanezt PostgreSQL-nél is megtehetjük, igaz, itt verziótól függően előfordulhat, hogy kicsit nehezebb dolgunk lesz, ha vannak már meglévő adatbázisok az új szerveren:

https://www.digitalocean.com/community/tutorials/how-to-set-up-master-s…

A 9.4-es postgres ugyanis még nem tud DB-szinten replikálni, így a slave szerveren lévő DB-knek mindenképp read-only módban kell üzemelnie.

Ezt úgy lehet kiküszöbölni, hogy létrehozunk egy új cluster-t a slave-en, ami mondjuk az 5433-as porton figyel, és erre állítjuk be a replikációt az éles cluster (5432-es port) helyett.

A migráláskor csak annyi lesz a teendőnk, hogy a master-en leállítjuk a postgres-t, majd a slave-et előléptetjük master-ré:

MASTER-en:

# /etc/init.d/postgresql stop

SLAVE-en:

# touch /var/lib/postgres/9.4/postgres/(trigger-file-neve) (lásd "trigger_file" paraméter a recovery.cf fájlban)

Ezt követően már csak az 5432-es porton figyelő, éles clusterben lévő DB-ket kell az 5433-as porton figyelő cluster-be átmozgatni, majd a portszámokat megcserélni a két cluster-nél és készen is vagyunk!

Persze, ha sok meglévő DB van a célszerveren, akkor ez növelni fogja a kiesés időtartamát, de jó eséllyel ez mindenképp rövidebb időt jelent mint egy teljes dump-restore futtatása a két szerver között.

Hozzászólások

Regi postgresek ujra koltoztetesehez meg ajanlanam a slony-t.

"leállás nélkül"
vs
"/etc/init.d/mysql restart"
"majd a portszámokat megcserélni a két cluster-nél " (mert ez ugye leállással jár)

Ez valahogy nem jött össze.