sql >> Database teknologi >  >> RDS >> MariaDB

Sådan kører du PHP 5-applikationer med MySQL 8.0 på CentOS 7

På trods af, at PHP 5 er nået end-of-life, er der stadig ældre applikationer bygget oven på det, som skal køre i produktions- eller testmiljøer. Hvis du installerer PHP-pakker via operativsystem-repository, er der stadig en chance for, at du ender med PHP 5-pakker, f.eks. CentOS 7 operativsystem. Når det er sagt, er der altid en måde at få dine ældre applikationer til at køre med de nyere databaseversioner og dermed drage fordel af nye funktioner.

I dette blogindlæg vil vi lede dig igennem, hvordan vi kan køre PHP 5-applikationer med den seneste version af MySQL 8.0 på CentOS 7-operativsystemet. Denne blog er baseret på faktiske erfaringer med et internt projekt, der krævede, at PHP 5-applikationen kørte sammen med vores nye MySQL 8.0 i et nyt miljø. Bemærk, at det ville fungere bedst at køre den nyeste version af PHP 7 sammen med MySQL 8.0 for at drage fordel af alle de væsentlige forbedringer, der er introduceret i de nyere versioner.

PHP og MySQL på CentOS 7

Først og fremmest, lad os se, hvilke filer der leveres af php-mysql-pakken:

$ 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

Som standard, hvis vi har installeret standard LAMP stack-komponenter, leveres CentOS 7, for eksempel:

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

Du vil få følgende relaterede pakker installeret:

$ 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

Følgende MySQL-relaterede moduler vil derefter blive indlæst i PHP:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Når man ser på API-versionen rapporteret af phpinfo() for MySQL-relaterede klienter, matches de alle til MariaDB-versionen, som vi har installeret:

$ 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

På dette tidspunkt kan vi konkludere, at det installerede php-mysql-modul er bygget og kompatibelt med MariaDB 5.5.60.

Installation af MySQL 8.0

I dette projekt er vi dog forpligtet til at køre på MySQL 8.0, så vi valgte Percona Server 8.0 til at erstatte den eksisterende MariaDB-installation, vi har på den server. For at gøre det skal vi installere Percona Repository og aktivere Percona Server 8.0 repository:

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

Vi fik dog følgende fejl efter at have kørt den allersidste kommando:

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

Ovenstående betyder blot, at Percona Server shared compat-pakken skal forælde mariadb-libs-5.5.60, som kræves af de allerede installerede mariadb-serverpakker. Da dette er en almindelig ny server, er det ikke et stort problem at fjerne de eksisterende MariaDB-pakker. Lad os fjerne dem først og derefter prøve at installere Percona Server 8.0 igen:

$ 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

Fjernelse af mariadb-libs vil også fjerne andre pakker, der afhænger af dette, fra systemet. Vores primære bekymring er php-mysql-pakkerne, som vil blive fjernet på grund af afhængigheden af ​​libmysqlclient.so.18 leveret af mariadb-libs. Det ordner vi senere.

Derefter skulle vi være i stand til at installere Percona Server 8.0 uden fejl:

$ yum install percona-server-server

På dette tidspunkt er her MySQL-relaterede pakker, som vi har på serveren:

$ 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

Bemærk, at vi ikke har php-mysql-pakker, der giver moduler til at forbinde vores PHP-applikation med vores nyinstallerede Percona Server 8.0-server. Vi kan bekræfte dette ved at tjekke det indlæste PHP-modul. Du bør få tom output med følgende kommando:

$ php -m | grep mysql

Lad os installere det igen:

$ yum install php-mysql
$ systemctl restart httpd

Nu har vi dem og er indlæst i PHP:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Og det kan vi også bekræfte ved at se på PHP-oplysningerne via kommandolinjen:

$ 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

Bemærk forskellen på Client API-biblioteksversionen og API-headerversionen. Vi vil se eftervirkningen af ​​det senere under testen.

Lad os starte vores MySQL 8.0-server for at teste vores PHP5-applikation. Da vi fik MariaDB til at bruge datadirigenten i /var/lib/mysql, skal vi først slette den, geninitialisere datadirigenten, tildele korrekt ejerskab og starte den op:

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

Få fat i den midlertidige MySQL root-adgangskode genereret af Percona Server fra MySQL fejllogfilen:

$ 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

Brug det til at logge ind under første gangs login af bruger [email protected] Vi er nødt til at ændre den midlertidige adgangskode til noget andet, før vi kan udføre yderligere handlinger på serveren:

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

Fortsæt derefter med at oprette vores databaseressourcer, der kræves af vores applikation:

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

Når du er færdig, skal du importere de eksisterende data fra backup til databasen, eller oprette dine databaseobjekter manuelt. Vores database er nu klar til at blive brugt af vores applikation.

Fejl og advarsler

I vores applikation havde vi en simpel testfil for at sikre, at applikationen er i stand til at oprette forbindelse via socket, eller med andre ord, localhost på port 3306 for at eliminere alle databaseforbindelser via netværk. Umiddelbart ville vi få advarslen om versionsmismatch:

$ 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

Samtidig vil du også støde på godkendelsesfejlen med php-mysql-modulet:

$ 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

Eller hvis du kørte med MySQL native driver library (php-mysqlnd), ville du få følgende fejl:

$ 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

Plus, der ville også være et andet problem, du ville se vedrørende tegnsæt:

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øsninger og løsninger

Authentication plugin

Hverken php-mysqlnd eller php-mysql-biblioteket til PHP5 understøtter den nye godkendelsesmetode til MySQL 8.0. Startende fra MySQL 8.0.4 er godkendelsesmetoden blevet ændret til 'caching_sha2_password', som tilbyder en mere sikker adgangskode-hashing, hvis man sammenligner med 'mysql_native_password', som er standard i de tidligere versioner.

For at tillade bagudkompatibilitet på vores MySQL 8.0. Inde i MySQL-konfigurationsfilen skal du tilføje følgende linje under [mysqld]-sektionen:

default-authentication-plugin=mysql_native_password

Genstart MySQL-serveren, og du burde være god. Hvis databasebrugeren er blevet oprettet før ovenstående ændringer, f.eks. via backup og gendannelse, skal du genskabe brugeren ved at bruge DROP USER og CREATE USER sætninger. MySQL følger det nye standardgodkendelsesplugin, når der oprettes en ny bruger.

Mindre versionsmismatch

Med php-mysql-pakken, hvis vi tjekker den installerede biblioteksversion, vil vi bemærke forskellen:

$ 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

PHP-biblioteket er kompileret med MariaDB 5.5.60 libmysqlclient, mens klient-API-versionen er på version 5.6.28, leveret af percona-server-shared-compat-pakken. På trods af advarslen kan du stadig få et korrekt svar fra serveren.

Brug php-mysqlnd-pakken, som ikke afhænger af MySQL Client Server-biblioteket (libmysqlclient) for at undertrykke denne advarsel om biblioteksversionens uoverensstemmelse. Dette er den anbefalede måde, som angivet i MySQL-dokumentationen.

For at erstatte php-mysql-biblioteket med php-mysqlnd skal du blot køre:

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

Hvis udskiftning af php-mysql ikke er en mulighed, er sidste udvej at kompilere PHP med MySQL 8.0 Client Server-biblioteket (libmysqlclient) manuelt og kopiere de kompilerede biblioteksfiler til /usr/lib64/php/modules/-biblioteket, der erstatter det gamle mysqli. så, mysql.so og pdo_mysql.so. Dette er lidt af et besvær med en lille chance for succesrate, for det meste på grund af forældede afhængigheder af header-filer i den nuværende MySQL-version. Der kræves kendskab til programmering for at omgå det.

Inkompatibelt tegnsæt

Fra MySQL 8.0.1 har MySQL ændret standardtegnsættet fra latin1 til utf8mb4. Tegnsættet utf8mb4 er nyttigt, fordi databasen i dag ikke kun skal gemme sprogtegn, men også symboler, nyligt introducerede emojis og så videre. Tegnsæt utf8mb4 er UTF-8-kodning af Unicode-tegnsættet, der bruger en til fire bytes pr. tegn, sammenlignet med standarden utf8 (a.k.a. utf8mb3), som bruger en til tre bytes pr. tegn.

Mange ældre applikationer blev ikke bygget oven på utf8mb4 tegnsæt. Så det ville være godt, hvis vi ændrer tegnindstillingen for MySQL-serveren til noget, der kan forstås af vores ældre PHP-driver. Tilføj følgende to linjer i MySQL-konfigurationen under [mysqld]-sektionen:

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

Du kan eventuelt også tilføje følgende linjer i MySQL-konfigurationsfilen for at strømline al klientadgang til at bruge utf8:

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

Glem ikke at genstarte MySQL-serveren for at ændringerne træder i kraft. På dette tidspunkt burde vores applikation komme overens med MySQL 8.0.

Det var det for nu. Del feedback med os i kommentarfeltet, hvis du har andre problemer med at flytte ældre applikationer til MySQL 8.0.


  1. MODIFY COLUMN i oracle - Hvordan kontrollerer man, om en kolonne er nullbar, før den indstilles til nullbar?

  2. Jeg får en Der blev gjort forsøg på at indlæse et program med en forkert formatfejl på et SQL Server-replikeringsprojekt

  3. Sådan fungerer SQLite Quote()

  4. Hvordan får jeg ID'et for flere indsatte rækker i MySQL?