Troubleshooting High I/O Wait in Linux

Linux has many tools available for troubleshooting some are easy to use, some are more advanced.

I/O Wait is an issue that requires use of some of the more advanced tools as well as an advanced usage of some of the basic tools. The reason I/O Wait is difficult to troubleshoot is due to the fact that by default there are plenty of tools to tell you that your system is I/O bound, but not as many that can narrow the problem to a specific process or processes.

Answering whether or not I/O is causing system slowness

To identify whether I/O is causing system slowness you can use several commands but the easiest is the unix command top.

 # top
 top - 14:31:20 up 35 min, 4 users, load average: 2.25, 1.74, 1.68
 Tasks: 71 total, 1 running, 70 sleeping, 0 stopped, 0 zombie
 Cpu(s): 2.3%us, 1.7%sy, 0.0%ni, 0.0%id, 96.0%wa, 0.0%hi, 0.0%si, 0.0%st
 Mem: 245440k total, 241004k used, 4436k free, 496k buffers
 Swap: 409596k total, 5436k used, 404160k free, 182812k cached

From the CPU(s) line you can see the current percentage of CPU in I/O Wait; The higher the number the more cpu resources are waiting for I/O access.

wa -- iowait
 Amount of time the CPU has been waiting for I/O to complete.

Finding which disk is being written to

The above top command shows I/O Wait from the system as a whole but it does not tell you what disk is being affected; for this we will use the iostat command.

 $ iostat -x 2 5
 avg-cpu: %user %nice %system %iowait %steal %idle
  3.66 0.00 47.64 48.69 0.00 0.00

 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
 sda 44.50 39.27 117.28 29.32 11220.94 13126.70 332.17 65.77 462.79 9.80 2274.71 7.60 111.41
 dm-0 0.00 0.00 83.25 9.95 10515.18 4295.29 317.84 57.01 648.54 16.73 5935.79 11.48 107.02
 dm-1 0.00 0.00 57.07 40.84 228.27 163.35 8.00 93.84 979.61 13.94 2329.08 10.93 107.02

The iostat command in the example will print a report every 2 seconds for 5 intervals; the -x tells iostat to print out an extended report.

The 1st report from iostat will print statistics based on the last time the system was booted; for this reason in most circumstances the first report from iostat should be ignored. Every sub-sequential report printed will be based on the time since the previous interval. For example in our command we will print a report 5 times, the 2nd report are disk statistics gathered since the 1st run of the report, the 3rd is based from the 2nd and so on.

In the above example the %utilized for sda is 111.41% this is a good indicator that our problem lies with processes writing to sda. While the test system in my example only has 1 disk this type of information is extremely helpful when the server has multiple disks as this can narrow down the search for which process is utilizing I/O.

Aside from %utilized there is a wealth of information in the output of iostat; items such as read and write requests per millisecond(rrqm/s & wrqm/s), reads and writes per second (r/s & w/s) and plenty more. In our example our program seems to be read and write heavy this information will be helpful when trying to identify the offending process.

Finding the processes that are causing high I/O

iotop

 # iotop
 Total DISK READ: 8.00 M/s | Total DISK WRITE: 20.36 M/s
  TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
 15758 be/4 root 7.99 M/s 8.01 M/s 0.00 % 61.97 % bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp

The simplest method of finding which process is utilizing storage the most is to use the command iotop. After looking at the statistics it is easy to identify bonnie++ as the process causing the most I/O utilization on this machine.

While iotop is a great command and easy to use, it is not installed on all (or the main) Linux distributions by default; and I personally prefer not to rely on commands that are not installed by default. A systems administrator may find themselves on a system where they simply cannot install the non-defualt packages until a scheduled time which may be far too late depending on the issue.

If iotop is not available the below steps will also allow you to narrow down the offending process/processes.

Process list “state”

The ps command has statistics for memory and cpu but it does not have a statistic for disk I/O. While it may not have a statistic for I/O it does show the processes state which can be used to indicate whether or not a process is waiting for I/O.

The ps state field provides the processes current state; below is a list of states from the man page.

PROCESS STATE CODES
 D uninterruptible sleep (usually IO)
 R running or runnable (on run queue)
 S interruptible sleep (waiting for an event to complete)
 T stopped, either by a job control signal or because it is being traced.
 W paging (not valid since the 2.6.xx kernel)
 X dead (should never be seen)
 Z defunct ("zombie") process, terminated but not reaped by its parent.

Processes that are waiting for I/O are commonly in an “uninterruptible sleep” state or “D”; given this information we can simply find the processes that are constantly in a wait state.

Example:

 # for x in `seq 1 1 10`; do ps -eo state,pid,cmd | grep "^D"; echo "----"; sleep 5; done
 D 248 [jbd2/dm-0-8]
 D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
 ----
 D 22 [kswapd0]
 D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
 ----
 D 22 [kswapd0]
 D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
 ----
 D 22 [kswapd0]
 D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
 ----
 D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
 ----

The above for loop will print the processes in a “D” state every 5 seconds for 10 intervals.

From the output above the bonnie++ process with a pid of 16528 is waiting for I/O more often than any other process. At this point the bonnie++ seems likely to be causing the I/O Wait, but just because the process is in an uninterruptible sleep state does not necessarily prove that it is the cause of I/O wait.

To help confirm our suspicions we can use the /proc file system. Within each processes directory there is a file called “io” which holds the same I/O statistics that iotop is utilizing.

 # cat /proc/16528/io
 rchar: 48752567
 wchar: 549961789
 syscr: 5967
 syscw: 67138
 read_bytes: 49020928
 write_bytes: 549961728
 cancelled_write_bytes: 0

The read_bytes and write_bytes are the number of bytes that this specific process has written and read from the storage layer. In this case the bonnie++ process has read 46 MB and written 524 MB to disk. While for some processes this may not be a lot, in our example this is enough write and reads to cause the high i/o wait that this system is seeing.

Finding what files are being written too heavily

The lsof command will show you all of the files open by a specific process or all processes depending on the options provided. From this list one can make an educated guess as to what files are likely being written to often based on the size of the file and the amounts present in the “io” file within /proc.

To narrow down the output we will use the -p <pid> options to print only files open by the specific process id.

 # lsof -p 16528
 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
 bonnie++ 16528 root cwd DIR 252,0 4096 130597 /tmp
 <truncated>
 bonnie++ 16528 root 8u REG 252,0 501219328 131869 /tmp/Bonnie.16528
 bonnie++ 16528 root 9u REG 252,0 501219328 131869 /tmp/Bonnie.16528
 bonnie++ 16528 root 10u REG 252,0 501219328 131869 /tmp/Bonnie.16528
 bonnie++ 16528 root 11u REG 252,0 501219328 131869 /tmp/Bonnie.16528
 bonnie++ 16528 root 12u REG 252,0 501219328 131869 <strong>/tmp/Bonnie.16528</strong>

To even further confirm that these files are being written to the heavily we can see if the /tmp filesystem is part of sda.

 # df /tmp
 Filesystem 1K-blocks Used Available Use% Mounted on
 /dev/mapper/workstation-root 7667140 2628608 4653920 37% /

From the output of df we can determine that /tmp is part of the root logical volume in the workstation volume group.

 # pvdisplay
  --- Physical volume ---
  PV Name /dev/sda5
  VG Name workstation
  PV Size 7.76 GiB / not usable 2.00 MiB
  Allocatable yes
  PE Size 4.00 MiB
  Total PE 1986
  Free PE 8
  Allocated PE 1978
  PV UUID CLbABb-GcLB-l5z3-TCj3-IOK3-SQ2p-RDPW5S

Using pvdisplay we can see that the /dev/sda5 partition part of the sda disk is the partition that the workstation volume group is using and in turn is where /tmp exists. Given this information it is safe to say that the large files listed in the lsof above are likely the files being read & written to frequently.

Deframmenta per ottimizzare le tabelle di MySQL

In MySQL, quando si eliminano record da una tabella, lo spazio è riassegnato automaticamente. E ‘come uno spazio vuoto e formando gli allegati nuovi vantaggio.

Il problema è che se una tabella di eseguire molte operazioni di DELETE, lo spazio fisico del tavolo sarà sempre più frammentato e il rendimento è ridotto.

Nel MyISAM InnoDBOPTIMIZE TABLE comando disponibile ad effettuare l’ottimizzazione su qualsiasi tabella che, tra l’altro, esegue una deframmentazione automatica del tavolo.

Si consiglia vivamente di utilizzare questo comando regolarmente in particolare su tabelle che sono più le dichiarazioni di smaltimento dei record.

Per precauzione, di tenere presente che durante l’esecuzione, naturalmente, la tabella è bloccato. Si deve ricordare quando si sta per l’utilizzo con tabelle di grandi dimensioni e occupato.

La sintassi è la seguente:

OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] TABLE mi_tabla1 [, mi_tabla2] ...;

Per fare un tavolo di ottimizzazione frammentati possono essere selezionati per avere spazio libero, probabilmente a causa di DELETE:

SELECT TABLE_SCHEMA,TABLE_NAME
FROM TABLES WHERE TABLE_SCHEMA NOT IN ("information_schema","mysql") AND
Data_free > 0

Un semplice script per deframmentare in automatico : 

#!/bin/bash

# Get a list of all fragmented tables
FRAGMENTED_TABLES="$( mysql -e 'use information_schema; SELECT TABLE_SCHEMA,TABLE_NAME \
FROM TABLES WHERE TABLE_SCHEMA NOT IN ("information_schema","mysql") AND \
Data_free > 0' | grep -v "^+" | sed "s,\t,.," )"

for fragment in $FRAGMENTED_TABLES; do
   database="$( echo $fragment | cut -d. -f1 )"
   table="$( echo $fragment | cut -d. -f2 )"
   [ $fragment != "TABLE_SCHEMA.TABLE_NAME" ] && mysql -e "USE $database;\
   OPTIMIZE TABLE $table;" > /dev/null 2>&1
done

Mysqldump per prendere solo lo schema di una tabella

Mysqldump è uno strumento che viene utilizzato per creare copie di backup (o dump) dei database, incusi dati struttura e schemi. Ci sono una serie di switch (flags) da riga di comando che si possono lanciare per scaricare solo i dati o solo la struttura invece di tutto.

Dump della struttura del database per tutte le tabelle senza dati

Aggiungere il flag -d per indicare che nessun dato deve essere incluso nell’output.

Il seguente comando dump della struttura della tabella per tutte le tabelle nel database specificato MySQL:

mysqldump -d -u -p someuser miodatabase

Il flag-d dice di non inserire i dati nel dump. In alternativa si può usare –no-data che è più semplice da ricordare.

mysqldump --no-data -u  -p someuser miodatabase

Dump della struttura del database per una sola tabella senza dati

Esempio per una tabella

mysqldump-d-u-p someuser miodatabase prodotti

Pratiche di dumping la struttura del database per la tabella con i diversi dati

Questa è la stessa per un tavolo, ma solo specificare tabelle aggiuntive come molti dopo il nome del database come vorreste discarica. Questo comando eseguirà il dump della struttura per i “prodotti” tavoli “categorie” e “utenti”:

mysqldump-d-u-p someuser prodotti miodatabase categorie di utenti

Pratiche di dumping la struttura in un file

Tutti i comandi di esempio sopra scrivere il dump sullo standard output, nel senso che ti scorrere verso l’alto il terminale / finestra prompt dei comandi che non può essere molto utile. Per salvare in un file invece reindirizzare l’output. Per esempio:

mysqldump-d-u-p someuser miodatabase> mydatabase.sql

È possibile utilizzare il contenuto di questo file con il tool comando “mysql” linea per creare tali tabelle stesse in un altro database:

mysql-u-p someuser anotherdatabase 
											

Creazione instanza mysql parallela

… ovvero come faccio ad avere due instanze indipendenti di mysql sullo stesso server ?

Attenzione :

Questo how-to è stato scritto e pensato per Ubuntu/Debian in particolare, alcuni path e directory potrebbero essere differenti nella vostra versione di Linux

1. Creo directory e predispongo i file di log

mkdir /var/lib/mysql2
chown −R mysql.mysql /var/lib/mysql2/
mkdir /var/log/mysql2
chown −R mysql.mysql /var/log/mysql2

2. Creo una nuova configurazione di mysql

cp -R /etc/mysql/ /etc/mysql2

A questo punto dobbiamo modificare il file di configurazione di mysql e cambiare la porta, socket e pid : 

cd /etc/mysql2/
sed −i 's/3306/3307/g' my.cnf
sed −i 's/mysqld.sock/mysqld2.sock/g' my.cnf
sed −i 's/mysqld.pid/mysqld2.pid/g' my.cnf
sed −i 's/var\/lib\/mysql/var\/lib\/mysql2/g' my.cnf
sed −i 's/var\/log\/mysql/var\/log\/mysql2/g' my.cnf

3. Inizializzazione e start

Abbiamo a questo punto dell’how-to due scelte da fare :

1. creiamo una instanza vuota con database di default come se fosse una nuova installazione 

2. Copiamo i database da un’altra instanza 

Nel caso :

1.  mysql_install_db −−user=mysql −−datadir=/var/lib/mysql2/
2. cp −R /var/lib/mysql/* /var/lib/mysql2/*

Possiamo a questo punto far partire l’instanza :

mysqld_safe --defaults-file=/etc/mysql2/my.cnf &

e connetterci in due modi :

mysql -S /var/run/mysqld/mysqld2.sock

o

mysql -h 127.0.0.1 -P 3307

Possiamo a questo punto creare uno script di init (es: mysql2) in /etc/init.d/

#!/bin/sh
# Begin /etc/init.d/mysql

#source /etc/init.d/functions

case "$1" in
start)
echo -n "Starting mysql..."
/usr/bin/mysqld_safe --defaults-file=/etc/mysql2/my.cnf >/dev/null 2>&1 &
ret=$?
;;

stop)
echo -n "Stopping mysqld..."
# kill `cat /var/run/mysqld/mysqld-rep.pid`
mysqladmin -S /var/run/mysqld/mysqld2.sock shutdown > /dev/null 2>&1
ret=$?
;;

restart)
$0 stop
/usr/bin/sleep 1
$0 start
;;

status)
statusproc /usr/bin/mysqld
;;

*)
echo "Usage: $0 {start|stop|restart|status}"
exit 1
;;

esac

exit $?

se voglio farlo partire al boot :

update-rc.d mysql2 defaults

Protezione [base] contro DOS

mod_evasive è un altro modulo di Apache in grado di aumentare la sicurezza del sistema proteggendoci da attacchi DOS e D-DOS sulla porta 80.
Gli attacchi di tipo DOS e D-DOS (Denial of Services e Distributed Denial of Services) sono attacchi atti a rendere inaccessibili i sistemi a causa di un intenso traffico dati. Grazie a questo modulo, però, riusciamo a prevenire questo tipo di attacco quando viene rivolto ad Apache in quanto il modulo tiene traccia del numero di connessioni provenienti da un determinato IP e, in caso di superamento della soglia, interviene bloccandole.
Per installare il modulo su Debian/Ubuntu è sufficiente lanciare il comando:

apt-get install libapache2-mod-evasive

Quindi creiamo la directory per i log:

mkdir -p /var/log/apache2/evasive
chown -R www-data:root /var/log/apache2/evasive

Ora creiamo un file di configurazione per il modulo:

/etc/apache2/conf.d/modevasive.conf
<IfModule mod_evasive20.c>
DOSHashTableSize 3097
DOSPageCount 5
DOSSiteCount 100
DOSPageInterval 1
DOSSiteInterval 1
DOSBlockingPeriod 600
DOSLogDir "/var/log/apache2/evasive"
</IfModule>

e riavviamo Apache:

/etc/init.d/apache2 restart

Per collaudare il funzionalmento del modulo, c’è un semplice script perl incluso con la documentazione:

# perl /usr/share/doc/libapache2-mod-evasive/examples/test.pl 
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
HTTP/1.1 200 OK
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden

List tutti i vhost di apache

Ecco uno script perl/bash dove tiro fuori formattati bene tutti i vhost di apache :

Modo più verboso :

/usr/sbin/apache2ctl −S 2>&1 | perl −ne 'm@.*port\s+([0−9]+)\s+\w+\s+(\S+)\s+\((.+):.*@ && do { print "$2:$1\n\t$3\n"; $root = qx{grep DocumentRoot $3}; $root =~ s/^\s+//; print "\t$root\n" };'

Modo meno verboso :

#!/bin/bash
apache2ctl −S 2>&1 | grep −v Syntax | perl −ne 'm@.*port\s+([0−9]+)\s+\w+\s+(\S+)\s+\((.+):.*@ && do { print "$2:$1\n";};'

Mysql Proxy

Vi è mai capitato di dover configurare un’applicazione in modo che in un’archiettura mysql master/slave scriva automaticamente sul master e legga dagli slave senza modificare l’applicativo ?

Mysql-proxy è quello che fa per te !

MySQL Proxy è un programma che si interpone fra un client e un server MySQL, per consentire di effettuare operazioni sul traffico di dati, in maniera trasparente per l’utente. MySQL Proxy usa il protocollo client/server esteso di MySQL, introdotto con la versione 4.1. Pertanto, questa applicazione è compatibile con i server dalla versione 4.1 e superiore.

MySQL Proxy è un’applicazione molto leggera (200 KB in compilazione dinamica, 1.5 MB in compilazione statica con le librerie), che è stata disegnata per interporsi fra un client e un server MySQL ed eseguire operazioni sui pacchetti inviati e ricevuti.
Il programma ha poche opzioni di configurazione. La caratteristica che lo rende interessante e funzionale è un interprete Lua integrato, grazie al quale è possibile analizzare ed eventualmente modificare i pacchetti passati fra client e server.
Il client non si accorge del Proxy, che agisce da man in the middle. Il client si connette con le solite credenziali. Il Proxy intercetta la richiesta e si collega al server. Da quel momento, ogni query inviata dal client e i relativi risultati restituiti dal server passano attraverso il Proxy.

Si noti che MySQL Proxy non è un’applicazione di malware, anche se la definizione resa sopra, con la sua possibilità di intercettazione, potrebbe farlo credere. L’uso del Proxy è trasparente per il client, in materia di protocollo, ovvero il client usa il server tramite il Proxy senza avvertire differenze (tranne quando usa funzioni esplicitamente create per il Proxy). Ma il Proxy usa una porta diversa dal server, e pertanto, anche se l’uso è trasparente per l’applicazione, l’amministratore è conscio della sua esistenza. L’uso del Proxy senza consenso di una delle due parti non è possibile. Il Proxy può essere usato dall’amministratore, per ampliare le funzionalità del server, o dall’utente, per lo stesso motivo. Nel primo caso, il Proxy sarà visibile a tutti gli utenti. Nel secondo caso solo l’utente che l’ha installato nella sua macchina è al corrente delle funzioni estese.

Nella sua forma essenziale, MySQL Proxy è uno strumento di ridirezione, che passa un pacchetto di richiesta dal client al server, prende dal server i risultati, e li passa al client. Nel passaggio di dati, il Proxy può intervenire, ed effettuare operazioni sulla query prima che venga inviata, o sui risultati, prima che vengano restituiti. Le modifiche vengono effettuate tramite script in Lua, che usano funzioni predefinite per alterare lo stato dei pacchetti. Le funzioni sono le seguenti:

  • connect_server in cui si può agire al momento della connessione al server;
  • read_handshake che avviene immediatamente dopo la connessione;
  • read_auth in cui si passano al server le credenziali di accesso;
  • read_auth_result dove viene ricevuto il risultato dell’operazione precedente;
  • read_query che si attiva per ogni query inviata al server;
  • read_query_result che viene richiamata quando il Proxy riceve il risultato di una query modificata;
  • disconnect_client che si attiva quando un client viene disconnesso.

Ecco come l’ho configurato ed installato  su Ubuntu per avere uno splitting r/w :

apt-get install mysql-proxy

Mi sono crato uno script dentro /root/scritpt/proxy.sh :

#!/bin/bash

MASTERDB=server1
SLAVEDB01=server2

LUA_PATH="/usr/share/mysql-proxy/?.lua" /usr/sbin/mysql-proxy \
 --daemon \
 --proxy-backend-addresses=$MASTERDB:3306 \
 --proxy-read-only-backend-addresses=$SLAVEDB01:3306 \
 --proxy-lua-script=/usr/share/mysql-proxy/rw-splitting.lua

e gli ho assegnato i permessi di esecuzione con chmod.
Notare che lo script puo’ essere modificato per avere + slave.

 A questo punto facciamo partire automaticamente lo script creando un file in /etc/init.d/mysql-proxy :

#!/bin/bash
#
# mysql-proxy: Start mysql-proxy in daemon mode
#
# Author: OpenX
#
# chkconfig: - 99 01
# description: Start mysql-proxy in daemon mode with r/w splitting
# processname: mysql-proxy
start(){
 echo "Starting mysql-proxy..."
 /root/script/proxy.sh
}
stop(){
  echo "Stopping mysql-proxy..."
  killall mysql-proxy
}

case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
start
;;
*)
echo "Usage: mysql-proxy {start|stop|restart}"
exit 1
esac

Occhio alle perfomance pero’ ! 
http://www.mysqlperformanceblog.com/2009/06/09/mysql-proxy-urgh-performance-and-scalability/ 

Bash script cambio password

Personalmente me lo sono scrittp per cabiare qualcosa come 54 password ftp.

Non volendolo fare a mano sono ricorso al solito bash

Gli utenti nei sistemi Linux sono contenuti in questo file  /etc/passwd
e si presentano in questo modo :

test.it:x:526:526:test.it:/home/test.it:/bin/sh

Per prima cosa elimino tutto quello che non mi serve :

awk -F":" '{ print $1 }' /etc/passwd > user.txt

ed ottengo quindi solo lo user :

test.it

A questo punto ecco che entra in azione lo script vero e proprio :

#!/bin/bash

function randpass
{
echo `</dev/urandom tr -dc A-Za-z0-9 | head -c8`
}

for i in `more ftp_ok`
do
p=`randpass`
echo $i $p

echo $p | passwd –stdin $i
done

Il gioco è fatto !

 

Allineare mysql slave

Cosa succede se si fa una bella insert sul nostro database mysql slave?
Due cose :

  1. Lo slave server si disallinea
  2. Il sistemista bestemmia 
Per controllore lo stato dello slave bisogna lanciare dallo slave :
mysql> show slave status\G 
Lo Slave utilizza piu’ thread. Il primo e’ una connessione remota al Master ed ha il compito di raccogliere i dati dal bin-log (BinLog Dump) ed e’ sempre attivo. Gli altri thread sono locali ed hanno il compito di ricevere il contenuto del bin-log (Slave I/O) e di applicarlo alla base dati (Slave SQL). In caso d’errore nell’inserimento dei dati il thread Slave SQL si interrompe mentre lo Slave I/O continua a raccogliere i dati dal Master. Con show slave status\G si ottiene l’indicazione dell’errore occorso; una volta corretto il problema la replicazione riprende dal punto in cui si era interrotta applicando il relay-log. 

Per risolvere il problema numero 1 bisogna seguire questa facile guida :

1. Stoppare sugli SLAVE SERVER il servizio di replica :

mysql> stop slave;

2. Lokkare le tabelle sul MYSQL MASTER (occhio a non uscire da mysql altrimenti questo comando viene flushato)

mysql> FLUSH TABLES WITH READ LOCK;

3. Effettuare un dump completo e copiarli sullo/i SLAVE/s :

mysqldump --all-database > databases.sql -u root -p 

4. Restore DB sugli SLAVE

mysql -u root -p databases.sql 

5. Controllare lo stato del MYSQL MASTER per vedere fino a che punto è arrivata il transaction bin log : (in un altra sessione ssh, vedi punto 2)

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000059 | 17908642 |              |                  |
+------------------+----------+--------------+------------------+

6. Riattivare il MYSQL SLAVE

CHANGE MASTER TO MASTER_LOG_FILE = 'mysql-bin.000059', MASTER_LOG_POS = 17148864;

7. Riattivare lo slave

mysql> start slave;

8. Riattivare il MYSQL MASTER in scrittura

UNLOCK TABLES;