Efter et stykke tid, vil du sikkert gerne vide om alt bliver replikeret korrekt til din slave og fikse eventuelle forskelle i data mellem master og slave. Her er percona-toolkit et rigtig godt værktøj
Bemærk i nedenstående kodeblokke: Når du ser ordet MASTER i første linie, skal blokken eksekveres på din master server, og vise versa når der står SLAVE.
Indholdsfortegnelse
Installér percona-toolkit
Vi skal bruge to værktøjer, nemlig pt-table-checksum og pt-table-sync. Begge tools er tilgængelige i percona-toolkit
1 2 3 4 5 6 |
# MASTER sudo su wget https://repo.percona.com/apt/percona-release_latest.generic_all.deb dpkg -i percona-release_latest.generic_all.deb apt-get update apt-get install percona-toolkit |
Læs evt. også her “Configuring percona repository on Debian and Ubuntu”
Tjek data med pt-table-checksum
Opret en checksum bruger
Opret en bruger til formålet. Denne bruger vil også blive brugt til at forbinde til din slave. Hvis du ikke replikerer mysql databasen, skal du derfor huske at oprette denne bruger både på master og slave. Bemærk at jeg opretter brugeren med ‘10.0.0%’ og ‘localhost’ for at sikre den kun kan opnå adgang fra det interne net:
1 2 3 4 5 6 |
/*MASTER [OG SLAVE] */ GRANT REPLICATION SLAVE,REPLICATION CLIENT,PROCESS,SUPER, RELOAD, SELECT, INSERT, UPDATE ON *.* TO `pt_checksum`@'10.0.0%' IDENTIFIED BY 'checksum_password'; GRANT ALL PRIVILEGES ON percona.* TO `pt_checksum`@'10.0.0%'; GRANT REPLICATION SLAVE,REPLICATION CLIENT,PROCESS,SUPER, RELOAD, SELECT, INSERT, UPDATE ON *.* TO `pt_checksum`@'localhost' IDENTIFIED BY 'checksum_password'; GRANT ALL PRIVILEGES ON percona.* TO `pt_checksum`@'localhost'; FLUSH PRIVILEGES; |
Man kan sagtens give privilegier til en database der ikke er oprettet endnu. Databasen Percona oprettes automatisk første gang du afvikler pt-table-checksum.
Husk at replikere Percona databasen
Percona databasen oprettes automatisk af pt-table-checksum og du skal sikre den bliver replikeret. Jeg kom engang til at føje den til bin-ignore-db i masterens konfiguration. Det har den konsekvens at pt-table-checksum hænger i al evighed (indtil du stopper den selv) og spytter denne fejl ud:
1 2 3 4 |
Waiting for the --replicate table to replicate... Waiting for the --replicate table to replicate... Waiting for the --replicate table to replicate... Waiting for the --replicate table to replicate... |
Hvis det sker:
- Slet Percona databasen på masteren
- Fjern Percona fra bin-ignore-db
- Genstart masteren
- Kør pt-table-checksum igen
Brug af pt-table-checksum
Sådan kunne det se ud når du tjekker din replikering for uoverensstemmelser i data mellem master og slave:
1 2 |
#MASTER pt-table-checksum --config master.conf --databases-regex=^firmanavn |
Filen master.conf
ser således ud:
1 2 3 |
user = pt_checksum password = hemmelig-kode host = localhost |
Første gang jeg afprøvede ovennævnte, fik jeg et fantastisk fint resultat. Alt så ud til at være replikeret til slaven… Lige indtil jeg læste en af de første linier:
pt-table-checksum diffs cannot be detected because no slaves were found
Det den fortæller her er, at den ikke kan konstatere forskel i data mellem master og slave, fordi den ganske enkelt ikke kan finde slaven.
Så først skal du sikre dig at pt-table-checksum
kan få information om din slave via din master. Det skal helst se således ud:
1 2 3 4 5 6 7 |
/*MASTER*/ SHOW SLAVE HOSTS; +-----------+-----------+------+-----------+ | Server_id | Host | Port | Master_id | +-----------+-----------+------+-----------+ | 2 | 10.0.0.49 | 3306 | 1 | +-----------+-----------+------+-----------+ |
Hvis SHOW SLAVE HOSTS ikke returnerer noget information, skal du sætte report_host i my.cnf på slaven. Du sætter den til et hostnavn eller ip som kan bruges til at forbinde fra masteren:
1 2 3 |
/*SLAVE*/ STOP SLAVE; FLUSH TABLES; |
1 2 3 4 |
#SLAVE my.cnf: [mysqld] report_host = 10.0.0.49 |
1 2 |
#SLAVE service mysql restart |
1 2 |
/*SLAVE*/ START SLAVE; |
Sådanne… vi prøver pt-table-checksum
igen på masteren. Men ak og ve:
Replica [hostnavn] has binlog_format MIXED which could cause pt-table-checksum to break replication. Please read “Replicas using row-based replication” in the LIMITATIONS section of the tool’s documentation. If you understand the risks, specify –no-check-binlog-format to disable this check.
Og under LIMITATIONS finder vi følgende:
pt-table-checksum requires statement-based replication, and it sets
binlog_format=STATEMENT
on the master, but due to a MySQL limitation replicas do not honor this change. Therefore, checksums will not replicate past any replicas using row-based replication that are masters for further replicas.
Det her er altså kun et problem hvis min slave er “relay” for andre slaver. Det er ikke tilfældet, så jeg skulle roligt kunne tilføje --no-check-binlog-format
:
1 2 |
#MASTER pt-table-checksum --config master.conf --databases-regex=^firmanavn --no-check-binlog-format |
Nå… fejl igen:
Replication filters are set on these hosts: [hostnavn]
slave_skip_errors = 1062,1146
Please read the –check-replication-filters documentation to learn how to solve this problem. at /usr/bin/pt-table-checksum line 9825.
Du kan læse om konsekvenserne ved brug af –no-check-replication-filters her. Det er ikke et problem for mit vedkommende:
1 2 |
#MASTER pt-table-checksum --config master.conf --databases-regex=^firmanavn --no-check-binlog-format --no-check-replication-filters |
… og nu kører den 🙂
I output skal du holde øje med kolonnerne diff og skipped. De skulle gerne være 0 (nul) hele vejen igennem, medmindre der er difference i data mellem master og slave.
Bug i version 3.0.4 – ?
Fra og med pt-table-checksum
version 3.0.4 kan du, såfremt output ikke viser fejl når den burde, være ramt af denne bug:
https://jira.percona.com/browse/PT-1443
Løsningen er at tilføje --set-vars binlog_format=statement
Denne bug var stadig ikke løst sidst jeg tjekkede i september 2020, og eksisterer således stadig i version 3.2.1.
Se yderligere info i mit spørgsmål/svar på StackOverflow: https://stackoverflow.com/questions/4609…
Synkronisér med pt-table-sync
Når du med pt-table-checksum har fundet differencer mellem master og slave, kan du udbedre det med pt-table-sync. Husk at vi her tager udgangspunkt i et simpelt master -> slave setup. Derudover forudsætter eksemplet her, at det er slaven der mangler data i forhold til masteren.
Brug af pt-table-sync
Find et tidspunkt hvor Seconds_Behind_Master
er 0 (nul), hvis det er muligt.
Først beder jeg pt-table-sync om at skrive de sql queries der skal til for at slaven kan føres up-to-date. Jeg udelader --execute
og bruger i stedet --print
. Output skrives til en sql fil så jeg kan vurdere de ændringer pt-table-sync mener der skal til. Derefter kan jeg vælge at eksekvere filen. :
1 2 |
#MASTER pt-table-sync --print --sync-to-master --databases=shop_test,shop_prod h=10.0.0.49, F=./auth.cnf > sync.sql |
Man bør ikke angive brugernavne og adgangskode på kommandolinien, og jeg har derfor disse oplysninger i auth.cnf
som ser således ud:
1 2 3 4 5 |
#SLAVE - auth.cnf [client] user=pt_checksum password=hemmelig-kode host=10.0.0.49 |
Erstat 10.0.0.49
med den interne ip på din slave, eller slavens hostnavn. Erstat pt_checksum
og hemmelig-kode
med dine egne værdier for den bruger du oprettede.
Det kan godt se lidt underligt ud at host angives begge steder, men pt-table-sync insisterer på at der skal angives en host i kommandoen, og host i filen læses af mysql der bruges når data indlæses (Se næste afsnit).
Hvis --databases
udelades vil den medtage alt. Du bør derfor angive de databaser der skal synkroniseres.
Indlæs data på slaven
På slaven kan du nu stoppe synkronisering midlertidigt, mens du indlæser data. Bemærk --default-character-set
som jeg har medtaget fordi databasen i dette tilfælde har latin1 som standard karaktersæt. Uden den parameter vil fejlen “Incorrect string value” opstå når data indlæses.
1 2 3 4 |
#SLAVE mysql --defaults-extra-file=auth.cnf -e "STOP SLAVE;FLUSH TABLES" mysql --defaults-extra-file=auth.cnf --default-character-set='latin1' < sync.sql mysql --defaults-extra-file=auth.cnf -e "START SLAVE" |