Installare e aggiornare MySQL 5.x

27 febbraio 2013 Roberto Puzzanghera0 commenti

La presente guida è stata testata con l'installazione delle versioni 5.6.10, 5.5, 5.1, 5.0 di mysql. Al momento in cui scrivo queste note la versione più recente è la 5.6.10.

Installazione dai sorgenti

Sarà bene installare dai sorgenti anche dai binari quando questi ultimi siano stati compilati con una versione di glibc diversa da quella installata nel nostro server.

cd /usr/local/mysql
wget latest mysql source
tar zxvf mysql-VERSION.tar.gz
cd mysql-VERSION
cmake .
make
make install
cd /usr/local
mv mysql mysql-VERSION
ln -s mysql-VERSION mysql

In questo modo abbiamo installato mysql in /usr/local/mysql.

Installazione dalla versione in binario

Scaricare la versione in binario di mysql e estrarre la tarball dove si vuole, ad esempio in /usr/local.

cd /usr/local
wget mysql binaries
tar xzf mysql-VERSION.tar.gz
ln -s mysql-VERSION mysql

Configurazione

Ora abbiamo i binari in /usr/local/mysql. Nel caso la tua distribuzione non fornisca per default un utente e un gruppo mysql è necessario crearli:

groupadd mysql 
useradd -r -g mysql mysql

Impostiamo i permessi sui file e le directory e installiamo il database (per maggiori informazioni leggere attentamente questo http://dev.mysql.com/doc/refman/5.1/en/installing-binary.html):

cd /usr/local/mysql 
chown -R mysql.mysql . 
scripts/mysql_install_db --user=mysql 
chown -R root . 
chown -R mysql data

Notare che questa procedura non predispone alcuna password per root, quindi bisogna accedere al server e mettere al sicuro l'account.

Ma dobbiamo ancora avviare il server; possiamo utilizzare lo startup script fornito da Slackware (che dovrebbe andar bene per qualunque altra distribuzione). Modifichiamolo secondo le nostre necessaità; se non abbiamo bisogno di agevolare connessioni di rete lasciamo --skip-networking commentato per preservare la sicurezza del sistema.

File rc.mysqld

Salvare questo file in /usr/local/bin (download). Gli utenti Slackware potrebbero preferire /etc/rc.d

# SKIP="--skip-networking"

DATA="/usr/local/mysqldata"
MYSQLD="/usr/local/mysql/bin/mysqld_safe"
PID="$DATA/mysql.pid"

# Start mysqld:
mysqld_start() {
  if [ -x $MYSQLD ]; then
    # If there is an old PID file (no mysqld running), clean it up:
    if [ -r $PID ]; then
      if ! ps axc | grep mysqld 1> /dev/null 2> /dev/null ; then
        echo "Cleaning up old $PID."
        rm -f $PID
      fi
    fi
    $MYSQLD --datadir=$DATA --pid-file=$PID $SKIP &
  fi
}

# Stop mysqld:
mysqld_stop() {
  # If there is no PID file, ignore this request...
  if [ -r $PID ]; then
    killall mysqld
    # Wait at least one minute for it to exit, as we dont know how big the DB is...
    for second in 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 \
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 60 ; do
      if [ ! -r $PID ]; then
        break;
      fi
      sleep 1
    done
    if [ "$second" = "60" ]; then
      echo "WARNING:  Gave up waiting for mysqld to exit!"
      sleep 15
    fi
  fi
}

# Restart mysqld:
mysqld_restart() {
  mysqld_stop
  mysqld_start
}

case "$1" in
'start')
  mysqld_start
  ;;
'stop')
  mysqld_stop
  ;;
'restart')
  mysqld_restart
  ;;
*)
  echo "usage $0 start|stop|restart"
esac

Ora avviamo il server:

./rc.mysqld start

Ora mettiamo al sicuro il server settando la password di root e cancellando il database test

# cd /usr/local/mysql/bin 
# ./mysql -u root -p
mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('newpwd');
mysql> SET PASSWORD FOR 'root'@'host_name' = PASSWORD('newpwd');
mysql> DROP DATABASE test;

Poi cancelliamo gli account anonimi:

mysql> DROP USER ''@'mysql-51';
mysql> DROP USER ''@'mysql-51';

mysql> SELECT User, Host, Password FROM mysql.user;
+------+-----------+-------------------------------------------+
| User | Host      | Password                                  |
+------+-----------+-------------------------------------------+
| root | localhost | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| root | host-name | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| root | 127.0.0.1 | xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
+------+-----------+-------------------------------------------+
3 rows in set (0.00 sec)

Infine, dal momento che le librerie vengono messe in /usr/local/mysql/lib e non in lib64, si potrebbero avere dei problemi nelle piattaforme a 64b quando si configura php, per esempio, che cerca le librerie nella directory lib64.

Ovviamo a questo inconveniente creando un link simbolico:

cd /usr/local/mysql
ln -s lib lib64

Aggiornare mysql

Come regola generale, per aggiornare MySQL da una release a un'altra, si dovrebbe fare l'aggiornamento alla serie immediatamente successiva. Le note seguenti sono state testate per quanto riguarda l'aggiornamento dalla v. 5.0 alla v. 5.1, dalla v. 5.1 alla v. 5.5 e dalla v. 5.5 alla v. 5.6.

Per fare l'aggiornamento è necessario lanciare il programma mysql/bin/mysql_upgrade. Ma se si hanno tabelle Innodb il processo può anche fallire, questo perchè Innodb non supporta REPAIR TABLE, quindi useremo mysqldump per creare un dump file (di backup) e mysql per caricare lo stesso file, come descritto sotto.

Supporrò di seguito che a questo punto del lavoro il vecchio server sia ancora installato nella cartella /usr/local/mysql-5.1 e il nuovo server debba essere installato nella cartella /usr/local/mysql-5.5. Il server che sarà messo in produzione sarà quello linkato simbolicamente a /usr/local/mysql:

root@mysqlserver:/usr/local> ls -l

lrwxrwxrwx 1 root root 9 Nov 1 16:52 mysql -> mysql-5.1/
drwxr-xr-x 2 root root 4096 Nov 1 16:50 mysql-5.1/
drwxr-xr-x 2 root root 4096 Nov 1 16:50 mysql-5.5/

Il file dump deve essere creato con il vecchio server, e ovviamente sarà ricaricato nel nuovo server. Pertanto ci logghiamo nel vecchio server e backuppiamo tutti i database:

cd /usr/local/mysql/bin 
./mysqldump --all-databases > ../../dump.sql -u root -p[password]

Ora arrestriamo il vecchio server

/path/to/rc.mysqld stop

Ridefiniamo ora il link simbolico, di modo che la prossima volta che lanceremo rc.mysqld verrà avviato il nuovo server:

rm mysql
ln -s mysql-5.5 mysql

Avviamo il server:

/path/to/rc.mysqld start

Ripristiniamo i database

/usr/local/mysql/bin/mysql < ../../dump.sql -u root -p

Se si ottiene un errore come ad esempio questo

ERROR 6 (HY000) at line 30: Error on delete of './db_name/table_name.MYI' (Errcode: 13)

ecco come gestire i codici di errore:

> /usr/local/mysql/bin/perror 13

OS error code  13:  Permission denied

Questo perchè (http://dev.mysql.com/doc/refman/5.5/en/load-data.html)

For security reasons, when reading text files located on the server, the files must either reside in the database directory or be readable by all. Also, to use LOAD DATA INFILE on server files, you must have the FILE privilege. See Section 5.4.1, “Privileges Provided by MySQL”. For non-LOCAL load operations, if the secure_file_priv system variable is set to a nonempty directory name, the file to be loaded must be located in that directory.

Alla fine ho capito che (prova ed errore parecchie volte) sia dump.sql che la cartella data devono avere privilegi777.

cd /usr/local/mysl/data 
chown -R root.root . 
chmod -R o+wrx . 
chmod 777 /usr/local/dump.sql 

/usr/local/mysql/bin/mysql < /usr/local/to/dump.sql -u root -p

e così ce l'abbiamo fatta!

Ora ripristiniamo i privilegi alla  cartella data

chmod -R o-wrx . 
chown -R mysql.mysql .

Per essere sicuri che tutto sia ora ok, lanciamo il comando mysql_upgrade

/usr/local/mysql/bin/mysql_upgrade -u root -p

Enter password:
Looking for 'mysql' as: ./mysql
Looking for 'mysqlcheck' as: ./mysqlcheck
Running 'mysqlcheck with default connection arguments
Running 'mysqlcheck with default connection arguments
db1.table1                           OK
db1.table2                           OK
db2.table1                           OK

questo esegue un mysqlcheck/repair. Se tutte le tabelle sono OK si può mettere il nuovo server mysql produzione.

Aggiungi un commento