====== 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"