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

Come eseguire applicazioni PHP 5 con MySQL 8.0 su CentOS 7

Nonostante il fatto che PHP 5 abbia raggiunto la fine del suo ciclo di vita, esistono ancora applicazioni legacy basate su di esso che devono essere eseguite in ambienti di produzione o di test. Se stai installando pacchetti PHP tramite il repository del sistema operativo, c'è ancora la possibilità che finirai con pacchetti PHP 5, ad es. Sistema operativo CentOS 7. Detto questo, c'è sempre un modo per far funzionare le tue applicazioni legacy con le versioni di database più recenti e sfruttare così le nuove funzionalità.

In questo post del blog, ti illustreremo come eseguire applicazioni PHP 5 con l'ultima versione di MySQL 8.0 sul sistema operativo CentOS 7. Questo blog si basa sull'esperienza reale con un progetto interno che richiedeva l'esecuzione dell'applicazione PHP 5 insieme al nostro nuovo MySQL 8.0 in un nuovo ambiente. Tieni presente che sarebbe meglio eseguire l'ultima versione di PHP 7 insieme a MySQL 8.0 per sfruttare tutti i miglioramenti significativi introdotti nelle versioni più recenti.

PHP e MySQL su CentOS 7

Prima di tutto, vediamo quali file vengono forniti dal pacchetto 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

Per impostazione predefinita, se abbiamo installato i componenti dello stack LAMP standard vengono forniti con CentOS 7, ad esempio:

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

Avresti installato i seguenti pacchetti correlati:

$ 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

I seguenti moduli relativi a MySQL verranno quindi caricati in PHP:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Osservando la versione dell'API riportata da phpinfo() per i client relativi a MySQL, sono tutti abbinati alla versione di MariaDB che abbiamo installato:

$ 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

A questo punto, possiamo concludere che il modulo php-mysql installato è compilato e compatibile con MariaDB 5.5.60.

Installazione di MySQL 8.0

Tuttavia, in questo progetto, ci viene richiesto di eseguire su MySQL 8.0, quindi abbiamo scelto Percona Server 8.0 per sostituire l'installazione predefinita esistente di MariaDB che abbiamo su quel server. Per farlo, dobbiamo installare Percona Repository e abilitare il repository 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

Tuttavia, abbiamo ricevuto il seguente errore dopo aver eseguito l'ultimo comando:

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

Quanto sopra significa semplicemente che il pacchetto compat condiviso di Percona Server renderà obsoleto mariadb-libs-5.5.60, che è richiesto dai pacchetti mariadb-server già installati. Poiché si tratta di un semplice server nuovo, la rimozione dei pacchetti MariaDB esistenti non è un grosso problema. Rimuoviamoli prima e poi proviamo a installare nuovamente 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 rimozione di mariadb-libs rimuoverà anche altri pacchetti che dipendono da questo dal sistema. La nostra preoccupazione principale sono i pacchetti php-mysql che verranno rimossi a causa della dipendenza da libmysqlclient.so.18 fornita da mariadb-libs. Lo sistemeremo più tardi.

Dopodiché, dovremmo essere in grado di installare Percona Server 8.0 senza errori:

$ yum install percona-server-server

A questo punto, ecco i pacchetti relativi a MySQL che abbiamo nel server:

$ 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

Si noti che non abbiamo pacchetti php-mysql che forniscono moduli per connettere la nostra applicazione PHP con il nostro server Percona Server 8.0 appena installato. Possiamo confermarlo controllando il modulo PHP caricato. Dovresti ottenere un output vuoto con il seguente comando:

$ php -m | grep mysql

Installiamolo di nuovo:

$ yum install php-mysql
$ systemctl restart httpd

Ora li abbiamo e sono caricati in PHP:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

E possiamo anche confermarlo guardando le informazioni PHP tramite la riga di comando:

$ 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

Notare la differenza tra la versione della libreria dell'API client e la versione dell'intestazione dell'API. Vedremo le conseguenze di ciò più avanti durante il test.

Iniziamo il nostro server MySQL 8.0 per testare la nostra applicazione PHP5. Dato che MariaDB ha usato la datadir in /var/lib/mysql, dobbiamo prima cancellarla, reinizializzare la datadir, assegnare la proprietà corretta e avviarla:

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

Prendi la password di root MySQL temporanea generata da Percona Server dal file di registro degli errori 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

Usalo per accedere durante il primo accesso dell'utente [email protected] Dobbiamo cambiare la password temporanea in qualcos'altro prima di poter eseguire qualsiasi ulteriore azione sul server:

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

Quindi, procedi alla creazione delle nostre risorse di database richieste dalla nostra applicazione:

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

Una volta terminato, importa i dati esistenti dal backup nel database o crea manualmente gli oggetti del database. Il nostro database è ora pronto per essere utilizzato dalla nostra applicazione.

Errori e avvisi

Nella nostra applicazione, avevamo un semplice file di test per assicurarci che l'applicazione sia in grado di connettersi tramite socket, o in altre parole, localhost sulla porta 3306 per eliminare tutte le connessioni al database tramite rete. Immediatamente, riceveremmo l'avviso di mancata corrispondenza della versione:

$ 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

Allo stesso tempo, incontreresti anche l'errore di autenticazione con il modulo 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

Oppure, se eri in esecuzione con la libreria di driver nativa MySQL (php-mysqlnd), avresti il ​​seguente errore:

$ 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

Inoltre, ci sarebbe anche un altro problema relativo al set di caratteri:

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

Soluzioni e soluzioni alternative

Plugin di autenticazione

Né la libreria php-mysqlnd né php-mysql per PHP5 supportano il nuovo metodo di autenticazione per MySQL 8.0. A partire da MySQL 8.0.4 il metodo di autenticazione è stato modificato in 'caching_sha2_password', che offre un hash delle password più sicuro rispetto a 'mysql_native_password', predefinito nelle versioni precedenti.

Per consentire la compatibilità con le versioni precedenti sul nostro MySQL 8.0. All'interno del file di configurazione di MySQL, aggiungi la seguente riga nella sezione [mysqld]:

default-authentication-plugin=mysql_native_password

Riavvia il server MySQL e dovresti essere a posto. Se l'utente del database è stato creato prima delle modifiche precedenti, ad esempio tramite backup e ripristino, ricreare l'utente utilizzando le istruzioni DROP USER e CREATE USER. MySQL seguirà il nuovo plug-in di autenticazione predefinito durante la creazione di un nuovo utente.

Versione minore non corrispondente

Con il pacchetto php-mysql, se controlliamo la versione della libreria installata, noteremo la differenza:

$ 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 libreria PHP è compilata con MariaDB 5.5.60 libmysqlclient, mentre la versione dell'API client è sulla versione 5.6.28, fornita dal pacchetto percona-server-shared-compat. Nonostante l'avviso, puoi comunque ottenere una risposta corretta dal server.

Per eliminare questo avviso sulla mancata corrispondenza della versione della libreria, utilizzare il pacchetto php-mysqlnd, che non dipende dalla libreria MySQL Client Server (libmysqlclient). Questo è il modo consigliato, come indicato nella documentazione di MySQL.

Per sostituire la libreria php-mysql con php-mysqlnd, esegui semplicemente:

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

Se la sostituzione di php-mysql non è un'opzione, l'ultima risorsa è compilare manualmente PHP con la libreria MySQL 8.0 Client Server (libmysqlclient) e copiare i file della libreria compilati nella directory /usr/lib64/php/modules/, sostituendo la vecchia mysqli. quindi, mysql.so e pdo_mysql.so. Questa è un po' una seccatura con poche possibilità di successo, principalmente a causa delle dipendenze deprecate dei file di intestazione nella versione corrente di MySQL. È richiesta la conoscenza della programmazione per aggirare il problema.

Set di caratteri non compatibile

A partire da MySQL 8.0.1, MySQL ha modificato il set di caratteri predefinito da latin1 a utf8mb4. Il set di caratteri utf8mb4 è utile perché al giorno d'oggi il database deve memorizzare non solo i caratteri della lingua ma anche i simboli, le emoji di nuova introduzione e così via. Charset utf8mb4 è la codifica UTF-8 del set di caratteri Unicode che utilizza da uno a quattro byte per carattere, rispetto allo standard utf8 (aka utf8mb3) che utilizza da uno a tre byte per carattere.

Molte applicazioni legacy non sono state costruite sul set di caratteri utf8mb4. Quindi sarebbe utile se cambiassimo l'impostazione dei caratteri per il server MySQL in qualcosa di comprensibile dal nostro driver PHP legacy. Aggiungi le seguenti due righe nella configurazione di MySQL nella sezione [mysqld]:

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

Facoltativamente, puoi anche aggiungere le seguenti righe nel file di configurazione di MySQL per semplificare l'accesso di tutti i client all'utilizzo di utf8:

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

Non dimenticare di riavviare il server MySQL per rendere effettive le modifiche. A questo punto, la nostra applicazione dovrebbe andare d'accordo con MySQL 8.0.

Per ora è tutto. Condividi qualsiasi feedback con noi nella sezione commenti se hai altri problemi con lo spostamento di applicazioni legacy su MySQL 8.0.