MariaDB
 sql >> Base de données >  >> RDS >> MariaDB

Comment exécuter des applications PHP 5 avec MySQL 8.0 sur CentOS 7

Bien que PHP 5 ait atteint sa fin de vie, il existe encore des applications héritées construites dessus qui doivent s'exécuter dans des environnements de production ou de test. Si vous installez des packages PHP via le référentiel du système d'exploitation, il est toujours possible que vous vous retrouviez avec des packages PHP 5, par ex. Système d'exploitation CentOS 7. Cela dit, il existe toujours un moyen de faire fonctionner vos applications héritées avec les nouvelles versions de base de données, et ainsi de tirer parti des nouvelles fonctionnalités.

Dans cet article de blog, nous vous expliquerons comment exécuter des applications PHP 5 avec la dernière version de MySQL 8.0 sur le système d'exploitation CentOS 7. Ce blog est basé sur une expérience réelle avec un projet interne qui nécessitait que l'application PHP 5 s'exécute parallèlement à notre nouveau MySQL 8.0 dans un nouvel environnement. Notez qu'il serait préférable d'exécuter la dernière version de PHP 7 avec MySQL 8.0 pour profiter de toutes les améliorations significatives introduites dans les nouvelles versions.

PHP et MySQL sur CentOS 7

Tout d'abord, voyons quels fichiers sont fournis par le package php-mysql :

$ cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
$ repoquery -q -l --plugins php-mysql
/etc/php.d/mysql.ini
/etc/php.d/mysqli.ini
/etc/php.d/pdo_mysql.ini
/usr/lib64/php/modules/mysql.so
/usr/lib64/php/modules/mysqli.so
/usr/lib64/php/modules/pdo_mysql.so

Par défaut, si nous avons installé les composants standard de la pile LAMP fournis avec CentOS 7, par exemple :

$ yum install -y httpd php php-mysql php-gd php-curl mod_ssl

Vous obtiendrez les packages associés suivants installés :

$ rpm -qa | egrep 'php-mysql|mysql|maria'
php-mysql-5.4.16-46.el7.x86_64
mariadb-5.5.60-1.el7_5.x86_64
mariadb-libs-5.5.60-1.el7_5.x86_64
mariadb-server-5.5.60-1.el7_5.x86_64

Les modules suivants liés à MySQL seront alors chargés dans PHP :

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Lorsque l'on regarde la version de l'API signalée par phpinfo() pour les clients liés à MySQL, ils correspondent tous à la version de MariaDB que nous avons installée :

$ php -i | egrep -i 'client.*version'
Client API version => 5.5.60-MariaDB
Client API library version => 5.5.60-MariaDB
Client API header version => 5.5.60-MariaDB
Client API version => 5.5.60-MariaDB

À ce stade, nous pouvons conclure que le module php-mysql installé est construit et compatible avec MariaDB 5.5.60.

Installer MySQL 8.0

Cependant, dans ce projet, nous devons exécuter MySQL 8.0, nous avons donc choisi Percona Server 8.0 pour remplacer l'installation MariaDB existante par défaut que nous avons sur ce serveur. Pour ce faire, nous devons installer Percona Repository et activer le référentiel Percona Server 8.0 :

$ yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
$ percona-release setup ps80
$ yum install percona-server-server

Cependant, nous avons obtenu l'erreur suivante après avoir exécuté la toute dernière commande :

--> Finished Dependency Resolution
Error: Package: 1:mariadb-5.5.60-1.el7_5.x86_64 (@base)
           Requires: mariadb-libs(x86-64) = 1:5.5.60-1.el7_5
           Removing: 1:mariadb-libs-5.5.60-1.el7_5.x86_64 (@anaconda)
               mariadb-libs(x86-64) = 1:5.5.60-1.el7_5
           Obsoleted By: percona-server-shared-compat-8.0.15-6.1.el7.x86_64 (ps-80-release-x86_64)
               Not found
Error: Package: 1:mariadb-server-5.5.60-1.el7_5.x86_64 (@base)
           Requires: mariadb-libs(x86-64) = 1:5.5.60-1.el7_5
           Removing: 1:mariadb-libs-5.5.60-1.el7_5.x86_64 (@anaconda)
               mariadb-libs(x86-64) = 1:5.5.60-1.el7_5
           Obsoleted By: percona-server-shared-compat-8.0.15-6.1.el7.x86_64 (ps-80-release-x86_64)
               Not found
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

Ce qui précède signifie simplement que le package de compatibilité partagée Percona Server rendra obsolète le mariadb-libs-5.5.60, qui est requis par les packages mariadb-server déjà installés. Comme il s'agit d'un nouveau serveur, la suppression des packages MariaDB existants n'est pas un gros problème. Supprimons-les d'abord, puis réinstallons Percona Server 8.0 :

$ yum remove mariadb mariadb-libs
...
Resolving Dependencies
--> Running transaction check
---> Package mariadb-libs.x86_64 1:5.5.60-1.el7_5 will be erased
--> Processing Dependency: libmysqlclient.so.18()(64bit) for package: perl-DBD-MySQL-4.023-6.el7.x86_64
--> Processing Dependency: libmysqlclient.so.18()(64bit) for package: 2:postfix-2.10.1-7.el7.x86_64
--> Processing Dependency: libmysqlclient.so.18()(64bit) for package: php-mysql-5.4.16-46.el7.x86_64
--> Processing Dependency: libmysqlclient.so.18(libmysqlclient_18)(64bit) for package: perl-DBD-MySQL-4.023-6.el7.x86_64
--> Processing Dependency: libmysqlclient.so.18(libmysqlclient_18)(64bit) for package: 2:postfix-2.10.1-7.el7.x86_64
--> Processing Dependency: libmysqlclient.so.18(libmysqlclient_18)(64bit) for package: php-mysql-5.4.16-46.el7.x86_64
--> Processing Dependency: mariadb-libs(x86-64) = 1:5.5.60-1.el7_5 for package: 1:mariadb-5.5.60-1.el7_5.x86_64
---> Package mariadb-server.x86_64 1:5.5.60-1.el7_5 will be erased
--> Running transaction check
---> Package mariadb.x86_64 1:5.5.60-1.el7_5 will be erased
---> Package perl-DBD-MySQL.x86_64 0:4.023-6.el7 will be erased
---> Package php-mysql.x86_64 0:5.4.16-46.el7 will be erased
---> Package postfix.x86_64 2:2.10.1-7.el7 will be erased

La suppression de mariadb-libs supprimera également les autres packages qui en dépendent du système. Notre principale préoccupation concerne les packages php-mysql qui seront supprimés en raison de la dépendance à libmysqlclient.so.18 fourni par mariadb-libs. Nous corrigerons cela plus tard.

Après cela, nous devrions pouvoir installer Percona Server 8.0 sans erreur :

$ yum install percona-server-server

À ce stade, voici les packages liés à MySQL que nous avons sur le serveur :

$ rpm -qa | egrep 'php-mysql|mysql|maria|percona'
percona-server-client-8.0.15-6.1.el7.x86_64
percona-server-shared-8.0.15-6.1.el7.x86_64
percona-server-server-8.0.15-6.1.el7.x86_64
percona-release-1.0-11.noarch
percona-server-shared-compat-8.0.15-6.1.el7.x86_64

Notez que nous n'avons pas de packages php-mysql qui fournissent des modules pour connecter notre application PHP à notre serveur Percona Server 8.0 fraîchement installé. Nous pouvons le confirmer en vérifiant le module PHP chargé. Vous devriez obtenir une sortie vide avec la commande suivante :

$ php -m | grep mysql

Réinstallons-le :

$ yum install php-mysql
$ systemctl restart httpd

Maintenant, nous les avons et nous les chargeons dans PHP :

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Et nous pouvons également le confirmer en consultant les informations PHP via la ligne de commande :

$ php -i | egrep -i 'client.*version'
Client API version => 5.6.28-76.1
Client API library version => 5.6.28-76.1
Client API header version => 5.5.60-MariaDB
Client API version => 5.6.28-76.1

Notez la différence entre la version de la bibliothèque de l'API client et la version de l'en-tête de l'API. Nous verrons l'effet secondaire de cela plus tard pendant le test.

Démarrons notre serveur MySQL 8.0 pour tester notre application PHP5. Puisque nous avons demandé à MariaDB d'utiliser le répertoire de données dans /var/lib/mysql, nous devons d'abord l'effacer, réinitialiser le répertoire de données, attribuer le propriétaire approprié et le démarrer :

$ rm -Rf /var/lib/mysql
$ mysqld --initialize
$ chown -Rf mysql:mysql /var/lib/mysql
$ systemctl start mysql

Récupérez le mot de passe racine MySQL temporaire généré par Percona Server à partir du fichier journal des erreurs MySQL :

$ grep root /var/log/mysqld.log
2019-07-22T06:54:39.250241Z 5 [Note] [MY-010454] [Server] A temporary password is generated for [email protected]: 1wAXsGrISh-D

Utilisez-le pour vous connecter lors de la première connexion de l'utilisateur [email protected] Nous devons changer le mot de passe temporaire en autre chose avant de pouvoir effectuer toute autre action sur le serveur :

$ mysql -uroot -p
mysql> ALTER USER [email protected] IDENTIFIED BY 'myP455w0rD##';

Procédez ensuite à la création de nos ressources de base de données requises par notre application :

mysql> CREATE SCHEMA testdb;
mysql> CREATE USER [email protected] IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON testdb.* TO [email protected];

Une fois cela fait, importez les données existantes de la sauvegarde dans la base de données ou créez manuellement vos objets de base de données. Notre base de données est maintenant prête à être utilisée par notre application.

Erreurs et avertissements

Dans notre application, nous avions un simple fichier de test pour nous assurer que l'application est capable de se connecter via socket, ou en d'autres termes, localhost sur le port 3306 pour éliminer toutes les connexions de base de données via le réseau. Immédiatement, nous recevions l'avertissement d'incompatibilité de version :

$ php -e test_mysql.php
PHP Warning:  mysqli::mysqli(): Headers and client library minor version mismatch. Headers:50560 Library:50628 in /root/test_mysql.php on line 9

Dans le même temps, vous rencontrerez également l'erreur d'authentification avec le module php-mysql :

$ php -e test_mysql.php
PHP Warning:  mysqli::mysqli(): (HY000/2059): Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory in /root/test_mysql.php on line 9

Ou, si vous utilisiez la bibliothèque de pilotes natifs MySQL (php-mysqlnd), vous obtiendriez l'erreur suivante :

$ php -e test_mysql.php
PHP Warning:  mysqli::mysqli(): The server requested authentication method unknown to the client [caching_sha2_password] in /root/test_mysql.php on line 9

De plus, il y aurait aussi un autre problème que vous verriez concernant le jeu de caractères :

PHP Warning:  mysqli::mysqli(): Server sent charset (255) unknown to the client. Please, report to the developers in /root/test_mysql.php on line 9

Solutions et contournements

Plug-in d'authentification

Ni les bibliothèques php-mysqlnd ni php-mysql pour PHP5 ne prennent en charge la nouvelle méthode d'authentification pour MySQL 8.0. À partir de MySQL 8.0.4, la méthode d'authentification a été remplacée par 'caching_sha2_password', qui offre un hachage de mot de passe plus sécurisé par rapport à 'mysql_native_password' qui était par défaut dans les versions précédentes.

Pour permettre la rétrocompatibilité sur notre MySQL 8.0. Dans le fichier de configuration MySQL, ajoutez la ligne suivante sous la section [mysqld] :

default-authentication-plugin=mysql_native_password

Redémarrez le serveur MySQL et vous devriez être bon. Si l'utilisateur de la base de données a été créé avant les modifications ci-dessus, par exemple via une sauvegarde et une restauration, recréez l'utilisateur à l'aide des instructions DROP USER et CREATE USER. MySQL suivra le nouveau plugin d'authentification par défaut lors de la création d'un nouvel utilisateur.

Incompatibilité de version mineure

Avec le package php-mysql, si nous vérifions la version de la bibliothèque installée, nous remarquerons la différence :

$ php -i | egrep -i 'client.*version'
Client API version => 5.6.28-76.1
Client API library version => 5.6.28-76.1
Client API header version => 5.5.60-MariaDB
Client API version => 5.6.28-76.1

La bibliothèque PHP est compilée avec MariaDB 5.5.60 libmysqlclient, tandis que la version de l'API client est sur la version 5.6.28, fournie par le package percona-server-shared-compat. Malgré l'avertissement, vous pouvez toujours obtenir une réponse correcte du serveur.

Pour supprimer cet avertissement sur l'incompatibilité de version de la bibliothèque, utilisez le package php-mysqlnd, qui ne dépend pas de la bibliothèque MySQL Client Server (libmysqlclient). C'est la méthode recommandée, comme indiqué dans la documentation MySQL.

Pour remplacer la bibliothèque php-mysql par php-mysqlnd, exécutez simplement :

$ yum remove php-mysql
$ yum install php-mysqlnd
$ systemctl restart httpd

Si le remplacement de php-mysql n'est pas une option, le dernier recours consiste à compiler manuellement PHP avec la bibliothèque MySQL 8.0 Client Server (libmysqlclient) et à copier les fichiers de bibliothèque compilés dans le répertoire /usr/lib64/php/modules/, en remplaçant l'ancien mysqli. donc, mysql.so et pdo_mysql.so. C'est un peu compliqué avec un faible taux de réussite, principalement en raison des dépendances obsolètes des fichiers d'en-tête dans la version actuelle de MySQL. Des connaissances en programmation sont nécessaires pour contourner ce problème.

Jeu de caractères incompatible

À partir de MySQL 8.0.1, MySQL a changé le jeu de caractères par défaut de latin1 à utf8mb4. Le jeu de caractères utf8mb4 est utile car de nos jours, la base de données doit stocker non seulement des caractères de langue, mais également des symboles, des emojis nouvellement introduits, etc. Le jeu de caractères utf8mb4 est l'encodage UTF-8 du jeu de caractères Unicode utilisant un à quatre octets par caractère, par rapport à l'utf8 standard (alias utf8mb3) qui utilise un à trois octets par caractère.

De nombreuses applications héritées n'ont pas été construites sur le jeu de caractères utf8mb4. Ce serait donc bien si nous modifions le paramètre de caractères pour le serveur MySQL en quelque chose de compréhensible par notre ancien pilote PHP. Ajoutez les deux lignes suivantes dans la configuration MySQL sous la section [mysqld] :

collation-server = utf8_unicode_ci
character-set-server = utf8

En option, vous pouvez également ajouter les lignes suivantes dans le fichier de configuration MySQL pour rationaliser tous les accès client pour utiliser utf8 :

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

N'oubliez pas de redémarrer le serveur MySQL pour que les modifications prennent effet. À ce stade, notre application devrait fonctionner avec MySQL 8.0.

C'est tout pour le moment. N'hésitez pas à nous faire part de vos commentaires dans la section des commentaires si vous rencontrez d'autres problèmes lors du déplacement d'anciennes applications vers MySQL 8.0.