📄 manual_problems.html
字号:
<p><code>ALTER TABLE</code>和<code>OPTIMIZE TABLE</code>在原数据库表的同一个目录中创建一张临时表。</p>
<h2><a NAME="Problems_with_mysql.sock" HREF="manual_toc.html#Problems_with_mysql.sock">18.6
怎样保护<tt>“/tmp/mysql.sock ”</tt>不被删除</a></h2>
<p>如果你有这个问题,事实上任何人可以删除<strong>MySQL</strong>通讯套接字<tt>“/tmp/mysql.sock”</tt>,在Unix的大多数版本上,你能通过为其设置<code>sticky</code>(t)位来保护你的<tt>“/tmp”</tt>文件系统。作为<code>root</code>登录并且做下列事情:</p>
<pre>shell> chmod +t /tmp
</pre>
<p>这将保护你的<tt>“/tmp”</tt>文件系统使得文件仅能由他们的所有者或超级用户(<code>root</code>)删除。</p>
<p>你能执行<code>ls -ld /tmp</code>检查<code>sticky</code>位是否被设置,如果最后一位许可位是<code>t</code>,该位被设置了。</p>
<h2><a NAME="Error_Access_denied" HREF="manual_toc.html#Error_Access_denied">18.7<code>
Access denied</code>错误</a></h2>
<p>见<a HREF="manual_Privilege_system.html#Privileges">6.6 权限系统如何工作</a>。并且特别要看<a href="manual_Privilege_system.html#Access_denied">6.13 引起<code>Access denied</code>错误的原因</a>。
</p>
<h2><a NAME="Changing_MySQL_user" HREF="manual_toc.html#Changing_MySQL_user">18.8
怎样作为一个一般用户运行MySQL</a></h2>
<p><strong>MySQL</strong>服务器<code>mysqld</code>能被任何用户启动并运行。为了将<code>mysqld</code>改由Unix用户<code>user_name</code>来运行,你必须做下列事情:
<ol>
<li>如果它正在运行,停止服务器(使用<code>mysqladmin shutdown</code>)。</li>
<li>改变数据库目录和文件以便<code>user_name</code>有权限读和写文件(你可能需要作为Unix的<code>root</code>用户才能做到):<pre>shell> chown -R user_name /path/to/mysql/datadir
</pre>
<p>如果在<strong>MySQL</strong>数据目录中的目录或文件是符号链接,你也将需要顺着那些链接并改变他们指向的目录和文件。<code>chown
-R</code>不能跟随符号链接。</p>
</li>
<li>以<code>user_name</code>用户启动服务器,或如果你正在使用<strong>MySQL</strong>
3.22或以后版本,以Unix<code> root</code>用户启动<code>mysqld</code>并使用<code>--user=user_name</code>选项,<code>mysqld</code>将在接受任何连接之前切换到以Unix
<code>user_name</code>用户运行。</li>
<li>如果在系统被重新启动时,你使用<code>mysql.server</code>脚本启动<code>mysqld</code>,你应该编辑<code>mysql.server</code>用<code>su</code>以用户<code>user_name</code>运行<code>mysqld</code>,或使用<code>--user</code>选项调用<code>mysqld</code>。(不改变<code>safe_mysqld</code>是必要的。)</li>
</ol>
<p>现在,你的<code>mysqld</code>进程应该正在作为Unix用户<code>user_name</code>运行,并运行完好。尽管有一件事情没有变化:权限表的内容。缺省
地(就在运行了脚本<code>mysql_install_db</code>安装的权限表后),<strong>MySQL</strong>用户<code>root</code>是唯一有存取<code>mysql</code>数据库或创建或抛弃数据库权限的用户。除非你改变了那些权限,否则他们仍然保持。当你作为一个Unix用户而不是<code>root</code>登录时,这不应该阻止你作为<strong>MySQL</strong>
<code>root</code>用户来存取<strong>MySQL</strong>;只要为客户程序指定<code>-u
root</code>的选项。</p>
<p>注意通过在命令行上提供<code>-u root</code>,作为<code>root</code>存取<strong>MySQL</strong>,与作为Unix
<code>root</code>用户或其他Unix用户运行<strong>MySQL</strong><em>没有关系</em>。<strong>MySQL</strong>的存取权限和用户名与Unix用户名字是完全分开的。唯一与Unix用户名有关的是,如果当你调用一个客户程序时,你不提供一个<code>-u</code>选项,客户将试图使用你的Unix登录名作为你的<strong>MySQL</strong>用户名进行连接。</p>
<p>如果你的Unix机器本身不安全,你可能应该至少在存取表中为<strong>MySQL</strong>
<code>root</code>用户放上一个口令。否则,在那台机器上有一个帐号的任何用户能运行<code>mysql
-u root db_name</code>并且做他喜欢做的任何事情。</p>
<h2><a NAME="Resetting_permissions" HREF="manual_toc.html#Resetting_permissions">18.9
怎样重新设置一个忘记的口令</a></h2>
<p>如果你忘记了<strong>MySQL</strong>的<code>root</code>用户的口令,你可以用下列过程恢复它。
<ol>
<li>通过发送一个<code>kill</code>(不是<code>kill -9</code>)到<code>mysqld</code>服务器来关闭mysqld服务器。pid
被保存在一个<code>.pid</code>文件中,通常在<strong>MySQL</strong>数据库目录中:<pre>kill `cat /mysql-data-directory/hostname.pid`
</pre>
<p>你必须是一个UNIX<code> root</code>用户或运行服务器的相同用户做这个。</p>
</li>
<li>使用<code>--skip-grant-tables</code>选项重启<code>mysqld</code>。 </li>
<li>用<code>mysql -h hostname mysql</code>连接mysqld服务器并且用一条<code>GRANT</code>命令改变口令。见<a HREF="manual_Reference.html#GRANT">7.26<code> GRANT</code>和<code>REVOKE</code>句法</a>。你也可以用<code>mysqladmin
-h hostname -u user password 'new password'</code> 进行。</li>
<li>用<code>mysqladmin -h hostname flush-privileges</code>或用SQL命令<code>FLUSH
PRIVILEGES</code>来装载权限表。</li>
</ol>
<h2><a NAME="File_permissions" HREF="manual_toc.html#File_permissions">18.10
文件许可权限问题</a></h2>
<p>如果你有与文件许可有关的问题,例如,如果当你创建一张表时,<code>mysql</code>发出下列错误消息:
</p>
<pre>ERROR: Can't find file: 'path/with/filename.frm' (Errcode: 13)
</pre>
<p><a NAME="IDX688"></a>那么可能是在<code>mysqld</code>启动时,环境变量<code>UMASK</code>可能设置不正确。缺省的umask值是<code>0660</code>。你可以如下启动<code>safe_mysqld</code>改变其行为:</p>
<pre>shell> UMASK=384 # = 600 in octal
shell> export UMASK
shell> /path/to/safe_mysqld &
</pre>
<h2><a NAME="Not_enough_file_handles" HREF="manual_toc.html#Not_enough_file_handles">18.11
文件没找到</a></h2>
<p>如果你从<strong>MySQL</strong>得到<code>ERROR '...' not found (errno: 23)</code>,
<code>Can't open file: ... (errno: 24)</code>或任何其他有<code>errno 23</code>或<code>errno
24</code>的错误,它意味着,你没有为<strong>MySQL</strong>分配足够的文件描述符。你能使用<code>perror</code>实用程序得到错误号含义是什么的描述:</p>
<pre>shell> perror 23
File table overflow
shell> perror 24
Too many open files
</pre>
<p>这里的问题是<code>mysqld</code>正在试图同时保持打开太多的文件。你也可以告诉<code>mysqld</code>一次不打开那么多的文件,或增加<code>mysqld</code>可得到的文件描述符数量。</p>
<p>为了告诉<code>mysqld</code>一次保持打开更少的文件,你可以通过使用<code>safe_mysqld</code>的<code>-O
table_cache=32</code>选项(缺省值是64)使表缓冲更小。减小<code>max_connections</code>值也将减少打开文件的数量(缺省值是90)。</p>
<p>要想<a NAME="IDX690"></a>改变<code>mysqld</code>可用的文件描述符数量,修改<code>safe_mysqld</code>脚本。脚本中有一条注释了的行<code>ulimit
-n 256</code>。你可以删除<code>'#'</code>字符来去掉该行的注释,并且改变数字256改变为<code>mysqld</code>可用的文件描述符的数量。</p>
<p><code>ulimit</code>能增加文件描述符的数量,但是只能到操作系统强加的限制。如果你需要增加每个进程可用的文件描述符数量的OS限制,参见你的操作系统文档。</p>
<p>注意,如果你运行<code>tcsh</code>外壳,<code>ulimit</code>将不工作!当你请求当前限制时,<code>tcsh</code>也将报告不正确的值!在这种情况下,你应该用<code>sh</code>启动<code>safe_mysqld</code>!</p>
<h2><a NAME="Using_DATE" HREF="manual_toc.html#Using_DATE">18.12 使用<code>DATE</code>列的问题</a></h2>
<p>一个<code>DATE</code>值的格式是<code>'YYYY-MM-DD'</code>。根据ANSI SQL,不允许其他格式。你应该在<code>UPDATE</code>表达式和<code>SELECT</code>语句的WHERE子句中使用这个格式。例如:</p>
<pre>mysql> SELECT * FROM tbl_name WHERE date >= '1997-05-05';
</pre>
<p>为了方便,如果日期用在数字上下文,<strong>MySQL</strong>自动变换一个日期到一个数字(并且反过来也如此)。当更新时和将一个日期与<code>TIMESTAMP</code>、<code>DATE</code>或<code>DATETIME</code>列比较的一个<code>WHERE</code>子句中,也是足够灵活以允许一种“宽松”的字符串格式。(宽松格式意味着任何标点字符用作在部件之间的分割符。例如,<code>'1998-08-15'</code>和<code>'1998#08#15'</code>是等价的。)<strong>MySQL</strong>也能变换不包含分割符的一个字符串(例如<code>
'19980815'</code>),如果它作为一个日期说得通。</p>
<p>特殊日期<code>'0000-00-00'</code>可以作为<code>'0000-00-00'</code>被存储和检索<code>。</code>当通过<strong>MyODBC</strong>使用一个<code>'0000-00-00'</code>日期时,在<strong>MyODBC</strong>
2.50.12和以上版本,它将自动被转换为<code>NULL</code>,因为ODBC不能处理这种日期。</p>
<p>因为<strong>MySQL</strong>实行了上述的变换,下列语句可以工作:</p>
<pre>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';
</pre>
<p>然而,下列将不工作: </p>
<pre>mysql> SELECT idate FROM tbl_name WHERE STRCMP(idate,'19970505')=0;
</pre>
<p><code>STRCMP()</code>是字符串函数,因此它将<code>idate</code>转换为一个字符串并且实施字符串比较。它不将<code>'19970505'</code>转换为一个日期并实施日期比较。</p>
<p>注意,<strong>MySQL</strong>不检查日期是否正确。如果你存储一个不正确的日期,例如<code>'1998-2-31'</code>,错误的日期将被存储。如果日期不能被变换到任何合理的值,在<code>DATE</code>字段中存储一个<code>0</code>。这主要是一个速度问题并且我们认为检查日期是应用程序的责任,而不服务器。</p>
<p><a NAME="IDX691"></a> </p>
<h2><a NAME="Timezone_problems" HREF="manual_toc.html#Timezone_problems">18.13
时区问题</a></h2>
<p>如果你有一个问题,<code>SELECT NOW()</code>以GMT时间返回值而不是你的本地时间,你必须设定<code>TZ</code>环境变量为你的当前时区。这应该在服务器运行的环境进行,例如在<code>safe_mysqld</code>或<code>mysql.server</code>中。</p>
<p><a NAME="IDX694"></a> <a NAME="IDX695"></a> <a NAME="IDX696"></a> </p>
<h2><a NAME="Case_sensitivity" HREF="manual_toc.html#Case_sensitivity">18.14
在搜索中的大小写敏感性</a></h2>
<p>缺省地,<strong>MySQL</strong>搜索是大小写不敏感的(尽管有一些字符集从来不是忽略大小写的,例如<code>捷克语</code>)。这意味着,如果你用<code>col_name
LIKE 'a%'</code>搜寻,你将得到所有以<code>A</code>或<code>a</code>开始的列值。如果你想要使这个搜索大小写敏感,使用象<code>INDEX(col_name,
"A")=0</code>检查一个前缀。或如果列值必须确切是<code>"A"</code>,使用<code>STRCMP(col_name,
"A") = 0</code>。</p>
<p>简单的比较操作(<code>>=、>、= 、< 、<=</code>、排序和聚合)是基于每个字符的“排序值”。有同样排序值的字符(象E,e和'e)被视为相同的字符!</p>
<p><code>LIKE</code>比较在每个字符的大写值上进行(E==e 但是E<>'e)。</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -