sql >> Databáze >  >> RDS >> MariaDB

Jak spouštět aplikace PHP 5 s MySQL 8.0 na CentOS 7

Navzdory skutečnosti, že PHP 5 dosáhlo konce své životnosti, stále existují starší aplikace postavené na jeho vrcholu, které musí běžet v produkčním nebo testovacím prostředí. Pokud instalujete balíčky PHP přes úložiště operačního systému, stále existuje šance, že skončíte s balíčky PHP 5, např. Operační systém CentOS 7. Vždy však existuje způsob, jak zajistit, aby vaše starší aplikace běžely s novějšími verzemi databází, a tak využít nových funkcí.

V tomto příspěvku na blogu vás provedeme tím, jak můžeme spouštět aplikace PHP 5 s nejnovější verzí MySQL 8.0 na operačním systému CentOS 7. Tento blog je založen na skutečných zkušenostech s interním projektem, který vyžadoval, aby aplikace PHP 5 běžela spolu s naším novým MySQL 8.0 v novém prostředí. Všimněte si, že nejlépe by fungovalo spouštět nejnovější verzi PHP 7 spolu s MySQL 8.0, abyste využili všech významných vylepšení zavedených v novějších verzích.

PHP a MySQL na CentOS 7

Nejprve se podívejme, jaké soubory poskytuje balíček 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

Ve výchozím nastavení, pokud jsme nainstalovali standardní komponenty zásobníku LAMP, jsou dodávány s CentOS 7, například:

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

Měli byste nainstalovat následující související balíčky:

$ 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

Do PHP se poté načtou následující moduly související s MySQL:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

Když se podíváte na verzi API hlášenou phpinfo() pro klienty související s MySQL, všechny odpovídají verzi MariaDB, kterou jsme nainstalovali:

$ 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

V tomto bodě můžeme dojít k závěru, že nainstalovaný modul php-mysql je sestaven a kompatibilní s MariaDB 5.5.60.

Instalace MySQL 8.0

V tomto projektu jsme však povinni běžet na MySQL 8.0, takže jsme zvolili Percona Server 8.0, který nahradí výchozí existující instalaci MariaDB, kterou máme na tomto serveru. K tomu musíme nainstalovat úložiště Percona a povolit úložiště 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

Po spuštění úplně posledního příkazu jsme však dostali následující chybu:

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

Výše uvedené jednoduše znamená, že sdílený kompatní balíček Percona Server bude zastaralý mariadb-libs-5.5.60, který vyžadují již nainstalované balíčky mariadb-server. Protože se jedná o obyčejný nový server, odstranění stávajících balíčků MariaDB není velký problém. Nejprve je odebereme a poté se pokusíme nainstalovat Percona Server 8.0 ještě jednou:

$ 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

Odstranění mariadb-libs také odstraní ze systému další balíčky, které jsou na něm závislé. Naším primárním zájmem jsou balíčky php-mysql, které budou odstraněny kvůli závislosti na libmysqlclient.so.18 poskytovaném mariadb-libs. Opravíme to později.

Poté bychom měli být schopni nainstalovat Percona Server 8.0 bez chyby:

$ yum install percona-server-server

V tuto chvíli jsou zde balíčky související s MySQL, které máme na serveru:

$ 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

Všimněte si, že nemáme balíčky php-mysql, které poskytují moduly pro připojení naší PHP aplikace s naším čerstvě nainstalovaným serverem Percona Server 8.0. To můžeme potvrdit kontrolou načteného PHP modulu. Pomocí následujícího příkazu byste měli získat prázdný výstup:

$ php -m | grep mysql

Pojďme to nainstalovat znovu:

$ yum install php-mysql
$ systemctl restart httpd

Nyní je máme a jsou načteny do PHP:

$ php -m | grep mysql
mysql
mysqli
pdo_mysql

A můžeme to také potvrdit pohledem na informace o PHP z příkazového řádku:

$ 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

Všimněte si rozdílu ve verzi knihovny API klienta a verzi záhlaví API. To uvidíme později během testu.

Spusťte náš server MySQL 8.0 a otestujte naši aplikaci PHP5. Protože jsme nechali MariaDB používat datadir v /var/lib/mysql, musíme jej nejprve vymazat, znovu inicializovat datadir, přiřadit správné vlastnictví a spustit jej:

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

Získejte dočasné kořenové heslo MySQL vygenerované serverem Percona ze souboru protokolu chyb 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

Použijte jej k přihlášení během prvního přihlášení uživatele [email protected] Než budeme moci na serveru provést jakoukoli další akci, musíme dočasné heslo změnit na jiné:

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

Poté pokračujte ve vytváření našich databázových zdrojů požadovaných naší aplikací:

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

Po dokončení importujte existující data ze zálohy do databáze nebo vytvořte databázové objekty ručně. Naše databáze je nyní připravena k použití naší aplikací.

Chyby a varování

V naší aplikaci jsme měli jednoduchý testovací soubor, abychom se ujistili, že se aplikace dokáže připojit přes soket, nebo jinými slovy, localhost na portu 3306, abychom odstranili všechna databázová připojení přes síť. Okamžitě bychom dostali varování o neshodě verzí:

$ 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

Současně byste také narazili na chybu ověřování s modulem 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

Nebo pokud používáte nativní knihovnu ovladačů MySQL (php-mysqlnd), zobrazí se následující chyba:

$ 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

Navíc by tu byl ještě další problém, který byste viděli ohledně znakové sady:

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

Řešení a zástupná řešení

Plugin pro ověřování

Knihovna php-mysqlnd ani php-mysql pro PHP5 nepodporuje novou metodu ověřování pro MySQL 8.0. Počínaje verzí MySQL 8.0.4 byla metoda autentizace změněna na 'caching_sha2_password', která nabízí bezpečnější hašování hesla ve srovnání s 'mysql_native_password', která byla výchozí v předchozích verzích.

Aby byla umožněna zpětná kompatibilita na našem MySQL 8.0. Do konfiguračního souboru MySQL přidejte do sekce [mysqld] následující řádek:

default-authentication-plugin=mysql_native_password

Restartujte MySQL server a měli byste být v pořádku. Pokud byl uživatel databáze vytvořen před výše uvedenými změnami, např. pomocí zálohování a obnovení, znovu vytvořte uživatele pomocí příkazů DROP USER a CREATE USER. MySQL bude při vytváření nového uživatele postupovat podle nového výchozího ověřovacího pluginu.

Drobná neshoda verzí

Pokud s balíčkem php-mysql zkontrolujeme nainstalovanou verzi knihovny, všimli bychom si rozdílu:

$ 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

Knihovna PHP je zkompilována pomocí MariaDB 5.5.60 libmysqlclient, zatímco verze klientského API je ve verzi 5.6.28, kterou poskytuje balíček percona-server-shared-compat. Navzdory varování můžete stále získat správnou odpověď ze serveru.

Chcete-li potlačit toto varování o neshodě verzí knihovny, použijte balíček php-mysqlnd, který nezávisí na knihovně MySQL Client Server (libmysqlclient). Toto je doporučený způsob, jak je uvedeno v dokumentaci MySQL.

Chcete-li nahradit knihovnu php-mysql php-mysqlnd, jednoduše spusťte:

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

Pokud nahrazení php-mysql není možné, poslední možností je zkompilovat PHP s knihovnou MySQL 8.0 Client Server (libmysqlclient) ručně a zkopírovat soubory zkompilované knihovny do adresáře /usr/lib64/php/modules/, čímž se nahradí staré mysqli. takže mysql.so a pdo_mysql.so. To je trochu problém s malou šancí na úspěch, většinou kvůli zastaralým závislostem hlavičkových souborů v aktuální verzi MySQL. K vyřešení tohoto problému je nutná znalost programování.

Nekompatibilní znaková sada

Počínaje MySQL 8.0.1 změnilo MySQL výchozí znakovou sadu z latin1 na utf8mb4. Znaková sada utf8mb4 je užitečná, protože v dnešní době musí databáze ukládat nejen znaky jazyků, ale i symboly, nově zavedené emotikony a tak dále. Znaková sada utf8mb4 je kódování UTF-8 znakové sady Unicode používající jeden až čtyři bajty na znak, ve srovnání se standardním utf8 (aka utf8mb3), které používá jeden až tři bajty na znak.

Mnoho starších aplikací nebylo postaveno na znakové sadě utf8mb4. Bylo by tedy dobré, kdybychom změnili nastavení znaků pro server MySQL na něco srozumitelného pro náš starší ovladač PHP. Přidejte následující dva řádky do konfigurace MySQL v sekci [mysqld]:

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

Volitelně můžete také přidat následující řádky do konfiguračního souboru MySQL, abyste zjednodušili veškerý přístup klientů k použití utf8:

[client]
default-character-set=utf8

[mysql]
default-character-set=utf8

Nezapomeňte restartovat server MySQL, aby se změny projevily. V tuto chvíli by naše aplikace měla vycházet s MySQL 8.0.

To je prozatím vše. Pokud máte nějaké další problémy s přesunem starších aplikací na MySQL 8.0, podělte se s námi o jakoukoli zpětnou vazbu v sekci komentářů.


  1. Postgres INTERVAL pomocí hodnoty z tabulky

  2. @@IDENTITY, SCOPE_IDENTITY(), OUTPUT a další metody získání poslední identity

  3. Porušuje MySQL standard tím, že umožňuje výběr sloupců, které nejsou součástí skupiny podle klauzule?

  4. Jedinečné omezení na více sloupců