MySQL : convertir les tables MyISAM au format InnoDB photo

MySQL : convertir les tables MyISAM au format InnoDB

MySQL : MyISAM et InnoDB

A ses débuts, MySQL utilisait le moteur de stockage MyISAM.

C’est la raison pour laquelle on retrouve beaucoup d’exemples de création de tables sur Internet avec l’instruction engine=MyISAM (ce qui, au passage, peut faire planter pas mal de créations de bases/tables).

Aujourd’hui, le moteur de stockage par défaut de MySQL est InnoDB.

MyISAM n’est plus activement développé, à l’inverse d’InnoDB. Il est donc recommandé de convertir les tables MyISAM au format InnoDB, afin de bénéficier des dernières optimisations de performance du nouveau moteur.

innodb-myisam-mysql

Le moteur InnoDB

InnoDB est un moteur de stockage inclus d’origine dans toutes les distributions fournies par MySQL AB. Son principal avantage par rapport aux autres moteurs de stockage de MySQL est qu’il permet des transactions ACID (Atomiques, Cohérentes, Isolées et Durables), ainsi que la gestion des clés étrangères (avec vérification de la cohérence).

Toutes les bases de données sont stockées au même endroit. Par défaut dans le fichier ibdata1 qui, sous les systèmes de type unix, se trouve généralement dans /var/lib/mysql. Il est également possible d’utiliser plusieurs fichiers ou même d’utiliser directement une ou plusieurs partitions sur le disque en mode RAW.

Ce moteur de base de données utilise aussi deux fichiers de logs, d’habitude ib_logfile0 et ib_logfile1. Les fichiers de définitions de table .frm sont également dans un dossier au nom de la base comme pour MyISAM.

Depuis sa version 5.5, MySQL utilise InnoDB comme moteur par défaut.

Comment connaitre le format actuel de vos tables ?

Pour faire un petit état des lieux du format actuel des tables de votre base de données, il suffit de vous identifier sur le serveur SQL et de lancer cette requête :

SHOW TABLE STATUS FROM `database`;Code language: JavaScript (javascript)

Il vous suffit de remplacer database par le nom de votre base de données et de regarder la valeur de la colonne Engine.

Convertir les tables MyISAM au format InnoDB

Pour convertir des tables MyISAM au format InnoDB, il suffit de lancer une requête SQL va grandement nous simplifier la vie:

SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')
FROM information_schema.tables
WHERE 1=1
    AND engine = 'MyISAM'
    AND table_schema NOT IN ('information_schema', 'mysql', 'performance_schema');Code language: JavaScript (javascript)

Le résultat de cette requête est une liste bien formatée de requêtes à lancer pour que toutes nos tables soient converties au format InnoDB.

Voici le résultat de cette requête sur le serveur :

+-----------------------------------------------------------+
| CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;')   |
+-----------------------------------------------------------+
| ALTER TABLE blog.blog_wc_comments_subscription ENGINE=InnoDB;
| ALTER TABLE blog.blog_wc_phrases ENGINE=InnoDB;
| ALTER TABLE blog.blog_wc_users_voted ENGINE=InnoDB;
+-----------------------------------------------------------+Code language: JavaScript (javascript)

Toutes les tables des bases de données qui sont au format MyISAM au format InnoDB sont listées, à l’exception des tables utilisées dans la gestion de MySQL (‘information_schema’, ‘mysql’, ‘performance_schema’) qui doivent rester en MyISAM.

Etape de Conversion

Il vous suffit ensuite de lancer cette liste de requêtes ALTER TABLE sous MySQL, Adminer ou PHPMyAdmin pour convertir vos tables. Lancez la liste de commandes que vous venez de trouver :

ALTER TABLE blog.blog_wc_comments_subscription ENGINE=InnoDB;
ALTER TABLE blog.blog_wc_phrases ENGINE=InnoDB;
ALTER TABLE blog.blog_wc_users_voted ENGINE=InnoDB;

Et voilà, vos tables MyISAM sont maintenant devenues des tables InnoDB.

Lire la suite

MySQL : résoudre l'erreur

MySQL : résoudre l’erreur “mysql_connect(): Headers and client library minor version mismatch”

Après la mise à jour vers MySQL 5.6, certaines applications peuvent renvoyer l’avertissement PHP suivant :

PHP Warning: mysql_connect(): Headers and client library minor version mismatch. Headers:50535 Library:50617Code language: CSS (css)
icon-mysql

C’est le cas lorsqu’une application est liée à l’utilisation d’une version spécifique de libmysqlclient18 alors qu’elle est connectée à un serveur MySQL qui tourne sur une version différente.

C’est libmysqlclient18 qui renvoie cet avertissement mais dans certains cas, cela peut impacter l’application et tient plus de l’erreur que de l’avertissement.

MySQL Native Driver

La solution est toute simple : il suffit d’utiliser le pilote MySQL Native Driver php5-mysqlnd au lieu du paquet php5-mysql.

Les avantages de php5-mysqlnd sont multiples : il vient en remplacement de php5-mysql, n’est pas lié à la librairie libmysqlclient, ne renvoie pas d’avertissement “version mismatch” et possède pas mal d’autres caractéristiques intéressantes.

Lire la suite

WordPress : récupérer la liste emails des membres et commentateurs photo

WordPress : récupérer la liste emails des membres et commentateurs

Wordpress icon

Voici deux requêtes SQL pour récupérer la liste des adresses email de tous les utilisateurs d’un site tournant sous WordPress.

Emails des membres

En supposant que le préfixe WordPress est ‘wp_’, cette requête extrait l’adresse email de chaque membre du site :

/* Query name : get members' emails
/* Author : Matt
/* Author URI : https://www.skyminds.net/
*/
SELECT DISTINCT user_email FROM wp_users GROUP BY user_emailCode language: JavaScript (javascript)

Emails des commentateurs

Et cette requête extrait l’adresse email de chaque personne ayant commenté sur le site :

/* Query name : get commenter' emails
/* Author : Matt
/* Author URI : https://www.skyminds.net/
*/
SELECT DISTINCT comment_author_email FROM wp_comments WHERE comment_approved<>'spam' GROUP BY comment_author_emailCode language: JavaScript (javascript)

Astuce SQL : la clause DISTINCT permet d’éviter d’avoir des doublons dans la liste.

WordPress : héberger les images sur un sous-domaine photo 1

WordPress : héberger les images sur un sous-domaine

Cela fait des années que je parle d’héberger les images du site sur un sous-domaine mais j’ai toujours remis cela à plus tard.

Je pensais que la configuration me prendrait un temps infini mais au final cela ne m’aura pris qu’un peu de réflexion et quelques minutes pour tout finaliser.

Le plus long aura été d’écrire ce tutoriel!

Aujourd’hui, c’est chose faite : les images des articles du site sont donc placées sur un sous-domaine pour des raisons de performances.

subdomains

Voici donc un petit tutoriel qui détaille toutes les étapes. Cela prend environ 20 minutes.

Principe de fonctionnement

Les fichiers du site sont présentement servis par Apache. Le domaine est skyminds.net et nous allons créer un sous-domaine, qui est en fait un répertoire au niveau de l’arborescence du site, qui contiendra toutes les images de nos articles.

Par défaut, WordPress place tous les fichiers uploadés via l’interface d’administration dans /wp-content/uploads.

Nous allons donc créer un sous-domaine (static.skyminds.net) qui pointera vers le répertoire /wp-content/uploads.

L’intérêt est que nous n’avons pas à copier ou à déplacer de fichiers. Cela permet aussi de revenir à une installation plus classique à tout moment, sans intervention majeure.

Une fois ce VirtualHost créé, il ne reste plus qu’à modifier les options de WordPress pour les futurs articles et changer les anciennes URI des images dans les anciens articles. P

our finir, nous redirigerons les anciennes URI vers les nouvelles via .htaccess.

Etape 1 : on crée le sous-domaine sur le serveur Apache

Commençons par créer un nouveau VirtualHost pour notre sous-domaine:

nano /etc/apache2/sites-available/static.skyminds.netCode language: JavaScript (javascript)

et ajoutons-y ceci :

ServerAdmin webmaster@localhost
DocumentRoot /home/skyminds/public_html/wp-content/uploads
ServerName static.skyminds.net
ErrorLog /var/log/apache2/www-error.log

        
          AllowOverride None
          RequestHeader unset Cookie
          Header unset Set-Cookie
          Options FollowSymLinks
          Order allow,deny
          Allow from allCode language: JavaScript (javascript)

Plusieurs choses sont importantes à noter dans ce fichier de configuration Apache:

  • DocumentRoot pointe vers le répertoire /home/skyminds/public_html/wp-content/uploads
  • on retire tous les cookies servis par static.skyminds.net

Pas de cookies, pas de soucis et un site qui gagne en rapidité !

Lire la suite

Serveur dédié : mise à jour vers Debian 7 Wheezy photo

Serveur dédié : mise à jour vers Debian 7 Wheezy

debian-wheezy

Hier soir, j’ai mis le serveur à jour : nous passons de Debian 6 (“Squeeze”) à Debian 7 (“Wheezy”) – vous l’aurez remarqué : chez Debian, les versions portent le nom de personnages de Toy Story :)

Histoire de garder une trace de ce que je fais, voici les étapes que j’ai suivies.

Contrairement aux versions précédentes, Debian recommande d’utiliser apt-get au lieu d’aptitude. Donc acte dans ce tutoriel.

Etape 1 : s’assurer que le système est à jour

On vérifie que notre Squeeze est à jour :

apt-get update && apt-get upgradeCode language: JavaScript (javascript)

Etape 2 : installer les nouveaux dépôts

Pour voir vos dépôts existants :

cat /etc/apt/sources.listCode language: PHP (php)

Résultat :

deb http://mirror.ovh.net/debian/ squeeze main contrib
deb-src http://mirror.ovh.net/debian/ squeeze main contrib

deb http://security.debian.org/ squeeze/updates main contrib
deb-src http://security.debian.org/ squeeze/updates main contrib

# Webmin
deb http://download.webmin.com/download/repository/  sarge contrib

# varnish
deb http://repo.varnish-cache.org/debian/ squeeze varnish-3.0

# mod security
deb  squeeze-backports main 

# dotdeb updated LAMP servers
deb http://packages.dotdeb.org squeeze all
deb-src http://packages.dotdeb.org squeeze allCode language: PHP (php)

Il faut remplacer toutes les occurrences de squeeze en wheezy. On peut le faire avec cette commande :

sed -i 's/squeeze/wheezy/g' /etc/apt/sources.listCode language: PHP (php)

Evidemment, il y a un piège : le dépôt des backports a changé de nom et d’adresse. Il se trouve désormais ici :

deb http://ftp.debian.org/debian/ wheezy-backports mainCode language: JavaScript (javascript)

Après modification, voici donc notre sources.list :

deb http://mirror.ovh.net/debian/ wheezy main contrib
deb-src http://mirror.ovh.net/debian/ wheezy main contrib

deb http://security.debian.org/ wheezy/updates main contrib
deb-src http://security.debian.org/ wheezy/updates main contrib

# Webmin
deb http://download.webmin.com/download/repository/  sarge contrib

# varnish
deb http://repo.varnish-cache.org/debian/ wheezy varnish-3.0

# mod security
deb http://ftp.debian.org/debian/ wheezy-backports main

# dotdeb updated LAMP servers
deb http://packages.dotdeb.org wheezy all
deb-src http://packages.dotdeb.org wheezy allCode language: PHP (php)

Etape 3 : lancement de la mise à jour partielle

Mise à jour des fichiers :

apt-get updateCode language: JavaScript (javascript)

Aucune erreur. On continue avec la mise à jour minimale des paquets :

apt-get upgradeCode language: JavaScript (javascript)

Lire la suite

WordPress : des images qui ont perdu leur chemin photo

WordPress : des images qui ont perdu leur chemin

Problème : chemin erroné pour certaines images

lost-sign

En allant faire un tour sur Google Search Console, je me suis aperçu qu’il y a avait des erreurs sur la page Si je pouvais (vraiment) choisir ma voiture… et effectivement, les images ne s’affichaient pas!

Après vérification, il se trouve que le chemin des images était totalement inexistant : c’était un mélange d’URL publique et de chemin privé, donc aucun moyen que les images d’affichent comme il faut avec le chemin privé. Et bien sûr, on ne peut pas éditer le chemin des fichiers depuis WordPress.

Solution : MySQL

En faisant une petite requête sur la table postmeta, je me suis aperçu que ce n’était pas le seul article touché. J’ai donc purement et simplement supprimé le chemin privé dans la table, via une requête SQL :

Query:

UPDATE wp_postmeta SET meta_value = replace(meta_value, '/home/public_html/images/', '') WHERE meta_key='_wp_attached_file';Code language: JavaScript (javascript)

Résultat : 173 rows affected.

Ah oui quand même, 173 enregistrements affectés, cela fait quand même quelques dizaines d’articles sur lesquels les images ne s’affichaient pas. Je n’ai aucune explication à ce phénomène, d’autant que certains de ces articles ont plusieurs années. Sûrement une mauvaise configuration de ma part à un moment donné, je suppose.

Enfin, tout cela pour dire que garder un oeil sur GWT, cela peut être utile pour débugger aussi.

Serveur dédié : installation d'Apache, PHP, MySQL et Webmin photo

Serveur dédié : des paquets LAMP à jour sous Debian

Problème : des paquets vieillots

Lorsque votre serveur tourne sous Debian, les paquets sont éprouvés mais souvent datés. Ils tournent bien mais on ne peut pas vraiment bénéficier des versions les plus actuelles pour Apache, MySQL ou PHP par exemple.

La solution : ajouter un nouveau dépôt pour LAMP

La solution est tout simple, il suffit d’ajouter un nouveau dépôt, Dotdeb, qui permet de mettre à jour les paquets libmemcached, mysql, nginx, percona-toolkit, php5, php5-pecl, pinba-engine, redis, ruby-passenger, zabbix.

On édite donc notre liste :

nano /etc/apt/sources.listCode language: PHP (php)

et on ajoute les dépôts de Dotdeb, qui sont maintenus à jour par Guillaume Plessis :

deb http://packages.dotdeb.org stable all
deb-src http://packages.dotdeb.org stable allCode language: JavaScript (javascript)

et enfin, on ajoute la clé GPG :

wget http://www.dotdeb.org/dotdeb.gpg
cat dotdeb.gpg | apt-key add -Code language: JavaScript (javascript)

La mise à jour se fait comme d’habitude :

apt update && apt upgrade

Lire la suite

Bash : réparer les tables MySQL en cas de crash photo

Bash : réparer les tables MySQL en cas de crash

Bash Il arrive que parfois une table SQL soit complètement plantée, ce qui peut bloquer l’accès à la base de données et donc l’accès au site.

Pour éviter cela, j’ai écrit un petit script bash qui me permet de stopper le serveur MySQL, procéder à la réparation de toutes les tables de toutes les bases de données puis relancer le serveur MySQL, Apache et Varnish.

#!/bin/sh
# MySQL Auto-Repair
# Written by Matt - skyminds.net

# stop the MySQL server
/etc/init.d/mysql stop

# check for errors
myisamchk /var/lib/mysql/*/*.MYI

# ask permission to repair
read -p "Repair tables ? (y/n)" -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]
then
	# repair everything
	myisamchk -r /var/lib/mysql/*/*.MYI

	# restart servers
	/etc/init.d/mysql restart
	/etc/init.d/apache2 restart
	/etc/init.d/varnish restart
else
	/etc/init.d/mysql restart
fi

C’est le genre de petit fichier bash à garder au frais sur le serveur, facile à lancer en SSH depuis n’importe quel terminal en cas de besoin.

Réinitialiser le mot de passe root de MySQL ou MariaDB sous Debian photo

MySQL : changer le mot de passe de l’utilisateur root

icon mysql

J’ai installé la mise à jour Ubuntu 12.04 Precise Pengolin il y a quelques semaines (et je n’aurais pas dû, ma machine laggue comme ce n’est pas permis) et au moment de lancer SAM Broadcaster, un message d’erreur apparaît comme quoi il ne peut se connecter à la base MySQL.

sudo service mysql restart

Résultat :

stop: Unknown instance: 
start: Job failed to startCode language: HTTP (http)

Autre message d’erreur :

/usr/bin/mysqladmin: connect to server at 'localhost' failed
error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)'Code language: JavaScript (javascript)

Etrange, je n’avais rien modifié.

Voici donc en quelques étapes comment changer le mot de passe MySQL de l’utilisateur root lorsqu’on l’a oublié ou qu’il faut le changer sans connaitre l’ancien.

Toutes ces commandes sont à exécuter en tant qu’utilisateur root donc :

sudo -i

Je vous propose deux méthodes : la première méthode s’adresse aux barbus qui veulent mettre les mains dans le cambouis, la seconde à ceux qui veulent faire ça en 2 commandes.

Méthode 1 (mode cambouis)

Etape 1 : arrêt du service mysql

/etc/init.d/mysql stop

Résultat :

Stopping MySQL database server: mysqld.

Etape 2 : lancement du serveur MySQL sans mot de passe

mysqld_safe --skip-grant-tables &

Résultat :

[1] 5025
mysqld_safe Logging to syslog.
mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql
Code language: JavaScript (javascript)

Lire la suite

WordPress : récupérer la liste emails des membres et commentateurs photo

WordPress : nettoyage de la base de données

wordpress_icon_blue Avec le temps, les mises à jour successives et l’installation de différents plugins, la base de données de WordPress a tendance à prendre du poids, ce qui nuit aux performances. Voici donc comment lui faire bénéficier d’un petit régime.

N’oubliez pas de faire une sauvegarde de votre base de données avant de lancer ces requêtes. Backup now.

Nettoyage de wp_postmeta

Avant optimisation, ma table wp-postmeta faisait 12 403 enregistrements.

DELETE FROM wp_postmeta WHERE meta_key = '_edit_lock';
DELETE FROM wp_postmeta WHERE meta_key = '_edit_last';
DELETE FROM wp_postmeta WHERE meta_key = '_wp_old_slug';

Maintenant : 12 240.

Nettoyage de wp_commentmeta

On supprime tout ce qu’Akismet nous a mis dans la table wp_commentmeta :

DELETE FROM wp_commentmeta WHERE meta_key LIKE '%akismet%';

et on supprime toutes les entrées qui n’ont aucune relation avec wp_comments :

DELETE FROM wp_commentmeta WHERE comment_id NOT IN (SELECT comment_id FROM wp_comments);

Nettoyage de wp_options

Passage de 880 enregistrements à 476. WordPress crée ces entrées automatiquement et les purge occasionnellement, autant l’aider un peu.

DELETE FROM wp_options WHERE option_name LIKE '_site_transient_browser_%';
DELETE FROM wp_options WHERE option_name LIKE '_site_transient_timeout_browser_%';
DELETE FROM wp_options WHERE option_name LIKE '_transient_%';

Lire la suite

WordPress : récupérer la liste emails des membres et commentateurs photo

WordPress : retrouver le bouton “Publier”

Problème : plus de bouton “Publier” sous WordPress

wordpress_icon_blue Juste après la migration des bases MySQL, alors que je pensais que tout était bon, je vais sous WordPress pour raconter mes aventures et… plus de bouton “publier” mais un bouton “Soumettre à relecture” comme pour les guests ! Tout cela alors que je suis loggué comme admin, il y a un truc qui cloche.

Après avoir cherché un peu, il s’avère que j’ai copié directement les fichiers de bases de données mais que MySQL n’a pas les droits dessus. Du coup, toutes les tables sont en lecture seule, comme me l’a indiqué une petite requête simple :

Failed to save field : SQL alter table `wp_posts` modify `ID` bigint(20) unsigned not null default NULL auto_increment failed : Table 'wp_posts' is read only

Solution : attribuer les bases de données à mysql

Vous avez besoin de modifier les droits d’accès et d’écriture des fichiers de bases de données. Il faut soit se connecter à distance en SSH sur votre serveur ou en local sur votre machine et lancer la commande chown.

On se met donc dans le répertoire de travail de MySQL :

cd /var/lib/mysql/

et on attribue à l’utilisateur mysql les droits à nos bases de données :

chown -R mysql:mysql *

Lire la suite

MySQL: résoudre l'erreur

MySQL : résoudre l’erreur “Access denied for user debian-sys-maint@localhost”

Problème : l’erreur “Access denied for user debian-sys-maint@localhost” au lancement de MySQL

Lors de la migration de mes bases de données d’un serveur à l’autre, j’ai aussi déplacé la base mysql qui contient tous les utilisateurs, droits… pour ne pas avoir à tout refaire.

Le problème, c’est que chaque installation de MySQL crée un utilisateur de maintenance – debian-sys-maint sur notre serveur Debian – avec un mot de passe unique.

Solution : penser à copier /etc/mysql/debian.cnf

En copiant les bases de données, il faut également penser à copier le fichier /etc/mysql/debian.cnf dans lequel se trouve, entre autres, le mot de passe SQL de l’utilisateur spécial maintenance de Debian.

Lire la suite