Sens-Interdit.fr

Tech date('Y-m', strtotime('2008-02')) = '2008-03'

mercredi 31 décembre 2008 à 11:28 (Julien Tartarin)

7 commentaires

Ça peut paraître incroyable mais pourtant c'est vrai :
date('Y-m', strtotime('2008-02')) = '2008-03'

Du moins, les 29 (sauf si l'année est bissextile), 30 et 31 de chaque mois. Il semblerait que strtotime remplace l'absence de numéro de jour par la date du jour courant. En ce qui me concerne, je m'attendais plutôt à ce qu'il considère ça comme le jour 0, jour 1 au pire.

La même règle est valable pour les mois à 30 jours parsés un 31...

Tech Comment réussir son changement de serveur sans prise de tête

samedi 12 juillet 2008 à 21:54 (Julien Tartarin)

8 commentaires

Déplacer un site entier d'un serveur (ou hébergeur) à un autre n'est pas toujours chose aisée, surtout quand il s'agit d'un site dynamique et actif.

Beaucoup ignorent le fonctionnement de la propagation des zones DNS (et des TTLs ou durées de vie). L'erreur numéro 1 à ne surtout pas commettre est de changer les serveurs DNS, leur pointage et le serveur en même temps. L'erreur est fréquente et conduit au mieux à des sites "parallèles" : deux versions à gérer, et des interactions aléatoires avec les utilisateurs. Au pire : le site disparaît, les mails n'arrivent plus et le monde s'écroule.

J'ai récemment vu plusieurs fois ce genre d'annonce de service :

Bon allez, c’est parti, la copie du blog est en place sur le nouveau serveur et la base remontée, je modifie le DNS et la propagation devra se faire dans les 24, 48h. Demain [le blog] aura donc changé de serveur si tout est Ok. [...]

Les éventuels commentaires postés sur l’ancien serveur pendant la période de migration ne seront pas présent sur le nouveau serveur. Ce post ne sera pas visible non plus sur le nouveau serveur.

(bold ajouté par mes soins)

Même si prévenir ses utilisateurs, lecteurs et clients est une bonne chose, je trouve dommage de s'avouer si vite vaincu par un outil technique inconnu. Et de leur faire subir, également.

Voici quelques exemples de migrations mal planifiées malgré une certaine notoriété des sites et/ou de leur responsable :

  • Jeremie Berrebi change son blog de serveur : ... Bon, c'est pas trop grave, seulement quelques commentaires perdus. Le contenu était toujours accessible (en dehors des nouveaux articles bien sûr)
  • Eric Dupin déménage Fuzz, domaine, DNS et serveur en même temps. Résultat : plus de 72 heures de downtime... Et autant de frustration pour les utilisateurs de ce service web.
  • Mathilde décide de déménager Bagatelles.fr : catastrophe ! Outre l'indisponibilité du site, l'export se passe mal (visiblement un problème d'encodage), mais surtout pendant plusieurs jours, pas de commande ni d'email... Dans le e-commerce, non seulement la perte est quantifiable, mais c'est aussi le sérieux, l'image et la confiance de l'enseigne qui est remise en cause.

Heureusement, tous les déménagements de serveur ne se passent pas aussi mal et tout un chacun (un minimum réceptif à la technique) peut parvenir à déplacer son site sans problème et surtout sans le classique délai inexploitable de 24 à 48 heures... Il suffit de faire les choses dans le bon ordre !

Voilà ma procédure :

On suppose que :

  • le domaine est configuré pour recevoir ses emails (MX) sur un serveur tiers (Google Apps, par exemple), le contraire étant pour moi une hérésie.
  • on n'a pas de solution type "IP fail-over" permettant de basculer le routage d'une adresse IP instantanément (et annulant la problématique des DNS)

Y a-t-il transfert de domaine ?

OUI : S'il y a transfert du domaine d'un registrar à un autre, il faut prévoir au moins 2 à 4 semaines pour avoir la certitude que le transfert sera fait au bon moment. Pour un .com, c'est plus rapide, pour un .fr, ça peut être plus lent... La procédure varie selon l'extension du domaine et les registrars entrant et sortant, je ne la détaille donc pas plus. Attention toutefois à bien laisser les mêmes serveurs DNS que précédemment, sans quoi le domaine risque d'être "parké"...

NON : Rien à faire pour l'instant.

Y a-t-il changement de serveurs DNS ?

OUI : Il faut s'y prendre au moins une semaine à l'avance. Dans un premier temps, configurer la nouvelle zone à l'identique de l'ancienne. Seuls les champs SOA et NS diffèrent, puisqu'ils doivent contenir l'identité des nouveaux serveurs DNS. Ensuite, lancer la procédure au niveau du registrar. Il peut se passer plusieurs heures (habituellement entre 6 et 48 heures) avant que le changement soit bien pris en compte partout. Toutefois, même pendant la transition, le site est accessible et fonctionnel. Zéro coupure.

Note : S'il y a transfert de domaine ET changement de serveurs DNS, la procédure au niveau du registrar peut n'être effectuée que sur le nouveau registrar au moment du transfert, tant que les nouveaux serveurs DNS sont configurés correctement. D'une pierre deux coups, et toujours aucune coupure malgré une transition un peu longue.

NON : Rien à faire pour l'instant.

Étapes préliminaires

Le nouveau serveur

Il faut bien le faire à un moment, ça peut être fait bien avant les transferts de domaine et DNS, ou pendant, ou après.

Commander, installer, configurer, et tester le nouveau serveur (ou hébergement). Mais surtout, y installer une copie du site : si le site crée/supprime des fichiers (upload d'images/vidéos par exemple), on utilisera de préférence rsync. Si les fichiers sont statiques (comme un blog : aucun fichier n'est créé en dehors des images ajoutées aux billets), une copie pure et dure à coup de scp ou via FTP est également possible. rsync est nettement plus souple (ne copie que ce qui diffère) et rapide (liaison serveur à serveur vs serveur vers client vers serveur), mais ne peut pas toujours être utilisé (il faut un accès SSH et/ou un hébergeur sympa).

Y installer une copie de la base de données. Un réimport de backup à peu près à jour peut faire l'affaire. J'ai une commande magique et extrêmement rapide pour ça, mais c'est secret défense :) Ce qui compte, c'est que la structure SQL soit à jour, peu importe pour les données elles-mêmes.

Pour pouvoir tester correctement le nouveau site sur le nouveau serveur, la meilleure solution à mon goût est de modifier temporairement son fichier hosts (ce fichier permet de passer outre les serveurs DNS pour résoudre un nom en adresse IP) pour tester le site sur le nouveau serveur et ajuster les petis détails si besoin (un module oublié, une permission mal remise, etc.). L'emplacement du fichier dépend du système d'exploitation, mais Google a la réponse.

Cette étape de test permet un passage en production sans aucun problème.

Réduire les TTLs au niveau de la zone DNS

Malgré des acronymes barbares, les TTLs (pour Time To Live) sont de précieux alliés s'ils sont bien utilisés, mais sont aussi la cause de tous les problèmes cités plus haut quand ils ne sont pas compris et maîtrisés. La propagation, ennemie jurée ? Je dirais plutôt amie incomprise...

Une fois les transferts administratifs effectués et effectifs (soit minimum 48h après l'application du changement de serveurs DNS et au moins autant après la notification de fin de changement de registrar), il faut donc réduire les TTLs. La procédure change du tout au tout selon l'entité qui gère les DNS : interface d'administration ou fichier de configuration... Le principe reste le même : il faut que chaque enregistrement dans la zone expire le plus vite possible. Par défaut, la valeur est souvent de 86400 secondes (24 heures). Je recommande une valeur de 5 minutes maximum (300 secondes), 1 minute si possible (60 secondes). Il ne faut surtout pas modifier le pointage des enregistrements pour l'instant.

Cela aura pour effet de rendre les prochains changements rapides, et de réduire la période de propagation à quelques minutes... Et pour l'instant toujours rien de visible par les utilisateurs, lecteurs et clients.

Transfert des données

Quand toutes les étapes précédentes sont terminées et vérifiées, on peut passer au transfert réel des données.

Afin de conserver l'intégrité des données, il convient de passer l'ancien site en lecture seule, sans quoi des évènements aléatoires peuvent se produire. Il faut ensuite mettre à jour les fichiers (rsync ou FTP) et la base de données. C'est pendant cette étape que la migration apparaît aux utilisateurs, puisqu'ils ne peuvent plus intéragir. Dans certains cas (média), cela peut tout à fait passer inaperçu. La durée de la copie est variable et dépend directement de la taille du site.

Une fois le transfert effectué, vérifier (toujours grâce au fichier hosts) une dernière fois que le nouveau site est en état, puis changer le pointage DNS sans modifier les TTLs (au cas où un problème survient, le retour en arrière doit rester possible rapidement). Le changement sera propagé en quelques minutes seulement (penser à retirer la ligne du fichier hosts pour confirmer...), le nouveau site est en production.

Finalisation

S'il n'y a toujours pas de problème après quelques minutes ou heures, il faut remettre les choses en mode croisière : remettre des TTLs longs (1 jour / 86400 secondes), lancer une première backup sur le nouveau serveur et récupérer (et conserver) la dernière backup de l'ancien serveur.

Conclusion

Zéro coupure, zéro bizarrerie, seulement un passage en lecture seule de quelques minutes (durée égale au temps de la mise à jour des données).

Tout ça parce que la transition a été planifiée, surtout pas précipitée, et que les choses ont été faites dans l'ordre.

Tech Mysqldump + InnoDB + grosse table

vendredi 27 juillet 2007 à 16:17 (Julien Tartarin)

2 commentaires

Pour dumper une grosse table InnoDB (manipulation inutile en MyISAM) malgré de nombreux accès clients simultanés, sans perte de performances, il ne faut surtout pas utiliser l'option --opt de mysqldump qui ajoutera un verrou sur la table et mettra en attente toutes les requêtes secondaires pendant toute la durée du dump, qui peut atteindre plusieurs minutes ou dizaines de minutes selon les cas...

Au lieu de ça, le plus efficace est d'ajouter les options suivantes :

  • --extended-insert ou -e : le résultat du dump sera optimisé avec des insert multiples : moins de texte brut et plus de performances lors de la récupération des données
  • --quick ou -q : pour ne pas utiliser de buffer lors de la lecture des tables (le cas contraire saturerait la RAM en quelques secondes)
  • --single-transaction : le plus important, ou presque, qui permettra de ne lire que l'état de la table au début du dump, malgré les modifications qu'elle peut continuer à accepter.

Le reste des options, hormis --opt et --lock-tables, est variable et à la convenance de l'utilisateur.

Rediriger le flux STDOUT directement vers gzip ou bzip2 permet d'économiser un espace non négligeable sur le disque : pour une table de 160 Mo une fois dumpée, 13 Mo après le passage de bzip2, ça fait mal !

Conclusion : mysqldump -q -e --single-transaction base | bzip2 -c > base.sql.bz2

Tech Gros bug MySQL

mercredi 16 août 2006 à 14:57 (Julien Tartarin)

Pas de commentaire

Après la mise à jour du serveur qui héberge ce blog (et ceux de mes collègues associés et amis), plus rien ne fonctionnait...

Au début, l'erreur affichée était très bizarre :

Fatal error: Call to a member function isEmpty() on a non-object

L'objet en question était une variable définie quelque part dans la classe "recordset" de Dotclear... Un vrai bazar pour aller la retrouver... et constater que ça n'avançait à rien.

Par chance, sur mon blog j'ai une requête SQL perso pour les tags (le plugin me plaisait pas), et elle échouait aussi. Un coup de "or die(mysql_error())" et j'ai pu voir la fameuse et surtout véritable erreur.

L'erreur ressemblait à ça :

Can't create/write to file './tmp/#sql-4e68_8.frm' (Errcode: 13)

Après recherche sur Google, j'ai trouvé une FAQ Wordpress qui a résumé le problème et sa solution :

Problem: The MySQL variable tmpdir is set to a directory that cannot be written to when using PHP to access MySQL.

To verify this, enter MySQL at the command line and type show variables;

You'll get a long list and one of them will read: tmpdir = /somedir/ (whatever your setting is.)

Solution: Alter the tmpdir variable to point to a writable directory.

Changer le dossier étant inutile à mon goût, j'ai juste chmodé /var/tmp en 777 puisqu'il était bizarrement devenu read-only (sauf par l'user root).

Et tout a remarché d'un coup (sauf le cache de Firefox...).

Tech Débloquer l'utilisation de l'event "onload" en Javascript

vendredi 30 juin 2006 à 09:05 (Julien Tartarin)

11 commentaires

L'event onload est très pratique pour initialiser des scripts Javascript, mais il a une limite : il attend que tout le contenu de la page soit chargé pour s'exécuter.

Lire la suite...

Tech preg_match()

lundi 19 juin 2006 à 18:09 (Julien Tartarin)

4 commentaires

Une petite expression régulière sympathique pour la route :

/^[a-z]{1}(-|(?<!--)([a-z0-9]{1})){2,18}[a-z0-9]{1}$/i

Son pitch, c'est de filtrer les pseudos de Lexode v8 selon leur nouveau format, c'est à dire en acceptant la présence de tirets. Par contre, pour des raisons d'arborescence de fichiers et de compatibilité/respect des normes, le pseudo doit commencer par une lettre et ne pas finir par un tiret. Et puisque c'est plus joli, les tirets consécutifs sont interdits !

J'ai eu la chance d'éplucher en détail la fantastique documentation de PHP (très complète !) pour écrire ce pattern un peu particulier (d'habitude, les expressions régulières sont un peu plus basiques).

Pour me faciliter la vie, j'ai décidé de mettre en place un unit test très basique et rapide pour être sûr en un coup d'œil que chaque cas prévu fonctionne comme attendu (ou pas, d'ailleurs), et j'ai écrit l'expression avec le modifier x (il permet de mettre des espaces pour faciliter la lecture des parenthèses).

Pour la petite histoire, la voilà décortiquée :

  • ^[a-z]{1} on commence par une lettre
  • [a-z0-9]{1}$ on finit par un chiffre ou une lettre
  • {2,18} entre tout ça, on a 2 à 18 caractères : le pseudo fait entre 4 et 20 caractères de toute façon
  • -|(?<!--)([a-z0-9]{1}) au milieu, on a soit un tiret, soit un chiffre ou une lettre qui n'est pas précédé(e) de deux tirets ((?<!--)([a-z0-9]{1}))

Pour exprimer cette condition sur les caractères précédents, c'est la chaîne ?<! qui importe. Et elle porte le doux nom d'assertion arrière négative.

C'est définitif : je suis amoureux des expressions régulières[1] !

Notes

[1] d'ailleurs, c'est comme ça que j'ai découvert la puissance de la programmation, il y a quelques années...

Tech Mesure de performances et optimisation en PHP

dimanche 18 juin 2006 à 23:03 (Julien Tartarin)

3 commentaires

Développer une application, ou plutôt des pages (scripts) à fort trafic (même si tout est relatif) n'est pas la chose la plus évidente à faire. Ces derniers mois m'ont appris quelques éléments non négligeables que je me permets de partager ici.

Lire la suite...

Sens-Interdit.fr