Incidentu reaģēšana

MySQL "Got a packet bigger than max_allowed_packet": kā to novērst

Atjaunošana apstājas 4127. rindā, vai liela faila augšupielāde pārtrauc savienojumu. MySQL piemēro izmēra limitu, un to ir divi, pa vienam katrā savienojuma galā. Lūk, kā noskaidrot, kuru sasniedzāt un cik daudz to palielināt.

· 11 min lasīšanai · AG Data komanda

MySQL kļūda "Got a packet bigger than 'max_allowed_packet' bytes" nozīmē, ka viena savienojuma puse saņēma vienu ziņojumu, kas lielāks, nekā tai atļauts pieņemt. Šis ziņojums var būt viens SQL vaicājums, viena rezultāta rinda vai viens binārā žurnāla notikums ceļā uz repliku. MySQL to atsaka un aizver savienojumu. Risinājums gandrīz vienmēr ir palielināt max_allowed_packet, taču pareizajā pusē un nevis akli līdz maksimumam.

Klasisks gadījums ir atjaunošana:

ERROR 1153 (08S01) at line 4127: Got a packet bigger than 'max_allowed_packet' bytes

Kļūda 1153 (ER_NET_PACKET_TOO_LARGE, SQLSTATE 08S01) nāk no servera. Klienta bibliotēkai ir sava versija, kļūda 2020 "Got packet bigger than 'max_allowed_packet' bytes" (servera kļūdas, klienta kļūdas). Tā kā savienojums tiek aizvērts, daži klienti ziņo tikai "Lost connection to MySQL server during query" vai labi zināmo MySQL server has gone away, kas slēpj īsto cēloni.

Divi limiti, pa vienam katrā galā

Šī ir daļa, kas mulsina. Saskaņā ar MySQL rokasgrāmatu klientam un serverim katram ir savs max_allowed_packet, un, lai pārsūtītu lielas paketes, jāpalielina abi. Noklusējumi atšķiras:

Tātad virziens ir svarīgs. 40MB vaicājuma sūtīšana no mysql klienta uz serveri ar 64MB joprojām neizdodas, jo klientam ir 16MB. Lasīšana darbojas tāpat pretējā virzienā: serveris nesūta vairāk par savu globālo max_allowed_packet, lai ko atļautu klients.

1. solis: noskaidrojiet, kura puse atteica

-- servera puse: globālā vērtība (to saņem jauni savienojumi)
SELECT @@GLOBAL.max_allowed_packet / 1024 / 1024 AS server_mb;

-- jūsu pašreizējā sesija (tikai lasāma, fiksēta pieslēgšanās brīdī)
SELECT @@SESSION.max_allowed_packet / 1024 / 1024 AS session_mb;

-- cik liela ir lielākā vērtība, ko jūs patiešām glabājat?
SELECT MAX(LENGTH(payload)) / 1024 / 1024 AS biggest_mb FROM documents;

Salīdziniet šos skaitļus ar to, ko sūtāt. Ja kļūda ir 1153 no servera, servera limits ir par mazu. Ja tā ir 2020 vai parādās klienta rīkā, skatieties klienta opciju failu vai savienojuma virkni. Pārbaudiet arī, no kurienes nāk lielā pakete. Tipiski avoti no mūsu pieredzes:

2. solis: pareizi palieliniet servera limitu

max_allowed_packet ir dinamisks, bet ar vienu āķi: sesijas vērtība ir tikai lasāma un tiek iestatīta, kad klients pieslēdzas. Globālās vērtības maiņa palīdz tikai jauniem savienojumiem. Jūsu lietotnes pūls patur veco vērtību, līdz pieslēdzas no jauna.

-- MySQL 8.0+: mainiet tagad un saglabājiet pēc restarta
SET PERSIST max_allowed_packet = 268435456;   -- 256MB

# vai my.cnf
[mysqld]
max_allowed_packet = 256M

Vai palielināt ir droši? Rokasgrāmata saka, ka jā: papildu atmiņa tiek piešķirta tikai tad, kad tā vajadzīga. Katra savienojuma buferis sākas ar net_buffer_length (pēc noklusējuma 16KB) un aug līdz max_allowed_packet tikai liela vaicājuma vai rindas dēļ. Mazais noklusējums ir piesardzība pret bojātām paketēm un pret nejaušu atmiņas izsīkšanu. Praksē mēs izvēlamies vērtību ar rezervi virs lielākās reālās vērtības, piemēram, 256MB, nevis 1GB visur. Tūkstotis savienojumu, kas vienlaikus sūta pa 1GB paketei, ir atmiņas problēma, no kuras neglābs neviens iestatījums.

Neaizmirstiet klientu. Pēc servera limita palielināšanas atjaunošana ar mysql klientu joprojām var neizdoties pie 16MB. Nododiet --max_allowed_packet arī klientam vai iestatiet to opciju faila sadaļā [mysql] vai [client].

Dampu atjaunošana

# dampa atjaunošana: mysql klienta noklusējums ir 16MB, palieliniet arī to
mysql --max_allowed_packet=256M appdb  < dump.sql

Divas piezīmes no mysqldump dokumentācijas. Pirmkārt, tā opcija --network-timeout pēc noklusējuma ir ieslēgta un dampa laikā paceļ mysqldump paša pakešu limitu līdz maksimumam, tāpēc dampis parasti izdodas, un problēma parādās atjaunošanā. Otrkārt, klienta iestatījums nevar pārspēt serveri: viena pakete nekad nevar pārsniegt servera max_allowed_packet, lai kā būtu iestatīts mysqldump. Ar --extended-insert (daļa no noklusējuma --opt) mysqldump būvē vairāku rindu INSERT līdz --net-buffer-length baitiem (pēc noklusējuma 16KB). Tātad vaicājums dampā ir milzīgs tikai tad, ja milzīga ir viena rinda, un tad vienīgais risinājums ir palielināt limitus. Tieši šādu kļūmi regulārs atjaunošanas tests atklāj, pirms to izdara incidents.

Replikācija

Lieli rindu notikumi var salauzt arī replikāciju. Replikā attiecīgais iestatījums ir replica_max_allowed_packet, kura noklusējums ir 1GB un kas attiecas uz saņēmēja un piemērotāja pavedieniem (replikas opcijas). Rokasgrāmata norāda, ka avots var ierakstīt notikumus, kas pēc galvenes pievienošanas ir garāki par tā paša max_allowed_packet, tāpēc replikas vērtībai jābūt lielākai par avota vērtību. Ja avots atsakās sūtīt notikumu, replikas kļūdā ir teksts "log event entry exceeded max_allowed_packet; Increase max_allowed_packet on source" (rpl_binlog_sender.cc). Ja to atsaka replika, žurnālā rakstīts "Log entry on source is longer than replica_max_allowed_packet". CLONE spraudnim arī ir sava pārbaude, un tas pasaka, kāda minimālā vērtība tam vajadzīga.

Kad limita palielināšana ir nepareizs risinājums

Ja lielā pakete nāk no lietotnes koda, labāks risinājums bieži ir kodā. Sadaliet masveida ievietošanu partijās pa dažiem tūkstošiem rindu. Aizstājiet milzīgu IN sarakstu ar pagaidu tabulu un join. Apsveriet simtiem megabaitu lielu failu glabāšanu objektu krātuvē, MySQL paturot tikai atsauci. Limits, kas palielināts līdz 1GB tikai tāpēc, lai izietu viens slikts vaicājums, ielaidīs arī nākamo slikto vaicājumu.

Galvenās atziņas

MySQL max_allowed_packet Atjaunošana Problēmu novēršana
Sadarbība ar mums

Atjaunošana vai migrācija iestrēgusi MySQL kļūdās?

Mēs atjaunojam un migrējam jebkura izmēra MySQL datubāzes, labojam limitus, kas salauž lielus importus un replikāciju, un pārliecināmies, ka nākamā atjaunošana strādā, pirms tā jums vajadzīga.

Sazināties Vairāk no emuāra