OpenSuse 10.2 – bilan

Finalement, je ne suis pas déçu (du moins pour l’instant), l’installation sous Linux OpenSuse 10.2 s’est merveilleusement passée – tous les périphériques ont été détectés et configurés correctement. Seul petite peur au démarrage : des barrette de DDR2 non reconnues par la CM (marque LDLC), mais qui marchent très bien sur ma P5B-VM empêchaient la carte de démarrer… mais du style encéphalogramme plat … petite frayeur !

Passé ce point, mise à jour du BIOS … de base était livré un 0401, je cherche donc a mettre le 0608 à partir d’une clef USB (qu’il faut brancher avant de demarrer le PC)… Ca ne marche pas … La carte mère croyant que 0401 est plus récent que 0608 … bravo Asus … solution : passer par l’utilitaire de flashage DOS. Les versions suivantes n’ont pas ce problème.

La configuration du Raid Jmicron s’est plutot bien passée sur mes deux disques SATA et le nouveau disque ainsi créé a tout de suite été identifié sous Linux, j’ai pu créer mes partitions dessus. les performances semblent bien meilleures que ce que j’obtenais par raid-soft.
Le reste de l’installation de linux s’est déroulé sans accros : adaptateur réseau détecté, pas de soucis pour l’instant avec 4Gb…

En bref, après tous mes déboirs lié au chipset 965G, je suis plutot satisfait de la P5N-E et sont N650i.

Asus P5B-VM, corruption au dela de 2 Go de mémoire

Depuis que j’utilise un P5B-VM d’assus, j’ai nombre d’ennui, mais celui-ci qui est la cause de pas mal de crash de mon serveur de production est de loin le plus ennuyeux : les données sont corrompues sur les disques… de façon aléatoire.
J’ai mis un moment pour cerner la cause … le temps de vérifier les deux disques utilisés en SATA, de checker la mémoire, puis de s’assurer que ce ne soit pas lié à l’usage de XEN ou du RAID… Maintenant, c’est clair, le problème apparaît sur une Linux de base fraîchement installé … pourquoi, c’est encore un grand mystere, mais donc attention à cette carte mère !!!

Ma config : ASUS P5B-VM (bios 901) avec core 2 duo underclocker (ca merde aussi à frequence normale) @ 1.6G / 4Go de Ram / 2 HD Sata 80Go. Kernel 2.6.18 (Opensuse 10.2)

Mise en evidence du problème :
xen-prod:/ # head –bytes=300m /dev/urandom > test
xen-prod:/ # for i in `seq 0 9` ; do cp test test$i ; done
xen-prod:/ # md5sum test*
014666c728c9e3b8299579fae499864a test
014666c728c9e3b8299579fae499864a test0
333fd93d093ac612cd8d5f65628f734e test1
1ab6ee68c6a7d9ff5a05f9d63f0f6df6 test2
96e96483e3175a59c9c05b6720514e1e test3
014666c728c9e3b8299579fae499864a test4
b24dbccc9f4831f8825ab4a55a3be4aa test5
8493efc9c14e4b5c162ac23696fbc16a test6
6a5f4301f66d0379049d79d0e14e2a87 test7
2c81cfa1c3a03aba134574922ee5d75c test8
2ea15c8392bfd0123472a80125bb3abe test9

Soit après copie, 70% des fichiers diffèrent de l’orignal !!

J’ai un peu tout essayé : desactivé le Memory remapping et me priver de 1.2G, passer le sata en mode “compatible” ; ext3 / reisefs … rien n’y fait !!!

Je suis a deux doigts d’aller m’acheter un autre carte mère, donc mon conseil, éviter celle-ci… et si vous avez une solution … contactez moi !
Après quelques recherches supplémentaires, en enlevant 2G le problème disparaît. la mémoire n’est pas en cause puisqu’en inversant les barrettes le problème n’apparaît plus non plus. C’est bien la carte mère (ou sa gestion sous linux) qui pose problème. J’avais lu des problèmes liés au chip ethernet, mais pas au contrôleur SATA … il y en a donc … Bref, au choix .. un serveur à 2Gb ou une nouvelle carte mère.. je crois que je vais tenter l’option n°2

OpenSuse 10.2, problème de niveau sonore

Toujours quelques soucis de plus … sans quoi je m’ennuierai sans doute … Bref, depuis que je suis passé de l’opensuse 10.1 à 10.2 j’ai perdu pas mal de dB sur ma carte son.

Je ne suis pas totalement sure de la cause, mais si ça vous arrive, je peux vous proposer la solution suivante :
Choisir comme système de son OSS (dans le control-panel de KDE > Son et multimédia > Système de son > Matériel). Une fois le système de son relancé (il faudra peut être un petit kill des familles pour tuer l’ancien…) il est possible via Kmix de modifier le niveau des VIA-DXS, ils étaient grosso-modo à 0 … quand on les passe à quelque chose comme 75% … comme par hasard ça fonctionne 😉
Une fois ce paramétrage fait, il est aussi possible de positionner les valeurs des DXS par les commandes suivantes:

amixer set ‘VIA DXS’,0 85% unmute
amixer set ‘VIA DXS’,1 85% unmute
amixer set ‘VIA DXS’,2 85% unmute
amixer set ‘VIA DXS’,3 85% unmute

Passage à Mysql5 et format des TIMESTAMP

Suite a une migration vers Mysql5 et le driver jdbc 3.1.12, mes programmes qui fonctionnaient bien avant se sont mis à générer des exceptions pour le motif suivant :
java.sql.SQLException: Cannot convert value ‘0000-00-00 00:00:00′ from column 11 to TIMESTAMP

Il semble donc que les dites versions, par rapport aux anciennes retournent un valeur “000-00-00 00:00:00” plutot que null lorsque l’on a cette valeur en base (ce qui soit dit en passant a peut être du sens) n’empeche que ca met bien la grouille… alors plutot que de se lancer dans une fastidieuse réécriture de code, il y a le paramètre miracle qui sauve la vie !!

Pour revenir au fonctionnement d’antant, il faut ajouter à la suite de la chaine de connexion l’option suivante:
jdbc:mysql://monHost/maBase?zeroDateTimeBehavior=convertToNull

Testé et approuvé !

Mise à jour avec Yast sur opensuse 10.1

J’ai rencontré quelques soucis pour mettre à jour ma Suse 10.1 ; plus particulièrement pour configurer le serveur de mise à jour. En effet dans mon cas la procédure d’inscription par Yast n’a jamais voulu fonctionner. Bref … Voila comment configurer manuellement le serveur de mise à jour ..

Vous procédé comme pour l’installation d’un fournisseur de RPM quelconque mais choisissez les modes et options suivantes:

  • HTTP
  • nom du serveur : ftp.tu-chemnitz.de
  • répertoire : /pub/linux/suse/ftp.suse.com/suse/update/10.1

Chez moi … ca fonctionne!

OpenSuse – Reconstruire la base corompue du gestionnaire RPM

Suite à un crash encore inexpliqué, la base RPM d’un de mes serveur s’est retrouvée totalement corompue !!! Que faire dans un tel cas ?

Il existe bien quelques option magiques telles que rpm –rebuilddb mais bien sure ce fu sans succès pour moi. Impact de ce problème : impossible de reinstaller des packages partis en morceau lors d’une mise à jour …. ennuyeux quand il s’agit de la JVM sur un serveur web j2ee … Bref… quand plus rien ne marche, il faut sortir l’artillerie lourde.
Attention, ce qui suit s’approche d’une opération de type arakiri … chacun assumera donc ses responabilités si ca venait à sateliser votre serveur …. Pour ma part ca m’a sauvé la vie.
Bon bref… c’est à vos risques et périls.

Donc, pour s’en sortir, il faut degager la base corompue et en installer un neuve. La base se trouvant dans /var/lib/rpm il faut commencer par une petite copie de sauvegarde :
cd /var/lib
cp -R rpm rpm.old

Ensuite créer un nouvel espace pour la base neuve :
mkdir rpm ; mkdir rpm/alternatives
Maintenant on cré la nouvelle base :
rpm –initdb –dbpath /var/lib/rpm

Il ne reste plus qu’a reinstaller les package en vrac dans la base d’origine… Mais bien sur, les dépendence n’etant plus dans la nouvelle base il faudra force un peu les choses avec les options suivantes :
rpm -i –nodeps –force nom_du_package.rpm
Cela ne fonctionne que si les packages etaient deja installé, je veux dire si les dépendences sont bien présentes sinon il faudra les reconstruire en installant tout à la main …

A la fin, il est plutot mieux de revenir à l’ancienne version de bdd en recopiant dans l’autre sens….

Impact applicatif du passage à UTF-8

Et oui la mode UTF8 arrive partout … et c’est un bien fait, c’est sur… comment envisager de continuer à créer des applications ne fonctionnant que dans une langue ?!?

Mais que se passe-t-il lorsque l’on transforme une application existante utilisant le classique WEBISO (ISO-8859-1) pour ses interfaces et traitements en une application du futur basée sur UTF8 ? C’est ce qui m’a occupé ces quelques derniers jours au travail, alors autant vous faire partager cette expérience !

Pour tout comprendre, il faut savoir qu’en WEBISO les caractères sont tous codés sur 8 bits (1 octet) et que par conséquent tous les caractères du monde ne peuvent être représentés, mais les traitements sont simples : par exemple tronquer une chaîne à 10 caractères signifie simplement ne garder que 10 octets.
En UTF8, la taille d’un caractère dépend du caractère lui-même. Les caractères basiques (les 128 premiers) sont codés sur 1 octet et l’encoding est identique à l’ASCII, si bien qu’un texte en anglais de base sera grosso modo le même en UTF8 et en WEBISO. Pour ce qui est de nos écris, latin que nous sommes, il n’en va pas de même : les caractères accentués valent généralement deux octets. Les caractères un peu plus spéciaux (comme TM) par exemple valent 3 octets…

Ceci a de nombreux impacts dans les programmes. Que l’on peut classer en deux familles:

  • Ceux qui concernent l’apparence du caractère
  • Ceux qui concernent la taille du caractère

Pour ce qui est du problème de l’apparence, vous l’aurez sans doute déjà rencontré sur Internet : à la place de caractères comme é vous allez trouver des choses comme ou d’autres hiéroglyphes du même ordre. Ce problème se résout par transcodification. Il arrive lorsque l’on charge des données d’un encoding donné (WEBISO) par exemple vers une base qui est dans un autre encoding (UTF8). Ainsi lorsque l’on migre une application en UTF8, il faudra bien faire attention à l’encoding des flux d’entrée de la base et l’encoding des flux de sortie. Si l’on ne fait pas attention, les applications réceptrices ne seront peut être plus à même de traduire les caractères correctement.
Lorsque les fichiers sont importés par SQL-LOADER ou Java, il est généralement possible de spécifier l’encoding du fichier source des données en positionnant simplement la locale de l’utilisateur lançant le batch de chargement. L’encodage de destination étant alors pris en charge par le moteur Oracle
Dans le cas de fichiers extraits de la base par PL-SQL, si rien n’est précisé, c’est l’encoding de la base qui est utilisé par le PL-SQL (en java par contre ce sera toujours celui de l’utilisateur batch). le fichier devra alors être converti. Les outils de conversion sont standard sous UNIX.

La seconde catégorie d’impacte concernant la taille de données est plus génant car il nécessite souvent de redéfinir le modèle de données.
Le type de données usuel en SQL pour stocker des chaînes de caractères est VARCHAR2. Une déclaration classique étant VARCHAR2(10) pour indiquer que l’on souhaite 10 … à votre avis ?!? … BYTES !! et c’est là tout le problème. Par défaut on compte en BYTE et ce à cause d’un paramètre qui est NLS_LEN_SEMANTIC qui fixe si l’on parle par defaut en BYTE ou en CHAR. Du coup une chaîne de carcatère UTF8 telle que “abcdefghij” qui fera 10 caractères et 10 octets tiendra dans le champ et une chaîne comme “àbcdéfghïj” fera 10 caractères toujours mais cette fois 13 octets (à=2 é=2 ï=2) et Oracle vous retournera une erreur. Le plantage ne sera donc pas systématique d’où le danger…
Pour ce sortir de cette embûche il existe une solution qui semble simple : changer le paramètre NLS_LEB_SEMANTIC, mais voilà, Oracle est un produit comment dire…. leader (c’est ca le terme) et ce paramètre est des plus mal supporté. Ainsi l’application de patch par exemple nécesiste un retour au mode BYTE qui pourra être désastreux pour l’intégrité de la base si l’on ne fait pas attention … ajoutons à cela d’autres problèmes d’incompatibilité avec certains progiciel… bref cette solution simple n’est pas vraiment applicable.
Les solutions qui sont donc plus adaptées conduisent à retoucher les modèles de données en transformant les VARCHAR en NVARCHAR, ce second type ayant le bon goût de se définir par défaut en nombre de caractères plutôt qu’on nombre d’octets ou encore de choisir des définitions explicites pour les VARCHAR. Par exemple VARCHAR2(10 CHAR) indiquera que l’on parle bien de 10 caractères et non 10 octets. Dans ce cas, Oracle allouera non pas 10 octets mais 40 octets dans la colonne (le maximum que l’on peut atteindre avec 10 caractères) et vérifiera lors des insert/update que l’on ne dépasse pas le nombre de caractères souhaité.

Cette solution de retouche du modèle de donnée est plutôt lourde mais c’est sans doute la seule vraiment pérenne. En plus de la définition des tables il faudra retoucher une partie du code:
Les PL-SQL si les variables intermédiaires ne sont pas construites par références aux colonnes de la table.
Les SQL/Loaer si les fichiers de contrôles spécifient le type de destination.
Les chargements de type ETL lorsque ceux-ci définissent les types en entrée et sortie (cas courant)

Une solution de replie qui peut être envisagé de façon temporaire consiste à tronquer les données en entrées (type sqlloader) en spécifiant une taille en octets plutôt qu’en caractères. En PL/SQL la commande SUBSTRB par exemple permet de couper une chaîne en une sous chaîne de n octets de long. La coupure est intelligente, elle ne laissera pas de demi-caractères.

An other version i wrote … for our english spoker friends ….

Intro

The xxxxx standards for database encoding, mainly for Applications, is now UTF8 and more precisely AL32UTF8. UTF8 encoding allow databases to support any languages even Asian ones. Most of the XXXX legacies are based on WEBISO8859-1 named also Latin-1 encoding to support special characters like éàî … This choice has a lots of benefic import for our master applications but it also create some new considerations we have to take into account during the development phase.

Let’s try to explain what change make the UTF8 encoding …

Some encoding definitions

WEBISO was an easy encoding for systems as it represents each character on one byte. the first 128 characters are ascii compabible and the next 128 characters represent local and special characters like our “éçà”. Some different encoding name and local pages are used to change the 128 to 255 character code for each country. That means that by the past a file provided from a country to an other (like EST Europe to WEST Europe) could be received with strange or incorrect characters. As an example a central europe file could contain a character like Č (encoded as 0xC8 in ISO-8859-2) this character would be print as a È (encoded as 0xC8 in ISO-8859-1) in a western europe application. A file transcodification is needed but as Č character do not exists in ISO-8859-1 it should be replaced by something like a C. That was for the past …

UTF-8 is a good way to represent any characters in the world. It allows to use up to 4 bytes to represent a character when the choosen encoding is AL32UTF8. As a consequence characters Č and È can be represented in the same page / file. Processing this king of encoding is a little bit more complicated as not all the caracters require 4 byte as to save space in files the most frequent characters will be encoded in 1 byte, the less frequent in 2 bytes … etc Some characters like ? will required 3 bytes (the encoding is 0xE284A2).

As a way to have compatible files (mainly US) a file containing only ASCII-7 characters will be exactly the same in ISO-8859-1, ISO-8859-2 and UTF8. This situation look like a good news but it hides most of the problems we are meeting by implementing UTF8.

Encoding difference consequences (first issues)

By the past when an application received a file in a wrong encoding, the data were load normally in the application but displayed badly as we saw previously. This end-user issue was solved by translating the incoming file and so transform the unknown letter to the nearest one.

UTF8 can create the same issue when a file/flow is imported without the needed translation into an ISO-8859-1 application. This application will print some non-understandable caracters. As an exemple ? character will be print as “â?¢” (with ? for a non printable character) that is for the classical problem…

Now, imagine that the incoming file use a fixed column format, the program will try to read a data at a certain position… concidering the file as an ISO-8859-1 it will try to find that position in a certain byte from the beginning. As the character lenght is not fixed, each time a character will need more than 1 byte, the program will reach the wrong position. As an impact of this jobs can abend or load wrong data in the database.

The solution to bypass this situation is simpely to convert the incoming file in the desired encoding as it was done by the past.

Now, as current caracters like “éèà” cause the described issue and our applications mix UTF8 and WEBISO, it is really important to describe each flow by an encoding type. I mean, when a functionnal analyst describes a flow between two application he must indicate what is the source encoding and what is the destination encoding. Each developpeur should request the encoding type he have to specify when he develop a flow input / output procedure. As a test procedure in unitary tests or qualification, testers should fill some data with the maximum number of non common characters to verify UTF8 application’s compatibility.

Regarding our experience of the problem:

  • EAI flow encoding is generally defined in the flow
  • File import default encoding is genererally defined by the batch user encoding. So by changing this batch user encoding Java will choose the right input encoding. Once java put the data in a String element, it will be converted in Unicode, then reconverted in the database encoding when stored. SQL-loader work in the same way by using the batch user encoding and detect then perform the conversion before updating the database.
  • File export with java run similary as import : output encoding will be by default batch user encoding.
  • PL/SQL export will cause trouble as the output encoding used is the Database encoding. The generated file will have to be converted by a shell command in part of the case.

Encoding lenght consequences (second issues)

The previously described problem hide an other one, more sensible at the origin of that article… To understand it we must go deeper in Oracle configuration parameters… By default an oracle database has a parameter named NLS_LEN_SEMANTIC set to BYTE. The meaning of this parameter is to defined whar we are talking about when we define a classical type like a VARCHAR(10). This parameter answer the following question : what kind of stuff I want to put 10 times in my string ?!?

Regarding the NLS_LEN_SEMANTIC parameter VARCHAR2(10) means “reserve a maximum of 10 BYTES for a string“. Here is the main issue …. as most of us would use this syntax to indicate Oracle to reserve 10 characters…. as we had allways done ! Why is it so different with UTF8 ? It is not different … VARCHAR2(10) or CHAR, VARCHAR allways defined a number of bytes but before using UTF8 1 characters was equivalent to 1 byte.

As a consequence of this, imagine an Xnet screen with a form containing a user free text column with a maximum size of 10. User will for exemple enter “à découper”, Java program will get it, count the characters and accept it as the number of character is equal to 10 – lower or egal the constraint . It will generate the SQL request and send it to Oracle. Oracle will verify the 10 byte constraint and reject it…. This issue is also impacting data flow loading : any data able to contain non ASCI-7 characters are able to abend a loading process. As an impact referential files (like item definition) can abend during loading and stop a batch plan in production because the day before someone create in the referential a longer line with “éàè” characters.

There are three solutions to avoid this situation

  • The simpler one is to change the NLS_LEN_SEMANTIC parameter. This one can be set to CHAR, in this case VARCHAR2(10) would significate 10 CHARS. This solution is really low cost as the database definition for programs do not change and no program have to be rewrite. Unfortunatelly Oracle do not really support this parameter and DBA actually refuse to put it in place. As an example of known problem each patch of the Oracle engine have to be execute in BYTE mode. When this parameter is not set back to CHAR at the end of the Oracle update process, the database could be corrupted and unrecoverable. more over some tools are not yet validated on that mode as Datastage.
  • An other way (the best in my point of view) is to precise for each VARCHAR2 the unit desired. Yous should declare VARCHAR2(10 CHAR). Oracle, il this case will reserve physically 4 more times bytes : 10 CHARS will correspond to 40 BYTES. But oracle will also add a constraints of 10 characters on the column.  In Toad or DB-Visualizer you will generally see the column definition as 40 … be carefull, on toad, is seem that this information is displayed differently …randomly.
  • The last way to implement it is to use the NVARCHAR2 definition as NVARCHAR2 (NVARCHAR, NCHAR) are Character mode storage type by default. so NVARCHAR(10) will correspond to 10 CHARS. So one of the way to convert entierly a database to be UTF8 ready with less effort is to convert all the VARCHAR2 elements to NVARCHAR2 equivalent elements. N/CHAR types encoding is not defined by the usual NLS_ENCODING parameter but it is defined by something likne NLS_NCHAR_ENCODING parameter, becarefull in most of our database, this last was not correclty defined : AL32UTF8 is the standard, not AL16UTF8.

Implemented solution

The best way to do is to study the situation during the analysis phase and to build the solution with the right type… use VARCHAR2(xx CHAR), CHAR(xx CHAR) … definitions is the best way to avoid encoding problems.

In other case you will discover these issues during Central Acceptance or worst in Production, in these situations we studdied two way to solve the problem:

  • The global way: Here, we will convert all the VARCHAR type into NVARCHAR or VARCHAR(xx CHAR). As un impact, most of the SQL/LOADER and ETL process will have to be rewrite. The rewriting time is not big as the unit operation is simple.But, if you own some hundreds of ETL process, it will require some weeks of work. Java should not be impacted. PL/SQL routine should be compatible as mutch as the internal variables use referenced type more instead of fixed types but they should have to be recompiled. All the non regression tests should be perform.
  • The selected way: This method is the oposite one, it consists to change the minimum number of column. As the UTF8 lenght issue only impacts user typed data we can limit the perimeter to columns provided by the internal UI and external flows. Generally these labels represents less than 1% or the overall. The method we used to do that is to determine the source column by the rules previously indicated. Then determine where these columns will be propagated in the application (data copy or transformation) until they reach an output like an ETL flow. The objective of this aproach is to reduce the rework perimiter, mainly regarding the number of impacted ETL and also limit the non regression tests. You will be able to adjust the final perimeter regarding the lavel of risk of each field.

A good way to simpely verify the result of the patch and the non regression is to fill all the source column with a full string of “éàè” characters and start the application…

Conclusion

UTF8 is not just a technical improvement there are consequencies during the analysis phase, the datamodel and the deducted database shema has to take it into account. In the application interfaces encoding has also to be described and sometime conversion scripts will be needed. As a standard a Master Application should store data in UTF8 and should provide an UTF8 interface to the external Master Applications.

When UTF8 encoding impact your application as defined previously, we know some workaround, intermediate solution or global solution we are able to put in place. All of these solution require time to be put in place. These solutions can be cumulative to be able to be planned in patch / release … step by step…

If your application is currently UTF8 and you never think about these problem … I invite you to try to enter a full line of “éééééé” in one of your UI and check the result in database… You may discover a source of risk…

Peformance de Xen comparé à OpenVZ

J’ai trouvé un document interressant sur Internet à ce sujet d’où cet article.

Il s’agit d’une etude comparant la performance d’un systeme de base avec un systeme Xen 3 et un systeme OpenVZ. Vous le trouverez ici. C’est signé HP et bien documenté.
Pour résumer, Xen impacte fortement les preformances du systeme : il divise au moins par deux les perf, principalement à cause de très nombreux echecs de cache de L2 lors des changement de contextes entre VM. OpenVZ semble ne pas souffrir de ce probleme. Bref, même si personnellement je suis très satisfait des résultats il semble qu’une machine Xen se charge beaucoup plus vite qu’une machine normale … il faudra donc se garder de la puissance sous le pied par rapport à une architecture classique.

Le second document est un power point: http://www.hpl.hp.com/techreports/2007/HPL-2007-59.pdf