⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manual_privilege_system.html

📁 MySQL参考手册中文版
💻 HTML
📖 第 1 页 / 共 5 页
字号:
<p>如果你想要初始的权限不同于上面描述的那些,在你运行<code>mysql_install_db</code>之前,你可以修改它。 
</p>

<p>为了完全重建权限表,删除在包含<code>mysql</code>数据库的目录下所有<tt>“*.frm”</tt>,<tt>“*.MYI”</tt>和<tt>“*.MYD”</tt>文件。(这是在数据库目录下面命名为<tt>“mysql”</tt>的目录,当你运行<code>mysqld 
--help</code>时,它被列出。)然后运行<code>mysql_install_db</code>脚本,可能在首先编辑它拥有你想要的权限之后。 
</p>

<p><strong>注意</strong>:对于比<strong>MySQL</strong> 3.22.10旧的版本,你不应该删除<tt>“*.frm”</tt>文件。如果你偶然做了,你应该在运行<code>mysql_install_db</code>之前你的<strong>MySQL</strong>分发中拷回它们。 
</p>

<h2><a NAME="Adding_users" HREF="manual_toc.html#Adding_users">6.11 向MySQL增加新用户权限</a></h2>

<p>你可以有2个不同的方法增加用户:通过使用<code>GRANT</code>语句或通过直接操作<strong>MySQL</strong>授权表。比较好的方法是使用<code>GRANT</code>语句,因为他们是更简明并且好像错误少些。 
</p>

<p>下面的例子显示出如何使用<code>mysql</code>客户安装新用户。这些例子假定权限根据以前的章节描述的缺省被安装。这意味着为了改变,你必须在<code>mysqld</code>正在运行同一台机器上,你必须作为<strong>MySQL</strong> 
<code>root</code>用户连接,并且<code>root</code>用户必须对<code>mysql</code>数据库有<strong>insert</strong>权限和<strong>reload</strong>管理权限。另外,如果你改变了<code>root</code>用户口令,你必须如下的<code>mysql</code>命令指定它。 
</p>

<p>你可以通过发出<code>GRANT</code>语句增加新用户: </p>

<pre>shell&gt; mysql --user=root mysql
mysql&gt; GRANT ALL PRIVILEGES ON *.* TO monty@localhost
           IDENTIFIED BY 'something' WITH GRANT OPTION;
mysql&gt; GRANT ALL PRIVILEGES ON *.* TO monty@&quot;%&quot;
           IDENTIFIED BY 'something' WITH GRANT OPTION;
mysql&gt; GRANT RELOAD,PROCESS ON *.* TO admin@localhost;
mysql&gt; GRANT USAGE ON *.* TO dummy@localhost;
</pre>

<p>这些<code>GRANT</code>语句安装3个新用户: 

<dl COMPACT="Adding_users">
  <dt><code>monty</code> </dt>
  <dd>可以从任何地方连接服务器的一个完全的超级用户,但是必须使用一个口令(<code>'something'</code>做这个。注意,我们必须对<code>monty@localhost</code>和<code>monty@&quot;%&quot;</code>发出<code>GRANT</code>语句。如果我们增加<code>localhost</code>条目,对<code>localhost</code>的匿名用户条目在我们从本地主机连接接时由<code>mysql_install_db</code>创建的条目将优先考虑,因为它有更特定的<code>Host</code>字段值,所以以<code>user</code>表排列顺序看更早到来。</dd>
  <dt><code>admin</code> </dt>
  <dd>可以从<code>localhost</code>没有一个口令进行连接并且被授予<strong>reload</strong>和<strong>process</strong>管理权限的用户。这允许用户执行<code>mysqladmin 
    reload</code>、<code>mysqladmin refresh</code>和<code>mysqladmin flush-*</code>命令,还有<code>mysqladmin 
    processlist</code>。没有授予数据库有关的权限。他们能在以后通过发出另一个<code>GRANT</code>语句授权。 
  </dd>
  <dt><code>dummy</code> </dt>
  <dd>可以不用一个口令连接的一个用户,但是只能从本地主机。全局权限被设置为<code>'N'</code>--<code>USAGE</code>权限类型允许你无需权限就可设置一个用户。它假定你将在以后授予数据库相关的权限。 
  </dd>
</dl>

<p>你也可以直接通过发出<code>INSERT</code>语句增加同样的用户存取信息,然后告诉服务器再次装入授权表: 
</p>

<pre>shell&gt; mysql --user=root mysql
mysql&gt; INSERT INTO user VALUES('localhost','monty',PASSWORD('something'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
mysql&gt; INSERT INTO user VALUES('%','monty',PASSWORD('something'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y')
mysql&gt; INSERT INTO user SET Host='localhost',User='admin',
                 Reload_priv='Y', Process_priv='Y';
mysql&gt; INSERT INTO user (Host,User,Password)
                        VALUES('localhost','dummy','');
mysql&gt; FLUSH PRIVILEGES;
</pre>

<p>取决于你的<strong>MySQL</strong>版本,对上述,你可能必须使用一个不同数目<code>'Y'</code>值(在3.22.11以前的版本有更少的权限列)。对<code>admin</code>用户,只用在3.22.11开始的版本具有的更加可读的<code>INSERT</code>扩充的语法。 
</p>

<p>注意,为了设置一个超级用户,你只需创造一个<code>user</code>表条目,其权限字段设为<code>'Y'</code>。不需要<code>db</code>或<code>host</code>表的条目。 
</p>

<p>在<code>user</code>表中的权限列不是由最后一个<code>INSERT</code>语句明确设置的(对<code>dummy</code>用户),因此那些列被赋予缺省值<code>'N'</code>。这是<code>GRANT 
USAGE</code>做的同样的事情。 </p>

<p>下列例子增加一个用户<code>custom</code>,他能从主机<code>localhost</code>、<code>server.domain</code>和<code>whitehouse.gov</code>连接。他只想要从<code>localhost</code>存取<code>bankaccount</code>数据库,从<code>whitehouse.gov</code>存取<code>expenses</code>数据库和从所有3台主机存取<code>customer</code>数据库。他想要从所有3台主机上使用口令<code>stupid</code>。 
</p>

<p>为了使用<code>GRANT</code>语句设置个用户的权限,运行这些命令: </p>

<pre>shell&gt; mysql --user=root mysql
mysql&gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON bankaccount.*
           TO custom@localhost
           IDENTIFIED BY 'stupid';
mysql&gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON expenses.*
           TO custom@whitehouse.gov
           IDENTIFIED BY 'stupid';
mysql&gt; GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON customer.*
           TO custom@'%'
           IDENTIFIED BY 'stupid';
</pre>

<p>通过直接修改授权表设置用户权限,运行这些命令(注意,在结束时<code>FLUSH 
PRIVILEGES</code>): </p>

<pre>shell&gt; mysql --user=root mysql
mysql&gt; INSERT INTO user (Host,User,Password)
       VALUES('localhost','custom',PASSWORD('stupid'));
mysql&gt; INSERT INTO user (Host,User,Password)
       VALUES('server.domain','custom',PASSWORD('stupid'));
mysql&gt; INSERT INTO user (Host,User,Password)
       VALUES('whitehouse.gov','custom',PASSWORD('stupid'));
mysql&gt; INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES
       ('localhost','bankaccount','custom','Y','Y','Y','Y','Y','Y');
mysql&gt; INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES
       ('whitehouse.gov','expenses','custom','Y','Y','Y','Y','Y','Y');
mysql&gt; INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES('%','customer','custom','Y','Y','Y','Y','Y','Y');
mysql&gt; FLUSH PRIVILEGES;
</pre>

<p>头3个<code>INSERT</code>语句增加<code>user</code>表条目,允许用户<code>custom</code>用给定口令从不同的主机进行连接,但是没有授予任何许可(所有权限被设置为缺省值<code>'N'</code>)。后3个<code>INSERT</code>语句增加<code>db</code>表条目,授予<code>custom</code>以<code>bankaccount</code>、<code>expenses</code>和<code>customer</code>数据库权限,但是只能在从正确的主机存取时。通常,在授权表直接被修改时,服务器必须被告知再次装入他们(用<code>FLUSH 
PRIVILEGES</code>)以便使权限修改生效。</p>

<p>如果你想要给特定的用户从一个给定的域上的任何机器上存取权限,你可以发出一个如下的<code>GRANT</code>语句: 
</p>

<pre>mysql&gt; GRANT ...
           ON *.*
           TO myusername@&quot;%.mydomainname.com&quot;
           IDENTIFIED BY 'mypassword';
</pre>

<p>为了通过直接修改授权表做同样的事情,这样做: </p>

<pre>mysql&gt; INSERT INTO user VALUES ('%.mydomainname.com', 'myusername',
           PASSWORD('mypassword'),...);
mysql&gt; FLUSH PRIVILEGES;
</pre>

<p>你也可以使用<code>xmysqladmin</code>、<code>mysql_webadmin</code>甚至<code>xmysql</code>在授权表中插入、改变和更新值。你可以在<strong>MySQL</strong>的<a HREF="http://www.mysql.com/Contrib/">Contrib目录</a>找到这些实用程序。 </p>

<h2><a NAME="Passwords" HREF="manual_toc.html#Passwords">6.12 怎样设置口令</a></h2>

<p>在前面小节的例子里说明了一个重要的原则:当你使用<code>INSERT</code>或<code>UPDATE</code>语句存储一个非空的口令时,你必须使用<code>PASSWORD()</code>函数加密它。这是因为在<code>user</code>表中以加密形式存储口令,而不是作为纯文本。如果你忘记这个事实,你可能像这样试图设置口令: 
</p>

<pre>shell&gt; mysql -u root mysql 
mysql&gt; INSERT INTO user (Host,User,Password) VALUES('%','jeffrey','biscuit'); 
mysql&gt; FLUSH PRIVILEGES
</pre>

<p>结果是纯文本值<code>'biscuit'</code>作为口令被存储在<code>user</code>表中。在用户<code>jeffrey</code>试图用这个口令连接服务器时,<code>mysql</code>客户用<code>PASSWORD()</code>加密它并且将结果送给服务器,服务器比较在<code>user</code>表中的值(它是纯文本值<code>'biscuit'</code>)和加密的口令(<em>而不是</em> 
<code>'biscuit'</code>),比较失败并且服务器拒绝连接: </p>

<pre>shell&gt; mysql -u jeffrey -pbiscuit test
Access denied
</pre>

<p>因为当他们被插入<code>user</code>表时,口令必须被加密,<code>相反,INSERT</code>语句应该象这样被指定: 
</p>

<pre>mysql&gt; INSERT INTO user (Host,User,Password)
       VALUES('%','jeffrey',PASSWORD('biscuit'));
</pre>

<p>当你使用<code>SET PASSWORD</code>语句时,你也必须使用<code>PASSWORD()</code>函数: 
</p>

<pre>mysql&gt; SET PASSWORD FOR jeffrey@&quot;%&quot; = PASSWORD('biscuit'); 
</pre>

<p>如果你使用<code>GRANT ... IDENTIFIED BY</code>语句或<code>mysqladmin password</code>命令设置口令,<code>PASSWORD()</code>函数是不必要的。他们都考虑到为你加密口令,多以你可像这样指定一个口令<code>'biscuit'</code>: 
</p>

<pre>mysql&gt; GRANT USAGE ON *.* TO jeffrey@&quot;%&quot; IDENTIFIED BY 'biscuit';
</pre>

<p>或</p>

<pre>shell&gt; mysqladmin -u jeffrey password biscuit 
</pre>

<p>注意: <code>PASSWORD()</code>不是以在Unix口令加密的同样方法施行口令加密。你不应该假定如果你的Unix口令和你的<strong>MySQL</strong>口令是一样的,<code>PASSWORD()</code>将导致与在Unix口令文件被存储的同样的加密值。见<a HREF="manual_Privilege_system.html#User_names">6.2 MySQL 用户名和口令</a>。 </p>

<h2><a NAME="Access_denied" HREF="manual_toc.html#Access_denied">6.13 <code>Access denied</code>错误的原因</a></h2>

<p>当你试着联接<strong>MySQL</strong>服务器时,如果你碰到<code>Access 
denied</code>错误,显示在下面的表指出一些你能用来更正这个问题的动作: 

<ul>
  <li>你是在安装<strong>MySQL</strong>以后运行<code>mysql_install_db</code>的脚本,来设置初始授权表内容吗?如果不是,这样做。见<a HREF="manual_Privilege_system.html#Default_privileges">6.10 设置初始MySQL权限</a>。通过执行这个命令测试初始权限: 
    <pre>shell&gt; mysql -u root test 
</pre>
    <p>服务器应该让你无误地连接。你也应该保证你在<strong>MySQL</strong>数据库目录有一个文件<tt>“user.MYD”</tt>。通常,它是<tt>“PATH/var/mysql/user.MYD”</tt>,在此<code>PATH</code>是<strong>MySQL</strong>安装根目录的路径。 
    </p>
  </li>
  <li>在一个新的安装以后,你应该连接服务器并且设置你的用户及其存取许可: 
    <pre>shell&gt; mysql -u root mysql 
</pre>
    <p>服务器应该让你连接,因为<strong>MySQL</strong> <code>root</code>用户初始时没有口令。既然那也是一个安全风险,当你正在设置其他<strong>MySQL</strong>用户时,设定<code>root</code>口令是一件重要的事请。如果你作为<code>root</code>尝试连接并且得到这个错误: 
    </p>
    <pre>Access denied for user: '@unknown' to database mysql 
</pre>
    <p>这意味着,你没有一个条目在<code>user</code>表中的一个<code>User</code>列值为<code>'root'</code>并且<code>mysqld</code>不能为你的客库解析主机名。在这种情况下,你必须用<code>--skip-grant-tables</code>选项重启服务器并且编辑你的<tt>“/etc/hosts”</tt>或<tt>“\windows\hosts”</tt>文件为你的主机增加一个条目。 
    </p>
  </li>
  <li><a NAME="IDX148"></a>如果你从一个3.22.11以前的版本更新一个现存的<strong>MySQL</strong>安装到3.22.11版或以后版本,你运行了<code>mysql_fix_privilege_tables</code>脚本吗?如果没有,运行它。在<code>GRANT</code>语句变得能工作时,授权表的结构用<strong>MySQL</strong> 
    3.22.11修改 。 </li>
  <li>如果你直接对授权表做修改(使用<code>INSERT</code>或<code>UPDATE</code>语句)并且你的改变似乎被忽略,记住,你必须发出一个<code>FLUSH 
    PRIVILEGES</code>语句或执行一个<code>mysqladmin flush-privileges</code>命令导致服务器再次读入表,否则你的改变要道下一次服务器被重启时再生效。记住在你设定<code>root</code>口令以后,你将不需要指定它,直到在你清洗(flush)权限以后,因为服务器仍然不会知道你改变了口令! 
  </li>
  <li>如果你的权限似乎在一个会话(session)当中改变了,可能是一个超级用户改变了他们。再次装入授权表作用于新客户连接,但是它也影响现存的连接,如<a HREF="manual_Privilege_system.html#Privilege_changes">6.9 权限改变何时生效</a>小节所述。 
  </li>
  <li>为了测试,用<code>--skip-grant-tables</code>选项启动<code>mysqld</code>守护进程,然后你可以改变<strong>MySQL</strong>授权表并且使用<code>mysqlaccess</code>脚本检查你的修改是否有如期的效果。当你对你的改变满意时,执行<code>mysqladmin 
    flush-privileges</code>告诉<code>mysqld</code>服务器开始使用新的权限表。<strong>注意:</strong>再次装入授权表覆盖了<code>--skip-grant-tables</code>选项。这允许你告诉服务器开始使用授权表,而不用停掉并重启它。 
  </li>
  <li>如果你有一个Perl、Python或ODBC程序的存取问题,试着用<code>mysql -u 
    user_name db_name</code>或<code>mysql -u user_name -pyour_pass db_name</code>与服务器连接。如果你能用<code>mysql</code>客户连接,这是你程序的一个问题而不是存取权限的问题。(注意在<code>-p</code>和口令之间没有空格;你也能使用<code>--password=your_pass</code>句法指定口令。)</li>
  <li>如果你不能让口令工作,记得如果你用<code>INSERT</code>, <code>UPDATE</code>或<code>SET 
    PASSWORD</code>语句设置口令,你必须使用<code>PASSWORD()</code>函数。如果你用<code>GRANT 
    ... INDENTIFIED BY</code>语句或<code>mysqladmin password</code>命令指定口令,<code>PASSWORD()</code>函数是不需要的。见<a HREF="manual_Privilege_system.html#Passwords">6.12 怎样设置口令</a>。 </li>
  <li><code>localhost</code>是你本地主机名的一个同义词,并且也是如果你不明确地指定主机而客户尝试连接的缺省主机。然而,如果你正在运行于一个使用MIT-pthreads的系统上,连接<code>localhost</code>是不行的(<code>localhost</code>连接使用Unix套接字进行,它没被 
    MIT-pthreads支持),为了在这样的系统上避免这个问题,你应该使用<code>--host</code>选项明确地命名服务器主机,这将做一个 
    TCP/IP连接到<code>mysqld</code>服务器。在这种情况下,你必须有在服务器主机上的<code>user</code>表中条目的你真实的主机名。(即使你在服务器同一台的主机上运行一个客户程序,这也是真的。)</li>
  <li>当尝试用<code>mysql -u user_name db_name</code>与数据库连接时,如果你得到一个<code>Access 
    denied</code>错误,你可能有与<code>user</code>桌有关的问题,通过执行<code>mysql 
    -u root mysql</code>并且发出下面的SQL语句检查: <pre>mysql&gt; SELECT * FROM u

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -