MySQL數據庫常見錯誤問題解答
添加時間:2014-4-25 16:45:02
添加:
思海網絡
MySQL數據庫常見錯誤問題解答:
1MySQLserverhasgoneaway錯誤
本小節也涉及有關Lostconnectiontoserverduringquery的錯誤。
對MySQLserverhasgoneaway錯誤最常見的原因是服務器超時了并且關閉了連接。缺省地,如果沒有事情發生,服務器在8個小時后關閉連接。你可在啟動mysqld時通過設置wait_timeout變量改變時間限制。
你可以通過執行mysqladminversion并且檢驗正常運行的時間來檢查MySQL還沒死掉。
如果你有一個腳本,你只須再發出查詢讓客護進行一次自動的重新連接。
在這種請下,你通常能獲得下列錯誤代碼(你得到的是OS相關的):
CR_SERVER_GONE_ERROR客戶不能發送一個問題給服務器。
CR_SERVER_LOST當寫服務器時,客戶沒有出錯,但是它沒有得到對問題的一個完整的答案(或任何答案)。
如果你向服務器發送不正確的或太大的查詢,你也可能得到這些錯誤。如果mysqld得到一個太大或不正常的包,它認為客戶出錯了并關閉連接。如果你需要較大的查詢(例如,如果你正在處理較大的BLOB列),你可以使用-Omax_allowed_packet=#選項(缺省1M)啟動mysqld以增加查詢限制。多余的內存按需分配,這樣mysqld只有在你發出較大差詢時或mysqld必須返回較大的結果行時,才使用更多的內存!
2Can’tconnectto[local]MySQLserver錯誤
一個MySQL客戶可以兩種不同的方式連接mysqld服務器:Unix套接字,它通過在文件系統中的一個文件(缺省“/tmp/mysqld.sock”)進行連接;或TCP/IP,它通過一個端口號連接。Unix套接字比TCP/IP更快,但是只有用在連接同一臺計算機上的服務器。如果你不指定主機名或如果你指定特殊的主機名localhost,使用Unix套接字。
錯誤(2002)Can’tconnectto...通常意味著沒有一個MySQL服務器運行在系統上或當試圖連接mysqld服務器時,你正在使用一個錯誤的套接字文件或TCP/IP端口。
由檢查(使用ps)在你的服務器上有一個名為mysqld的進程啟動!如果沒有任何mysqld過程,你應該啟動一個。見4.15.2啟動MySQL服務器的問題。
如果一個mysqld過程正在運行,你可以通過嘗試這些不同的連接來檢查服務器(當然,端口號和套接字路徑名可能在你的安裝中是不同的):
shell>mysqladminversion
shell>mysqladminvariables
shell>mysqladmin-h`hostname`versionvariables
shell>mysqladmin-h`hostname`--port=3306version
shell>mysqladmin-h’ipforyourhost’version
shell>mysqladmin--socket=/tmp/mysql.sockversion
注意hostname命令使用反引號“`”而非正引號“’”;這些導致hostname輸出(即,當前主機名)被代替進mysqladmin命令中。
這是可能造成Can’tconnecttolocalMySQLserver錯誤的一些原因:
mysqld不在運行。
你正在使用MIT-pthreads的一個系統上運行。如果正在運行在一個沒有原生線程的系統上,mysqld使用MIT-pthreads軟件包。見4.2由MySQL支持的操作系統。然而,MIT-pthreads不支持Unix套接字,因此當與服務器連接時,在這樣一個系統上,你總是必須明確地指定主機名。試試使用這個命令檢查到服務器的連接:
shell>mysqladmin-h`hostname`version
某人刪除了mysqld使用的Unix套接字(缺省“/tmp/mysqld.sock”)。你可能有一個cron任務刪除了MySQL套接字(例如,一個把舊文件從“/tmp”目錄中刪除的任務)。你總是可以運行mysqladminversion并且檢查mysqladmin正在試圖使用的套接字確實存在。在這種情況下,修復方法是刪除cron任務而不刪除“mysqld.sock或將套接字放在其他地方。你能用這個命令在MySQL配置時指定一個不同的套接字地點:
shell>./configure--with-unix-socket-path=/path/to/socket
你也可以使用--socket=/path/to/socket選項啟動safe_mysqld和在啟動你的MySQL客戶前設置環境變量MYSQL_UNIX_PORT為套接字路徑名。你可用--socket=/path/to/socket選項啟動mysqld服務器。如果你改變了服務器的套接字路徑名,你也必須通知MySQL客戶關于新路徑的情況。你可以通過設置環境變量MYSQL_UNIX_PORT為套接字路徑名或由提供套接字路徑名作為客戶的參數做到。你可用這個命令測試套接字:
shell>mysqladmin--socket=/path/to/socketversion
你正在使用Linux和線程已經死了(核心傾倒了)。在這種情況中,你必須殺死其它mysqld線程(例如在啟動一個新的MySQL服務器之前,可以用mysql_zap腳本)。見18.1如果MySQL總是崩潰怎么辦。
如果你得到錯誤Can’tconnecttoMySQLserveronsome_hostname,你可以嘗試下列步驟找出問題是什么:
通過執行telnetyour-host-nametcp-ip-port-number并且按幾次回車來檢查服務器是否正常運行。如果有一個MySQL運行在這個端口上,你應該得到一個包含正在運行的MySQL服務器的版本號的應答。如果你得到類似于telnet:Unabletoconnecttoremotehost:Connectionrefused的一個錯誤,那么沒有服務器在使用的端口上運行。
嘗試連接本地機器上的mysqld守護進程,并用mysqladminvariables檢查mysqld被配置使用的TCP/IP端口(變量port)。
檢查你的mysqld服務器沒有用--skip-networking選項啟動。
3Host’...’isblocked錯誤
如果你得到象這樣的一個錯誤:
Host’hostname’isblockedbecauseofmanyconnectionerrors.
Unblockwith’mysqladminflush-hosts’
這意味著,mysqld已經得到了大量(max_connect_errors)的主機’hostname’的在中途被中斷了的連接請求。在max_connect_errors次失敗請求后,mysqld認定出錯了(象來字一個黑客的攻擊),并且阻止該站點進一步的連接,直到某人執行命令mysqladminflush-hosts。
缺省地,mysqld在10個連接錯誤后阻塞一臺主機。你可以通過象這樣啟動服務器很容易地調整它:
shell>safe_mysqld-Omax_connect_errors=10000&
注意,對給定的主機,如果得到這條錯誤消息,你應該首先檢查該主機的TCP/IP連接有沒有問題。如果你的TCP/IP連接不在運行,增加max_connect_errors變量的值對你也不會有幫助!
4Toomanyconnections錯誤
如果在你試土連接MySQL時,你得到錯誤Toomanyconnections,這意味著已經有max_connections個客戶連接了mysqld服務器。
如果你需要比缺省(100)更多的連接,那么你應該重啟mysqld,用更大的max_connections變量值。
注意,mysqld實際上允許(max_connections+1)個客戶連接。最后一個連接是為一個用Process權限的用戶保留的。通過不把這個權限給一般用戶(他們不應該需要它),有這個權限一個管理員可以登錄并且使用SHOWPROCESSLIST找出什么可能出錯。見7.21SHOW句法(得到表,列的信息)。
5Outofmemory錯誤
如果你發出查詢并且得到類似于下面的錯誤:
mysql:Outofmemoryatline42,’malloc.c’
mysql:needed8136byte(8k),memoryinuse:12481367bytes(12189k)
ERROR2008:MySQLclientranoutofmemory
注意,錯誤指向了MySQL客戶mysql。這個錯誤的原因很簡單,客戶沒有足夠的內存存儲全部結果。
為了修正這個問題,首先檢查你的查詢是否正確。它應該返回這么多的行,這合理嗎?如果是這樣,你可以使用mysql--quick,它使用mysql_use_result()檢索結果集合。這將較少的負擔放在了客戶端(只是服務器更多)。
6Packettoolarge錯誤
當一個MySQL客戶或mysqld服務器得到一個比max_allowed_packet個字節長的包,它發出一個Packettoolarge錯誤并終止連接。
如果你正在使用mysql客戶,你可以通過用mysql--set-variable=max_allowed_packet=8M指定一個更大的緩沖區來啟動客戶程序。
如果你正在使用不允許你指定最大包大小的其他客戶(例如DBI),你需要在你啟動服務器時設置包大小。你可以使用mysqld的命令行選項設置max_allowed_packet為一個更大的尺寸。例如,如果你正期望將一個全長的BLOB存入一張表中,你將需要用--set-variable=max_allowed_packet=24M選項來啟動服務器。
7Thetableisfull錯誤
這個錯誤發生在內存臨時表變得比tmp_table_size字節大時。為了避免這個問題,你可以使用mysqld的-Otmp_table_size=#選項來增加臨時表的大小,或在你發出有疑問的查詢之前使用SQL選項SQL_BIG_TABLES。見7.25SETOPTION句法。
你也可以使用--big-tables選項啟動mysqld。這與為所有查詢使用SQL_BIG_TABLES完全相同。
8Commandsoutofsyncinclient錯誤
如果你在你的客戶代碼中得到Commandsoutofsync;Youcan’trunthiscommandnow,你正在以錯誤的次序調用客戶函數!
這可能發生,例如,如果你正在使用mysql_use_result()并且在你已經調用了mysql_free_result()之前試圖執行新查詢。如果你在mysql_use_result()或mysql_store_result()之間試圖執行返回數據的2個查詢,它也可能發生。
9Ignoringuser錯誤
如果你得到下列錯誤:
Foundwrongpasswordforuser:’some_user@some_host’;Ignoringuser
這意味著在mysqld啟動時或在它再次裝載權限表時,它在user表中找到了一個有一個無效口令的條目。結果,條目簡單地被權限系統忽略。
可能導致這個問題的原因和修正:
你可能正在運行一個有一個老的user表的新版本mysqld。你可以通過執行mysqlshowmysqluser看看口令字段是否少于16個字符來檢查它。如果是這樣,你可以通過運行s/add_long_password腳本改正這種情況。
用戶有一個老式的口令(8個字符長)并且你沒使用--old-protocol選項啟動mysqld。用一個新口令更新在user表中的用戶或用--old-protocol重啟mysqld。
你沒有使用PASSWORD()函數在在user表中指定了一個口令。使用mysql以一個新口令更新在user表中的用戶。確保使用PASSWORD()函數:
mysql>updateusersetpassword=PASSWORD(’yourpassword’)
whereuser=’XXX’;
10Table’xxx’doesn’texist錯誤
如果你得到錯誤Table’xxx’doesn’texist或Can’tfindfile:’xxx’(errno:2),這意味著在當前數據庫中沒有名為xxx的表存在。
注意,因為MySQL使用目錄和文件存儲數據庫和表,數據庫和表名件是區分大小寫的!(在Win32上,數據庫和表名不是區分大小寫的,但是在查詢中對所有表的引用必須使用相同的大小寫!)
你可以用SHOWTABLES檢查你在當前數據庫中有哪個表。見7.21SHOW句法(得到表、列的信息)。
18.3MySQL怎樣處理一個溢出的磁盤
當出現一個磁盤溢出的情況時,MySQL做下列事情:
它每分鐘檢查一次看是否有足夠空間寫入當前行。如果有足夠的空間,它繼續好像發生什么事情。
每6分鐘它將有關磁盤溢出的警告寫入日志文件。
為了緩和這個問題,你可以采取下列行動:
繼續,你只需釋放足夠的空閑磁盤空間以便插入所有記錄。
放棄線程,你必須發一個mysqladminkill到線程。在下一次檢查磁盤時,線程將被放棄(在1分鐘內)。
注意,其他線程可能正在等待引起“磁盤溢出”條件的表。如果你有幾個“鎖定的”的線程,殺死正在等待磁盤溢出條件的那個線程將允許其他線程繼續。
18.4如何從一個文本文件運行SQL命令
一般地,mysql客戶被交互性地使用,象這樣:
shell>mysqldatabase
然而,也可以把你的SQL命令放在一個文件中并且告訴mysql從該文件讀取其輸入。要想這樣做,創造一個文本文件“text_file”,它包含你想要執行的命令。然后如下那樣調用mysql:
shell>mysqldatabase<text_file
你也能啟動有一個USEdb_name語句的文本文件。在這種情況下,在命令行上指定數據庫名是不必要的:
shell>mysql<text_file
見12.1不同的MySQL程序概述。
18.5MySQL在哪兒存儲臨時文件
MySQL使用TMPDIR環境變量的值作為存儲臨時文件的目錄的路徑名。如果你沒有設置TMPDIR,MySQL使用系統缺省值,它通常是“/tmp”或“/usr/tmp”。如果包含你的臨時文件目錄的文件系統太小,你應該編輯safe_mysqld設定TMPDIR指向你有足夠空間的一個文件系統!你也可以使用mysqld的--tmpdir選項目設置臨時目錄。
MySQL以“隱含文件”創建所有臨時文件。這保證了如果mysqld被終止,臨時文件也將被刪除。使用隱含文件的缺點是你將看不到一個大的臨時文件填滿了臨時文件目錄所在的文件系統。
當排序(ORDERBY或GROUPBY)時,MySQL通常使用一個或兩個臨時文件。最大磁盤空間需求是:
(存儲東西的長度+sizeof(數據庫指針))
*匹配的行數
*2
sizeof(數據庫指針)通常是4,但是在未來對確實很大的表可能增加。
對一些SELECT查詢,MySQL也創建臨時SQL表。這些沒被隱含且有“SQL_*”格式的名字。
ALTERTABLE和OPTIMIZETABLE在原數據庫表的同一個目錄中創建一張臨時表。
18.6怎樣保護“/tmp/mysql.sock”不被刪除
如果你有這個問題,事實上任何人可以刪除MySQL通訊套接字“/tmp/mysql.sock”,在Unix的大多數版本上,你能通過為其設置sticky(t)位來保護你的“/tmp”文件系統。作為root登錄并且做下列事情:
shell>chmod+t/tmp
這將保護你的“/tmp”文件系統使得文件僅能由他們的所有者或超級用戶(root)刪除。
你能執行ls-ld/tmp檢查sticky位是否被設置,如果最后一位許可位是t,該位被設置了。
18.7Accessdenied錯誤
見6.6權限系統如何工作。并且特別要看6.13引起Accessdenied錯誤的原因。
18.8怎樣作為一個一般用戶運行MySQL
MySQL服務器mysqld能被任何用戶啟動并運行。為了將mysqld改由Unix用戶user_name來運行,你必須做下列事情:
如果它正在運行,停止服務器(使用mysqladminshutdown)。
改變數據庫目錄和文件以便user_name有權限讀和寫文件(你可能需要作為Unix的root用戶才能做到):
shell>chown-Ruser_name/path/to/mysql/datadir
如果在MySQL數據目錄中的目錄或文件是符號鏈接,你也將需要順著那些鏈接并改變他們指向的目錄和文件。chown-R不能跟隨符號鏈接。
以user_name用戶啟動服務器,或如果你正在使用MySQL3.22或以后版本,以Unixroot用戶啟動mysqld并使用--user=user_name選項,mysqld將在接受任何連接之前切換到以Unixuser_name用戶運行。
如果在系統被重新啟動時,你使用mysql.server腳本啟動mysqld,你應該編輯mysql.server用su以用戶user_name運行mysqld,或使用--user選項調用mysqld。(不改變safe_mysqld是必要的。)
現在,你的mysqld進程應該正在作為Unix用戶user_name運行,并運行完好。盡管有一件事情沒有變化:權限表的內容。缺省地(就在運行了腳本mysql_install_db安裝的權限表后),MySQL用戶root是唯一有存取mysql數據庫或創建或拋棄數據庫權限的用戶。除非你改變了那些權限,否則他們仍然保持。當你作為一個Unix用戶而不是root登錄時,這不應該阻止你作為MySQLroot用戶來存取MySQL;只要為客戶程序指定-uroot的選項。
注意通過在命令行上提供-uroot,作為root存取MySQL,與作為Unixroot用戶或其他Unix用戶運行MySQL沒有關系。MySQL的存取權限和用戶名與Unix用戶名字是完全分開的。唯一與Unix用戶名有關的是,如果當你調用一個客戶程序時,你不提供一個-u選項,客戶將試圖使用你的Unix登錄名作為你的MySQL用戶名進行連接。
如果你的Unix機器本身不安全,你可能應該至少在存取表中為MySQLroot用戶放上一個口令。否則,在那臺機器上有一個帳號的任何用戶能運行mysql-urootdb_name并且做他喜歡做的任何事情。
18.9怎樣重新設置一個忘記的口令
如果你忘記了MySQL的root用戶的口令,你可以用下列過程恢復它。
通過發送一個kill(不是kill-9)到mysqld服務器來關閉mysqld服務器。pid被保存在一個.pid文件中,通常在MySQL數據庫目錄中:
kill`cat/mysql-data-directory/hostname.pid`
你必須是一個UNIXroot用戶或運行服務器的相同用戶做這個。
使用--skip-grant-tables選項重啟mysqld。
用mysql-hhostnamemysql連接mysqld服務器并且用一條GRANT命令改變口令。見7.26GRANT和REVOKE句法。你也可以用mysqladmin-hhostname-uuserpassword’newpassword’進行。
用mysqladmin-hhostnameflush-privileges或用SQL命令FLUSHPRIVILEGES來裝載權限表。
18.10文件許可權限問題
如果你有與文件許可有關的問題,例如,如果當你創建一張表時,mysql發出下列錯誤消息:
ERROR:Can’tfindfile:’path/with/filename.frm’(Errcode:13)
那么可能是在mysqld啟動時,環境變量UMASK可能設置不正確。缺省的umask值是0660。你可以如下啟動safe_mysqld改變其行為:
shell>UMASK=384 #=600inoctal
shell>exportUMASK
shell>/path/to/safe_mysqld&
18.11文件沒找到
如果你從MySQL得到ERROR’...’notfound(errno:23),Can’topenfile:...(errno:24)或任何其他有errno23或errno24的錯誤,它意味著,你沒有為MySQL分配足夠的文件描述符。你能使用perror實用程序得到錯誤號含義是什么的描述:
shell>perror23
Filetableoverflow
shell>perror24
Toomanyopenfiles
這里的問題是mysqld正在試圖同時保持打開太多的文件。你也可以告訴mysqld一次不打開那么多的文件,或增加mysqld可得到的文件描述符數量。為了告訴mysqld一次保持打開更少的文件,你可以通過使用safe_mysqld的-Otable_cache=32選項(缺省值是64)使表緩沖更小。減小max_connections值也將減少打開文件的數量(缺省值是90)。
關鍵字:MySQL、數據庫、服務器
1MySQLserverhasgoneaway錯誤
本小節也涉及有關Lostconnectiontoserverduringquery的錯誤。
對MySQLserverhasgoneaway錯誤最常見的原因是服務器超時了并且關閉了連接。缺省地,如果沒有事情發生,服務器在8個小時后關閉連接。你可在啟動mysqld時通過設置wait_timeout變量改變時間限制。
你可以通過執行mysqladminversion并且檢驗正常運行的時間來檢查MySQL還沒死掉。
如果你有一個腳本,你只須再發出查詢讓客護進行一次自動的重新連接。
在這種請下,你通常能獲得下列錯誤代碼(你得到的是OS相關的):
CR_SERVER_GONE_ERROR客戶不能發送一個問題給服務器。
CR_SERVER_LOST當寫服務器時,客戶沒有出錯,但是它沒有得到對問題的一個完整的答案(或任何答案)。
如果你向服務器發送不正確的或太大的查詢,你也可能得到這些錯誤。如果mysqld得到一個太大或不正常的包,它認為客戶出錯了并關閉連接。如果你需要較大的查詢(例如,如果你正在處理較大的BLOB列),你可以使用-Omax_allowed_packet=#選項(缺省1M)啟動mysqld以增加查詢限制。多余的內存按需分配,這樣mysqld只有在你發出較大差詢時或mysqld必須返回較大的結果行時,才使用更多的內存!
2Can’tconnectto[local]MySQLserver錯誤
一個MySQL客戶可以兩種不同的方式連接mysqld服務器:Unix套接字,它通過在文件系統中的一個文件(缺省“/tmp/mysqld.sock”)進行連接;或TCP/IP,它通過一個端口號連接。Unix套接字比TCP/IP更快,但是只有用在連接同一臺計算機上的服務器。如果你不指定主機名或如果你指定特殊的主機名localhost,使用Unix套接字。
錯誤(2002)Can’tconnectto...通常意味著沒有一個MySQL服務器運行在系統上或當試圖連接mysqld服務器時,你正在使用一個錯誤的套接字文件或TCP/IP端口。
由檢查(使用ps)在你的服務器上有一個名為mysqld的進程啟動!如果沒有任何mysqld過程,你應該啟動一個。見4.15.2啟動MySQL服務器的問題。
如果一個mysqld過程正在運行,你可以通過嘗試這些不同的連接來檢查服務器(當然,端口號和套接字路徑名可能在你的安裝中是不同的):
shell>mysqladminversion
shell>mysqladminvariables
shell>mysqladmin-h`hostname`versionvariables
shell>mysqladmin-h`hostname`--port=3306version
shell>mysqladmin-h’ipforyourhost’version
shell>mysqladmin--socket=/tmp/mysql.sockversion
注意hostname命令使用反引號“`”而非正引號“’”;這些導致hostname輸出(即,當前主機名)被代替進mysqladmin命令中。
這是可能造成Can’tconnecttolocalMySQLserver錯誤的一些原因:
mysqld不在運行。
你正在使用MIT-pthreads的一個系統上運行。如果正在運行在一個沒有原生線程的系統上,mysqld使用MIT-pthreads軟件包。見4.2由MySQL支持的操作系統。然而,MIT-pthreads不支持Unix套接字,因此當與服務器連接時,在這樣一個系統上,你總是必須明確地指定主機名。試試使用這個命令檢查到服務器的連接:
shell>mysqladmin-h`hostname`version
某人刪除了mysqld使用的Unix套接字(缺省“/tmp/mysqld.sock”)。你可能有一個cron任務刪除了MySQL套接字(例如,一個把舊文件從“/tmp”目錄中刪除的任務)。你總是可以運行mysqladminversion并且檢查mysqladmin正在試圖使用的套接字確實存在。在這種情況下,修復方法是刪除cron任務而不刪除“mysqld.sock或將套接字放在其他地方。你能用這個命令在MySQL配置時指定一個不同的套接字地點:
shell>./configure--with-unix-socket-path=/path/to/socket
你也可以使用--socket=/path/to/socket選項啟動safe_mysqld和在啟動你的MySQL客戶前設置環境變量MYSQL_UNIX_PORT為套接字路徑名。你可用--socket=/path/to/socket選項啟動mysqld服務器。如果你改變了服務器的套接字路徑名,你也必須通知MySQL客戶關于新路徑的情況。你可以通過設置環境變量MYSQL_UNIX_PORT為套接字路徑名或由提供套接字路徑名作為客戶的參數做到。你可用這個命令測試套接字:
shell>mysqladmin--socket=/path/to/socketversion
你正在使用Linux和線程已經死了(核心傾倒了)。在這種情況中,你必須殺死其它mysqld線程(例如在啟動一個新的MySQL服務器之前,可以用mysql_zap腳本)。見18.1如果MySQL總是崩潰怎么辦。
如果你得到錯誤Can’tconnecttoMySQLserveronsome_hostname,你可以嘗試下列步驟找出問題是什么:
通過執行telnetyour-host-nametcp-ip-port-number并且按幾次回車來檢查服務器是否正常運行。如果有一個MySQL運行在這個端口上,你應該得到一個包含正在運行的MySQL服務器的版本號的應答。如果你得到類似于telnet:Unabletoconnecttoremotehost:Connectionrefused的一個錯誤,那么沒有服務器在使用的端口上運行。
嘗試連接本地機器上的mysqld守護進程,并用mysqladminvariables檢查mysqld被配置使用的TCP/IP端口(變量port)。
檢查你的mysqld服務器沒有用--skip-networking選項啟動。
3Host’...’isblocked錯誤
如果你得到象這樣的一個錯誤:
Host’hostname’isblockedbecauseofmanyconnectionerrors.
Unblockwith’mysqladminflush-hosts’
這意味著,mysqld已經得到了大量(max_connect_errors)的主機’hostname’的在中途被中斷了的連接請求。在max_connect_errors次失敗請求后,mysqld認定出錯了(象來字一個黑客的攻擊),并且阻止該站點進一步的連接,直到某人執行命令mysqladminflush-hosts。
缺省地,mysqld在10個連接錯誤后阻塞一臺主機。你可以通過象這樣啟動服務器很容易地調整它:
shell>safe_mysqld-Omax_connect_errors=10000&
注意,對給定的主機,如果得到這條錯誤消息,你應該首先檢查該主機的TCP/IP連接有沒有問題。如果你的TCP/IP連接不在運行,增加max_connect_errors變量的值對你也不會有幫助!
4Toomanyconnections錯誤
如果在你試土連接MySQL時,你得到錯誤Toomanyconnections,這意味著已經有max_connections個客戶連接了mysqld服務器。
如果你需要比缺省(100)更多的連接,那么你應該重啟mysqld,用更大的max_connections變量值。
注意,mysqld實際上允許(max_connections+1)個客戶連接。最后一個連接是為一個用Process權限的用戶保留的。通過不把這個權限給一般用戶(他們不應該需要它),有這個權限一個管理員可以登錄并且使用SHOWPROCESSLIST找出什么可能出錯。見7.21SHOW句法(得到表,列的信息)。
5Outofmemory錯誤
如果你發出查詢并且得到類似于下面的錯誤:
mysql:Outofmemoryatline42,’malloc.c’
mysql:needed8136byte(8k),memoryinuse:12481367bytes(12189k)
ERROR2008:MySQLclientranoutofmemory
注意,錯誤指向了MySQL客戶mysql。這個錯誤的原因很簡單,客戶沒有足夠的內存存儲全部結果。
為了修正這個問題,首先檢查你的查詢是否正確。它應該返回這么多的行,這合理嗎?如果是這樣,你可以使用mysql--quick,它使用mysql_use_result()檢索結果集合。這將較少的負擔放在了客戶端(只是服務器更多)。
6Packettoolarge錯誤
當一個MySQL客戶或mysqld服務器得到一個比max_allowed_packet個字節長的包,它發出一個Packettoolarge錯誤并終止連接。
如果你正在使用mysql客戶,你可以通過用mysql--set-variable=max_allowed_packet=8M指定一個更大的緩沖區來啟動客戶程序。
如果你正在使用不允許你指定最大包大小的其他客戶(例如DBI),你需要在你啟動服務器時設置包大小。你可以使用mysqld的命令行選項設置max_allowed_packet為一個更大的尺寸。例如,如果你正期望將一個全長的BLOB存入一張表中,你將需要用--set-variable=max_allowed_packet=24M選項來啟動服務器。
7Thetableisfull錯誤
這個錯誤發生在內存臨時表變得比tmp_table_size字節大時。為了避免這個問題,你可以使用mysqld的-Otmp_table_size=#選項來增加臨時表的大小,或在你發出有疑問的查詢之前使用SQL選項SQL_BIG_TABLES。見7.25SETOPTION句法。
你也可以使用--big-tables選項啟動mysqld。這與為所有查詢使用SQL_BIG_TABLES完全相同。
8Commandsoutofsyncinclient錯誤
如果你在你的客戶代碼中得到Commandsoutofsync;Youcan’trunthiscommandnow,你正在以錯誤的次序調用客戶函數!
這可能發生,例如,如果你正在使用mysql_use_result()并且在你已經調用了mysql_free_result()之前試圖執行新查詢。如果你在mysql_use_result()或mysql_store_result()之間試圖執行返回數據的2個查詢,它也可能發生。
9Ignoringuser錯誤
如果你得到下列錯誤:
Foundwrongpasswordforuser:’some_user@some_host’;Ignoringuser
這意味著在mysqld啟動時或在它再次裝載權限表時,它在user表中找到了一個有一個無效口令的條目。結果,條目簡單地被權限系統忽略。
可能導致這個問題的原因和修正:
你可能正在運行一個有一個老的user表的新版本mysqld。你可以通過執行mysqlshowmysqluser看看口令字段是否少于16個字符來檢查它。如果是這樣,你可以通過運行s/add_long_password腳本改正這種情況。
用戶有一個老式的口令(8個字符長)并且你沒使用--old-protocol選項啟動mysqld。用一個新口令更新在user表中的用戶或用--old-protocol重啟mysqld。
你沒有使用PASSWORD()函數在在user表中指定了一個口令。使用mysql以一個新口令更新在user表中的用戶。確保使用PASSWORD()函數:
mysql>updateusersetpassword=PASSWORD(’yourpassword’)
whereuser=’XXX’;
10Table’xxx’doesn’texist錯誤
如果你得到錯誤Table’xxx’doesn’texist或Can’tfindfile:’xxx’(errno:2),這意味著在當前數據庫中沒有名為xxx的表存在。
注意,因為MySQL使用目錄和文件存儲數據庫和表,數據庫和表名件是區分大小寫的!(在Win32上,數據庫和表名不是區分大小寫的,但是在查詢中對所有表的引用必須使用相同的大小寫!)
你可以用SHOWTABLES檢查你在當前數據庫中有哪個表。見7.21SHOW句法(得到表、列的信息)。
18.3MySQL怎樣處理一個溢出的磁盤
當出現一個磁盤溢出的情況時,MySQL做下列事情:
它每分鐘檢查一次看是否有足夠空間寫入當前行。如果有足夠的空間,它繼續好像發生什么事情。
每6分鐘它將有關磁盤溢出的警告寫入日志文件。
為了緩和這個問題,你可以采取下列行動:
繼續,你只需釋放足夠的空閑磁盤空間以便插入所有記錄。
放棄線程,你必須發一個mysqladminkill到線程。在下一次檢查磁盤時,線程將被放棄(在1分鐘內)。
注意,其他線程可能正在等待引起“磁盤溢出”條件的表。如果你有幾個“鎖定的”的線程,殺死正在等待磁盤溢出條件的那個線程將允許其他線程繼續。
18.4如何從一個文本文件運行SQL命令
一般地,mysql客戶被交互性地使用,象這樣:
shell>mysqldatabase
然而,也可以把你的SQL命令放在一個文件中并且告訴mysql從該文件讀取其輸入。要想這樣做,創造一個文本文件“text_file”,它包含你想要執行的命令。然后如下那樣調用mysql:
shell>mysqldatabase<text_file
你也能啟動有一個USEdb_name語句的文本文件。在這種情況下,在命令行上指定數據庫名是不必要的:
shell>mysql<text_file
見12.1不同的MySQL程序概述。
18.5MySQL在哪兒存儲臨時文件
MySQL使用TMPDIR環境變量的值作為存儲臨時文件的目錄的路徑名。如果你沒有設置TMPDIR,MySQL使用系統缺省值,它通常是“/tmp”或“/usr/tmp”。如果包含你的臨時文件目錄的文件系統太小,你應該編輯safe_mysqld設定TMPDIR指向你有足夠空間的一個文件系統!你也可以使用mysqld的--tmpdir選項目設置臨時目錄。
MySQL以“隱含文件”創建所有臨時文件。這保證了如果mysqld被終止,臨時文件也將被刪除。使用隱含文件的缺點是你將看不到一個大的臨時文件填滿了臨時文件目錄所在的文件系統。
當排序(ORDERBY或GROUPBY)時,MySQL通常使用一個或兩個臨時文件。最大磁盤空間需求是:
(存儲東西的長度+sizeof(數據庫指針))
*匹配的行數
*2
sizeof(數據庫指針)通常是4,但是在未來對確實很大的表可能增加。
對一些SELECT查詢,MySQL也創建臨時SQL表。這些沒被隱含且有“SQL_*”格式的名字。
ALTERTABLE和OPTIMIZETABLE在原數據庫表的同一個目錄中創建一張臨時表。
18.6怎樣保護“/tmp/mysql.sock”不被刪除
如果你有這個問題,事實上任何人可以刪除MySQL通訊套接字“/tmp/mysql.sock”,在Unix的大多數版本上,你能通過為其設置sticky(t)位來保護你的“/tmp”文件系統。作為root登錄并且做下列事情:
shell>chmod+t/tmp
這將保護你的“/tmp”文件系統使得文件僅能由他們的所有者或超級用戶(root)刪除。
你能執行ls-ld/tmp檢查sticky位是否被設置,如果最后一位許可位是t,該位被設置了。
18.7Accessdenied錯誤
見6.6權限系統如何工作。并且特別要看6.13引起Accessdenied錯誤的原因。
18.8怎樣作為一個一般用戶運行MySQL
MySQL服務器mysqld能被任何用戶啟動并運行。為了將mysqld改由Unix用戶user_name來運行,你必須做下列事情:
如果它正在運行,停止服務器(使用mysqladminshutdown)。
改變數據庫目錄和文件以便user_name有權限讀和寫文件(你可能需要作為Unix的root用戶才能做到):
shell>chown-Ruser_name/path/to/mysql/datadir
如果在MySQL數據目錄中的目錄或文件是符號鏈接,你也將需要順著那些鏈接并改變他們指向的目錄和文件。chown-R不能跟隨符號鏈接。
以user_name用戶啟動服務器,或如果你正在使用MySQL3.22或以后版本,以Unixroot用戶啟動mysqld并使用--user=user_name選項,mysqld將在接受任何連接之前切換到以Unixuser_name用戶運行。
如果在系統被重新啟動時,你使用mysql.server腳本啟動mysqld,你應該編輯mysql.server用su以用戶user_name運行mysqld,或使用--user選項調用mysqld。(不改變safe_mysqld是必要的。)
現在,你的mysqld進程應該正在作為Unix用戶user_name運行,并運行完好。盡管有一件事情沒有變化:權限表的內容。缺省地(就在運行了腳本mysql_install_db安裝的權限表后),MySQL用戶root是唯一有存取mysql數據庫或創建或拋棄數據庫權限的用戶。除非你改變了那些權限,否則他們仍然保持。當你作為一個Unix用戶而不是root登錄時,這不應該阻止你作為MySQLroot用戶來存取MySQL;只要為客戶程序指定-uroot的選項。
注意通過在命令行上提供-uroot,作為root存取MySQL,與作為Unixroot用戶或其他Unix用戶運行MySQL沒有關系。MySQL的存取權限和用戶名與Unix用戶名字是完全分開的。唯一與Unix用戶名有關的是,如果當你調用一個客戶程序時,你不提供一個-u選項,客戶將試圖使用你的Unix登錄名作為你的MySQL用戶名進行連接。
如果你的Unix機器本身不安全,你可能應該至少在存取表中為MySQLroot用戶放上一個口令。否則,在那臺機器上有一個帳號的任何用戶能運行mysql-urootdb_name并且做他喜歡做的任何事情。
18.9怎樣重新設置一個忘記的口令
如果你忘記了MySQL的root用戶的口令,你可以用下列過程恢復它。
通過發送一個kill(不是kill-9)到mysqld服務器來關閉mysqld服務器。pid被保存在一個.pid文件中,通常在MySQL數據庫目錄中:
kill`cat/mysql-data-directory/hostname.pid`
你必須是一個UNIXroot用戶或運行服務器的相同用戶做這個。
使用--skip-grant-tables選項重啟mysqld。
用mysql-hhostnamemysql連接mysqld服務器并且用一條GRANT命令改變口令。見7.26GRANT和REVOKE句法。你也可以用mysqladmin-hhostname-uuserpassword’newpassword’進行。
用mysqladmin-hhostnameflush-privileges或用SQL命令FLUSHPRIVILEGES來裝載權限表。
18.10文件許可權限問題
如果你有與文件許可有關的問題,例如,如果當你創建一張表時,mysql發出下列錯誤消息:
ERROR:Can’tfindfile:’path/with/filename.frm’(Errcode:13)
那么可能是在mysqld啟動時,環境變量UMASK可能設置不正確。缺省的umask值是0660。你可以如下啟動safe_mysqld改變其行為:
shell>UMASK=384 #=600inoctal
shell>exportUMASK
shell>/path/to/safe_mysqld&
18.11文件沒找到
如果你從MySQL得到ERROR’...’notfound(errno:23),Can’topenfile:...(errno:24)或任何其他有errno23或errno24的錯誤,它意味著,你沒有為MySQL分配足夠的文件描述符。你能使用perror實用程序得到錯誤號含義是什么的描述:
shell>perror23
Filetableoverflow
shell>perror24
Toomanyopenfiles
這里的問題是mysqld正在試圖同時保持打開太多的文件。你也可以告訴mysqld一次不打開那么多的文件,或增加mysqld可得到的文件描述符數量。為了告訴mysqld一次保持打開更少的文件,你可以通過使用safe_mysqld的-Otable_cache=32選項(缺省值是64)使表緩沖更小。減小max_connections值也將減少打開文件的數量(缺省值是90)。
關鍵字:MySQL、數據庫、服務器
新文章:
- CentOS7下圖形配置網絡的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統后丟失windows啟動項
- CentOS單網卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網打印機IP講解
- CentOS7使用hostapd實現無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網絡重啟出錯
- 解決Centos7雙系統后丟失windows啟動項
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統有什么不同呢
- Centos 6.6默認iptable規則詳解