中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

MySQL數(shù)據(jù)庫常見錯(cuò)誤問題解答

2018-06-11    來源:

容器云強(qiáng)勢(shì)上線!快速搭建集群,上萬Linux鏡像隨意使用
18.2.1 MySQL server has gone away錯(cuò)誤
本小節(jié)也涉及有關(guān)Lost connection to server during query的錯(cuò)誤。
對(duì)MySQL server has gone away錯(cuò)誤最常見的原因是服務(wù)器超時(shí)了并且關(guān)閉了連接。缺省地,如果沒有事情發(fā)生,服務(wù)器在 8個(gè)小時(shí)后關(guān)閉連接。你可在啟動(dòng)mysqld時(shí)通過設(shè)置wait_timeout變量改變時(shí)間限制。
你可以通過執(zhí)行mysqladmin version并且檢驗(yàn)正常運(yùn)行的時(shí)間來檢查MySQL還沒死掉。
如果你有一個(gè)腳本,你只須再發(fā)出查詢讓客護(hù)進(jìn)行一次自動(dòng)的重新連接。
在這種請(qǐng)下,你通常能獲得下列錯(cuò)誤代碼(你得到的是OS相關(guān)的):
CR_SERVER_GONE_ERROR 客戶不能發(fā)送一個(gè)問題給服務(wù)器。
CR_SERVER_LOST 當(dāng)寫服務(wù)器時(shí),客戶沒有出錯(cuò),但是它沒有得到對(duì)問題的一個(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)存!


18.2.2 Can’t connect to [local] MySQL server錯(cuò)誤
一個(gè)MySQL客戶可以兩種不同的方式連接mysqld服務(wù)器:Unix套接字,它通過在文件系統(tǒng)中的一個(gè)文件(缺省“/tmp/mysqld.sock”)進(jìn)行連接;或TCP/IP,它通過一個(gè)端口號(hào)連接。Unix套接字比TCP/IP更快,但是只有用在連接同一臺(tái)計(jì)算機(jī)上的服務(wù)器。如果你不指定主機(jī)名或如果你指定特殊的主機(jī)名localhost,使用Unix套接字。
錯(cuò)誤(2002)Can’t connect to ...通常意味著沒有一個(gè)MySQL服務(wù)器運(yùn)行在系統(tǒng)上或當(dāng)試圖連接mysqld服務(wù)器時(shí),你正在使用一個(gè)錯(cuò)誤的套接字文件或TCP/IP端口。
由檢查(使用ps)在你的服務(wù)器上有一個(gè)名為mysqld的進(jìn)程啟動(dòng)!如果沒有任何mysqld過程,你應(yīng)該啟動(dòng)一個(gè)。見4.15.2 啟動(dòng)MySQL服務(wù)器的問題。
如果一個(gè)mysqld過程正在運(yùn)行,你可以通過嘗試這些不同的連接來檢查服務(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è)沒有原生線程的系統(tǒng)上,mysqld使用 MIT-pthreads 軟件包。見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ū)⑻捉幼址旁谄渌胤。你能用這個(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)于新路徑的情況。你可以通過設(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腳本)。見18.1 如果MySQL總是崩潰怎么辦。
如果你得到錯(cuò)誤Can’t connect to MySQL server on some_hostname,你可以嘗試下列步驟找出問題是什么:
通過執(zhí)行telnet your-host-name tcp-ip-port-number并且按幾次回車來檢查服務(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ò)誤,那么沒有服務(wù)器在使用的端口上運(yùn)行。
嘗試連接本地機(jī)器上的mysqld守護(hù)進(jìn)程,并用mysqladmin variables檢查mysqld被配置使用的TCP/IP端口(變量port)。
檢查你的mysqld服務(wù)器沒有用--skip-networking選項(xiàng)啟動(dòng)。


18.2.3 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ò)了(象來字一個(gè)黑客的攻擊),并且阻止該站點(diǎn)進(jìn)一步的連接,直到某人執(zhí)行命令mysqladmin flush-hosts。
缺省地,mysqld在10個(gè)連接錯(cuò)誤后阻塞一臺(tái)主機(jī)。你可以通過象這樣啟動(dòng)服務(wù)器很容易地調(diào)整它:
shell> safe_mysqld -O max_connect_errors=10000 &

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


18.2.4 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)限的用戶保留的。通過不把這個(gè)權(quán)限給一般用戶(他們不應(yīng)該需要它),有這個(gè)權(quán)限一個(gè)管理員可以登錄并且使用SHOW PROCESSLIST找出什么可能出錯(cuò)。見7.21 SHOW句法(得到表,列的信息)。
18.2.5 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ò)誤的原因很簡單,客戶沒有足夠的內(nèi)存存儲(chǔ)全部結(jié)果。
為了修正這個(gè)問題,首先檢查你的查詢是否正確。它應(yīng)該返回這么多的行,這合理嗎?如果是這樣,你可以使用mysql --quick,它使用mysql_use_result()檢索結(jié)果集合。這將較少的負(fù)擔(dān)放在了客戶端(只是服務(wù)器更多)。


18.2.6 Packet too large錯(cuò)誤
當(dāng)一個(gè)MySQL客戶或mysqld服務(wù)器得到一個(gè)比max_allowed_packet個(gè)字節(jié)長的包,它發(fā)出一個(gè)Packet too large錯(cuò)誤并終止連接。
如果你正在使用mysql客戶,你可以通過用mysql --set-variable=max_allowed_packet=8M指定一個(gè)更大的緩沖區(qū)來啟動(dòng)客戶程序。
如果你正在使用不允許你指定最大包大小的其他客戶(例如 DBI),你需要在你啟動(dòng)服務(wù)器時(shí)設(shè)置包大小。你可以使用mysqld的命令行選項(xiàng)設(shè)置max_allowed_packet為一個(gè)更大的尺寸。例如,如果你正期望將一個(gè)全長的BLOB存入一張表中,你將需要用--set-variable=max_allowed_packet=24M選項(xiàng)來啟動(dòng)服務(wù)器。
18.2.7 The table is full錯(cuò)誤
這個(gè)錯(cuò)誤發(fā)生在內(nèi)存臨時(shí)表變得比tmp_table_size字節(jié)大時(shí)。為了避免這個(gè)問題,你可以使用mysqld的-O tmp_table_size=#選項(xiàng)來增加臨時(shí)表的大小,或在你發(fā)出有疑問的查詢之前使用SQL選項(xiàng)SQL_BIG_TABLES。見7.25 SET OPTION句法。
你也可以使用--big-tables選項(xiàng)啟動(dòng)mysqld。這與為所有查詢使用SQL_BIG_TABLES完全相同。
18.2.8 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ā)生。


18.2.9 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è)無效口令的條目。結(jié)果,條目簡單地被權(quán)限系統(tǒng)忽略。
可能導(dǎo)致這個(gè)問題的原因和修正:
你可能正在運(yùn)行一個(gè)有一個(gè)老的user表的新版本mysqld。你可以通過執(zhí)行mysqlshow mysql user看看口令字段是否少于 16個(gè)字符來檢查它。如果是這樣,你可以通過運(yùn)行scripts/add_long_password腳本改正這種情況。
用戶有一個(gè)老式的口令(8個(gè)字符長)并且你沒使用--old-protocol選項(xiàng)啟動(dòng)mysqld。用一個(gè)新口令更新在user表中的用戶或用--old-protocol重啟mysqld。
你沒有使用PASSWORD()函數(shù)在在user表中指定了一個(gè)口令。使用mysql以一個(gè)新口令更新在user表中的用戶。確保使用PASSWORD()函數(shù):
mysql> update user set password=PASSWORD(’your password’)
where user=’XXX’;


18.2.10 Table ’xxx’ doesn’t exist錯(cuò)誤
如果你得到錯(cuò)誤Table ’xxx’ doesn’t exist或Can’t find file: ’xxx’ (errno: 2),這意味著在當(dāng)前數(shù)據(jù)庫中沒有名為xxx的表存在。
注意,因?yàn)镸ySQL使用目錄和文件存儲(chǔ)數(shù)據(jù)庫和表,數(shù)據(jù)庫和表名件是區(qū)分大小寫的。ㄔ赪in32上,數(shù)據(jù)庫和表名不是區(qū)分大小寫的,但是在查詢中對(duì)所有表的引用必須使用相同的大小寫!)
你可以用SHOW TABLES檢查你在當(dāng)前數(shù)據(jù)庫中有哪個(gè)表。見7.21 SHOW句法(得到表、列的信息)。
18.3 MySQL怎樣處理一個(gè)溢出的磁盤
當(dāng)出現(xiàn)一個(gè)磁盤溢出的情況時(shí),MySQL做下列事情:
它每分鐘檢查一次看是否有足夠空間寫入當(dāng)前行。如果有足夠的空間,它繼續(xù)好像發(fā)生什么事情。
每6分鐘它將有關(guān)磁盤溢出的警告寫入日志文件。
為了緩和這個(gè)問題,你可以采取下列行動(dòng):
繼續(xù),你只需釋放足夠的空閑磁盤空間以便插入所有記錄。
放棄線程,你必須發(fā)一個(gè)mysqladmin kill到線程。在下一次檢查磁盤時(shí),線程將被放棄(在1分鐘內(nèi))。
注意,其他線程可能正在等待引起“磁盤溢出”條件的表。如果你有幾個(gè)“鎖定的”的線程,殺死正在等待磁盤溢出條件的那個(gè)線程將允許其他線程繼續(xù)。


18.4 如何從一個(gè)文本文件運(yùn)行SQL命令
一般地,mysql客戶被交互性地使用,象這樣:
shell> mysql database
然而,也可以把你的SQL命令放在一個(gè)文件中并且告訴mysql從該文件讀取其輸入。要想這樣做,創(chuàng)造一個(gè)文本文件“text_file”,它包含你想要執(zhí)行的命令。然后如下那樣調(diào)用mysql:
shell> mysql database < text_file

你也能啟動(dòng)有一個(gè)USE db_name語句的文本文件。在這種情況下,在命令行上指定數(shù)據(jù)庫名是不必要的:
shell> mysql < text_file

見12.1 不同的MySQL程序概述。


18.5 MySQL在哪兒存儲(chǔ)臨時(shí)文件
MySQL使用TMPDIR環(huán)境變量的值作為存儲(chǔ)臨時(shí)文件的目錄的路徑名。如果你沒有設(shè)置TMPDIR,MySQL使用系統(tǒng)缺省值,它通常是“/tmp”或“/usr/tmp”。如果包含你的臨時(shí)文件目錄的文件系統(tǒng)太小,你應(yīng)該編輯safe_mysqld設(shè)定TMPDIR指向你有足夠空間的一個(gè)文件系統(tǒng)!你也可以使用mysqld的--tmpdir選項(xiàng)目設(shè)置臨時(shí)目錄。
MySQL以“隱含文件”創(chuàng)建所有臨時(shí)文件。這保證了如果mysqld被終止,臨時(shí)文件也將被刪除。使用隱含文件的缺點(diǎn)是你將看不到一個(gè)大的臨時(shí)文件填滿了臨時(shí)文件目錄所在的文件系統(tǒng)。
當(dāng)排序(ORDER BY或GROUP BY)時(shí),MySQL通常使用一個(gè)或兩個(gè)臨時(shí)文件。最大磁盤空間需求是:
(存儲(chǔ)東西的長度 + sizeof (數(shù)據(jù)庫指針))
* 匹配的行數(shù)
* 2

sizeof(數(shù)據(jù)庫指針)通常是4,但是在未來對(duì)確實(shí)很大的表可能增加。
對(duì)一些SELECT查詢,MySQL也創(chuàng)建臨時(shí)SQL表。這些沒被隱含且有“SQL_*”格式的名字。
ALTER TABLE和OPTIMIZE TABLE在原數(shù)據(jù)庫表的同一個(gè)目錄中創(chuàng)建一張臨時(shí)表。


18.6 怎樣保護(hù)“/tmp/mysql.sock ”不被刪除
如果你有這個(gè)問題,事實(shí)上任何人可以刪除MySQL通訊套接字“/tmp/mysql.sock”,在Unix的大多數(shù)版本上,你能通過為其設(shè)置sticky(t)位來保護(hù)你的“/tmp”文件系統(tǒng)。作為root登錄并且做下列事情:
shell> chmod +t /tmp

這將保護(hù)你的“/tmp”文件系統(tǒng)使得文件僅能由他們的所有者或超級(jí)用戶(root)刪除。
你能執(zhí)行l(wèi)s -ld /tmp檢查sticky位是否被設(shè)置,如果最后一位許可位是t,該位被設(shè)置了。


18.7 Access denied錯(cuò)誤
見6.6 權(quán)限系統(tǒng)如何工作。并且特別要看6.13 引起Access denied錯(cuò)誤的原因。


18.8 怎樣作為一個(gè)一般用戶運(yùn)行MySQL
MySQL服務(wù)器mysqld能被任何用戶啟動(dòng)并運(yùn)行。為了將mysqld改由Unix用戶user_name來運(yùn)行,你必須做下列事情:
如果它正在運(yùn)行,停止服務(wù)器(使用mysqladmin shutdown)。
改變數(shù)據(jù)庫目錄和文件以便user_name有權(quán)限讀和寫文件(你可能需要作為Unix的root用戶才能做到):
shell> chown -R user_name /path/to/mysql/datadir

如果在MySQL數(shù)據(jù)目錄中的目錄或文件是符號(hào)鏈接,你也將需要順著那些鏈接并改變他們指向的目錄和文件。chown -R不能跟隨符號(hào)鏈接。
以u(píng)ser_name用戶啟動(dòng)服務(wù)器,或如果你正在使用MySQL 3.22或以后版本,以Unix root用戶啟動(dòng)mysqld并使用--user=user_name選項(xiàng),mysqld將在接受任何連接之前切換到以Unix user_name用戶運(yùn)行。
如果在系統(tǒng)被重新啟動(dòng)時(shí),你使用mysql.server腳本啟動(dòng)mysqld,你應(yīng)該編輯mysql.server用su以用戶user_name運(yùn)行mysqld,或使用--user選項(xiàng)調(diào)用mysqld。(不改變safe_mysqld是必要的。)
現(xiàn)在,你的mysqld進(jìn)程應(yīng)該正在作為Unix用戶user_name運(yùn)行,并運(yùn)行完好。盡管有一件事情沒有變化:權(quán)限表的內(nèi)容。缺省 地(就在運(yùn)行了腳本mysql_install_db安裝的權(quán)限表后),MySQL用戶root是唯一有存取mysql數(shù)據(jù)庫或創(chuàng)建或拋棄數(shù)據(jù)庫權(quán)限的用戶。除非你改變了那些權(quán)限,否則他們?nèi)匀槐3。?dāng)你作為一個(gè)Unix用戶而不是root登錄時(shí),這不應(yīng)該阻止你作為MySQL root用戶來存取MySQL;只要為客戶程序指定-u root的選項(xiàng)。
注意通過在命令行上提供-u root,作為root存取MySQL,與作為Unix root用戶或其他Unix用戶運(yùn)行MySQL沒有關(guān)系。MySQL的存取權(quán)限和用戶名與Unix用戶名字是完全分開的。唯一與Unix用戶名有關(guān)的是,如果當(dāng)你調(diào)用一個(gè)客戶程序時(shí),你不提供一個(gè)-u選項(xiàng),客戶將試圖使用你的Unix登錄名作為你的MySQL用戶名進(jìn)行連接。
如果你的Unix機(jī)器本身不安全,你可能應(yīng)該至少在存取表中為MySQL root用戶放上一個(gè)口令。否則,在那臺(tái)機(jī)器上有一個(gè)帳號(hào)的任何用戶能運(yùn)行mysql -u root db_name并且做他喜歡做的任何事情。
18.9 怎樣重新設(shè)置一個(gè)忘記的口令
如果你忘記了MySQL的root用戶的口令,你可以用下列過程恢復(fù)它。
通過發(fā)送一個(gè)kill(不是kill -9)到mysqld服務(wù)器來關(guān)閉mysqld服務(wù)器。pid 被保存在一個(gè).pid文件中,通常在MySQL數(shù)據(jù)庫目錄中:
kill `cat /mysql-data-directory/hostname.pid`

你必須是一個(gè)UNIX root用戶或運(yùn)行服務(wù)器的相同用戶做這個(gè)。
使用--skip-grant-tables選項(xiàng)重啟mysqld。
用mysql -h hostname mysql連接mysqld服務(wù)器并且用一條GRANT命令改變口令。見7.26 GRANT和REVOKE句法。你也可以用mysqladmin -h hostname -u user password ’new password’ 進(jìn)行。
用mysqladmin -h hostname flush-privileges或用SQL命令FLUSH PRIVILEGES來裝載權(quán)限表。
18.10 文件許可權(quán)限問題
如果你有與文件許可有關(guān)的問題,例如,如果當(dāng)你創(chuàng)建一張表時(shí),mysql發(fā)出下列錯(cuò)誤消息:
ERROR: Can’t find file: ’path/with/filename.frm’ (Errcode: 13)

那么可能是在mysqld啟動(dòng)時(shí),環(huán)境變量UMASK可能設(shè)置不正確。缺省的umask值是0660。你可以如下啟動(dòng)safe_mysqld改變其行為:
shell> UMASK=384 # = 600 in octal
shell> export UMASK
shell> /path/to/safe_mysqld &


18.11 文件沒找到
如果你從MySQL得到ERROR ’...’ not found (errno: 23), Can’t open file: ... (errno: 24)或任何其他有errno 23或errno 24的錯(cuò)誤,它意味著,你沒有為MySQL分配足夠的文件描述符。你能使用perror實(shí)用程序得到錯(cuò)誤號(hào)含義是什么的描述:
shell> perror 23
File table overflow
shell> perror 24
Too many open files

這里的問題是mysqld正在試圖同時(shí)保持打開太多的文件。你也可以告訴mysqld一次不打開那么多的文件,或增加mysqld可得到的文件描述符數(shù)量。為了告訴mysqld一次保持打開更少的文件,你可以通過使用safe_mysqld的-O table_cache=32選項(xiàng)(缺省值是64)使表緩沖更小。減小max_connections值也將減少打開文件的數(shù)量(缺省值是90)。
要想改變mysqld可用的文件描述符數(shù)量,修改safe_mysqld腳本。腳本中有一條注釋了的行ulimit -n 256。你可以刪除’#’字符來去掉該行的注釋,并且改變數(shù)字256改變?yōu)閙ysqld可用的文件描述符的數(shù)量。
ulimit能增加文件描述符的數(shù)量,但是只能到操作系統(tǒng)強(qiáng)加的限制。如果你需要增加每個(gè)進(jìn)程可用的文件描述符數(shù)量的OS限制,參見你的操作系統(tǒng)文檔。注意,如果你運(yùn)行tcsh外殼,ulimit將不工作!當(dāng)你請(qǐng)求當(dāng)前限制時(shí),tcsh也將報(bào)告不正確的值!在這種情況下,你應(yīng)該用sh啟動(dòng)safe_mysqld!


18.12 使用DATE列的問題
一個(gè)DATE值的格式是’YYYY-MM-DD’。根據(jù)ANSI SQL,不允許其他格式。你應(yīng)該在UPDATE表達(dá)式和SELECT語句的WHERE子句中使用這個(gè)格式。例如:
mysql> SELECT * FROM tbl_name WHERE date >= ’1997-05-05’;

為了方便,如果日期用在數(shù)字上下文,MySQL自動(dòng)變換一個(gè)日期到一個(gè)數(shù)字(并且反過來也如此)。當(dāng)更新時(shí)和將一個(gè)日期與TIMESTAMP、DATE或DATETIME列比較的一個(gè)WHERE子句中,也是足夠靈活以允許一種“寬松”的字符串格式。(寬松格式意味著任何標(biāo)點(diǎn)字符用作在部件之間的分割符。例如,’1998-08-15’和’1998#08#15’是等價(jià)的。)MySQL也能變換不包含分割符的一個(gè)字符串(例如 ’19980815’),如果它作為一個(gè)日期說得通。特殊日期’0000-00-00’可以作為’0000-00-00’被存儲(chǔ)和檢索。當(dāng)通過MyODBC使用一個(gè)’0000-00-00’日期時(shí),在MyODBC 2.50.12和以上版本,它將自動(dòng)被轉(zhuǎn)換為NULL,因?yàn)镺DBC不能處理這種日期。
因?yàn)镸ySQL實(shí)行了上述的變換,下列語句可以工作:
mysql> INSERT INTO tbl_name (idate) VALUES (19970505);
mysql> INSERT INTO tbl_name (idate) VALUES (’19970505’);
mysql> INSERT INTO tbl_name (idate) VALUES (’97-05-05’);
mysql> INSERT INTO tbl_name (idate) VALUES (’1997.05.05’);
mysql> INSERT INTO tbl_name (idate) VALUES (’1997 05 05’);
mysql> INSERT INTO tbl_name (idate) VALUES (’0000-00-00’);

mysql> SELECT idate FROM tbl_name WHERE idate >= ’1997-05-05’;
mysql> SELECT idate FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT mod(idate,100) FROM tbl_name WHERE idate >= 19970505;
mysql> SELECT idate FROM tbl_name WHERE idate >= ’19970505’;

然而,下列將不工作:
mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,’19970505’)=0;

STRCMP()是字符串函數(shù),因此它將idate轉(zhuǎn)換為一個(gè)字符串并且實(shí)施字符串比較。它不將’19970505’轉(zhuǎn)換為一個(gè)日期并實(shí)施日期比較。
注意,MySQL不檢查日期是否正確。如果你存儲(chǔ)一個(gè)不正確的日期,例如’1998-2-31’,錯(cuò)誤的日期將被存儲(chǔ)。如果日期不能被變換到任何合理的值,在DATE字段中存儲(chǔ)一個(gè)0。這主要是一個(gè)速度問題并且我們認(rèn)為檢查日期是應(yīng)用程序的責(zé)任,而不服務(wù)器。


18.13 時(shí)區(qū)問題
如果你有一個(gè)問題,SELECT NOW()以GMT時(shí)間返回值而不是你的本地時(shí)間,你必須設(shè)定TZ環(huán)境變量為你的當(dāng)前時(shí)區(qū)。這應(yīng)該在服務(wù)器運(yùn)行的環(huán)境進(jìn)行,例如在safe_mysqld或mysql.server中。


18.14 在搜索中的大小寫敏感性
缺省地,MySQL搜索是大小寫不敏感的(盡管有一些字符集從來不是忽略大小寫的,例如捷克語)。這意味著,如果你用col_name LIKE ’a%’搜尋,你將得到所有以A或a開始的列值。如果你想要使這個(gè)搜索大小寫敏感,使用象INDEX(col_name, "A")=0檢查一個(gè)前綴;蛉绻兄当仨毚_切是"A",使用STRCMP(col_name, "A") = 0。
簡單的比較操作(>=、>、= 、< 、<=、排序和聚合)是基于每個(gè)字符的“排序值”。有同樣排序值的字符(象E,e和’e)被視為相同的字符!
LIKE比較在每個(gè)字符的大寫值上進(jìn)行(E==e 但是E<>’e)。
如果你想要一個(gè)列總是被當(dāng)作大小寫敏感的方式,聲明它為BINARY。見7.7 CREATE TABLE句法。
如果你使用以所謂的big5編碼的中文數(shù)據(jù),你要使所有的字符列是BINARY,它可行,是因?yàn)閎ig5編碼字符的排序順序基于 ASCII代碼的順序。


18.15 NULL值問題
NULL值的概念是造成SQL的新手的混淆的普遍原因,他們經(jīng)常認(rèn)為NULL是和一個(gè)空字符串’’的一樣的東西。不是這樣的!例如,下列語句是完全不同的:
mysql> INSERT INTO my_table (phone) VALUES (NULL);
mysql> INSERT INTO my_table (phone) VALUES ("");

兩個(gè)語句把值插入到phone列,但是第一個(gè)插入一個(gè)NULL值而第二個(gè)插入一個(gè)空字符串。第一個(gè)的含義可以認(rèn)為是“電話號(hào)碼不知道”,而第二個(gè)則可意味著“她沒有電話”。
在SQL中,NULL值在于任何其他值甚至NULL值比較時(shí)總是假的(FALSE)。包含NULL的一個(gè)表達(dá)式總是產(chǎn)生一個(gè)NULL值,除非在包含在表達(dá)式中的運(yùn)算符和函數(shù)的文檔中指出。在下列例子,所有的列返回NULL:
mysql> SELECT NULL,1+NULL,CONCAT(’Invisible’,NULL);

如果你想要尋找值是NULL的列,你不能使用=NULL測(cè)試。下列語句不返回任何行,因?yàn)閷?duì)任何表達(dá)式,expr = NULL是假的:
mysql> SELECT * FROM my_table WHERE phone = NULL;

要想尋找NULL值,你必須使用IS NULL測(cè)試。下例顯示如何找出NULL電話號(hào)碼和空的電話號(hào)碼:
mysql> SELECT * FROM my_table WHERE phone IS NULL;
mysql> SELECT * FROM my_table WHERE phone = "";

在MySQL中,就像很多其他的SQL服務(wù)器一樣,你不能索引可以有NULL值的列。你必須聲明這樣的列為NOT NULL,而且,你不能插入NULL到索引的列中。當(dāng)用LOAD DATA INFILE讀取數(shù)據(jù)時(shí),空列用’’更新。如果你想要在一個(gè)列中有NULL值,你應(yīng)該在文本文件中使用N。字面詞’NULL’也可以在某些情形下使用。見7.16 LOAD DATA INFILE句法。當(dāng)使用ORDER BY時(shí),首先呈現(xiàn)NULL值。如果你用DESC以降序排序,NULL值最后顯示。當(dāng)使用GROUP BY時(shí),所有的NULL值被認(rèn)為是相等的。為了有助于NULL的處理,你能使用IS NULL和IS NOT NULL運(yùn)算符和IFNULL()函數(shù)。
對(duì)某些列類型,NULL值被特殊地處理。如果你將NULL插入表的第一個(gè)TIMESTAMP列,則插入當(dāng)前的日期和時(shí)間。如果你將NULL插入一個(gè)AUTO_INCREMENT列,則插入順序中的下一個(gè)數(shù)字。
18.16 alias問題
你可以在GROUP BY、ORDER BY或在HAVING部分中使用別名引用列。別名也可以用來為列取一個(gè)更好點(diǎn)的名字:
SELECT SQRT(a*b) as rt FROM table_name GROUP BY rt HAVING rt > 0;
SELECT id,COUNT(*) AS cnt FROM table_name GROUP BY id HAVING cnt > 0;
SELECT id AS "Customer identity" FROM table_name;

注意,你的 ANSI SQL 不允許你在一個(gè)WHERE子句中引用一個(gè)別名。這是因?yàn)樵赪HERE代碼被執(zhí)行時(shí),列值還可能沒有終結(jié)。例如下列查詢是不合法:SELECT id,COUNT(*) AS cnt FROM table_name WHERE cnt > 0 GROUP BY id;

WHERE語句被執(zhí)行以確定哪些行應(yīng)該包括GROUP BY部分中,而HAVING用來決定應(yīng)該只用結(jié)果集合中的哪些行。


18.17 從關(guān)聯(lián)的表中刪除行
因?yàn)镸ySQL不支持子選擇或在DELETE語句中使用多個(gè)表,你應(yīng)該使用下列方法從2個(gè)關(guān)聯(lián)的表中刪除行:
在主表中基于某個(gè)WHERE條件SELECT行。
在主表中基于相同的條件DELETE行。
DELETE FROM related_table WHERE related_column IN (selected_rows)
如果在related_column查詢中的字符的全部數(shù)量超過1,048,576(缺省值max_allowed_packet),你應(yīng)該分成更小的部分并且執(zhí)行多個(gè)DELETE語句。如果related_column是一個(gè)索引,你每次只刪除100-1000個(gè)related_column id將可能使得DELETE最快。如果related_column不是一個(gè)索引,速度與IN子句中參數(shù)的數(shù)量無關(guān)。


18.18 解決沒有匹配行的問題
如果你有一個(gè)復(fù)雜的查詢,涉及多個(gè)表,但沒有返回任何行,你應(yīng)該使用下列過程查找你的詢問有什么不對(duì):
EXPLAIN測(cè)試查詢并且檢查你是否能找出顯然是錯(cuò)誤的一些東西。見7.22 EXPLAIN句法(得到關(guān)于一個(gè)SELECT的信息)。
僅選擇那些在WHERE子句中使用的字段。
一次從查詢中刪除一個(gè)表,直到它返回一些行。如果表很大,對(duì)查詢使用LIMIT 10是一個(gè)好主意。
對(duì)應(yīng)該已經(jīng)匹配一行的列做一個(gè)SELECT,針對(duì)從詢問中做后被刪除的表。
如果你將FLOAT或DOUBLE列與有小數(shù)的數(shù)字進(jìn)行比較,你不能使用=!。這個(gè)問題在大多數(shù)計(jì)算機(jī)語言是常見的,因?yàn)楦↑c(diǎn)值不是準(zhǔn)確的值。
mysql> SELECT * FROM table_name WHERE float_column=3.5;
->
mysql> SELECT * FROM table_name WHERE float_column between 3.45 and 3.55;

在大多數(shù)情況下,將FLOAT改成一個(gè)DOUBLE將修正它!
如果你仍然不能發(fā)現(xiàn)錯(cuò)誤是什么,創(chuàng)建一個(gè)最小的可運(yùn)行mysql test < query.sql的測(cè)試來顯示你的問題。你可以用mysqldump --quick database tables > query.sql創(chuàng)建一個(gè)測(cè)試文件,在一個(gè)編輯器編輯文件,刪除一些插入行(如果有太多這些語句)并且在文件末尾加入你的選擇語句。測(cè)試你仍然有問題,可以這樣做:
shell> mysqladmin create test2
shell> mysql test2 < query.sql

使用mysqlbug的郵寄測(cè)試文件到mysql@lists.mysql.com。


18.19 與ALTER TABLE有關(guān)的問題
如果ALTER TABLE死于這樣一個(gè)錯(cuò)誤:
Error on rename of ’./database/name.frm’ to ’./database/B-a.frm’ (Errcode: 17)

問題可能是MySQL在前一個(gè)ALTER TABLE中已經(jīng)崩潰并且留下了一個(gè)名為“A-xxx”或“B-xxx”的老的數(shù)據(jù)庫表。在這種情況下,到MySQL數(shù)據(jù)目錄中并刪除所有名字以A-或B-開始的文件。(你可以把他們移到別的地方而不是刪除他們)。
ALTER TABLE工作方式是:
以要求的改變創(chuàng)建一個(gè)名為“A-xxx”的新表。
從老表把所有行拷貝到“A-xxx”。
老表被改名為“B-xxx”。
“A-xxx”被改名為你的老表的名字。
“B-xxx”被刪除。
如果某些改名操作出錯(cuò),MySQL試圖還原改變。如果出錯(cuò)嚴(yán)重(當(dāng)然,這不應(yīng)該發(fā)生。),MySQL可能留下了老表為“B-xxx”但是一個(gè)簡單改名就應(yīng)該恢復(fù)你的數(shù)據(jù)。


18.20 怎樣改變一張表中列的順序
SQL的要點(diǎn)是中抽象應(yīng)用程序以避免數(shù)據(jù)存儲(chǔ)格式。你應(yīng)該總是以你想要檢索數(shù)據(jù)的意愿指定順序。例如:
SELECT col_name1, col_name2, col_name3 FROM tbl_name;

將以col_name1、col_name2、col_name3的順序返回列,而:
SELECT col_name1, col_name3, col_name2 FROM tbl_name;

將以col_name1、col_name3、col_name2的順序返回列。
在一個(gè)應(yīng)用程序中,你應(yīng)該決不基于他們的位置使用SELECT * 檢索列,因?yàn)楸环祷氐牧械捻樞蛴肋h(yuǎn)不能保證;對(duì)你的數(shù)據(jù)庫的一個(gè)簡單改變可能導(dǎo)致你的應(yīng)用程序相當(dāng)有戲劇性地失敗。
不管怎樣,如果你想要改變列的順序,你可以這樣做:
以正確的列順序創(chuàng)建一張新表。
執(zhí)行INSERT INTO new_table SELECT fields-in-new_table-order FROM old_table.
刪除或改名old_table。
ALTER TABLE new_table RENAME old_table。

標(biāo)簽: linux Mysql ssl 安全 代碼 服務(wù)器 腳本 權(quán)限 數(shù)據(jù)庫 搜索 問題 選擇 用戶

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:微軟公司發(fā)布7個(gè)及時(shí)下載安裝漏洞補(bǔ)丁程序

下一篇:戴爾NB起火原因未查明 同型號(hào)電池仍在用