Project

General

Profile

MySQLMulti » History » Version 7

Simone Piccardi, 06/06/2016 05:26 PM

1 2 Simone Piccardi
h1. Configurare istanze multiple di MySQL
2 1 Simone Piccardi
3 3 Simone Piccardi
In alcuni casi, ad esempio se si devono gestire una serie di repliche di database diversi su una singola macchina, può essere necessario lanciare più istanze di MySQL. Benché sia possibile duplicare gli script di avvio e la configurazione dell'istanza principale (quella installata e configurata direttamente dal pacchetto), questo comporta anche l'uso di diverse directory e file di configurazione. Ma con MySQL viene distribuito il programma @mysqld_multi@ il cui scopo è proprio quello di lanciare e gestire istanze multiple, utilizzando un solo file di configurazione.
4 1 Simone Piccardi
5 3 Simone Piccardi
Di default il programma usa come configurazione direttamente @/etc/mysql/my.cnf@, ma se si vuole mantenere separata la gestione dell'istanza principale rispetto a quelle gestite tramite @mysqld_multi@ si può fare ricorso ad un file qualunque, da indicare con l'opzione @--defaults-file@, nel nostro caso useremo @/etc/mysql-multi/my.cnf@. Per evitare errori, e semplificarsi la vita nello scrivere i comandi, abbiamo provveduto a definire un alias di shell in @.bashrc@ nella forma:
6 3 Simone Piccardi
7 3 Simone Piccardi
<pre>
8 3 Simone Piccardi
alias mysqld_multi='mysqld_multi --defaults-file=/etc/mysql-multi/my.cnf'
9 3 Simone Piccardi
</pre>
10 3 Simone Piccardi
11 7 Simone Piccardi
Per poter lanciare istanze multiple queste devono essere identificate nel file di configurazione con un numero (denominato GNR), da configurare in altrettante sezioni distinte del file di configurazione, introdotte da una voce nella forma @[mysqldN]@. Inoltre devono essere indicate le configurazioni specifiche di @mysqld_multi@ stesso in una sezione @[mysqld_multi]@, nel nostro caso il contenuto di questa sezione è:
12 3 Simone Piccardi
13 3 Simone Piccardi
<pre>
14 3 Simone Piccardi
[mysqld_multi]
15 3 Simone Piccardi
mysqld = /usr/bin/mysqld_safe
16 3 Simone Piccardi
mysqladmin = /usr/bin/mysqladmin
17 3 Simone Piccardi
log = /var/log/multi_mysql.log
18 3 Simone Piccardi
</pre>
19 3 Simone Piccardi
20 3 Simone Piccardi
Le configurazioni da applicare alle varie istanze aggiuntive sono identiche a quelle della sezione @[mysqld]@ di una installazione ordinaria, si tratta però di evitare l'uso degli stessi file e delle stesse directory, inoltre ogni istanza dovrà mettersi in ascolto su un indirizzo IP o su una porta diversa. Questo significa che si dovrà o usare la direttiva @port@ per indicare una diversa porta ad ogni istanza, o usare la direttiva @bind-address@ per specificare un indirizzo IP diverso (nel qual caso ovviamente si saranno dovuti assegnare indirizzi multipli alla propria scheda di rete). In quest'ultimo caso si deve tenere presente che non sarà più possibile per nessuna istanza usare l'indirizzo generico @0.0.0.0@ e che per ascoltare su @localhost@ occorrerà usare specificamente @bind-address=127.0.0.1@ e che questo sarà possibile per una sola istanza.
21 3 Simone Piccardi
22 4 Simone Piccardi
Un esempio di configurazione di una istanza aggiuntiva lanciata con @mysqld_multi@ è il seguente, si noti come si sia usata la convenzione di aggiungere ai vari file e directory utilizzati il numero che identifica l'istanza stessa; si noti anche la presenza di una direttiva @skip-grant-tables@ che andrà rimossa completata la configurazione iniziale.
23 3 Simone Piccardi
24 3 Simone Piccardi
<pre>
25 3 Simone Piccardi
[mysqld1]
26 3 Simone Piccardi
user            = mysql
27 3 Simone Piccardi
pid-file        = /var/run/mysqld/mysqld1.pid
28 3 Simone Piccardi
socket          = /var/run/mysqld/mysqld1.sock
29 3 Simone Piccardi
basedir         = /usr
30 3 Simone Piccardi
datadir         = /var/lib/mysql1
31 3 Simone Piccardi
tmpdir          = /tmp
32 3 Simone Piccardi
lc-messages-dir = /usr/share/mysql
33 3 Simone Piccardi
log-error=/var/log/mysqld1.log
34 3 Simone Piccardi
skip-external-locking
35 3 Simone Piccardi
bind-address    = istanza1.miodominio.it
36 3 Simone Piccardi
key_buffer              = 16M
37 3 Simone Piccardi
max_allowed_packet      = 16M
38 3 Simone Piccardi
thread_stack            = 192K
39 3 Simone Piccardi
thread_cache_size       = 8
40 3 Simone Piccardi
myisam-recover         = BACKUP
41 3 Simone Piccardi
query_cache_limit       = 1M
42 3 Simone Piccardi
query_cache_size        = 16M
43 1 Simone Piccardi
expire_logs_days        = 10
44 3 Simone Piccardi
max_binlog_size         = 100M
45 6 Simone Piccardi
# to be removed #
46 6 Simone Piccardi
skip-grant-tables
47 6 Simone Piccardi
# to be removed #
48 3 Simone Piccardi
</pre>
49 3 Simone Piccardi
50 7 Simone Piccardi
Si ripeta la sezione precedente per le ulteriori istanze volute, inserendo altrettante analoghe sezioni [mysqldN] con contenuto analogo ed un valore diverso per N. Si tenga presente che ogni istanza *deve* avere una @datadir@ diversa, pertanto per ciascuna le si creino nella forma:
51 1 Simone Piccardi
52 7 Simone Piccardi
<pre>
53 7 Simone Piccardi
mkdir /var/lib/mysql1 -m 700
54 7 Simone Piccardi
mkdir /var/lib/mysql2 -m 700
55 7 Simone Piccardi
...
56 7 Simone Piccardi
chown mysql.mysql /var/lib/mysql1
57 7 Simone Piccardi
chown mysql.mysql /var/lib/mysql2
58 7 Simone Piccardi
...
59 7 Simone Piccardi
</pre>
60 7 Simone Piccardi
61 5 Simone Piccardi
Una volta configurate le varie istanze occorre creare per ciascuna di esse il database iniziale di MySQL (@mysql@), questo nel caso dell'istanza precedente potrà essere effettuato con il comando:
62 1 Simone Piccardi
63 5 Simone Piccardi
<pre>
64 3 Simone Piccardi
mysql_install_db --user=mysql --datadir=/var/lib/mysql1
65 3 Simone Piccardi
</pre>
66 5 Simone Piccardi
67 3 Simone Piccardi
ripetendo eventualmente il comando per tutte le istanze successive. A questo punto si potranno avviare manualmente le istanze (si da per assunto che si stato creato l'alias descritto in precedenza) con:
68 1 Simone Piccardi
69 1 Simone Piccardi
<pre>
70 1 Simone Piccardi
mysqld_multi start
71 1 Simone Piccardi
</pre>
72 1 Simone Piccardi
73 7 Simone Piccardi
A questo punto, come richiesto nelle istruzioni stampate da @mysql_install_db@, occorrerebbe impostare una password di accesso per l'utente @root@ dei database appena creati. 
74 5 Simone Piccardi
75 7 Simone Piccardi
L'installazione del database di default però restringe l'accesso senza password a @root@ a @localhost@ ed all'hostname principale della macchina, per cui non è possibile accedervi usando un indirizzo IP diverso ed i comandi indicati da @mysql_install_db@ non funzionerebbero. 
76 7 Simone Piccardi
77 5 Simone Piccardi
Per questo è necessario far partire la prima volta il servizio con la direttiva @skip-grant-tables@, in modo di poter accedere comuqnue al database ed effettuare le correzioni necessarie rispetto a quanto installato da @mysql_install_db@. Pertanto una volta fatte partire le istanze ci si colleghi a ciascuna di esse con @mysql -h istanzaN.miodominio.it -u root@ e si eseguano i comandi:
78 5 Simone Piccardi
79 5 Simone Piccardi
<pre>
80 5 Simone Piccardi
DROP DATABASE test;
81 5 Simone Piccardi
use mysql
82 1 Simone Piccardi
DELETE FROM user WHERE user='';
83 5 Simone Piccardi
UPDATE user SET host='istanzaN.miodominio.it' WHERE host='nomemacchina';
84 1 Simone Piccardi
UPDATE user SET Password=PASSWORD("passwordlungaecomplicata") WHERE User="root";
85 1 Simone Piccardi
</pre>
86 7 Simone Piccardi
 
87 1 Simone Piccardi
A questo punto si potrà fermare l'esecuzione delle istanze aggiuntive, rimuovere l'opzione  @skip-grant-tables@ dal file di configurazione, e riavviare le stesse, collegandosi normalmente con la password impostata. 
88 7 Simone Piccardi
89 7 Simone Piccardi
Questo non è necessario se invece si stanno usando istanze su porte diverse, ma in tal caso è necessario collegarsi con @mysqladmin@ indicando la porta corretta. La cosa sembrerebbe banale non fosse per il fatto che se si esegue la connessione senza specificare l'hostname con @-h@ il programma ignora la direttiva @--port@ ed usa la connessione via socket locale, ma non solo, in maniera idiota lo fa anche quando si usa come hostname @localhost@, per cui se non si sta attenti ci si collegherà, se è attiva, sempre all'istanza principale usando il socket di default. 
90 7 Simone Piccardi
91 7 Simone Piccardi
Pertanto occorre specificare sempre esplicitamente @-h 127.0.0.1@ che per fortuna non viene liberamente (e stupidamente) reinterpretata. Questo significa che in caso di uso delle porte sarà possibile cambiare password di root con @mysqladmin@ usando il comando:
92 7 Simone Piccardi
93 7 Simone Piccardi
<pre>
94 7 Simone Piccardi
mysqladmin -h 127.0.0.1 --port NNNN -u root -p password 'passwordlungaecomplicata'
95 7 Simone Piccardi
</pre>
96 7 Simone Piccardi
97 7 Simone Piccardi
(dove @NNNN@ è il numero di porta indicato nella configurazione per l'istanza in questione) sfruttando il fatto che la password iniziale dell'utente @root@ è vuota.
98 7 Simone Piccardi
99 7 Simone Piccardi
h2. Gestione dei servizi
100 7 Simone Piccardi
101 7 Simone Piccardi
Con il pacchetto di @mysql@ fino a Wheezy è disponibile uno script di avvio minimale @/usr/share/mysql/mysqld_multi.server@ che può essere adattato per essere inserito nel sistema di avvio a dipendenze di Wheezy con qualche modifica (alternativamente si può modificare lo script di avvio  @/etc/init.d/mysql@ usando @mysqld_multi@ al posto di @mysqladmin@ e togliendo i controlli che non fanno riferimento all'uso di @mysqld_multi@.
102 7 Simone Piccardi
103 7 Simone Piccardi
Con Jessie e l'introduzione di @systemd@ si può ricorrere ad una _unit file_ template dedicata, da installare sotto @/etc/systemd/system@, e nel caso specifico si è fatto riferimento ad una configurazione mantenuta sotto @/etc/mysql-multi/my.cnf@ come descritto in precedenza. Per questo basterà inserire il seguente contenuto nel file /etc/systemd/system/mysqld@.service:
104 7 Simone Piccardi
105 7 Simone Piccardi
<pre>
106 7 Simone Piccardi
[Unit]
107 7 Simone Piccardi
Description=MySQL Multi for instance %i
108 7 Simone Piccardi
After=syslog.target
109 7 Simone Piccardi
After=network.target
110 7 Simone Piccardi
111 7 Simone Piccardi
[Service]
112 7 Simone Piccardi
User=mysql
113 7 Simone Piccardi
Group=mysql
114 7 Simone Piccardi
Type=forking
115 7 Simone Piccardi
ExecStart=/usr/bin/mysqld_multi --defaults-file=/etc/mysql-multi/my.cnf start %i
116 7 Simone Piccardi
ExecStop=/usr/bin/mysqld_multi  --defaults-file=/etc/mysql-multi/my.cnf stop %i
117 7 Simone Piccardi
Restart=always
118 7 Simone Piccardi
PrivateTmp=true
119 7 Simone Piccardi
120 7 Simone Piccardi
[Install]
121 7 Simone Piccardi
WantedBy=multi-user.target
122 7 Simone Piccardi
</pre>
123 7 Simone Piccardi
124 7 Simone Piccardi
In questo caso, essendo eseguiti i programmi per conto dell'utente @mysql@ occorrerà sincerarsi che i file di log citati nella configurazione esistano (o possano essere creati) e siano scrivibili dal suddetto utente. Una volta creato il file occorrerà eseguire @systemctl daemon-reload@ per fargli leggere la nuova unit. 
125 7 Simone Piccardi
126 7 Simone Piccardi
127 7 Simone Piccardi
A questo punto si potrà far partire l'istanza N di mysql (che deve essere definita nella configurazione) con:
128 7 Simone Piccardi
129 7 Simone Piccardi
<pre>
130 7 Simone Piccardi
systemctl start mysqld@N
131 7 Simone Piccardi
</pre>
132 7 Simone Piccardi
133 7 Simone Piccardi
controllarne lo stato con: 
134 7 Simone Piccardi
135 7 Simone Piccardi
<pre>
136 7 Simone Piccardi
systemctl status mysqld@N
137 7 Simone Piccardi
</pre>
138 7 Simone Piccardi
139 7 Simone Piccardi
fermarla con:
140 7 Simone Piccardi
141 7 Simone Piccardi
<pre>
142 7 Simone Piccardi
systemctl stop mysqld@N
143 7 Simone Piccardi
</pre>
144 7 Simone Piccardi
145 7 Simone Piccardi
ed abilitarne la partenza all'avvio del sistema con:
146 7 Simone Piccardi
147 7 Simone Piccardi
<pre>
148 7 Simone Piccardi
systemctl enable mysqld@N
149 7 Simone Piccardi
</pre>