====== MySQL ======
===== Benchmark de MySQL =====
SELECT benchmark(100000000,1+2);
===== Reset un mot de passe root perdu =====
sudo /etc/init.d/mysql stop
sudo mysqld_safe --skip-grant-tables &
mysql
update mysql.user set password = password('VOTRENOUVEAUMOTDEPASSE') where user = 'root';
flush privileges;
exit
sudo /etc/init.d/mysql stop
sudo /etc/init.d/mysql start
===== Dump des privilèges des utilisateurs =====
mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
'SHOW GRANTS FOR ''', user, '''@''', host, ''';'
) AS query FROM mysql.user" | \
mysql $@ | \
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
===== Réplication Master-Master =====
* Serveur 1 : 192.168.88.101
* Serveur 2 : 192.168.88.102
**Principe : ** Le serveur 1 sera à la fois master pour le serveur 2 et le slave pour serveur 2 et inversement.
**Remarque : ** Il est possible en adaptant un peu cette configuration de synchroniser que certaine bases.
* Instalation sur les deux machines des paquets **mysql-server** et **mysql-client**
* Sur serveur 1 :
* Editer le fichier ///etc/mysql/my.cnf//
* Ajouter dans //[mysqld]// : server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
* Commenter la ligne : bind-address = 127.0.0.1
* Exécuter la requête SQL suivante : grant replication slave on *.* to 'replication'@192.168.88.102 identified by 'mdpslave';
* Redémarrer le service //MySQL//
* Sur serveur 2 :
* Editer le fichier ///etc/mysql/my.cnf//
* Ajouter dans //[mysqld]// : server-id = 2
log_bin = /var/log/mysql/mysql-bin.log
* Commenter la ligne : bind-address = 127.0.0.1
* Ajouter dans //[mysqld]// : master-host = 192.168.88.101
master-user = replication
master-password = mdpslave
master-port = 3306
A partir de MySQL 5.7, cette configuration est faite à l'aide de la requête SQL suivante : CHANGE MASTER TO MASTER_HOST='192.168.88.101', MASTER_USER='replication', MASTER_PASSWORD='mdpslave';
* Redémarrer le service //MySQL//
* Exécuter la requête SQL suivante : start slave;
* Pour savoir si la réplication se passe correctement exécuter la requête suivante : show slave status\G;
* Le résultat de cette requête devrais être a peu près : *************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.88.101
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 263
Relay_Log_File: mysqld-relay-bin.000003
Relay_Log_Pos: 408
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
* Les valeurs //Slave_IO_Running// et //Slave_SQL_Running// doivent être à **Yes**.
* Cette vérification est également possible depuis serveur 1 en exécutant la requête SQL suivante : show master status;
* Le résultat de cette requête devrais être a peu près : +------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 106 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
* Exécuter ensuite la requête SQL suivante : grant replication slave on *.* to 'replication'@192.168.88.101 identified by 'mdpslave2';
* Sur serveur 1 :
* Editer le fichier ///etc/mysql/my.cnf//
* Ajouter dans //[mysqld]// : master-host = 192.168.88.102
master-user = replication
master-password = mdpslave2
master-port = 3306
* Redémarrer le service //MySQL//
* Exécuter la requête SQL suivante : start slave;
* Vérifier que la synchronisation se passe correctement dans se sens également en exécutant la requête SQL : show slave status\G;
* Le résultat de cette requête devrais être a peu près : *************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.88.102
Master_User: replication
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 263
Relay_Log_File: mysqld-relay-bin.000003
Relay_Log_Pos: 408
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
* Les valeurs //Slave_IO_Running// et //Slave_SQL_Running// doivent être à **Yes**.
* Sur serveur 2, la requête SQL suivante show master status;
devrais retourner à peut près la même chose que sur serveur 1
La synchronisation est normalement opérationnel.
===== Si ça se passe mal =====
==== Could not find first log file name in binary log index file ====
Si vous rencontrez une erreur du type :
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: ‘Could not find first log file name in binary log index file’
Voici la solution à appliquer :
* Sur le slave : stop slave;
* Sur le master :
* Exécuter : flush logs;
show master status;
* Noter le nom du log et la position
*Sur le slave : CHANGE MASTER TO MASTER_LOG_FILE=’log-bin.00000X′, MASTER_LOG_POS=106;
start slave;
==== Resynchro complète d'une des machines sur l'autre ====
* Sur une des deux machines que l'on choisira comme étant **master** :
* Exécuter les commandes SQL suivantes : RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
* Copier le résultat de la dernière requête (//File// & //Position//)
* Faire un dump des bases : mysqldump --all-databases > /tmp/mysql.sql
* Exécuter la commande SQL suivante : UNLOCK TABLES;
* Sur l'autre machine :
* Exécuter la commande SQL suivante : STOP SLAVE;
* Importer le dump généré sur l'autre machine : mysql < /tmp/mysql.sql
* Exécuter les commandes SQL suivantes en adaptant les variables //MASTER_LOG_FILE// et //MASTER_LOG_POS// avec les informations obtenu lors des premières requêtes sur la machine master : RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;
START SLAVE;
* Vérifier que la synchro est bien reparti à l'aide de la requête SQL : show slave status\G;
===== Optimiser MySQL =====
Utiliser l'outil **mysqltuner** qui vous dira que faire. Si il vous en parle, pour défragmenter vos tables, utiliser le script suivant :
#!/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,.,' )"
# Run Optimize on
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
**Source : ** http://blog.barfoo.org/2008/09/19/defragmenting-all-fragmented-myisam-tables/
===== Recrée l'utilisateur debian-sys-maint =====
GRANT ALL PRIVILEGES ON *.* TO 'debian-sys-maint'@'localhost' IDENTIFIED BY '' WITH GRANT OPTION;
===== Extraire les dumps DB par DB d'un dump complet =====
Le script ci-dessous automatise cela :
#!/bin/bash
IN="$1"
[ -z "$IN" -o ! -r "$IN" ] && echo "Usage : $0 input.sql" && exit 1
currentdb=""
dbline=""
endline=""
nbextracted=0
headend=""
function extract() {
headend="$1"
db="$2"
f="$3"
e="$4"
file=db_$( echo "$db"|sed 's/[^A-Za-z\-\_]//g' ).sql
echo -n "Extract DB $db (from $f to $e) to $file ... "
sed -n 1,${headend}p $IN > $file
sed -n ${f},${e}p $IN >> $file
echo "end."
let nbextracted=nbextracted+1
}
IFS="
"
for line in $( grep -n '\-\- Current Database:' $IN )
do
nbline=$( echo "$line"|cut -d':' -f1 )
if [ ! -z "$currentdb" ]
then
let f=dbline-1
let e=nbline-2
extract "$headend" "$currentdb" $f $e
else
let headend=nbline-2
fi
dbline=$nbline
currentdb=$( echo "$line"|cut -d'`' -f2 )
done
if [ ! -z "$currentdb" ]
then
let f=dbline-1
e=$( wc -l $IN|awk '{print $1}' )
extract "$headend" "$currentdb" $f $e
fi
echo "$nbextracted extracted DB(s) from $IN"