Incidentu reaģēšana

MySQL "Can't connect to local MySQL server through socket" (kļūda 2002): risinājumi

mysql klients, cron darbs vai PHP lietotne pēkšņi saka, ka nevar sasniegt lokālo serveri caur .sock failu. Parasti serveris nedarbojas vai klients un serveris nav vienisprātis, kur atrodas socket. Skaitlis iekavās beigās pasaka, kurš no gadījumiem tas ir.

· 12 min lasīšanai · AG Data komanda

MySQL kļūda "Can't connect to local MySQL server through socket" (kļūda 2002) nozīmē, ka klients tajā pašā datorā mēģināja atvērt MySQL Unix socket failu un tas neizdevās. Praksē iemeslu ir tikai daži: serveris nedarbojas, tas darbojas, bet tā socket ir citur, vai klientam nav atļauts atvērt šo failu. Skaitlis iekavās ziņojuma beigās pasaka, ko pārbaudīt vispirms.

Tipisks ziņojums:

ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

Kāpēc "localhost" nozīmē socket

Unix sistēmās MySQL klients var pieslēgties divos veidos: caur Unix socket failu failu sistēmā vai caur TCP/IP. Saskaņā ar MySQL rokasgrāmatu socket fails tiek izmantots, ja jūs nenorādāt resursdatora nosaukumu vai norādāt īpašo nosaukumu localhost. Tātad mysql -h localhost portu 3306 nemaz neaiztiek, bet mysql -h 127.0.0.1 gan. Šī viena detaļa izskaidro daudz mulsinošu situāciju: "ports ir atvērts, bet localhost nestrādā" ir socket problēma, nevis tīkla problēma.

Kļūda 2002 ir socket gadījums. Ja klients ietu caur TCP, jūs redzētu kļūdu 2003, "Can't connect to MySQL server on 'host:port'". Abi ziņojumi nāk no klienta bibliotēkas libmysql/errmsg.cc, un pēdējais skaitlis iekavās ir operētājsistēmas kļūdas kods.

Nolasiet skaitli iekavās

Tās ir parastas Linux errno vērtības, un tās uzreiz sašaurina meklēšanu:

(2)    ENOENT        šajā ceļā nav faila: serveris nedarbojas vai ceļš ir nepareizs
(13)   EACCES        fails vai tā direktorija šim OS lietotājam nav pieejama
(111)  ECONNREFUSED  socket fails eksistē, bet neviens serveris to neklausās

Četras pārbaudes, kas atrod cēloni

# 1. Vai serveris vispār darbojas?
systemctl status mysql          # vai mysqld, atkarībā no pakotnes
ps aux | grep [m]ysqld

# 2. Kuru socket serveris patiesībā klausās?
ss -xlp | grep mysql

# 3. Kuru socket mēģina izmantot klients?
my_print_defaults client mysql
mysql --print-defaults

# 4. Ko serveris saka par sevi (caur TCP)?
mysql -h 127.0.0.1 -P 3306 -u root -p -e "SELECT @@socket, @@port, @@skip_networking"
  1. Nav mysqld procesa nozīmē, ka tā vispār nav socket problēma. Serveris nedarbojas, un īstais jautājums ir, kāpēc. Pirms jebko restartējat, paskatieties kļūdu žurnālā (komandas zem saraksta).
  2. Serveris klausās citu socket. ss -xlp parāda īsto ceļu. Salīdziniet to ar ceļu kļūdas ziņojumā.
  3. Klients lasa citu konfigurāciju. my_print_defaults client mysql izdrukā opcijas, ko mysql klients saņem no opciju failu grupām [client] un [mysql] (skatiet my_print_defaults dokumentāciju). Nepareiza socket= rinda tur vai tās trūkums ir ierastais vaininieks.
  4. Pajautājiet serverim. Ja TCP ir ieslēgts, @@socket parāda, kur serveris novietoja failu. Ja @@skip_networking ir 1, TCP ir izslēgts un socket ir vienīgā ieeja.
journalctl -u mysql -n 100 --no-pager
tail -n 100 /var/log/mysql/error.log      # Debian/Ubuntu pakotnes
tail -n 100 /var/log/mysqld.log           # bieži RPM sistēmās

Ja serveris nedarbojas, tipiski iemesli žurnālā ir pilns disks, InnoDB atkopšanas kļūda, nepareiza opcija tikko rediģētā konfigurācijas failā vai serveris, ko apturējis OOM killer. Restartēšana, neizlasot žurnālu, bieži vienkārši atkārto avāriju.

Kur atrodas socket

Iekompilētais noklusējums sistēmas mainīgajam socket ir /tmp/mysql.sock, un rokasgrāmata piebilst, ka dažos distribūcijas formātos direktorija ir cita, piemēram, /var/lib/mysql RPM pakotnēm. Debian/Ubuntu pakotnes, kas būvētas no paša MySQL pirmkoda, failā mysqld.cnf iestata /var/run/mysqld/mysqld.sock. Tāpēc kļūda tik bieži parādās pēc kādām izmaiņām:

Pastāvīgs risinājums ir ierakstīt to pašu ceļu abās grupās:

# /etc/mysql/my.cnf vai /etc/my.cnf: serverim un klientiem jāsakrīt
[mysqld]
socket = /var/run/mysqld/mysqld.sock

[client]
socket = /var/run/mysqld/mysqld.sock

Rokasgrāmatas lapa par socket failu min arī citus veidus, kā klientiem pateikt ceļu: opciju --socket un vides mainīgo MYSQL_UNIX_PORT. Vienreizējam savienojumam vai kamēr vēl izmeklējat, der jebkurš no tiem:

mysql --socket=/var/lib/mysql/mysql.sock -u root -p     # norādiet socket skaidri
mysql -h 127.0.0.1 --protocol=TCP -u app -p             # apejiet socket, izmantojiet TCP
MYSQL_UNIX_PORT=/var/lib/mysql/mysql.sock mysqldump ...  # vides mainīgais

Pāreja uz TCP ne vienmēr ir neitrāla. Serveris var piemeklēt citu kontu, un spraudnis auth_socket, kas autentificē klientus, kuri pieslēdzas caur Unix socket failu, caur TCP jūs vispār neielaidīs. Ja root izmanto auth_socket, paturiet socket un salabojiet ceļu. Ja savienojums izdodas, bet pieteikšanās ne, tā ir cita kļūda; skatiet mūsu ceļvedi par MySQL kļūdu 1045.

Pazudusi direktorija pēc pārstartēšanas

Mūsdienu distribūcijās ar systemd /var/run ir saite uz /run, kas atrodas atmiņā un pēc katras ielādes ir tukša. Oficiālais Debian/Ubuntu serviss to atrisina: tā pirmsstarta skripts failā mysql-helpers izveido /var/run/mysqld ar īpašnieku mysql un režīmu 0755, ja tās nav. Ja mysqld startējat citādi, ar roku, no pielāgota unit faila vai konteinerā, šo direktoriju neviens neizveido, un serveris tur nevar izveidot savu socket. Pārbaudiet to un izveidojiet tāpat:

ls -ld /var/run/mysqld /var/run/mysqld/mysqld.sock
# oficiālais Debian/Ubuntu serviss izveido direktoriju pirms starta:
install -d -m0755 -o mysql -g mysql /var/run/mysqld
Nelabojiet 2002 ar chmod 777. Socket direktorijas vai datu direktorijas atvēršana visiem paslēpj īsto problēmu un dod katram lokālajam lietotājam ceļu uz serveri. Noskaidrojiet, kurš lietotājs palaiž klientu, kuram pieder socket, un labāk salabojiet ceļu vai grupas piederību.

PHP, konteineri un citi klienti

PHP lietotnes to pašu problēmu ziņo kā SQLSTATE[HY000] [2002]. PDO_MYSQL dokumentācija paskaidro, kāpēc: Unix sistēmās resursdatora nosaukums localhost liek savienojumam iet caur domēna socket, un ar mysqlnd noklusējuma ceļš nāk no pdo_mysql.default_socket, kura dokumentētā vērtība ir /tmp/mysql.sock, lai gan PHP būvējumā kompilēšanas laikā var būt iestatīts cits noklusējums. Salabojiet to php.ini vai norādiet socket DSN virknē:

; php.ini
pdo_mysql.default_socket = /var/run/mysqld/mysqld.sock
mysqli.default_socket    = /var/run/mysqld/mysqld.sock

// vai DSN virknē
$pdo = new PDO('mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=app', $user, $pass);

Konteineros tas pats noteikums izraisa citu kļūmi. Lietotnes konteiners, kas pieslēdzas localhost, meklē socket failu savā failu sistēmā, kur tā nav. Izmantojiet datubāzes servisa resursdatora nosaukumu vai IP, kas iet caur TCP, vai apzināti piemontējiet socket direktoriju konteinerā.

Ja savienojumi sākumā strādā un tad pārtrūkst vaicājumu vidū, tā arī nav 2002; šo gadījumu apskata "MySQL server has gone away".

Galvenās atziņas

MySQL Savienojumi Linux Problēmu novēršana
Sadarbība ar mums

MySQL nedarbojas un lietotne nevar pieslēgties?

Ja MySQL nestartē vai klienti to nesasniedz, varam palīdzēt uzreiz: atrodam iemeslu, atjaunojam serveri un salabojam konfigurāciju, lai tas paliktu darbā. Pastāstiet, ko redzat žurnālos.

Sazināties Vairāk no emuāra