MariaDB
 sql >> Datenbank >  >> RDS >> MariaDB

So führen Sie PHP 5-Anwendungen mit MySQL 8.0 unter CentOS 7 aus

Trotz der Tatsache, dass PHP 5 das Ende seiner Lebensdauer erreicht hat, gibt es immer noch Legacy-Anwendungen, die darauf aufbauen und in Produktions- oder Testumgebungen ausgeführt werden müssen. Wenn Sie PHP-Pakete über das Betriebssystem-Repository installieren, besteht immer noch die Möglichkeit, dass Sie PHP-5-Pakete erhalten, z. Betriebssystem CentOS 7. Allerdings gibt es immer eine Möglichkeit, Ihre alten Anwendungen mit den neueren Datenbankversionen zum Laufen zu bringen und so von neuen Funktionen zu profitieren.

In diesem Blogbeitrag führen wir Sie durch, wie wir PHP 5-Anwendungen mit der neuesten Version von MySQL 8.0 auf dem Betriebssystem CentOS 7 ausführen können. Dieser Blog basiert auf tatsächlichen Erfahrungen mit einem internen Projekt, bei dem eine PHP 5-Anwendung neben unserem neuen MySQL 8.0 in einer neuen Umgebung ausgeführt werden musste. Beachten Sie, dass es am besten funktioniert, die neueste Version von PHP 7 zusammen mit MySQL 8.0 auszuführen, um alle wesentlichen Verbesserungen zu nutzen, die in den neueren Versionen eingeführt wurden.

PHP und MySQL auf CentOS 7

Sehen wir uns zunächst an, welche Dateien vom php-mysql-Paket bereitgestellt werden:

$ 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

Wenn wir die standardmäßigen LAMP-Stack-Komponenten installiert haben, werden sie standardmäßig mit CentOS 7 geliefert, zum Beispiel:

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

Sie würden die folgenden verwandten Pakete installieren:

$ 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

Die folgenden MySQL-bezogenen Module werden dann in PHP geladen:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Wenn Sie sich die API-Version ansehen, die von phpinfo() für MySQL-bezogene Clients gemeldet wird, stimmen sie alle mit der MariaDB-Version überein, die wir installiert haben:

$ 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

An dieser Stelle können wir schlussfolgern, dass das installierte php-mysql-Modul gebaut und mit MariaDB 5.5.60 kompatibel ist.

Installieren von MySQL 8.0

In diesem Projekt müssen wir jedoch auf MySQL 8.0 laufen, also haben wir uns für Percona Server 8.0 entschieden, um die standardmäßig vorhandene MariaDB-Installation zu ersetzen, die wir auf diesem Server haben. Dazu müssen wir das Percona-Repository installieren und das Percona Server 8.0-Repository aktivieren:

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

Wir haben jedoch den folgenden Fehler erhalten, nachdem wir den allerletzten Befehl ausgeführt haben:

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

Das Obige bedeutet einfach, dass das gemeinsam genutzte Compat-Paket von Percona Server die mariadb-libs-5.5.60 überflüssig machen soll, die von den bereits installierten mariadb-server-Paketen benötigt wird. Da es sich um einen einfachen neuen Server handelt, ist das Entfernen der vorhandenen MariaDB-Pakete kein großes Problem. Entfernen wir sie zuerst und versuchen Sie dann erneut, Percona Server 8.0 zu installieren:

$ 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

Durch das Entfernen von mariadb-libs werden auch andere Pakete, die davon abhängen, aus dem System entfernt. Unser Hauptanliegen sind die php-mysql-Pakete, die aufgrund der Abhängigkeit von libmysqlclient.so.18 entfernt werden, die von mariadb-libs bereitgestellt wird. Wir werden das später beheben.

Danach sollten wir Percona Server 8.0 ohne Fehler installieren können:

$ yum install percona-server-server

An dieser Stelle sind hier MySQL-bezogene Pakete, die wir auf dem Server haben:

$ 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

Beachten Sie, dass wir keine php-mysql-Pakete haben, die Module bereitstellen, um unsere PHP-Anwendung mit unserem frisch installierten Percona Server 8.0-Server zu verbinden. Wir können dies bestätigen, indem wir das geladene PHP-Modul überprüfen. Mit dem folgenden Befehl sollten Sie eine leere Ausgabe erhalten:

$ php -m | grep mysql

Lassen Sie uns es erneut installieren:

$ yum install php-mysql
$ systemctl restart httpd

Jetzt haben wir sie und werden in PHP geladen:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Und wir können das auch bestätigen, indem wir uns die PHP-Informationen über die Befehlszeile ansehen:

$ 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

Beachten Sie den Unterschied zwischen der Version der Client-API-Bibliothek und der API-Header-Version. Wir werden die Nachwirkung davon später während des Tests sehen.

Lassen Sie uns unseren MySQL 8.0-Server starten, um unsere PHP5-Anwendung zu testen. Da MariaDB das Datadir in /var/lib/mysql verwendet hat, müssen wir es zuerst löschen, das Datadir neu initialisieren, den richtigen Besitz zuweisen und es starten:

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

Holen Sie sich das von Percona Server generierte temporäre MySQL-Root-Passwort aus der MySQL-Fehlerprotokolldatei:

$ 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

Verwenden Sie es, um sich während der ersten Anmeldung des Benutzers [email protected] anzumelden. Wir müssen das temporäre Passwort in etwas anderes ändern, bevor wir weitere Aktionen auf dem Server ausführen können:

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

Fahren Sie dann mit der Erstellung unserer Datenbankressourcen fort, die von unserer Anwendung benötigt werden:

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

Importieren Sie anschließend die vorhandenen Daten aus der Sicherung in die Datenbank oder erstellen Sie Ihre Datenbankobjekte manuell. Unsere Datenbank kann jetzt von unserer Anwendung verwendet werden.

Fehler und Warnungen

In unserer Anwendung hatten wir eine einfache Testdatei, um sicherzustellen, dass die Anwendung eine Verbindung über Socket herstellen kann, oder mit anderen Worten, localhost auf Port 3306, um alle Datenbankverbindungen über das Netzwerk zu eliminieren. Sofort erhalten wir die Versionskonfliktwarnung:

$ 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

Gleichzeitig würde Ihnen auch der Authentifizierungsfehler mit dem php-mysql-Modul begegnen:

$ 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

Oder, wenn Sie mit der nativen MySQL-Treiberbibliothek (php-mysqlnd) arbeiten, erhalten Sie die folgende Fehlermeldung:

$ 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

Außerdem würde es noch ein weiteres Problem bezüglich des Zeichensatzes geben:

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

Lösungen und Problemumgehungen

Authentifizierungs-Plugin

Weder php-mysqlnd noch die php-mysql-Bibliothek für PHP5 unterstützen die neue Authentifizierungsmethode für MySQL 8.0. Beginnend mit MySQL 8.0.4 wurde die Authentifizierungsmethode in „caching_sha2_password“ geändert, was im Vergleich zu „mysql_native_password“, das in den vorherigen Versionen standardmäßig voreingestellt ist, ein sichereres Passwort-Hashing bietet.

Um die Abwärtskompatibilität auf unserem MySQL 8.0 zu ermöglichen. Fügen Sie in der MySQL-Konfigurationsdatei die folgende Zeile im Abschnitt [mysqld] hinzu:

default-authentication-plugin=mysql_native_password

Starten Sie den MySQL-Server neu und Sie sollten gut sein. Wenn der Datenbankbenutzer vor den obigen Änderungen erstellt wurde, z. B. durch Sicherung und Wiederherstellung, erstellen Sie den Benutzer mithilfe der Anweisungen DROP USER und CREATE USER neu. MySQL folgt dem neuen Standard-Authentifizierungs-Plug-In, wenn ein neuer Benutzer erstellt wird.

Nebenversionskonflikt

Wenn wir mit dem php-mysql-Paket die installierte Bibliotheksversion überprüfen, würden wir den Unterschied bemerken:

$ 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

Die PHP-Bibliothek wird mit MariaDB 5.5.60 libmysqlclient kompiliert, während die Client-API-Version Version 5.6.28 ist, die vom Paket percona-server-shared-compat bereitgestellt wird. Trotz der Warnung können Sie immer noch eine korrekte Antwort vom Server erhalten.

Um diese Warnung bei nicht übereinstimmenden Bibliotheksversionen zu unterdrücken, verwenden Sie das Paket php-mysqlnd, das nicht von der MySQL-Client-Server-Bibliothek (libmysqlclient) abhängt. Dies ist der empfohlene Weg, wie in der MySQL-Dokumentation angegeben.

Um die php-mysql-Bibliothek durch php-mysqlnd zu ersetzen, führen Sie einfach Folgendes aus:

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

Wenn das Ersetzen von php-mysql keine Option ist, besteht der letzte Ausweg darin, PHP mit der MySQL 8.0-Client-Server-Bibliothek (libmysqlclient) manuell zu kompilieren und die kompilierten Bibliotheksdateien in das Verzeichnis /usr/lib64/php/modules/ zu kopieren und das alte mysqli zu ersetzen. also mysql.so und pdo_mysql.so. Dies ist ein bisschen mühsam mit geringer Erfolgswahrscheinlichkeit, hauptsächlich aufgrund veralteter Abhängigkeiten von Header-Dateien in der aktuellen MySQL-Version. Programmierkenntnisse sind erforderlich, um dies zu umgehen.

Inkompatibler Zeichensatz

Ab MySQL 8.0.1 hat MySQL den Standardzeichensatz von latin1 auf utf8mb4 geändert. Der utf8mb4-Zeichensatz ist nützlich, da die Datenbank heutzutage nicht nur Sprachzeichen, sondern auch Symbole, neu eingeführte Emojis usw. speichern muss. Charset utf8mb4 ist eine UTF-8-Codierung des Unicode-Zeichensatzes, die ein bis vier Bytes pro Zeichen verwendet, im Vergleich zum Standard-utf8 (alias utf8mb3), das ein bis drei Bytes pro Zeichen verwendet.

Viele Legacy-Anwendungen wurden nicht auf dem utf8mb4-Zeichensatz aufgebaut. Es wäre also gut, wenn wir die Zeicheneinstellung für den MySQL-Server so ändern, dass sie für unseren alten PHP-Treiber verständlich ist. Fügen Sie die folgenden zwei Zeilen zur MySQL-Konfiguration im Abschnitt [mysqld] hinzu:

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

Optional können Sie auch die folgenden Zeilen zur MySQL-Konfigurationsdatei hinzufügen, um den gesamten Clientzugriff für die Verwendung von utf8 zu optimieren:

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

Vergessen Sie nicht, den MySQL-Server neu zu starten, damit die Änderungen wirksam werden. An diesem Punkt sollte unsere Anwendung mit MySQL 8.0 zurechtkommen.

Das war es fürs Erste. Teilen Sie uns Ihr Feedback im Kommentarbereich mit, wenn Sie andere Probleme haben, ältere Anwendungen auf MySQL 8.0 zu verschieben.