?? manual_problems.html
字號:
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312">
<title>MySQL中文參考手冊-18 問題和常見錯誤</title>
<style type="text/css">
<!--
.p14{font-size:14.8px;font-family:宋體;line-height:14pt;}
.p5{ border: 1px solid rgb(146,201,201) }
.a:hover{color:red;}
a.t1:visited{color:red;}
-->
</style>
</head>
<body BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#101090" VLINK="#7030B0" class="p4">
<h1><img src="Img/mysql-logo.gif" alt="mysql-logo.gif (3082 bytes)" WIDTH="127" HEIGHT="60"><font color="#FF0000">MySQL中文參考手冊</font></h1>
<p>翻譯:<a href="mailto:clyan@sohu.com">晏子</a>(yanzi)
主頁:<a href="http://linuxdn.yeah.net">http://linuxdb.yeah.net</a></p>
<hr>
<p><a HREF="manual_Introduction.html">第一章</a>, <a HREF="manual_Common_programs.html">前一章</a>,
<a HREF="manual_Common_problems.html">下一章</a>, <a HREF="manual_Concept_Index.html">最后一章</a>,<a HREF="manual_toc.html">目錄</a>. </p>
<hr>
<h1><a NAME="Problems" HREF="manual_toc.html#Problems">18 問題和常見錯誤</a></h1>
<h2><a NAME="Crashing" HREF="manual_toc.html#Crashing">18.1 如果MySQL總是崩潰怎么辦</a></h2>
<p>所有<strong>MySQL</strong>在發布它們之前,在許多平臺上被測試。這并不意味著在<strong>MySQL</strong>中沒有任何錯誤,但是如果有錯誤,它們是很少的并且很能難發現。如果你有一個問題并且如果你嘗試找出究竟是什么摧毀了你的系統,它將總是有幫助的,因為你將有一個更好機會使得它被快速修復。</p>
<p>首先你應該試著找出問題<code>mysqld</code>守護進程是否死掉或你的問題是否與你的客戶有關。你可以用<code>mysqladmin
version</code>檢查你的<code>mysqld</code>服務器正常執行了多長時間,如果<code>mysqld</code>死了,你可以在文件<tt>“mysql-data-directory/'hostname'.err”</tt>中找到其原因。
</p>
<p>因為很難知道一些東西為什么崩潰,首先試著檢查為其它人工作的東西是否使你崩潰。請嘗試下列事情:
<ul>
<li>與<code>mysqladmin shutdown</code>停止<code>mysqld</code>守護進程,在所有表上運行<code>myisamchk
--silent --force */*.MYI</code>并重啟<code>mysqld</code>守護經進程。這將保證你從一個干凈的狀態運行。見<a HREF="manual_Maintenance.html#Maintenance">13 維護MySQL安裝</a>。</li>
<li>使用<code>mysqld --log</code>并且試著從日志信息確定是否是某個特定的查詢殺死了服務器。全部錯誤的95%與特定的查詢有關!通常它是在日志文件中就在<strong>MySQL</strong>重啟之前的最后查詢之一。你也許可以使用下列過程驗證它:<ul>
<li>停止<strong>MySQL</strong>守護進程(用<code>mysqladmin shutdown</code>)。</li>
<li>在<strong>MySQL</strong>數據庫目錄下做文件的一個備份。 </li>
<li>與<code>myisamchk -s */*.MYI</code>檢查表以驗證所有表是正確的。如果有任何表被損壞,用<code>myisamchk
-r path-to-table.MYI</code>修復它。</li>
<li>從<strong>MySQL</strong>數據目錄刪除(或移走)任何舊的日志文件。 </li>
<li>用<code>safe_mysql --log</code>啟動服務器。</li>
<li>如果<code>mysqld</code>現在死掉,你可以通過恢復備份并執行<code>mysql
< mysql-log-file</code>來測試問題是否是一個特定的查詢引起的。當然你可以通過用<code>safe_mysqld
--data=path-to-backup-directory</code>啟動另一個<strong>MySQL</strong>服務器,在某個其他目錄而不是標準<strong>MySQL</strong>數據庫目錄下做后面的測試。</li>
</ul>
</li>
<li>你試用了基準測試嗎?他們應該很好地測試<strong>MySQL</strong>。你也可以增加代碼模擬你的應用程序!基準程序可在源代碼分發的<tt>“bench”</tt>目錄下找到,或對二進制分發,在你的<strong>MySQL</strong>安裝目錄下<tt>“sql-bench”</tt>目錄。
</li>
<li>試一下<code>fork_test.pl</code>和<code>fork2_test.pl</code>。</li>
<li>對任何錯誤檢查文件<tt>“mysql-data-directory/'hostname'.err”</tt>。 </li>
<li>如果你配置<strong>MySQL</strong>以便調試,如果出錯,收集可能的錯誤信息將更容易。使用<code>--with-debug</code>選項的<code>configure</code>重新配置<strong>MySQL</strong>然后重新編譯。見<a HREF="manual_Porting.html#Debugging_server">G.1 調試一個 MySQL 服務器</a>。</li>
<li>為調試而配置<strong>MySQL</strong>使它包含一個安全的內存分配器以便能發現一些錯誤。它也提供關于正在發生什么的大量輸出。</li>
<li>你為你的操作系統使用了最新的補丁嗎? </li>
<li>使用<code>mysql</code>的<code>--skip-locking</code>選項.在一些系統上,<code>lockd</code>鎖管理器不能正確工作;<code>--skip-locking</code>選項告訴<code>mysqld</code>不使用外部鎖。(這意味著你不能在同一個數據上運行兩個<code>mysqld</code>服務器而且如果你使用<code>myisamchk</code>,你一定要小心,但是它對為了測試試用選項可能有益。)</li>
<li>當<code>mysqld</code>好象正在運行但沒有反應時,你嘗試過<code>mysqladmin
-u root processlist</code>嗎?有時<code>mysqld</code>不是毫無反應,盡管你可能這樣認為。問題可能是所有在用的連接,或可能用內部鎖定問題。<code>mysqladmin
processlist</code>甚至在這些情況下將通常可以進行一個連接,并且能提供有關當前連接數量及其狀態的有用信息。</li>
<li>在你運行其他查詢時,在一個單獨窗口中運行命令<code>mysqladmin -i 5
status</code>,產生統計。</li>
<li>嘗試下列步驟: <ol>
<li>通過<code>gdb</code>(或其他調試器)啟動<code>mysqld</code>。</li>
<li>運行你的測試腳本。 </li>
<li>當<code>mysqld</code>核心傾倒(core dump),做<code>back</code>(或你調試器中的回溯-backtrace命令)。</li>
</ol>
</li>
<li>嘗試用一個Perl腳本模擬你的應用程序以強制<strong>MySQL</strong>崩潰或表現不正確。</li>
<li>或發一份正式的錯誤報告。見<a HREF="manual_Questions.html#Bug_reports">2.3
如何報告錯誤或問題</a>,但是要不平常更詳細。因為<strong>MySQL</strong>為很多人的工作,導致崩潰的東西可能只存在于你的計算機上(例如,與你的特定系統庫有關的一個錯誤)。</li>
<li>如果你的問題有具有動態長度行的表有關,并且你不使用<code>BLOB/TEXT</code>列(但是僅<code>VARCHAR</code>列),你可以用<code>ALTER
TABLE</code>試著將全部<code>VARCHAR</code>改為<code>CHAR</code>,這將強制<strong>MySQL</strong>使用固定尺寸的行。固定尺寸的行占據很小的額外空間,但是更能容忍崩潰!當前動態行的代碼在
TCX 至少使用3
年的時間,沒有任何問題,但是從本質上講,動態長度的行對錯誤更敏感,因此如果上述對你有幫助,嘗試一下可能是一個好主意!</li>
</ul>
<h2><a NAME="Common_errors" HREF="manual_toc.html#Common_errors">18.2 使用MySQL時的一些常見錯誤</a></h2>
<h3><a NAME="Gone_away" HREF="manual_toc.html#Gone_away">18.2.1<code> MySQL server has
gone away</code>錯誤</a></h3>
<p>本小節也涉及有關<code>Lost connection to server during query</code>的錯誤。</p>
<p>對<code>MySQL server has gone away</code>錯誤最常見的原因是服務器超時了并且關閉了連接。缺省地,如果沒有事情發生,服務器在
8個小時后關閉連接。你可在啟動mysqld時通過設置<code>wait_timeout</code>變量改變時間限制。</p>
<p>你可以通過執行<code>mysqladmin version</code>并且檢驗正常運行的時間來檢查<strong>MySQL</strong>還沒死掉。</p>
<p>如果你有一個腳本,你只須再發出查詢讓客護進行一次自動的重新連接。</p>
<p>在這種請下,你通常能獲得下列錯誤代碼(你得到的是OS相關的):</p>
<table BORDER="1" WIDTH="100%" NOSAVE="#101090" class="p4">
<tr>
<td><code>CR_SERVER_GONE_ERROR</code> </td>
<td>客戶不能發送一個問題給服務器。 </td>
</tr>
<tr>
<td><code>CR_SERVER_LOST</code> </td>
<td>當寫服務器時,客戶沒有出錯,但是它沒有得到對問題的一個完整的答案(或任何答案)。
</td>
</tr>
</table>
<p>如果你向服務器發送不正確的或太大的查詢,你也可能得到這些錯誤。如果<code>mysqld</code>得到一個太大或不正常的包,它認為客戶出錯了并關閉連接。如果你需要較大的查詢(例如,如果你正在處理較大的<code>BLOB</code>列),你可以使用<code>-O
max_allowed_packet=#</code>選項(缺省1M)啟動<code>mysqld</code>以增加查詢限制。多余的內存按需分配,這樣<code>mysqld</code>只有在你發出較大差詢時或<code>mysqld</code>必須返回較大的結果行時,才使用更多的內存!</p>
<h3><a NAME="Can_not_connect_to_server" HREF="manual_toc.html#Can_not_connect_to_server">18.2.2<code>
Can't connect to [local] MySQL server</code>錯誤</a></h3>
<p>一個<strong>MySQL</strong>客戶可以兩種不同的方式連接<code>mysqld</code>服務器:Unix套接字,它通過在文件系統中的一個文件(缺省<tt>“/tmp/mysqld.sock”</tt>)進行連接;或TCP/IP,它通過一個端口號連接。Unix套接字比TCP/IP更快,但是只有用在連接同一臺計算機上的服務器。如果你不指定主機名或如果你指定特殊的主機名<code>localhost</code>,使用Unix套接字。</p>
<p>錯誤(2002)<code>Can't connect to ...</code>通常意味著沒有一個<strong>MySQL</strong>服務器運行在系統上或當試圖連接<code>mysqld</code>服務器時,你正在使用一個錯誤的套接字文件或TCP/IP端口。
</p>
<p>由檢查(使用<code>ps</code>)在你的服務器上有一個名為<code>mysqld</code>的進程啟動!如果沒有任何<code>mysqld</code>過程,你應該啟動一個。見<a HREF="manual_Installing.html#Starting_server">4.15.2 啟動MySQL服務器的問題</a>。</p>
<p>如果一個<code>mysqld</code>過程正在運行,你可以通過嘗試這些不同的連接來檢查服務器(當然,端口號和套接字路徑名可能在你的安裝中是不同的):</p>
<pre>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
</pre>
<p>注意<code>hostname</code>命令使用反引號“`”而非正引號“'”;這些導致<code>hostname</code>輸出(即,當前主機名)被代替進<code>mysqladmin</code>命令中。</p>
<p>這是可能造成<code>Can't connect to local MySQL server</code>錯誤的一些原因:
<ul>
<li><code>mysqld</code>不在運行。 </li>
<li>你正在使用MIT-pthreads的一個系統上運行。如果正在運行在一個沒有原生線程的系統上,<code>mysqld</code>使用
MIT-pthreads 軟件包。見<a HREF="manual_Installing.html#Which_OS">4.2 由MySQL支持的操作系統</a>。然而,MIT-pthreads不支持Unix套接字,因此當與服務器連接時,在這樣一個系統上,你總是必須明確地指定主機名。試試使用這個命令檢查到服務器的連接:<pre>shell> mysqladmin -h `hostname` version
</pre>
</li>
<li>某人刪除了<code>mysqld</code>使用的Unix套接字(缺省<tt>“/tmp/mysqld.sock”</tt>)。你可能有一個<code>cron</code>任務刪除了<strong>MySQL</strong>套接字(例如,一個把舊文件從<tt>“/tmp”</tt>目錄中刪除的任務)。你總是可以運行<code>mysqladmin
version</code>并且檢查<code>mysqladmin</code>正在試圖使用的套接字確實存在。在這種情況下,修復方法是刪除<code>cron</code>任務而不刪除<tt>“mysqld.sock
</tt>或將套接字放在其他地方。你能用這個命令在<strong>MySQL</strong>配置時指定一個不同的套接字地點:<pre>shell> ./configure --with-unix-socket-path=/path/to/socket
</pre>
<p>你也可以使用<code>--socket=/path/to/socket</code>選項啟動<code>safe_mysqld</code>和在啟動你的<strong>MySQL</strong>客戶前設置環境變量<code>MYSQL_UNIX_PORT</code>為套接字路徑名。你可用<code>--socket=/path/to/socket</code>選項啟動<code>mysqld</code>服務器。如果你改變了服務器的套接字路徑名,你也必須通知<strong>MySQL</strong>客戶關于新路徑的情況。你可以通過設置環境變量<code>MYSQL_UNIX_PORT</code>為套接字路徑名或由提供套接字路徑名作為客戶的參數做到。你可用這個命令測試套接字:</p>
<pre>shell> mysqladmin --socket=/path/to/socket version
</pre>
</li>
<li>你正在使用 Linux和線程已經死了(核心傾倒了)。在這種情況中,你必須殺死其它<code>mysqld</code>線程(例如在啟動一個新的<strong>MySQL</strong>服務器之前,可以用<code>mysql_zap</code>腳本)。見<a HREF="manual_Problems.html#Crashing">18.1 如果MySQL總是崩潰怎么辦</a>。</li>
</ul>
<p>如果你得到錯誤<code>Can't connect to MySQL server on some_hostname</code>,你可以嘗試下列步驟找出問題是什么:
<ul>
<li>通過執行<code>telnet your-host-name tcp-ip-port-number</code>并且按幾次回車來檢查服務器是否正常運行。如果有一個<strong>MySQL</strong>運行在這個端口上,你應該得到一個包含正在運行的<strong>MySQL</strong>服務器的版本號的應答。如果你得到類似于<code>telnet:
Unable to connect to remote host: Connection refused</code>的一個錯誤,那么沒有服務器在使用的端口上運行。</li>
<li>嘗試連接本地機器上的<code>mysqld</code>守護進程,并用<code>mysqladmin
variables</code>檢查mysqld被配置使用的TCP/IP端口(變量<code>port</code>)。 </li>
<li>檢查你的<code>mysqld</code>服務器沒有用<code>--skip-networking</code>選項啟動。
</li>
</ul>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -