MySQLReplication » Cronologia » Versione 26
Simone Piccardi, 24-01-2014 17:30
1 | 1 | japoco romagnoli | h1. Configurare la replicazione di MySQL |
---|---|---|---|
2 | 2 | japoco romagnoli | |
3 | 19 | Simone Piccardi | Occorrono almeno due installazioni indipendenti di MySQL, una macchina deve fare da master, le altre da slave. Inoltre non è possibile per fare da slave per master diversi, questo significa che se si devono replicare database che stanno su macchine diverse, queste dovranno essere replicata su istanze diverse. |
4 | 2 | japoco romagnoli | |
5 | 19 | Simone Piccardi | Prenderemo in considerazione solo il caso elementare di due macchine. Le due istanze devono essere configurate per essere raggiungibili via rete. La replicazione si basa sul configurare il master per creare un log binario con le operazioni che vengono eseguite in scrittura. Lo slave leggendo i file su cui vengono registrate queste operazione le ripete su se stesso per “allinearsi”. |
6 | 2 | japoco romagnoli | |
7 | 19 | Simone Piccardi | h2. Configurazione del Master |
8 | 1 | japoco romagnoli | |
9 | 19 | Simone Piccardi | Il primo passo è la configurarazione del master, per questo occorre modificare il file @/etc/mysql/my.cnf@ per abilitare la connessione via rete e la scrittura del file di log binario. Le modifiche da effettuare prevedono linseremento delle seguenti configurazioni al posto di quelle installate normalmente dal pacchetto Debian di MySQL: |
10 | 5 | japoco romagnoli | |
11 | 3 | japoco romagnoli | <pre> |
12 | [...] |
||
13 | 1 | japoco romagnoli | bind-address = 0.0.0.0 |
14 | 23 | Simone Piccardi | # oppure |
15 | # bind-address = IP.O.NOME.MASTER |
||
16 | 4 | japoco romagnoli | [...] |
17 | 1 | japoco romagnoli | server-id = 1 |
18 | 3 | japoco romagnoli | log_bin = /var/log/mysql/mysql-bin.log |
19 | expire_logs_days = 10 |
||
20 | 6 | japoco romagnoli | max_binlog_size = 100M |
21 | 1 | japoco romagnoli | [...] |
22 | 5 | japoco romagnoli | </pre> |
23 | |||
24 | 23 | Simone Piccardi | (qualora si voglia usare un IP specifico per @bind-address@ invece di quello generico, è in genere preferibile utilizzare un nome a dominio opportunamente risolto invece del valore numerico, il valore di @server-id@ è arbitrario, ma deve essere diverso per tutte le istanze). |
25 | 20 | Simone Piccardi | |
26 | 19 | Simone Piccardi | Qualora si siano fatti tentativi precedenti, per ripartire da zero, è necessario cancellare eventuali vecchi file di log binario, in modo tale che il server crei un log pulito a prova di errore, con: |
27 | 5 | japoco romagnoli | |
28 | <pre> |
||
29 | rm /var/log/mysql/mysql-bin.* |
||
30 | </pre> |
||
31 | |||
32 | 19 | Simone Piccardi | si provveda poi a riavviare il server MySQL, in modo che prenda le nuove configurazioni: |
33 | 5 | japoco romagnoli | |
34 | 1 | japoco romagnoli | <pre> |
35 | 19 | Simone Piccardi | service mysql restart |
36 | 1 | japoco romagnoli | </pre> |
37 | 5 | japoco romagnoli | |
38 | 19 | Simone Piccardi | A questo punto si dovrà impostare MySQL per abilitare un utente con accesso da remoto che possa leggere i log ed eseguire la replicazione, l'utente deve essere definito sul master, e sarà usato dagli slave per connettersi, questo si fa collegandosi con @mysql@ ed eseguendo il codice SQL: |
39 | 6 | japoco romagnoli | |
40 | 1 | japoco romagnoli | <pre> |
41 | 23 | Simone Piccardi | GRANT REPLICATION SLAVE ON *.* TO 'utentereplicazione'@'IP.O.NOME.SLAVE' IDENTIFIED BY 'passwordlungaecomplicata'; |
42 | 1 | japoco romagnoli | FLUSH PRIVILEGES; |
43 | 8 | japoco romagnoli | </pre> |
44 | |||
45 | 19 | Simone Piccardi | Una volta attive le nuove configurazioni occorre trasferire i dati dal master allo slave per l'importazione iniziale. Questi devono essere in uno stato coerente per cui non è possibile eseguire operazioni sul database durante la sincronizzazione iniziale. Pur essendo possibile far eseguire tutta la transazione via rete, per mantenerla in stato coerente questa necessita di mantenere un lock sul database per tutto il tempo impiegato a replicare i dati, che con database popolati significativamente può essere anche molto lungo. |
46 | 8 | japoco romagnoli | |
47 | 19 | Simone Piccardi | Per questo è in genere preferibile fare un dump ad un certo momento e per ripartire dallo stato in cui lo si era fatto. In questo caso il lock è necessario solo per il tempo, in genere molto minore, in cui si crea il dump. Una volta effettuato il dump si potrà rimuovere il blocco e indicare allo slave, una volta importato il dump, di ripartire dal punto in cui questo era stato fatto usando le informazioni registrate sul file di log mantenuto dal master. |
48 | 7 | japoco romagnoli | |
49 | 19 | Simone Piccardi | Per far questo si deve collegarsi sulla CLI di MySQL, selezionare il database da replicare e bloccare le tabelle in scrittura, così da avere uno stato coerente dei dati, con le istruzioni: |
50 | |||
51 | 6 | japoco romagnoli | <pre> |
52 | USE nome_database |
||
53 | FLUSH TABLES WITH READ LOCK; |
||
54 | </pre> |
||
55 | |||
56 | 19 | Simone Piccardi | Si dovrà poi controllare lo stato del master (che ci servirà per stabilire il punto da cui far ripartire la replicazione sullo slave) con il comando @SHOW MASTER STATUS@, questo darà un risultato del tipo: |
57 | 6 | japoco romagnoli | |
58 | <pre> |
||
59 | 1 | japoco romagnoli | mysql> SHOW MASTER STATUS; |
60 | 24 | Simone Piccardi | +------------------+----------+--------------+------------------+ |
61 | | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | |
||
62 | +------------------+----------+--------------+------------------+ |
||
63 | | mysql-bin.000005 | 13955148 | | | |
||
64 | +------------------+----------+--------------+------------------+ |
||
65 | 6 | japoco romagnoli | 1 row in set (0.00 sec) |
66 | 1 | japoco romagnoli | </pre> |
67 | 6 | japoco romagnoli | |
68 | A questo punto, senza chiudere la shell di MySQL (per evitare di perdere il lock sulle tabelle), si effettui il dump del database su un file @.sql@ da trasferire sul server slave con: |
||
69 | 1 | japoco romagnoli | |
70 | 6 | japoco romagnoli | <pre> |
71 | 20 | Simone Piccardi | mysqldump -u root nome_database_da_replicare > dati_database.sql |
72 | 6 | japoco romagnoli | </pre> |
73 | |||
74 | 19 | Simone Piccardi | una volta finita l'esportazione potremo tornare sulla shell di MySQL e sbloccare il lock in lettura con: |
75 | 11 | japoco romagnoli | |
76 | 6 | japoco romagnoli | <pre> |
77 | UNLOCK TABLES; |
||
78 | </pre> |
||
79 | 1 | japoco romagnoli | |
80 | 19 | Simone Piccardi | A questo punto le operazioni sul master sono terminate, la scrittura riprenderà, ma essendo registrata nel log lo slave sarà in grado di ripartire senza problemi utilizzando il punto di partenza indicato dai risultati di @SHOW MASTER STATUS@. |
81 | 1 | japoco romagnoli | |
82 | 16 | japoco romagnoli | |
83 | 19 | Simone Piccardi | h2. Configurazione dello Slave |
84 | 15 | japoco romagnoli | |
85 | 19 | Simone Piccardi | Anche in questo caso occorre riconfigurare il server MySQL, in particolare occorrerà assegnargli un diverso @server-id@ ed inoltre occorrerà spostare @tmpdir@ su una directory il cui contenuto sia garantito in caso di riavvio, in quanto la cancellazione dei file temporanei potrebbe compromettere l'aggiornamento della replicazione. Rispetto al file di configurazione standard occorrerà apportare le seguenti modifiche: |
86 | 1 | japoco romagnoli | |
87 | <pre> |
||
88 | [...] |
||
89 | tmpdir = /var/tmp |
||
90 | [...] |
||
91 | 12 | japoco romagnoli | bind-address = 0.0.0.0 |
92 | 23 | Simone Piccardi | # oppure |
93 | 1 | japoco romagnoli | # bind-address = IP.O.NOME.SLAVE |
94 | [...] |
||
95 | 23 | Simone Piccardi | server-id = 2 |
96 | 6 | japoco romagnoli | log_bin = /var/log/mysql/mysql-bin.log |
97 | expire_logs_days = 10 |
||
98 | 1 | japoco romagnoli | max_binlog_size = 100M |
99 | 24 | Simone Piccardi | replicate_wild_do_table = database_da_replicare.% |
100 | replicate_wild_do_table = altrodb_da_replicare.% |
||
101 | 1 | japoco romagnoli | [...] |
102 | 6 | japoco romagnoli | </pre> |
103 | |||
104 | 23 | Simone Piccardi | (di nuovo qualora si voglia usare un IP specifico per @bind-address@ è preferibile utilizzare un nome a dominio opportunamente risolto invece del valore numerico, ed il valore di @server-id@ è arbitrario, ma deve essere diverso da quello del master e di altri eventuali slave). |
105 | 7 | japoco romagnoli | |
106 | 23 | Simone Piccardi | A questo punto si dovrà rendere effettive le nuovo configurazioni riavviando il server MySQL anche sulla macchina slave: |
107 | |||
108 | 13 | japoco romagnoli | <pre> |
109 | service mysql restart |
||
110 | </pre> |
||
111 | |||
112 | |||
113 | 19 | Simone Piccardi | Per l'importazione iniziale dei dati occorrerà anzitutto creare sullo slave un database con lo stesso nome di quello che vogliamo replicare: |
114 | |||
115 | <pre> |
||
116 | 1 | japoco romagnoli | mysqladmin -u root -p create nome_database_da_replicare |
117 | 7 | japoco romagnoli | </pre> |
118 | 1 | japoco romagnoli | |
119 | a questo punto si potranno caricare i dati dal file con il dump ottenuto sul master con: |
||
120 | 7 | japoco romagnoli | |
121 | 1 | japoco romagnoli | <pre> |
122 | mysql nome_database_da_replicare < dati_database.sql |
||
123 | </pre> |
||
124 | |||
125 | 23 | Simone Piccardi | Si verifichi inoltre che l'utente di replicazione impostato sul master sia effettivamente utilizzabile, per questo basterà effettuare una connessione verso il master con: |
126 | 1 | japoco romagnoli | |
127 | 23 | Simone Piccardi | <pre> |
128 | mysql -h IP.O.NOME.MASTER -u utentereplicazione -p |
||
129 | </pre> |
||
130 | |||
131 | (usando la password impostata in precedenza). |
||
132 | |||
133 | 20 | Simone Piccardi | L'ultimo passo è impostare il server come slave, questo richiede che si usino le credenziali dell'utente creato in precedenza sul master, e che si indichi anche, utilizzando i dati ottenuti dal precedente comando @SHOW MASTER STATUS@, il riferimento da cui partire nei log per proseguire con la relicazione (questo è essenziale perché lo slave possa sincronizzarsi correttamente). Facendo riferimento a quanto ottenuto nel paragrafo precedente si dovrà pertanto eseguire sulla CLI di MySQL la seguente istruzione: |
134 | |||
135 | 1 | japoco romagnoli | <pre> |
136 | 23 | Simone Piccardi | CHANGE MASTER TO master_host='IP.O.NOME.MASTER', master_user='utentereplicazione', |
137 | 21 | Simone Piccardi | master_port=3306, master_password='passwordlungaecomplicata', master_log_file='mysql-bin.000005', |
138 | master_log_pos=13955148; |
||
139 | 1 | japoco romagnoli | START SLAVE; |
140 | 17 | japoco romagnoli | </pre> |
141 | 1 | japoco romagnoli | |
142 | 21 | Simone Piccardi | dove appunto mysql-bin.000005 e 13955148 sono rispettivamente il file di log e la posizione riportati da @SHOW MASTER STATUS@. |
143 | 11 | japoco romagnoli | |
144 | 20 | Simone Piccardi | Fatto questo si potrà controllare lo status dello slave da MySQL con il comando, e verificare che questo venga aggiornato in corrispondenza a quanto ottenuto con @SHOW MASTER STATUS@: |
145 | |||
146 | 17 | japoco romagnoli | <pre> |
147 | 25 | Simone Piccardi | SHOW SLAVE STATUS \G; |
148 | 17 | japoco romagnoli | </pre> |
149 | 11 | japoco romagnoli | |
150 | 17 | japoco romagnoli | |
151 | 20 | Simone Piccardi | h2. Trasformare lo slave in master |
152 | 1 | japoco romagnoli | |
153 | 20 | Simone Piccardi | Volendo cambiare il nostro server slave nel nuovo master su cui indirizzare i servizi che appoggiano sul database mysql replicato si deve prima di tutto andare a cambiare il file @/etc/mysql/my.cnf@ controllando che siano abilitate le opzioni di @log-bin@ e disabilitato tutto quello che riguarda i log del tipo @slave-updates@. Si deve anche verificare che il @bind-address@ sia effettivamente impostato su @0.0.0.0@ permettendo così il raggiungimento della macchina dalla rete: |
154 | |||
155 | 17 | japoco romagnoli | <pre> |
156 | [...] |
||
157 | bind-address = 0.0.0.0 |
||
158 | [...] |
||
159 | 1 | japoco romagnoli | log_bin = /var/log/mysql/mysql-bin.log |
160 | 17 | japoco romagnoli | expire_logs_days = 10 |
161 | max_binlog_size = 100M |
||
162 | 1 | japoco romagnoli | [...] |
163 | 17 | japoco romagnoli | </pre> |
164 | |||
165 | A questo punto, entrando in MySQL, si può fermate il server slave e reimpostarlo come nuovo master: |
||
166 | |||
167 | <pre> |
||
168 | STOP SLAVE; |
||
169 | RESET MASTER; |
||
170 | 18 | japoco romagnoli | </pre> |
171 | 1 | japoco romagnoli | |
172 | 26 | Simone Piccardi | Volendo reimpostare l'ormai defunto master nel nuovo slave che replichi il nuovo master, dovremo ... |
173 | 1 | japoco romagnoli | |
174 | 26 | Simone Piccardi | da finire |
175 | |||
176 | h2. Riallineare uno slave |
||
177 | 25 | Simone Piccardi | |
178 | Qualora la replicazione si sia interrotta (cosa che può accadere se ad esempio l'istanza replicata resta ferma per un numero di giorni superiore a quello indicato dalla direttiva @expire_logs_days@) si può effettuare un riallineamento manuale della stessa. La procedura è simile a quella della impostazione iniziale, occorre infatti ripetere un sottoinsieme dei passi. |
||
179 | |||
180 | La prima fase è quella di ottenere, con la stessa procedura descritta in precedenza, un dump dell'istanza principale conoscendo lo stato del master in quel momento: occorrerà pertanto selezionare il database, bloccarne le tabelle con @FLUSH TABLES WITH READ LOCK;@ ed ottenere lo stato corrente del master con @SHOW MASTER STATUS;@ segnandosi i numeri del file di log e dlla posizione corrente mentre al contempo, senza uscire dalla shell di @mysql@ per mantenere il lock sulle tabelle, si eseguirà il dump del database. |
||
181 | |||
182 | Una volta eseguito il dump si potrà rilasciare il lock (o esplicitamente con @UNLOCK TABLES@ o abbandonano la shell). Dopo di che, copiato il dump sull'istanza slave lo si potrà reimportare elimanando i dati correnti. In questo caso si dovrà preventivamente bloccare la replicazione con il comando: |
||
183 | |||
184 | <pre> |
||
185 | STOP SLAVE; |
||
186 | </pre> |
||
187 | |||
188 | e poi eseguire il caricamento dei dati allo stato noto con: |
||
189 | |||
190 | <pre> |
||
191 | mysql nome_database_da_replicare < dump_del_database.sql |
||
192 | </pre> |
||
193 | |||
194 | e a questo punto basterà ricollegarsi all'istanza secondaria e ripetere una istruzione @CHANGE MASTER@ identica a quella già illustrata usando il file di log e la posizione segnata in precedenza, infine si farà ripartire la replicazione con: |
||
195 | |||
196 | <pre> |
||
197 | START SLAVE; |
||
198 | </pre> |
||
199 | |||
200 | e si potrà controllare che tutto sia a posta con @SHOW SLAVE STATUS \G;@ verificando che la replicazione sti aggiornando i dati della posizione del master. |