 Autor: [Tomasz Nowosielski](/autorzy/tomasz-nowosielski) Redaktor naczelny, analityk hostingu · Zweryfikowano Kwiecień 2026

1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  MySQL replikacja master-replica

# MySQL replikacja — konfiguracja master-replica

Opublikowano: 9 kwietnia 2026 · Kategoria: Bazy danych

Replikacja MySQL pozwala automatycznie kopiować dane z serwera master na jeden lub więcej serwerów replica (slave). Zastosowania: wysoka dostępność (HA) — replica przejmuje ruch gdy master padnie, skalowanie odczytu — aplikacja czyta z replik, odciążając mastera, a także backupy bez obciążenia produkcji. Ten artykuł przeprowadzi Cię przez konfigurację od zera.

## Po co replikacja — trzy główne zastosowania

-   **Wysoka dostępność (HA)** — gdy master padnie, możesz ręcznie lub automatycznie (MHA, Orchestrator) promować replikę na nowego mastera. Czas przestoju: minuty zamiast godzin.
-   **Skalowanie odczytu (Read Scaling)** — zapytania SELECT (raporty, listy, API read-only) kieruj na repliki. Master obsługuje tylko zapisy. Dzięki temu jeden zapis generuje dane dla wielu replik obsługujących ruch odczytowy.
-   **Backupy bez blokowania produkcji** — `mysqldump` na replice nie obciąża mastera. Replika może być tymczasowo zatrzymana (`STOP REPLICA SQL_THREAD`) dla spójnego dumpa.

## Typy replikacji: statement vs row vs mixed

Typ

Co zapisuje w binlog

Zalety

Wady

**Statement (SBR)**

Oryginalne zapytanie SQL

Mały rozmiar logów

Niebezpieczny dla NOW(), RAND(), UUID()

**Row (RBR)**

Zmienione wiersze (before/after)

Deterministyczny, bezpieczny

Duże logi przy masowych UPDATE

**Mixed**

SBR gdy bezpieczne, RBR gdy konieczne

Kompromis

Trudniejsza analiza logów

MySQL 8+ domyślnie używa **Row-based replication** — jest bezpieczniejszy i zalecany dla nowych instalacji.

## Konfiguracja mastera — my.cnf

Na serwerze master edytuj `/etc/mysql/mysql.conf.d/mysqld.cnf` (lub `/etc/my.cnf`):

\[mysqld\]
# Unikalny identyfikator serwera w topologii replikacji (1 = master)
server-id = 1

# Włącz binary log — WYMAGANE dla replikacji
log\_bin = /var/log/mysql/mysql-bin.log

# Format replikacji (row jest domyślny i zalecany w MySQL 8+)
binlog\_format = ROW

# Opcjonalnie: replikuj tylko konkretne bazy
# binlog\_do\_db = moja\_baza
# binlog\_ignore\_db = information\_schema

# Czas przechowywania binary logów (sekundy) — 7 dni
binlog\_expire\_logs\_seconds = 604800

# Synchronizacja dysku po każdym commicie (bezpieczniej, wolniej)
sync\_binlog = 1
innodb\_flush\_log\_at\_trx\_commit = 1

sudo systemctl restart mysql

# Sprawdź czy binary log działa
mysql -u root -p -e "SHOW MASTER STATUS\\G"

Zapamiętaj wartości `File` i `Position` z SHOW MASTER STATUS — będą potrzebne przy konfiguracji repliki.

## Tworzenie użytkownika replikacji

\-- Na masterze: utwórz dedykowanego użytkownika dla repliki
mysql -u root -p

CREATE USER 'replika\_user'@'10.0.0.11' IDENTIFIED WITH mysql\_native\_password BY 'BezpieczneHaslo123!';
GRANT REPLICATION SLAVE ON \*.\* TO 'replika\_user'@'10.0.0.11';
FLUSH PRIVILEGES;

-- Zrób dump bazy z pozycją binary logu (dla pierwszej synchronizacji)
-- Opcja 1: zablokuj zapisy na czas dumpa
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;   -- zanotuj File i Position!

-- W osobnej sesji (lub po zanotowaniu pozycji):
mysqldump -u root -p --all-databases --master-data=2 > /tmp/dump.sql

-- Odblokuj
UNLOCK TABLES;

## Konfiguracja repliki — my.cnf i CHANGE REPLICATION SOURCE

\# /etc/mysql/mysql.conf.d/mysqld.cnf na REPLICE
\[mysqld\]
# Unikalny ID — inny niż master
server-id = 2

# Replika nie musi mieć binary logu (chyba że to kaskadowa replikacja)
# log\_bin = ...

# Zabezpieczenie — replika nie przyjmuje zapisów bezpośrednio
super\_read\_only = ON

# Opcjonalnie: relay log
relay\_log = /var/log/mysql/mysql-relay-bin.log

sudo systemctl restart mysql

# Zaimportuj dump z mastera
mysql -u root -p < /tmp/dump.sql

# Skonfiguruj połączenie z masterem
mysql -u root -p

CHANGE REPLICATION SOURCE TO
  SOURCE\_HOST = '10.0.0.10',
  SOURCE\_USER = 'replika\_user',
  SOURCE\_PASSWORD = 'BezpieczneHaslo123!',
  SOURCE\_LOG\_FILE = 'mysql-bin.000001',   -- z SHOW MASTER STATUS
  SOURCE\_LOG\_POS = 1234;                  -- z SHOW MASTER STATUS

START REPLICA;

-- Sprawdź status replikacji
SHOW REPLICA STATUS\\G

## SHOW REPLICA STATUS — interpretacja kluczowych pól

Pole

Oczekiwana wartość

Co oznacza problem

`Replica_IO_Running`

Yes

No — problem z połączeniem do mastera (hasło, firewall, sieć)

`Replica_SQL_Running`

Yes

No — błąd SQL przy odtwarzaniu (duplikat klucza, brakująca tabela)

`Seconds_Behind_Source`

0 lub bliskie 0

Duże wartości = replika nie nadąża za masterem

`Last_SQL_Error`

puste

Komunikat błędu SQL — napraw lub pomiń

`Last_IO_Error`

puste

Błąd połączenia — sprawdź dostęp sieciowy i credentials

## Replikacja GTID — lepsza alternatywa

GTID (Global Transaction Identifier) eliminuje potrzebę ręcznego podawania pozycji w binary logu. Każda transakcja ma unikalny ID, replika wie skąd kontynuować po restarcie lub failoverze.

\# Na masterze I replice (my.cnf):
\[mysqld\]
gtid\_mode = ON
enforce\_gtid\_consistency = ON
log\_slave\_updates = ON   # replikuje GTID do binary logu repliki

# Na replice — CHANGE SOURCE bez podawania pozycji:
CHANGE REPLICATION SOURCE TO
  SOURCE\_HOST = '10.0.0.10',
  SOURCE\_USER = 'replika\_user',
  SOURCE\_PASSWORD = 'BezpieczneHaslo123!',
  SOURCE\_AUTO\_POSITION = 1;   -- GTID: replika sama znajdzie pozycję

START REPLICA;
SHOW REPLICA STATUS\\G         -- sprawdź Executed\_Gtid\_Set

Przy GTID: `super_read_only = ON` na replice jest krytyczne — zapobiegnie przypadkowym zapisom które złamałyby sekwencję GTID i wymagały reiniicjalizacji replikacji.

## Typowe błędy i jak je naprawić

\# Błąd: Duplicate entry 'X' for key 'PRIMARY' (Error 1062)
# Przyczyna: wiersz już istnieje na replice (rozbieżność danych)
# Rozwiązanie tymczasowe (pomiń jeden błąd):
STOP REPLICA;
SET GLOBAL sql\_replica\_skip\_counter = 1;
START REPLICA;
-- Lepiej: reinicjalizuj replikację lub napraw dane ręcznie

# Błąd: Access denied for user 'replika\_user'@'10.0.0.11'
# Sprawdź na masterze:
SELECT user, host FROM mysql.user WHERE user = 'replika\_user';
SHOW GRANTS FOR 'replika\_user'@'10.0.0.11';

# Błąd: Slave\_IO\_Running: Connecting (nie Yes)
# Sprawdź czy port 3306 jest dostępny z repliki:
# mysql -h 10.0.0.10 -u replika\_user -p (z serwera repliki)
# Sprawdź firewall: ufw allow from 10.0.0.11 to any port 3306

## Najczęstsze pytania

Czym różni się replikacja statement-based od row-based? +

Statement-based replication (SBR) zapisuje w binary logu oryginalne zapytania SQL (INSERT, UPDATE, DELETE). Row-based replication (RBR) zapisuje faktycznie zmienione wiersze. SBR jest bardziej zwięzły dla zapytań modyfikujących wiele wierszy jednym UPDATE, ale niebezpieczny przy funkcjach niedeterministycznych (NOW(), RAND(), UUID()) — replika może dostać inny wynik niż master. RBR jest bezpieczniejszy i domyślny w MySQL 8+, ale generuje więcej danych w binarnym logu. Mixed (domyślnie przed MySQL 8) używa SBR gdy to bezpieczne, RBR gdy konieczne.

Jak długo może trwać lag replikacji (Seconds\_Behind\_Source)? +

Seconds\_Behind\_Source powinien być bliski 0 przy normalnym obciążeniu. Lag wzrasta gdy: (1) master ma dużo zapisów a replika nie nadąża z ich odtwarzaniem — rozwiązanie: parallel replication (slave\_parallel\_workers &gt; 1), (2) replika wykonuje wolne zapytania (blokady) — sprawdź SHOW PROCESSLIST na replice, (3) długie transakcje na masterze — replika czeka na ich zakończenie. Przy lag &gt; 60s backupy z repliki mogą mieć nieaktualne dane.

Czym jest GTID i dlaczego jest lepszy niż replikacja pozycyjna? +

GTID (Global Transaction ID) to unikalny identyfikator każdej transakcji w formacie uuid:sequence\_number. Replika śledzi GTID zamiast pozycji w binary logu (file:position). Korzyści: (1) Po failoverze nowa replika automatycznie wie od której transakcji zacząć synchronizację — nie trzeba ręcznie szukać pozycji w logu. (2) Łatwiejszy failover i rekonfiguracja topologii replikacji. (3) Narzędzia jak pt-slave-restart lepiej radzą sobie z błędami. Wada: wymaga włączenia gtid\_mode=ON na wszystkich węzłach jednocześnie.

Jak zresetować błędną replikację bez utraty danych? +

Gdy SHOW REPLICA STATUS pokazuje błąd (Last\_SQL\_Errno): (1) Sprawdź treść błędu (Last\_SQL\_Error) — czy to problem z duplikowanym kluczem, brakującą tabelą itp. (2) Jeśli błąd można pominąć bezpiecznie: STOP REPLICA; SET GLOBAL sql\_replica\_skip\_counter = 1; START REPLICA; (3) Lepiej: napraw przyczynę (np. wstaw brakujący wiersz na replice), a potem START REPLICA. (4) Przy replikacji GTID: możesz pominąć konkretny GTID przez SET GTID\_NEXT = "uuid:N"; BEGIN; COMMIT; SET GTID\_NEXT = "AUTOMATIC";. Nigdy nie pomijaj błędów produkcyjnych blindly — mogą oznaczać rozbieżność danych.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

Tani VPS z dużym dyskiem — idealny do testowania replikacji MySQL master-replica

Duży dysk

[Aktywuj rabat →](/out/contabo)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

home.pl

Hosting z MariaDB i codziennym backupem — dane chronione nawet bez własnej replikacji

Backup included

[Aktywuj rabat →](/out/home-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/home-pl)

LH.pl

Hosting z MySQL 8.0 — dla projektów nie wymagających własnej konfiguracji replikacji

MySQL 8.0

[Aktywuj rabat →](/out/lh-pl)

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/lh-pl)

## Powiązane strony

-   [MySQL slow query log — optymalizacja zapytań](/baza-wiedzy/mysql-slow-query-log)
-   [MariaDB vs MySQL — porównanie](/baza-wiedzy/mariadb-vs-mysql-hosting)
-   [Strategia backupu — 3-2-1](/baza-wiedzy/backup-strategia-hosting)
-   [Redis Sentinel — wysoka dostępność](/baza-wiedzy/redis-sentinel-konfiguracja)
-   [Wszystkie artykuły](/baza-wiedzy/)