Ondanks het feit dat PHP 5 het einde van zijn levensduur heeft bereikt, zijn er nog steeds legacy-applicaties bovenop gebouwd die in productie- of testomgevingen moeten worden uitgevoerd. Als je PHP-pakketten installeert via de repository van het besturingssysteem, is er nog steeds een kans dat je PHP 5-pakketten krijgt, b.v. CentOS 7-besturingssysteem. Dat gezegd hebbende, is er altijd een manier om uw oude applicaties te laten werken met de nieuwere databaseversies en zo te profiteren van nieuwe functies.
In deze blogpost laten we u zien hoe we PHP 5-applicaties kunnen uitvoeren met de nieuwste versie van MySQL 8.0 op het CentOS 7-besturingssysteem. Deze blog is gebaseerd op daadwerkelijke ervaring met een intern project waarbij de PHP 5-applicatie naast onze nieuwe MySQL 8.0 in een nieuwe omgeving moest draaien. Merk op dat het het beste zou werken om de nieuwste versie van PHP 7 naast MySQL 8.0 te gebruiken om te profiteren van alle belangrijke verbeteringen die in de nieuwere versies zijn geïntroduceerd.
PHP en MySQL op CentOS 7
Laten we eerst eens kijken welke bestanden worden geleverd door het php-mysql-pakket:
$ 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
Als we standaard LAMP-stackcomponenten hebben geïnstalleerd, worden ze standaard geleverd met CentOS 7, bijvoorbeeld:
$ yum install -y httpd php php-mysql php-gd php-curl mod_ssl
U krijgt dan de volgende gerelateerde pakketten geïnstalleerd:
$ 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
De volgende MySQL-gerelateerde modules worden dan in PHP geladen:
$ php -m | grep mysql
mysql
mysqli
pdo_mysql
Als we kijken naar de API-versie gerapporteerd door phpinfo() voor MySQL-gerelateerde clients, komen ze allemaal overeen met de MariaDB-versie die we hebben geïnstalleerd:
$ 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
Op dit punt kunnen we concluderen dat de geïnstalleerde php-mysql-module is gebouwd en compatibel is met MariaDB 5.5.60.
MySQL 8.0 installeren
In dit project moeten we echter op MySQL 8.0 draaien, dus kozen we Percona Server 8.0 om de standaard bestaande MariaDB-installatie die we op die server hebben te vervangen. Om dat te doen, moeten we Percona Repository installeren en de Percona Server 8.0-repository inschakelen:
$ yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
$ percona-release setup ps80
$ yum install percona-server-server
We kregen echter de volgende foutmelding na het uitvoeren van de allerlaatste opdracht:
--> 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
Het bovenstaande betekent eenvoudigweg dat het Percona Server gedeelde compat-pakket de mariadb-libs-5.5.60, die vereist is door de reeds geïnstalleerde mariadb-server-pakketten, zal verouderen. Aangezien dit een eenvoudige nieuwe server is, is het verwijderen van de bestaande MariaDB-pakketten geen groot probleem. Laten we ze eerst verwijderen en dan proberen de Percona Server 8.0 nog een keer te installeren:
$ 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
Als u mariadb-libs verwijdert, worden ook andere pakketten die hiervan afhankelijk zijn van het systeem verwijderd. Onze eerste zorg zijn de php-mysql-pakketten die zullen worden verwijderd vanwege de afhankelijkheid van libmysqlclient.so.18 geleverd door mariadb-libs. We zullen dat later oplossen.
Daarna zouden we Percona Server 8.0 foutloos moeten kunnen installeren:
$ yum install percona-server-server
Op dit moment zijn hier MySQL-gerelateerde pakketten die we op de server hebben:
$ 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
Merk op dat we geen php-mysql-pakketten hebben die modules bieden om onze PHP-toepassing te verbinden met onze vers geïnstalleerde Percona Server 8.0-server. We kunnen dit bevestigen door de geladen PHP-module te controleren. U zou lege uitvoer moeten krijgen met het volgende commando:
$ php -m | grep mysql
Laten we het opnieuw installeren:
$ yum install php-mysql
$ systemctl restart httpd
Nu hebben we ze en worden ze in PHP geladen:
$ php -m | grep mysql
mysql
mysqli
pdo_mysql
En we kunnen dat ook bevestigen door naar de PHP-info te kijken via de opdrachtregel:
$ 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
Let op het verschil tussen de versie van de Client API-bibliotheek en de versie van de API-header. We zullen het effect daarvan later tijdens de test zien.
Laten we onze MySQL 8.0-server starten om onze PHP5-toepassing te testen. Aangezien we MariaDB de datadir in /var/lib/mysql hadden laten gebruiken, moeten we deze eerst wissen, de datadir opnieuw initialiseren, het juiste eigendom toewijzen en opstarten:
$ rm -Rf /var/lib/mysql
$ mysqld --initialize
$ chown -Rf mysql:mysql /var/lib/mysql
$ systemctl start mysql
Pak het tijdelijke MySQL-rootwachtwoord dat door Percona Server is gegenereerd uit het MySQL-foutlogbestand:
$ 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
Gebruik het om in te loggen tijdens de eerste keer inloggen van gebruiker [email protected] We moeten het tijdelijke wachtwoord wijzigen in iets anders voordat we verdere actie op de server kunnen uitvoeren:
$ mysql -uroot -p
mysql> ALTER USER [email protected] IDENTIFIED BY 'myP455w0rD##';
Ga dan verder met het maken van onze databasebronnen die nodig zijn voor onze applicatie:
mysql> CREATE SCHEMA testdb;
mysql> CREATE USER [email protected] IDENTIFIED BY 'password';
mysql> GRANT ALL PRIVILEGES ON testdb.* TO [email protected];
Als u klaar bent, importeert u de bestaande gegevens van de back-up in de database of maakt u handmatig uw database-objecten. Onze database is nu klaar voor gebruik door onze applicatie.
Fouten en waarschuwingen
In onze applicatie hadden we een eenvoudig testbestand om er zeker van te zijn dat de applicatie verbinding kan maken via socket, of met andere woorden, localhost op poort 3306 om alle databaseverbindingen via het netwerk te elimineren. Onmiddellijk kregen we de waarschuwing voor niet-overeenkomende versie:
$ 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
Tegelijkertijd zou je ook de authenticatiefout tegenkomen met de php-mysql-module:
$ 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
Of, als u met MySQL native driverbibliotheek (php-mysqlnd) zou werken, zou u de volgende foutmelding krijgen:
$ 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
Bovendien zou er ook een ander probleem zijn met betrekking tot tekensets:
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
Oplossingen en tijdelijke oplossingen
Verificatieplugin
Noch php-mysqlnd noch php-mysql-bibliotheek voor PHP5 ondersteunt de nieuwe authenticatiemethode voor MySQL 8.0. Vanaf MySQL 8.0.4 is de authenticatiemethode gewijzigd in 'caching_sha2_password', wat een veiligere hashing van wachtwoorden biedt in vergelijking met 'mysql_native_password' dat standaard was in de vorige versies.
Om achterwaartse compatibiliteit op onze MySQL 8.0. Voeg in het MySQL-configuratiebestand de volgende regel toe onder de sectie [mysqld]:
default-authentication-plugin=mysql_native_password
Start de MySQL-server opnieuw en je zou goed moeten zijn. Als de databasegebruiker is gemaakt vóór de bovenstaande wijzigingen, bijvoorbeeld via back-up en herstel, maak de gebruiker dan opnieuw aan met behulp van de instructies DROP USER en CREATE USER. MySQL zal de nieuwe standaard authenticatie plug-in volgen bij het aanmaken van een nieuwe gebruiker.
Kleine versie komt niet overeen
Als we met het php-mysql-pakket de geïnstalleerde bibliotheekversie controleren, zouden we het verschil opmerken:
$ 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
De PHP-bibliotheek is gecompileerd met MariaDB 5.5.60 libmysqlclient, terwijl de client-API-versie op versie 5.6.28 staat, geleverd door het pakket percona-server-shared-compat. Ondanks de waarschuwing kun je nog steeds een correct antwoord krijgen van de server.
Om deze waarschuwing bij niet-overeenkomende bibliotheekversies te onderdrukken, gebruikt u het php-mysqlnd-pakket, dat niet afhankelijk is van de MySQL Client Server-bibliotheek (libmysqlclient). Dit is de aanbevolen manier, zoals vermeld in de MySQL-documentatie.
Om de php-mysql-bibliotheek te vervangen door php-mysqlnd, voert u eenvoudig het volgende uit:
$ yum remove php-mysql
$ yum install php-mysqlnd
$ systemctl restart httpd
Als het vervangen van php-mysql geen optie is, is het laatste redmiddel om PHP handmatig te compileren met de MySQL 8.0 Client Server-bibliotheek (libmysqlclient) en de gecompileerde bibliotheekbestanden te kopiëren naar de map /usr/lib64/php/modules/, waarbij de oude mysqli wordt vervangen. dus, mysql.so en pdo_mysql.so. Dit is een beetje gedoe met een kleine kans op succes, voornamelijk vanwege verouderde afhankelijkheden van header-bestanden in de huidige MySQL-versie. Kennis van programmeren is vereist om dat te omzeilen.
Incompatibele tekenset
Vanaf MySQL 8.0.1 heeft MySQL de standaardtekenset gewijzigd van latin1 in utf8mb4. De tekenset utf8mb4 is handig omdat de database tegenwoordig niet alleen taaltekens moet opslaan, maar ook symbolen, nieuw geïntroduceerde emoji's, enzovoort. Tekenset utf8mb4 is UTF-8-codering van de Unicode-tekenset met één tot vier bytes per teken, in vergelijking met de standaard utf8 (ook bekend als utf8mb3) die één tot drie bytes per teken gebruikt.
Veel legacy-applicaties zijn niet gebouwd op de utf8mb4-tekenset. Het zou dus goed zijn als we de tekeninstelling voor de MySQL-server wijzigen in iets dat begrijpelijk is voor onze oudere PHP-driver. Voeg de volgende twee regels toe aan de MySQL-configuratie onder de sectie [mysqld]:
collation-server = utf8_unicode_ci
character-set-server = utf8
Optioneel kunt u ook de volgende regels toevoegen aan het MySQL-configuratiebestand om alle clienttoegang voor het gebruik van utf8 te stroomlijnen:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
Vergeet niet de MySQL-server opnieuw op te starten om de wijzigingen door te voeren. Op dit moment zou onze applicatie moeten opschieten met MySQL 8.0.
Dat is het voor nu. Deel eventuele feedback met ons in het opmerkingengedeelte als je andere problemen hebt met het verplaatsen van oudere applicaties naar MySQL 8.0.