sql >> Databasteknik >  >> RDS >> MariaDB

Hur man kör PHP 5-applikationer med MySQL 8.0 på CentOS 7

Trots att PHP 5 har nått slutet av sin livslängd finns det fortfarande äldre applikationer byggda ovanpå det som måste köras i produktions- eller testmiljöer. Om du installerar PHP-paket via operativsystemets repository, finns det fortfarande en chans att du kommer att sluta med PHP 5-paket, t.ex. CentOS 7 operativsystem. Med det sagt finns det alltid ett sätt att få dina äldre applikationer att köras med de nyare databasversionerna och därmed dra nytta av nya funktioner.

I det här blogginlägget går vi igenom hur vi kan köra PHP 5-applikationer med den senaste versionen av MySQL 8.0 på CentOS 7 operativsystem. Den här bloggen är baserad på faktiska erfarenheter av ett internt projekt som krävde att PHP 5-applikationen kördes tillsammans med vår nya MySQL 8.0 i en ny miljö. Observera att det skulle fungera bäst att köra den senaste versionen av PHP 7 tillsammans med MySQL 8.0 för att dra fördel av alla betydande förbättringar som introducerats i de nyare versionerna.

PHP och MySQL på CentOS 7

Först och främst, låt oss se vilka filer som tillhandahålls av php-mysql-paketet:

$ 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, om vi installerade standard LAMP stack-komponenter kommer med CentOS 7, till exempel:

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

Du skulle få följande relaterade paket installerade:

$ 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öljande MySQL-relaterade moduler kommer sedan att laddas in i PHP:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

När man tittar på API-versionen som rapporterats av phpinfo() för MySQL-relaterade klienter, matchas de alla med MariaDB-versionen som vi har installerat:

$ 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

Vid det här laget kan vi dra slutsatsen att den installerade php-mysql-modulen är byggd och kompatibel med MariaDB 5.5.60.

Installera MySQL 8.0

Men i det här projektet måste vi köra på MySQL 8.0 så vi valde Percona Server 8.0 för att ersätta den befintliga standardinstallationen av MariaDB som vi har på den servern. För att göra det måste vi installera Percona Repository och aktivera Percona Server 8.0-förvaret:

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

Vi fick dock följande fel efter att ha kört det allra sista kommandot:

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

Ovanstående betyder helt enkelt att Percona Server shared compat-paketet ska föråldra mariadb-libs-5.5.60, vilket krävs av de redan installerade mariadb-serverpaketen. Eftersom detta är en helt ny server är det inte ett stort problem att ta bort de befintliga MariaDB-paketen. Låt oss först ta bort dem och sedan försöka installera Percona Server 8.0 en gång till:

$ 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

Att ta bort mariadb-libs kommer också att ta bort andra paket som är beroende av detta från systemet. Vårt primära bekymmer är php-mysql-paketen som kommer att tas bort på grund av beroendet av libmysqlclient.so.18 som tillhandahålls av mariadb-libs. Vi fixar det senare.

Efter det bör vi kunna installera Percona Server 8.0 utan fel:

$ yum install percona-server-server

Vid det här laget, här är MySQL-relaterade paket som vi har på servern:

$ 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

Observera att vi inte har php-mysql-paket som tillhandahåller moduler för att ansluta vår PHP-applikation med vår nyinstallerade Percona Server 8.0-server. Vi kan bekräfta detta genom att kontrollera den laddade PHP-modulen. Du bör få tom utdata med följande kommando:

$ php -m | grep mysql

Låt oss installera det igen:

$ yum install php-mysql
$ systemctl restart httpd

Nu har vi dem och är inlästa i PHP:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Och vi kan också bekräfta det genom att titta på PHP-informationen via kommandoraden:

$ 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

Lägg märke till skillnaden på klient-API-biblioteksversionen och API-huvudversionen. Vi kommer att se eftereffekten av det senare under testet.

Låt oss starta vår MySQL 8.0-server för att testa vår PHP5-applikation. Eftersom vi lät MariaDB använda datadirigenten i /var/lib/mysql, måste vi först radera den, återinitiera datadirigenten, tilldela korrekt äganderätt och starta den:

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

Ta det tillfälliga MySQL-rootlösenordet som genereras av Percona Server från MySQL-felloggfilen:

$ 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

Använd den för att logga in vid första inloggningen av användare [email protected] Vi måste ändra det tillfälliga lösenordet till något annat innan vi kan utföra någon ytterligare åtgärd på servern:

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

Fortsätt sedan med att skapa våra databasresurser som krävs av vår 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 är klar importerar du befintlig data från säkerhetskopian till databasen eller skapar dina databasobjekt manuellt. Vår databas är nu redo att användas av vår applikation.

Fel och varningar

I vår applikation hade vi en enkel testfil för att säkerställa att applikationen kan ansluta via socket, eller med andra ord, localhost på port 3306 för att eliminera alla databasanslutningar via nätverk. Omedelbart skulle vi få varningen om versionsfelmatchning:

$ 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

Samtidigt skulle du också stöta på autentiseringsfelet med php-mysql-modulen:

$ 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, om du körde med MySQL-drivrutinsbiblioteket (php-mysqlnd), skulle du få följande felmeddelande:

$ 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

Dessutom skulle det också finnas ett annat problem du skulle se angående teckenuppsättning:

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ösningar och lösningar

Autentiseringsplugin

Varken php-mysqlnd eller php-mysql-biblioteket för PHP5 stöder den nya autentiseringsmetoden för MySQL 8.0. Från och med MySQL 8.0.4 har autentiseringsmetoden ändrats till 'caching_sha2_password', som erbjuder en säkrare lösenordshashing jämfört med 'mysql_native_password' som är standard i de tidigare versionerna.

För att tillåta bakåtkompatibilitet på vår MySQL 8.0. Inuti MySQL-konfigurationsfilen lägger du till följande rad under avsnittet [mysqld]:

default-authentication-plugin=mysql_native_password

Starta om MySQL-servern och du borde vara bra. Om databasanvändaren har skapats innan ändringarna ovan, t.ex. via säkerhetskopiering och återställning, återskapa användaren genom att använda DROP USER och CREATE USER-satser. MySQL kommer att följa det nya standardinsticksprogrammet för autentisering när en ny användare skapas.

Mindre versionsfel matchar

Med php-mysql-paketet, om vi kontrollerar den installerade biblioteksversionen, skulle vi märka skillnaden:

$ 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 är kompilerat med MariaDB 5.5.60 libmysqlclient, medan klientens API-version är på version 5.6.28, tillhandahållen av percona-server-shared-compat-paketet. Trots varningen kan du fortfarande få ett korrekt svar från servern.

För att undertrycka denna varning om biblioteksversionen inte matchar, använd php-mysqlnd-paketet, som inte är beroende av MySQL Client Server-biblioteket (libmysqlclient). Detta är det rekommenderade sättet, som anges i MySQL-dokumentationen.

För att ersätta php-mysql-biblioteket med php-mysqlnd, kör helt enkelt:

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

Om att ersätta php-mysql inte är ett alternativ, är den sista utvägen att kompilera PHP med MySQL 8.0 Client Server-biblioteket (libmysqlclient) manuellt och kopiera de kompilerade biblioteksfilerna till katalogen /usr/lib64/php/modules/, och ersätta den gamla mysqli. så, mysql.so och pdo_mysql.so. Detta är lite av ett krångel med liten chans att lyckas, mestadels på grund av föråldrade beroenden av header-filer i den nuvarande MySQL-versionen. Kunskaper om programmering krävs för att komma runt det.

Inkompatibel teckenuppsättning

Från och med MySQL 8.0.1 har MySQL ändrat standardteckenuppsättningen från latin1 till utf8mb4. Teckenuppsättningen utf8mb4 är användbar eftersom databasen numera måste lagra inte bara språktecken utan även symboler, nyligen introducerade emojis och så vidare. Teckenuppsättning utf8mb4 är UTF-8-kodning av Unicode-teckenuppsättningen med en till fyra byte per tecken, om man jämför med standarden utf8 (a.k.a utf8mb3) som använder en till tre byte per tecken.

Många äldre applikationer byggdes inte ovanpå utf8mb4 teckenuppsättning. Så det skulle vara bra om vi ändrar teckeninställningen för MySQL-servern till något som kan förstås av vår äldre PHP-drivrutin. Lägg till följande två rader i MySQL-konfigurationen under avsnittet [mysqld]:

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

Alternativt kan du också lägga till följande rader i MySQL-konfigurationsfilen för att effektivisera all klientåtkomst för att använda utf8:

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

Glöm inte att starta om MySQL-servern för att ändringarna ska träda i kraft. Vid det här laget borde vår applikation komma överens med MySQL 8.0.

Det var allt för nu. Dela eventuell feedback med oss ​​i kommentarsektionen om du har några andra problem med att flytta äldre applikationer till MySQL 8.0.


  1. En introduktion till Hadoop och Big Data

  2. Hur man får det korta månadsnamnet från ett datum i MariaDB

  3. Skillnaden mellan primärnyckel och unik nyckel

  4. Java:Infoga flera rader i MySQL med PreparedStatement