明輝手游網(wǎng)中心:是一個(gè)免費(fèi)提供流行視頻軟件教程、在線學(xué)習(xí)分享的學(xué)習(xí)平臺(tái)!

使用MySQL時(shí)的一些經(jīng)常見(jiàn)出錯(cuò)

[摘要]MySQL server has gone away錯(cuò)誤本小節(jié)也涉及有關(guān)Lost connection to server during query的錯(cuò)誤。對(duì)MySQL server has gone away錯(cuò)誤最常見(jiàn)的原因是服務(wù)器超時(shí)了并且關(guān)閉了連接。缺省地,如果沒(méi)有事情發(fā)生,服務(wù)器在 8個(gè)小...
MySQL server has gone away錯(cuò)誤
本小節(jié)也涉及有關(guān)Lost connection to server during query的錯(cuò)誤。

對(duì)MySQL server has gone away錯(cuò)誤最常見(jiàn)的原因是服務(wù)器超時(shí)了并且關(guān)閉了連接。缺省地,如果沒(méi)有事情發(fā)生,服務(wù)器在 8個(gè)小時(shí)后關(guān)閉連接。你可在啟動(dòng)mysqld時(shí)通過(guò)設(shè)置wait_timeout變量改變時(shí)間限制。

你可以通過(guò)執(zhí)行mysqladmin version并且檢驗(yàn)正常運(yùn)行的時(shí)間來(lái)檢查MySQL還沒(méi)死掉。

如果你有一個(gè)腳本,你只須再發(fā)出查詢讓客護(hù)進(jìn)行一次自動(dòng)的重新連接。

在這種請(qǐng)下,你通常能獲得下列錯(cuò)誤代碼(你得到的是OS相關(guān)的):

CR_SERVER_GONE_ERROR客戶不能發(fā)送一個(gè)問(wèn)題給服務(wù)器。
CR_SERVER_LOST當(dāng)寫(xiě)服務(wù)器時(shí),客戶沒(méi)有出錯(cuò),但是它沒(méi)有得到對(duì)問(wèn)題的一個(gè)完整的答案(或任何答案)。

如果你向服務(wù)器發(fā)送不正確的或太大的查詢,你也可能得到這些錯(cuò)誤。如果mysqld得到一個(gè)太大或不正常的包,它認(rèn)為客戶出錯(cuò)了并關(guān)閉連接。如果你需要較大的查詢(例如,如果你正在處理較大的BLOB列),你可以使用-O max_allowed_packet=#選項(xiàng)(缺省1M)啟動(dòng)mysqld以增加查詢限制。多余的內(nèi)存按需分配,這樣mysqld只有在你發(fā)出較大差詢時(shí)或mysqld必須返回較大的結(jié)果行時(shí),才使用更多的內(nèi)存!

Can't connect to [local] MySQL server錯(cuò)誤
一個(gè)MySQL客戶可以兩種不同的方式連接mysqld服務(wù)器:Unix套接字,它通過(guò)在文件系統(tǒng)中的一個(gè)文件(缺省“/tmp/mysqld.sock”)進(jìn)行連接;或TCP/IP,它通過(guò)一個(gè)端口號(hào)連接。Unix套接字比TCP/IP更快,但是只有用在連接同一臺(tái)計(jì)算機(jī)上的服務(wù)器。如果你不指定主機(jī)名或如果你指定特殊的主機(jī)名localhost,使用Unix套接字。

錯(cuò)誤(2002)Can't connect to ...通常意味著沒(méi)有一個(gè)MySQL服務(wù)器運(yùn)行在系統(tǒng)上或當(dāng)試圖連接mysqld服務(wù)器時(shí),你正在使用一個(gè)錯(cuò)誤的套接字文件或TCP/IP端口。

由檢查(使用ps)在你的服務(wù)器上有一個(gè)名為mysqld的進(jìn)程啟動(dòng)!如果沒(méi)有任何mysqld過(guò)程,你應(yīng)該啟動(dòng)一個(gè)。見(jiàn)4.15.2 啟動(dòng)MySQL服務(wù)器的問(wèn)題。

如果一個(gè)mysqld過(guò)程正在運(yùn)行,你可以通過(guò)嘗試這些不同的連接來(lái)檢查服務(wù)器(當(dāng)然,端口號(hào)和套接字路徑名可能在你的安裝中是不同的):

shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h `hostname` version variables
shell> mysqladmin -h `hostname` --port=3306 version
shell> mysqladmin -h 'ip for your host' version
shell> mysqladmin --socket=/tmp/mysql.sock version

注意hostname命令使用反引號(hào)“`”而非正引號(hào)“'”;這些導(dǎo)致hostname輸出(即,當(dāng)前主機(jī)名)被代替進(jìn)mysqladmin命令中。

這是可能造成Can't connect to local MySQL server錯(cuò)誤的一些原因:

mysqld不在運(yùn)行。
你正在使用MIT-pthreads的一個(gè)系統(tǒng)上運(yùn)行。如果正在運(yùn)行在一個(gè)沒(méi)有原生線程的系統(tǒng)上,mysqld使用 MIT-pthreads 軟件包。見(jiàn)4.2 由MySQL支持的操作系統(tǒng)。然而,MIT-pthreads不支持Unix套接字,因此當(dāng)與服務(wù)器連接時(shí),在這樣一個(gè)系統(tǒng)上,你總是必須明確地指定主機(jī)名。試試使用這個(gè)命令檢查到服務(wù)器的連接:
shell> mysqladmin -h `hostname` version

某人刪除了mysqld使用的Unix套接字(缺省“/tmp/mysqld.sock”)。你可能有一個(gè)cron任務(wù)刪除了MySQL套接字(例如,一個(gè)把舊文件從“/tmp”目錄中刪除的任務(wù))。你總是可以運(yùn)行mysqladmin version并且檢查mysqladmin正在試圖使用的套接字確實(shí)存在。在這種情況下,修復(fù)方法是刪除cron任務(wù)而不刪除“mysqld.sock 或?qū)⑻捉幼址旁谄渌胤健D隳苡眠@個(gè)命令在MySQL配置時(shí)指定一個(gè)不同的套接字地點(diǎn):
shell> ./configure --with-unix-socket-path=/path/to/socket

你也可以使用--socket=/path/to/socket選項(xiàng)啟動(dòng)safe_mysqld和在啟動(dòng)你的MySQL客戶前設(shè)置環(huán)境變量MYSQL_UNIX_PORT為套接字路徑名。你可用--socket=/path/to/socket選項(xiàng)啟動(dòng)mysqld服務(wù)器。如果你改變了服務(wù)器的套接字路徑名,你也必須通知MySQL客戶關(guān)于新路徑的情況。你可以通過(guò)設(shè)置環(huán)境變量MYSQL_UNIX_PORT為套接字路徑名或由提供套接字路徑名作為客戶的參數(shù)做到。你可用這個(gè)命令測(cè)試套接字:

shell> mysqladmin --socket=/path/to/socket version

你正在使用 Linux和線程已經(jīng)死了(核心傾倒了)。在這種情況中,你必須殺死其它mysqld線程(例如在啟動(dòng)一個(gè)新的MySQL服務(wù)器之前,可以用mysql_zap腳本)。見(jiàn)18.1 如果MySQL總是崩潰怎么辦。
如果你得到錯(cuò)誤Can't connect to MySQL server on some_hostname,你可以嘗試下列步驟找出問(wèn)題是什么:

通過(guò)執(zhí)行telnet your-host-name tcp-ip-port-number并且按幾次回車來(lái)檢查服務(wù)器是否正常運(yùn)行。如果有一個(gè)MySQL運(yùn)行在這個(gè)端口上,你應(yīng)該得到一個(gè)包含正在運(yùn)行的MySQL服務(wù)器的版本號(hào)的應(yīng)答。如果你得到類似于telnet: Unable to connect to remote host: Connection refused的一個(gè)錯(cuò)誤,那么沒(méi)有服務(wù)器在使用的端口上運(yùn)行。
嘗試連接本地機(jī)器上的mysqld守護(hù)進(jìn)程,并用mysqladmin variables檢查mysqld被配置使用的TCP/IP端口(變量port)。
檢查你的mysqld服務(wù)器沒(méi)有用--skip-networking選項(xiàng)啟動(dòng)。
Host '...' is blocked錯(cuò)誤
如果你得到象這樣的一個(gè)錯(cuò)誤:

Host 'hostname' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'

這意味著,mysqld已經(jīng)得到了大量(max_connect_errors)的主機(jī)'hostname'的在中途被中斷了的連接請(qǐng)求。在max_connect_errors次失敗請(qǐng)求后,mysqld認(rèn)定出錯(cuò)了(象來(lái)字一個(gè)黑客的攻擊),并且阻止該站點(diǎn)進(jìn)一步的連接,直到某人執(zhí)行命令mysqladmin flush-hosts。

缺省地,mysqld在10個(gè)連接錯(cuò)誤后阻塞一臺(tái)主機(jī)。你可以通過(guò)象這樣啟動(dòng)服務(wù)器很容易地調(diào)整它:

shell> safe_mysqld -O max_connect_errors=10000 &

注意,對(duì)給定的主機(jī),如果得到這條錯(cuò)誤消息,你應(yīng)該首先檢查該主機(jī)的TCP/IP連接有沒(méi)有問(wèn)題。如果你的TCP/IP連接不在運(yùn)行,增加max_connect_errors變量的值對(duì)你也不會(huì)有幫助!

Too many connections錯(cuò)誤
如果在你試土連接MySQL時(shí),你得到錯(cuò)誤Too many connections,這意味著已經(jīng)有max_connections個(gè)客戶連接了mysqld服務(wù)器。

如果你需要比缺省(100)更多的連接,那么你應(yīng)該重啟mysqld,用更大的 max_connections 變量值。

注意,mysqld實(shí)際上允許(max_connections+1)個(gè)客戶連接。最后一個(gè)連接是為一個(gè)用Process權(quán)限的用戶保留的。通過(guò)不把這個(gè)權(quán)限給一般用戶(他們不應(yīng)該需要它),有這個(gè)權(quán)限一個(gè)管理員可以登錄并且使用SHOW PROCESSLIST找出什么可能出錯(cuò)。見(jiàn)7.21 SHOW句法(得到表,列的信息)。

Out of memory錯(cuò)誤
如果你發(fā)出查詢并且得到類似于下面的錯(cuò)誤:

mysql: Out of memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 bytes (12189k)
ERROR 2008: MySQL client ran out of memory

注意,錯(cuò)誤指向了MySQL客戶mysql。這個(gè)錯(cuò)誤的原因很簡(jiǎn)單,客戶沒(méi)有足夠的內(nèi)存存儲(chǔ)全部結(jié)果。

為了修正這個(gè)問(wèn)題,首先檢查你的查詢是否正確。它應(yīng)該返回這么多的行,這合理嗎?如果是這樣,你可以使用mysql --quick,它使用mysql_use_result()檢索結(jié)果集合。這將較少的負(fù)擔(dān)放在了客戶端(只是服務(wù)器更多)。

Packet too large錯(cuò)誤
當(dāng)一個(gè)MySQL客戶或mysqld服務(wù)器得到一個(gè)比max_allowed_packet個(gè)字節(jié)長(zhǎng)的包,它發(fā)出一個(gè)Packet too large錯(cuò)誤并終止連接。

如果你正在使用mysql客戶,你可以通過(guò)用mysql --set-variable=max_allowed_packet=8M指定一個(gè)更大的緩沖區(qū)來(lái)啟動(dòng)客戶程序。

如果你正在使用不允許你指定最大包大小的其他客戶(例如 DBI),你需要在你啟動(dòng)服務(wù)器時(shí)設(shè)置包大小。你可以使用mysqld的命令行選項(xiàng)設(shè)置max_allowed_packet為一個(gè)更大的尺寸。例如,如果你正期望將一個(gè)全長(zhǎng)的BLOB存入一張表中,你將需要用--set-variable=max_allowed_packet=24M選項(xiàng)來(lái)啟動(dòng)服務(wù)器。

 

The table is full錯(cuò)誤
這個(gè)錯(cuò)誤發(fā)生在內(nèi)存臨時(shí)表變得比tmp_table_size字節(jié)大時(shí)。為了避免這個(gè)問(wèn)題,你可以使用mysqld的-O tmp_table_size=#選項(xiàng)來(lái)增加臨時(shí)表的大小,或在你發(fā)出有疑問(wèn)的查詢之前使用SQL選項(xiàng)SQL_BIG_TABLES。見(jiàn)7.25 SET OPTION句法。

你也可以使用--big-tables選項(xiàng)啟動(dòng)mysqld。這與為所有查詢使用SQL_BIG_TABLES完全相同。


Commands out of sync in client錯(cuò)誤
如果你在你的客戶代碼中得到Commands out of sync; You can't run this command now,你正在以錯(cuò)誤的次序調(diào)用客戶函數(shù)!

這可能發(fā)生,例如,如果你正在使用mysql_use_result()并且在你已經(jīng)調(diào)用了mysql_free_result()之前試圖執(zhí)行新查詢。如果你在mysql_use_result()或mysql_store_result()之間試圖執(zhí)行返回?cái)?shù)據(jù)的2個(gè)查詢,它也可能發(fā)生。

Ignoring user錯(cuò)誤
如果你得到下列錯(cuò)誤:

Found wrong password for user: 'some_user@some_host'; Ignoring user

這意味著在mysqld啟動(dòng)時(shí)或在它再次裝載權(quán)限表時(shí),它在user表中找到了一個(gè)有一個(gè)無(wú)效口令的條目。結(jié)果,條目簡(jiǎn)單地被權(quán)限系統(tǒng)忽略。

可能導(dǎo)致這個(gè)問(wèn)題的原因和修正:

你可能正在運(yùn)行一個(gè)有一個(gè)老的user表的新版本mysqld。你可以通過(guò)執(zhí)行mysqlshow mysql user看看口令字段是否少于 16個(gè)字符來(lái)檢查它。如果是這樣,你可以通過(guò)運(yùn)行scripts/add_long_password腳本改正這種情況。
用戶有一個(gè)老式的口令(8個(gè)字符長(zhǎng))并且你沒(méi)使用--old-protocol選項(xiàng)啟動(dòng)mysqld。用一個(gè)新口令更新在user表中的用戶或用--old-protocol重啟mysqld。
你沒(méi)有使用PASSWORD()函數(shù)在在user表中指定了一個(gè)口令。使用mysql以一個(gè)新口令更新在user表中的用戶。確保使用PASSWORD()函數(shù):
mysql> update user set password=PASSWORD('your password')
 where user='XXX';

Table 'xxx' doesn't exist錯(cuò)誤
如果你得到錯(cuò)誤Table 'xxx' doesn't exist或Can't find file: 'xxx' (errno: 2),這意味著在當(dāng)前數(shù)據(jù)庫(kù)中沒(méi)有名為xxx的表存在。

注意,因?yàn)镸ySQL使用目錄和文件存儲(chǔ)數(shù)據(jù)庫(kù)和表,數(shù)據(jù)庫(kù)和表名件是區(qū)分大小寫(xiě)的。ㄔ赪in32上,數(shù)據(jù)庫(kù)和表名不是區(qū)分大小寫(xiě)的,但是在查詢中對(duì)所有表的引用必須使用相同的大小寫(xiě)!)

你可以用SHOW TABLES檢查你在當(dāng)前數(shù)據(jù)庫(kù)中有哪個(gè)表。