Replikace MySQL do Synology NAS

Máte server nebo web s MySQL databází, záložní disky v Synology NAS a chcete vytvořit zálohu databáze? Stačí server a NAS nastavit pro Master – Slave replikaci a vše bude fungovat automaticky.

Master-Slave replikace funguje tak, že Slave (záloha) se pravidelně (každých pár sekund) připojí k Masteru (hlavní server s databází) a stáhne si seznam změn. Ty pak zapíše do vlastní databáze. Slave má tak vždy přesnou kopii hlavní databáze bez toho, aby se kopírovala všechna data.

Konfigurace Master-Slave

První krok je potřeba udělat na hlavním serveru, kde běží MySQL. Pokud to je server provozovaný hostingem bez přímého přístupu, musíte požádat jejich technickou podporu, aby provedla potřebná nastavení. Musíte totiž povolit tzv. binární log. To je soubor, do kterého bude server ukládat všechny změny dat, které provedl, a který si pak Slave servery budou stahovat. V souboru my.ini najděte sekci [mysqld] (všimněte si „d“ na konci!) a přidejte do ní:

[mysqld]
log-bin=mysql-bin
server-id=1

Server ID musí být unikátní v rámci celé Master-Slave sítě (pokud chcete zálohovat více serverů nebo mít více záložních kopií). Moje doporučení je použít stejné číslo jako je IP serveru (např. pro server 192.168.10.250 použijte server-id=10250). Po změně ID je potřeba restartovat server nebo MySQL démona (MySQL službu na Windows).

Pokud zrovna nemůžete server restartovat (což je u produkčního serveru pochopitelné), můžete dočasně nastavit server ID pomocí SQL proměnné:

mysql> SET GLOBAL server_id=1

Tímto způsobem nastavíte hodnotu okamžitě, ale bude platná jen do příštího restartu démona nebo služby – proto musíte mít hodnotu uloženou v my.ini, aby se po restartu automaticky sama znovu nastavila.

Stejnou změnu pak musíte provést i na každém Slave serveru. Pokud je Slavem Synology NAS s DSM 6.0+ systémem, musíte na něm nejprve povolit SSH (nebo Telnet), což provedete v Ovládacím panelu (po přihlášení do DSM jako správce) pod Terminál – Povolit službu SSH (nebo Telnet). Pokud se připojujete z Linuxu nebo MacOS, povolte SSH, pro připojení z Windows povolte Telnet. Pokud máte Windows 8 nebo starší, budete muset Telnet povolit i na vašem počítači (Ovládací Panely – Programy a funkce – Zapnout funkce systému – Klient Telnet).

Jako další krok musíte do NAS nainstalovat MySQL databázi. Ta je dostupná v aplikaci Centrum balíčků jako „MariaDB 10“. Po její instalaci ještě můžete nainstalovat balíčky „Web Station“, „PHP 5.6“ a „PhpMyAdmin“, abyste mohli databázi spravovat přes prohlížeč (samozřejmě je to možné i přes SSH nebo Telnet konzoli pomocí příkazu „/usr/local/mariadb10/bin/mysql„). Důležitým krokem je zakázat automatické aktualizace balíčku „MariaDB“. Za prvé s každým updatem se vymaže nastavení v souboru my.cnf, takže přestane fungovat replikace a za druhé se s updatem může začít DB chovat jinak, což může být nežádoucí bez správného otestování. Jděte tedy do Centra balíčků, otevřete MariaDB 10 a zrušte zaškrtnutí „Automaticky aktualizovat“. V případě, že disky přesunete do jiného Synology NAS (migrace disků), budete muset opravit všechny balíčky, čímž se konfigurace také vymaže!

Až bude vše nainstalováno, připojte se k NAS (v příkazovém řádku „ssh 192.168.10.100“ nebo „telnet 192.168.10.100„, kde IP je adresa NAS). Jako přihlašovací jméno zadejte „admin“ a jako heslo použijte to, kterým se přihlašuje správce DSM. Následně zadejte příkaz „sudo -i„, čímž se přepnete na uživatele root (znovu zadejte heslo administrátora NAS).

Teď můžete nastavit databázi jako Slave, což provedete v souboru „/usr/local/mariadb10/etc/mysql/my.cnf. Zadejte příkaz:

sudo vi /usr/local/mariadb10/etc/mysql/my.cnf

Až se soubor otevře, stiskněte klávesu „i“ (insert mode), najděte sekci [mysqld] a přidejte „server-id=2“ (nebo vámi zvolené číslo).

Update: Nově můžete vkládat vlastní konfiguraci do souboru  /var/packages/MariaDB10/etc/my.cnf, který se následně vkládá do výše uvedeného souboru. Výhoda tohoto souboru by měla být v tom, že se nesmaže při updatu balíku MariaDB. Soubor ale nemusí existovat, takže může být potřeba použít příkaz pro vytvoření souboru:

sudo vi /var/packages/MariaDB10/etc/my.cnf

Následně stiskněte „i“ (insert mode) a zadejte do prázdného souboru:

[mysqld]
server-id=2

Následně stiskněte ESC, pak „:“ (dvojtečka, na české klávesnici SHIFT + klávesa „.:>“ vpravo dole), zadejte „wq“ (Write and Quit) a stiskněte ENTER. Pro restart MySQL se přihlašte do DSM a buď restartuje celý NAS (ikona uživatele vpravo nahoře) nebo zastavte a zase spusťte balíček „MariaDB 10“. Alternativně můžete hodnotu dočasně nastavit SQL příkazem (viz výše):

mysql> SET GLOBAL server_id=2

Alternativně k výše uvedeným postupům můžete nastavit persistentní proměnnou, která vydrží i po restartu serveru, aniž by bylo potřeba ji zapisovat do konfiguračního souboru (nevím ale, v jakých verzích MySQL je podporována):

mysql> SET PERSIST server_id=2

Další možnost zápisu globální nebo persistentní proměnné (pokud předchozí nefunguje) je:

mysql> SET @@global.server_id=2
mysql> SET @@persist.server_id=2

Nyní musíte na Master serveru vytvořit uživatele, pomocí jehož jména a hesla se bude Slave připojovat. V PhpMyAdmin Mastera klikněte na Server – Uživatelské účty (nesmí být vybrána žádná Databáze) a pak Přidat uživatele. Zadejte jméno (např. „slave“) a pod Název počítače zadejte IP adresu Slave serveru (vlastně to není potřeba, ale zvýší to bezpečnost). Nakonec zadejte nějaké bezpečné heslo a dole pod Globální oprávnění zaškrtněte „RELOAD“, „REPLICATION CLIENT“ a „REPLICATION SLAVE“. Klikněte na Proveď. Následně klikněte v seznamu uživatelů na „Upravit oprávnění“ u právě vytvořeného uživatele, nahoře klikněte na tlačítko Databáze (vedle Globální) a vyberte databáze, které má Slave zálohovat. Klikněte na Proveď a zaškrtněte „SELECT“, a „LOCK TABLES“. Pokud máte v databázi nějaké pohledy a události, ještě zaškrtněte „SHOW VIEW“ a/nebo „EVENT“. Pak klikněte na Proveď. To samé provedete přes příkazovou řádku pomocí:

mysql> CREATE USER 'slave'@'192.168.10.10' IDENTIFIED BY 'heslo';
mysql> GRANT RELOAD, REPLICATION CLIENT, REPLICATION SLAVE, SELECT,
          LOCK TABLES ON *.* TO 'slave'@'192.168.10.10';

Zkopírování dat z Master do Slave

Další krok budeme opět provádět přes SSH/Telnet Slave serveru. Po připojení se přepněte do domovské složky (příkaz „cd ~“; v 99% už tam budete, ověřte to příkazem „pwd„) a stáhněte si zálohu databáze Master serveru příkazem:

> /usr/local/mariadb10/bin/mysqldump -h192.168.10.250 -uslave -p -P3306 --master-data=1 --databases db1 db2 > master_dump.sql

V příkazu jsou parametry, kde -h určuje IP adresu Master serveru, -u je jméno uživatele vytvořeného v předchozím kroku a -P je port, na kterém běží MySQL na Master serveru (jelikož MariaDB od Synology má zakódovaný výchozí port 3307, zatímco většina MySQL běží na 3306, musíte ho uvést). Parametr -p pak říká, že chcete zadat heslo, ale nechcete ho psát do příkazového řádku. Parametr --master-data=1 vynutí vytvoření zálohy pro slave replikaci a za parametrem --databases je výčet všech databází, které má Slave zálohovat (jsou to ty, ke kterým jste mu v předchozím kroku dávali práva). Poslední parametr za ‚>‚ určuje jméno souboru, do kterého se dočasně uloží záloha Master serveru. Po spuštění příkazu zadejte heslo pro daný účet a pak počkejte. V závislosti na velikosti databáze a rychlosti sítě může export trvat i desítky minut.

Až bude záloha vytvořena, zadejte příkaz:

> /usr/local/mariadb10/bin/mysql -uroot -p < master_dump.sql

Tím do databáze naimportujete všechny tabulky z Master a zároveň nastavíte pozici v binárním logu (díky předchozímu parametru --master-data=1).

Pokud máte k dispozici pouze export jedné databáze, musíte příkaz upravit:

> /usr/local/mariadb10/bin/mysql -uroot -p db_name < db_export.sql

Import zálohy může opět trvat několik minut, protože NAS nemá tak výkonný procesor a disky jako běžné servery. Pokud chcete mít přehled o tom, jak import probíhá, přidejte parametr -v (verbose):

> /usr/local/mariadb10/bin/mysql -uroot -v -p < master_dump.sql

nebo

> /usr/local/mariadb10/bin/mysql -uroot -v -p db_name < db_export.sql

Počítejte ale s tím, že výpis prováděných příkazů může zpomalovat komunikaci se serverem, protože bude muset vlastně celý exportovaný soubor přenést do vašeho počítače.

Pokud se vám zobrazí chyba „… you have a running slave„, pravděpodobně jste již zkusili spustit slave službu. Přihlaste se tedy do MySQL a zadejte příkaz „STOP SLAVE;“ (nezapomeňte ukončit středníkem):

> /usr/local/mariadb10/bin/mysql -uroot -p
mysql> STOP SLAVE;

Spuštění replikace

Další příkazy již můžete provádět přes PhpMyAdmin nebo přes konzoli (po zadání příkazu „> /usr/local/mariadb10/bin/mysql -uroot -p„). Pokud jste nainstalovali balíček „PhpMyAdmin“, můžete ho spustit zástupcem z nabídky aplikací v DSM nebo na adrese http://192.168.10.10/phpMyAdmin, kde IP je adresa NAS serveru. (Pozor, balíček PhpMyAdmin vždy běží na Nginx, i pokud nainstalujete a nastavíte Apache nebo jiný serverový engine!).

Zadejte SQL příkaz:

CHANGE MASTER TO
         MASTER_HOST='192.168.10.250',
         MASTER_USER='slave',
         MASTER_PASSWORD='heslo'
         ;

Parametr MASTER_HOST je adresa Master serveru a MASTER_USER a MASTER_PASSWORD jsou přihlašovací údaje uživatele, kterého jsme výše vytvořili.

Nyní musíte Slave serveru říct, které databáze má zálohovat, protože ve výchozím stavu posílá Master všechny změny. Pokud máte MariaDB 10, provedete to příkazem:

mysql> SET GLOBAL replicate_do_db = "db1,db2"

Tato změna je (jak je vysvětleno výše) pouze dočasná, takže stejnou hodnotu musíte zapsat i do souboru „/usr/local/mariadb10/etc/mysql/my.cnf“ (také vysvětleno výše) tak, že ji přidáte do sekce [mysqld]:

[mysqld]
replicate_do_db = "db1,db2"

Pokud máte jako Slave MySQL 5.5 a starší, provedete to samé příkazem:

CHANGE REPLICATION FILTER REPLICATE_DO_DB = ('db1', 'db2');

Pokud chcete místo celé databáze zálohovat jen některé tabulky, můžete použít např. SET GLOBAL replicate_wild_do_table = "db%.data_%"; (zálohuje jen tabulky začínající „data_“ z databází jejichž jméno začíná „db„) nebo SET GLOBAL replicate_wild_ignore_table = "db1.tmp_%"; (zálohuje vše kromě tabulek z databáze db1 jejichž jméno začíná „tmp_„). Díky tomu můžete Slave serveru ušetřit práci s kopírováním něčeho, co nepotřebuje zálohu (např. dočasné tabulky, pomocné pohledy, apod.) nebo zálohu rozdělit na více SLAVE serverů pomocí PARTITION principu.

Nakonec zadejte příkaz:

START SLAVE;

Tím jste dokončili konfiguraci a Slave nyní kopíruje všechny změny provedené na Master.

Ověření stavu replikace

Pokud chcete ověřit, že vše běží, jak má, zadejte příkaz:

SHOW SLAVE STATUS;

Pokud zadáváte příkaz přes konzoli, zadejte na konci „\G“ místo středníku, aby se výstup upravil pro lepší čitelnost. Ve výpisu vás zajímají položky Slave_IO_State, který by v 99% případů měl být „Waiting for Master...„, což znamená, že Slave běží a čeká, až Master pošle informaci o změnách. Pokud je stav jiný, podívejte se na položky Slave_IO_Running a Slave_SQL_Running. Pokud mají obě hodnotu „Yes„, znamená to, že Slave běží v pořádku. Pokud je alespoň jedna „No„, znamená to, že Slave neběží a buď nepřijímá změny (Slave_IO_Running=No) nebo je sice přijímá, ale nemůže je zpracovat (Slave_SQL_Running=No). Pak se musíte podívat na Last_Error, Last_IO_Error nebo Last_SQL_Error abyste zjistili, k čemu došlo a proč Slave neběží.

Další položka, která vás zajímá v okamžiku, kdy je Master hodně vytížený a Slave nemusí stíhat kopírovat zálohu, je Seconds_Behind_Master. Pokud je hodnota nulová (0 nebo NULL), znamená to, že Slave obsahuje přesně to samé co Master. Pokud je hodnota vyšší, určuje to počet sekund, o kolik Slave nestíhá za Master (podobně jako třeba při závodech). Pokud toto číslo neustále narůstá, znamená to, že Slave není dostatečně výkonný. Hodnotu ale kontrolujte až po několika hodinách nebo dnech, protože v podobné situaci může prostě dojít k tomu, že přes den, kdy je Master vytížen, nebude Slave stíhat, ale přes noc, kdy zatížení opadne, ho stihne dohnat. Také pozor na to, že ihned po prvním spuštění Slave serveru se tato hodnota nevynuluje a bude ukazovat čas od doby spuštění Master serveru. Na nulu se nastaví až po prvním přijatém příkazu. Se zpožděním souvisí další dvě položky Read_Master_Log_Pos a Exec_Master_Log_Pos, kde první určuje pozici, který se jako poslední načetla z Master a druhá pak pozici, která se naposledy zpracovala. Pokud jsou stejné, je vše v pořádku. Pokud je ale Exec_Master_Log_Pos menší, znamená to, že Slave ještě neprovedl všechny příkazy, které od Mastera přijal. To se může hodit v případě, že potřebujete zjistit, na kterém příkazu se replikace zastavila (je to právě hodnota Exec_Master_Log_Pos).

Pro manuální ověření replikace můžete použít tento postup: v replikované databázi na Masteru vytvořte novou tabulku (např. „replication_test„) s jedním sloupcem (např. „test„), přidejte do ní pár hodnot (třeba 1, 2, 3) a pak pár hodnot vymažte (např. vymažte 2 a ponechte 1 a 3) . Pak se podívejte na Slave server, jestli obsahuje novou tabulku s očekávanými hodnotami (v příkladu to jsou 1 a 3). Pokud je vše jak má, můžete tabulku na Masteru vymazat a pak ověřit, že se smazala i ze Slave serveru.

Pokud používáte cizí klíče (InnoDB), doporučuji ještě jeden test, kdy ověříte, že Slave pracuje s klíči stejně jako Master. Akce vyvolané cizími klíči se totiž nezapisují do binárního logu a každý server je zpracovává po svém. Vytvořte tedy tabulku replication_list se sloupcem id, do které přidejte hodnoty 1, 2, 3 a vytvořte na nich index (např. PRIMARY). Pak vytvořte druhou tabulku replication_ref, do které dejte dva sloupce (např. id a list_id). Na druhém sloupci vytvořte cizí klíč do replication_list.id a nastavíte UPDATE i DELETE na hodnotu CASCADE. Do tabulky replication_ref pak přidejte řádky [1,1], [2,2], [3,3]. Nakonec na Master vymažte hodnotu 2 z tabulky replication_list a ověřte, že Slave server vymazal hodnoty 2 jak z replication_list (akce z binárního logu) tak i z replication_ref (akce vyvolaná cizím klíčem). Pokud je vše v pořádku, na Master nejprve smažte tabulku replication_ref a pak i replication_list.

Nakonec si ukážeme ještě jeden příkaz, který můžete spustit na Master serveru:

SHOW MASTER STATUS;

Tímto příkazem vám Master ukáže aktuální pozici binárního logu, která se skládá ze jména souboru (File) a čísla řádky (Position). Pokud následně na Slave serveru spustíte „SHOW SLAVE STATUS„, musí jeho údaje v položkách Master_Log_File a Read_Master_Log_Pos ukázat stejnou (nebo novější) pozici. Pokud je pozice menší než má Master, buď to znamená, že Slave nestíhá (a pak bude nenulová i Seconds_Behind_Master) nebo že replikace vůbec nefunguje (pokud je Seconds_Behind_Master nula nebo NULL).

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *

Tato stránka používá Akismet k omezení spamu. Podívejte se, jak vaše data z komentářů zpracováváme..