Table of Contents
The primary function of the MySQL privilege system is to
authenticate a user who connects from a given host and to associate
that user with privileges on a database such as
SELECT,
INSERT,
UPDATE, and
DELETE. Additional functionality
includes the ability to have anonymous users and to grant privileges
for MySQL-specific functions such as
LOAD DATA
INFILE and administrative operations.
There are some things that you cannot do with the MySQL privilege system:
You cannot explicitly specify that a given user should be denied access. That is, you cannot explicitly match a user and then refuse the connection.
You cannot specify that a user has privileges to create or drop tables in a database but not to create or drop the database itself.
A password applies globally to an account. You cannot associate a password with a specific object such as a database, table, or routine.
The user interface to the MySQL privilege system consists of SQL
statements such as CREATE USER,
GRANT, and
REVOKE. See
Account Management Statements.
Internally, the server stores privilege information in the grant
tables of the mysql database (that is, in the
database named mysql). The MySQL server reads the
contents of these tables into memory when it starts and bases
access-control decisions on the in-memory copies of the grant
tables.
The MySQL privilege system ensures that all users may perform only the operations permitted to them. As a user, when you connect to a MySQL server, your identity is determined by the host from which you connect and the user name you specify. When you issue requests after connecting, the system grants privileges according to your identity and what you want to do.
MySQL considers both your host name and user name in identifying you
because there is no reason to assume that a given user name belongs
to the same person on all hosts. For example, the user
joe who connects from
office.example.com need not be the same person as
the user joe who connects from
home.example.com. MySQL handles this by enabling
you to distinguish users on different hosts that happen to have the
same name: You can grant one set of privileges for connections by
joe from office.example.com,
and a different set of privileges for connections by
joe from home.example.com. To
see what privileges a given account has, use the
SHOW GRANTS statement. For example:
SHOW GRANTS FOR 'joe'@'office.example.com'; SHOW GRANTS FOR 'joe'@'home.example.com';
MySQL access control involves two stages when you run a client program that connects to the server:
Stage 1: The server accepts or rejects the connection based on your identity and whether you can verify your identity by supplying the correct password.
Stage 2: Assuming that you can
connect, the server checks each statement you issue to determine
whether you have sufficient privileges to perform it. For example,
if you try to select rows from a table in a database or drop a table
from the database, the server verifies that you have the
SELECT privilege for the table or the
DROP privilege for the database.
For a more detailed description of what happens during each stage, see Section 4.4, “Access Control, Stage 1: Connection Verification”, and Section 4.5, “Access Control, Stage 2: Request Verification”.
If your privileges are changed (either by yourself or someone else) while you are connected, those changes do not necessarily take effect immediately for the next statement that you issue. For details about the conditions under which the server reloads the grant tables, see Section 4.6, “When Privilege Changes Take Effect”.
For general security-related advice, see Chapter 2, General Security Issues. For help in diagnosing privilege-related problems, see Section 4.7, “Troubleshooting Problems Connecting to MySQL”.
MySQL provides privileges that apply in different contexts and at different levels of operation:
Administrative privileges enable users to manage operation of the MySQL server. These privileges are global because they are not specific to a particular database.
Database privileges apply to a database and to all objects within it. These privileges can be granted for specific databases, or globally so that they apply to all databases.
Privileges for database objects such as tables, indexes, views, and stored routines can be granted for specific objects within a database, for all objects of a given type within a database (for example, all tables in a database), or globally for all objects of a given type in all databases).
Information about account privileges is stored in the
user, db,
host, tables_priv,
columns_priv, and procs_priv
tables in the mysql database (see
Section 4.2, “Grant Tables”). The MySQL server reads the
contents of these tables into memory when it starts and reloads
them under the circumstances indicated in
Section 4.6, “When Privilege Changes Take Effect”. Access-control decisions are
based on the in-memory copies of the grant tables.
Some releases of MySQL introduce changes to the structure of the grant tables to add new privileges or features. To make sure that you can take advantage of any new capabilities, update your grant tables to have the current structure whenever you update to a new version of MySQL. See mysql_upgrade — Check and Upgrade MySQL Tables.
The following table shows the privilege names used at the SQL
level in the GRANT and
REVOKE statements, along with the
column name associated with each privilege in the grant tables and
the context in which the privilege applies.
Table 4.1 Permissible Privileges for GRANT and REVOKE
| Privilege | Column | Context |
|---|---|---|
CREATE | Create_priv | databases, tables, or indexes |
DROP | Drop_priv | databases, tables, or views |
GRANT OPTION | Grant_priv | databases, tables, or stored routines |
LOCK TABLES | Lock_tables_priv | databases |
REFERENCES | References_priv | databases or tables |
EVENT | Event_priv | databases |
ALTER | Alter_priv | tables |
DELETE | Delete_priv | tables |
INDEX | Index_priv | tables |
INSERT | Insert_priv | tables or columns |
SELECT | Select_priv | tables or columns |
UPDATE | Update_priv | tables or columns |
CREATE TEMPORARY TABLES | Create_tmp_table_priv | tables |
TRIGGER | Trigger_priv | tables |
CREATE VIEW | Create_view_priv | views |
SHOW VIEW | Show_view_priv | views |
ALTER ROUTINE | Alter_routine_priv | stored routines |
CREATE ROUTINE | Create_routine_priv | stored routines |
EXECUTE | Execute_priv | stored routines |
FILE | File_priv | file access on server host |
CREATE TABLESPACE | Create_tablespace_priv | server administration |
CREATE USER | Create_user_priv | server administration |
PROCESS | Process_priv | server administration |
PROXY | see proxies_priv table | server administration |
RELOAD | Reload_priv | server administration |
REPLICATION CLIENT | Repl_client_priv | server administration |
REPLICATION SLAVE | Repl_slave_priv | server administration |
SHOW DATABASES | Show_db_priv | server administration |
SHUTDOWN | Shutdown_priv | server administration |
SUPER | Super_priv | server administration |
ALL [PRIVILEGES] | server administration | |
USAGE | server administration |
The following list provides a general description of each privilege available in MySQL. Particular SQL statements might have more specific privilege requirements than indicated here. If so, the description for the statement in question provides the details.
The ALL or
ALL PRIVILEGES
privilege specifier is shorthand. It stands for “all
privileges available at a given privilege level”
(except GRANT OPTION). For
example, granting ALL at the
global or table level grants all global privileges or all
table-level privileges.
The ALTER privilege enables use
of ALTER TABLE to change the
structure of tables. ALTER
TABLE also requires the
CREATE and
INSERT privileges. Renaming a
table requires ALTER and
DROP on the old table,
CREATE, and
INSERT on the new table.
The ALTER ROUTINE privilege is
needed to alter or drop stored routines (procedures and
functions).
The CREATE privilege enables
creation of new databases and tables.
The CREATE ROUTINE privilege is
needed to create stored routines (procedures and functions).
The CREATE TABLESPACE privilege
is needed to create, alter, or drop tablespaces and log file
groups.
The CREATE TEMPORARY TABLES
privilege enables the creation of temporary tables using the
CREATE TEMPORARY
TABLE statement.
However, other operations on a temporary table, such as
INSERT,
UPDATE, or
SELECT, require additional
privileges for those operations for the database containing
the temporary table, or for the nontemporary table of the same
name.
To keep privileges for temporary and nontemporary tables
separate, a common workaround for this situation is to create
a database dedicated to the use of temporary tables. Then for
that database, a user can be granted the
CREATE TEMPORARY TABLES
privilege, along with any other privileges required for
temporary table operations done by that user.
The CREATE USER privilege
enables use of CREATE USER,
DROP USER,
RENAME USER, and
REVOKE ALL
PRIVILEGES.
The CREATE VIEW privilege
enables use of CREATE VIEW.
The DELETE privilege enables
rows to be deleted from tables in a database.
The DROP privilege enables you
to drop (remove) existing databases, tables, and views. The
DROP privilege is required in
order to use the statement ALTER TABLE ... DROP
PARTITION on a partitioned table. The
DROP privilege is also required
for TRUNCATE TABLE.
If you grant the DROP
privilege for the mysql database to a user,
that user can drop the database in which the MySQL access
privileges are stored.
The EVENT privilege is required
to create, alter, drop, or see events for the Event Scheduler.
The EXECUTE privilege is
required to execute stored routines (procedures and
functions).
The FILE privilege gives you
permission to read and write files on the server host using
the LOAD DATA
INFILE and
SELECT ... INTO
OUTFILE statements and the
LOAD_FILE() function. A user
who has the FILE privilege can
read any file on the server host that is either world-readable
or readable by the MySQL server. (This implies the user can
read any file in any database directory, because the server
can access any of those files.) The
FILE privilege also enables the
user to create new files in any directory where the MySQL
server has write access. This includes the server's data
directory containing the files that implement the privilege
tables. As a security measure, the server will not overwrite
existing files.
To limit the location in which files can be read and written,
set the secure_file_priv
system to a specific directory. See
Server System Variables.
The GRANT OPTION privilege
enables you to give to other users or remove from other users
those privileges that you yourself possess.
The INDEX privilege enables you
to create or drop (remove) indexes.
INDEX applies to existing
tables. If you have the CREATE
privilege for a table, you can include index definitions in
the CREATE TABLE statement.
The INSERT privilege enables
rows to be inserted into tables in a database.
INSERT is also required for the
ANALYZE TABLE,
OPTIMIZE TABLE, and
REPAIR TABLE table-maintenance
statements.
The LOCK TABLES privilege
enables the use of explicit LOCK
TABLES statements to lock tables for which you have
the SELECT privilege. This
includes the use of write locks, which prevents other sessions
from reading the locked table.
The PROCESS privilege pertains
to display of information about the threads executing within
the server (that is, information about the statements being
executed by sessions). The privilege enables use of
SHOW PROCESSLIST or
mysqladmin processlist to see threads
belonging to other accounts; you can always see your own
threads. The PROCESS privilege
also enables use of SHOW
ENGINE.
The PROXY privilege enables a
user to impersonate or become known as another user. See
Section 5.7, “Proxy Users”. This privilege was added in
MySQL 5.5.7.
The REFERENCES privilege is
unused before MySQL 5.5.41. As of 5.5.41, creation of a
foreign key constraint requires at least one of the
SELECT,
INSERT,
UPDATE,
DELETE, or
REFERENCES privileges for the
parent table.
The RELOAD privilege enables
use of the FLUSH statement. It
also enables mysqladmin commands that are
equivalent to FLUSH operations:
flush-hosts, flush-logs,
flush-privileges,
flush-status,
flush-tables,
flush-threads, refresh,
and reload.
The reload command tells the server to
reload the grant tables into memory.
flush-privileges is a synonym for
reload. The refresh
command closes and reopens the log files and flushes all
tables. The other
flush-
commands perform functions similar to
xxxrefresh, but are more specific and may be
preferable in some instances. For example, if you want to
flush just the log files, flush-logs is a
better choice than refresh.
The REPLICATION CLIENT
privilege enables the use of SHOW MASTER
STATUS and SHOW SLAVE
STATUS. In MySQL 5.5.25 and later, it also enables
the use of the SHOW BINARY LOGS
statement.
The REPLICATION SLAVE privilege
should be granted to accounts that are used by slave servers
to connect to the current server as their master. Without this
privilege, the slave cannot request updates that have been
made to databases on the master server.
The SELECT privilege enables
you to select rows from tables in a database.
SELECT statements require the
SELECT privilege only if they
actually retrieve rows from a table. Some
SELECT statements do not access
tables and can be executed without permission for any
database. For example, you can use
SELECT as a simple calculator
to evaluate expressions that make no reference to tables:
SELECT 1+1; SELECT PI()*2;
The SELECT privilege is also
needed for other statements that read column values. For
example, SELECT is needed for
columns referenced on the right hand side of
col_name=expr
assignment in UPDATE statements
or for columns named in the WHERE clause of
DELETE or
UPDATE statements.
The SHOW DATABASES privilege
enables the account to see database names by issuing the
SHOW DATABASE statement. Accounts that do
not have this privilege see only databases for which they have
some privileges, and cannot use the statement at all if the
server was started with the
--skip-show-database option.
Note that any global privilege is a
privilege for the database.
The SHOW VIEW privilege enables
use of SHOW CREATE VIEW.
The SHUTDOWN privilege enables
use of the mysqladmin shutdown command and
the mysql_shutdown() C API
function. There is no corresponding SQL statement.
The SUPER privilege enables an
account to use CHANGE MASTER
TO, KILL or
mysqladmin kill to kill threads belonging
to other accounts (you can always kill your own threads),
PURGE BINARY LOGS, the
mysqladmin debug command, enabling or
disabling logging, performing updates even if the
read_only system variable is
enabled, starting and stopping replication on slave servers,
specification of any account in the DEFINER
attribute of stored programs and views, and enables you to
connect (once) even if the connection limit controlled by the
max_connections system
variable is reached.
The SUPER privilege is required
to make configuration changes by modifying the global value of
system variables. For some system variables, setting the
session value also requires the
SUPER privilege; if so, it is
indicated in the variable description.
To create or alter stored functions if binary logging is
enabled, you may also need the
SUPER privilege, as described
in Binary Logging of Stored Programs.
The TRIGGER privilege enables
trigger operations. You must have this privilege for a table
to create, drop, execute, or display triggers for that table.
When a trigger is activated (by a user who has privileges to
execute INSERT,
UPDATE, or
DELETE statements for the table
associated with the trigger), trigger execution requires that
the user who defined the trigger still have the
TRIGGER privilege.
The UPDATE privilege enables
rows to be updated in tables in a database.
The USAGE privilege specifier
stands for “no privileges.” It is used at the
global level with GRANT to
modify account attributes such as resource limits or SSL
characteristics without affecting existing account privileges.
It is a good idea to grant to an account only those privileges
that it needs. You should exercise particular caution in granting
the FILE and administrative
privileges:
The FILE privilege can be
abused to read into a database table any files that the MySQL
server can read on the server host. This includes all
world-readable files and files in the server's data directory.
The table can then be accessed using
SELECT to transfer its contents
to the client host.
The GRANT OPTION privilege
enables users to give their privileges to other users. Two
users that have different privileges and with the
GRANT OPTION privilege are able
to combine privileges.
The ALTER privilege may be used
to subvert the privilege system by renaming tables.
The SHUTDOWN privilege can be
abused to deny service to other users entirely by terminating
the server.
The PROCESS privilege can be
used to view the plain text of currently executing statements,
including statements that set or change passwords.
The SUPER privilege can be used
to terminate other sessions or change how the server operates.
Privileges granted for the mysql database
itself can be used to change passwords and other access
privilege information. Passwords are stored encrypted, so a
malicious user cannot simply read them to know the plain text
password. However, a user with write access to the
user table Password
column can change an account's password, and then connect to
the MySQL server using that account.
The mysql system database includes several
grant tables that contain information about user accounts and the
privileges held by them. This section describes those tables. For
information about other tables in the system database, see
The mysql System Database.
Normally, to manipulate the contents of grant tables, you modify
them indirectly by using account-management statements such as
CREATE USER,
GRANT, and
REVOKE to set up accounts and
control the privileges available to each one. See
Account Management Statements. The discussion here
describes the underlying structure of the grant tables and how the
server uses their contents when interacting with clients.
Direct modification of grant tables using statements such as
INSERT,
UPDATE, or
DELETE is discouraged and done at
your own risk. The server is free to ignore rows that become
malformed as a result of such modifications.
These mysql database tables contain grant
information:
Each grant table contains scope columns and privilege columns:
Scope columns determine the scope of each row in the tables;
that is, the context in which the row applies. For example, a
user table row with Host
and User values of
'thomas.loc.gov' and
'bob' applies to authenticating connections
made to the server from the host
thomas.loc.gov by a client that specifies a
user name of bob. Similarly, a
db table row with Host,
User, and Db column
values of 'thomas.loc.gov',
'bob' and 'reports'
applies when bob connects from the host
thomas.loc.gov to access the
reports database. The
tables_priv and
columns_priv tables contain scope columns
indicating tables or table/column combinations to which each
row applies. The procs_priv scope columns
indicate the stored routine to which each row applies.
Privilege columns indicate which privileges a table row grants; that is, which operations it permits to be performed. The server combines the information in the various grant tables to form a complete description of a user's privileges. Section 4.5, “Access Control, Stage 2: Request Verification”, describes the rules for this.
The server uses the grant tables in the following manner:
The user table scope columns determine
whether to reject or permit incoming connections. For
permitted connections, any privileges granted in the
user table indicate the user's global
privileges. Any privileges granted in this table apply to
all databases on the server.
Because any global privilege is considered a privilege for
all databases, any global privilege enables a user to see
all database names with SHOW
DATABASES or by examining the
SCHEMATA table of
INFORMATION_SCHEMA.
The db table scope columns determine which
users can access which databases from which hosts. The
privilege columns determine the permitted operations. A
privilege granted at the database level applies to the
database and to all objects in the database, such as tables
and stored programs.
The host table is used in conjunction with
the db table when you want a given
db table row to apply to several hosts. For
example, if you want a user to be able to use a database from
several hosts in your network, leave the
Host value empty in the user's
db table row, then populate the
host table with a row for each of those
hosts. This mechanism is described more detail in
Section 4.5, “Access Control, Stage 2: Request Verification”.
The tables_priv and
columns_priv tables are similar to the
db table, but are more fine-grained: They
apply at the table and column levels rather than at the
database level. A privilege granted at the table level applies
to the table and to all its columns. A privilege granted at
the column level applies only to a specific column.
The procs_priv table applies to stored
routines (procedures and functions). A privilege granted at
the routine level applies only to a single procedure or
function.
The proxies_priv table indicates which
users can act as proxies for other users and whether a user
can grant the PROXY privilege
to other users.
The server uses the user,
db, and host tables in the
mysql database at both the first and second
stages of access control (see Chapter 4, The MySQL Access Privilege System).
The columns in the user and
db tables are shown here. The
host table is similar to the
db table but has a specialized use as described
in Section 4.5, “Access Control, Stage 2: Request Verification”.
Table 4.2 user and db Table Columns
| Table Name | user | db |
|---|---|---|
| Scope columns | Host | Host |
User | Db | |
Password | User | |
| Privilege columns | Select_priv | Select_priv |
Insert_priv | Insert_priv | |
Update_priv | Update_priv | |
Delete_priv | Delete_priv | |
Index_priv | Index_priv | |
Alter_priv | Alter_priv | |
Create_priv | Create_priv | |
Drop_priv | Drop_priv | |
Grant_priv | Grant_priv | |
Create_view_priv | Create_view_priv | |
Show_view_priv | Show_view_priv | |
Create_routine_priv | Create_routine_priv | |
Alter_routine_priv | Alter_routine_priv | |
Execute_priv | Execute_priv | |
Trigger_priv | Trigger_priv | |
Event_priv | Event_priv | |
Create_tmp_table_priv | Create_tmp_table_priv | |
Lock_tables_priv | Lock_tables_priv | |
References_priv | References_priv | |
Reload_priv | ||
Shutdown_priv | ||
Process_priv | ||
File_priv | ||
Show_db_priv | ||
Super_priv | ||
Repl_slave_priv | ||
Repl_client_priv | ||
Create_user_priv | ||
Create_tablespace_priv | ||
| Security columns | ssl_type | |
ssl_cipher | ||
x509_issuer | ||
x509_subject | ||
plugin | ||
authentication_string | ||
| Resource control columns | max_questions | |
max_updates | ||
max_connections | ||
max_user_connections |
The user table has a
Password column for storing credential
information. As of MySQL 5.5.7, the user table
also has plugin and
authentication_string columns for storing
authentication plugin and credential information.
If an account row names a plugin in the plugin
column, the server uses it to authenticate connection attempts for
the account. It is up to the plugin whether it uses the
Password and
authentication_string column values.
If the plugin column for an account row is
empty, the server authenticates the account using either the
mysql_native_password or
mysql_old_password plugin, depending on whether
the password hash value in the Password column
used native hashing or the older pre-4.1 hashing method. Clients
must match the password in the Password column
of the account row.
Prior to MySQL 5.5.11, the length of the plugin
column was 60 characters. This was increased to 64 characters in
MySQL 5.5.11 for compatibility with the
mysql.plugin table's
name column. (Bug #11766610, Bug #59752)
During the second stage of access control, the server performs
request verification to ensure that each client has sufficient
privileges for each request that it issues. In addition to the
user, db, and
host grant tables, the server may also consult
the tables_priv and
columns_priv tables for requests that involve
tables. The latter tables provide finer privilege control at the
table and column levels. They have the columns shown in the
following table.
Table 4.3 tables_priv and columns_priv Table Columns
| Table Name | tables_priv | columns_priv |
|---|---|---|
| Scope columns | Host | Host |
Db | Db | |
User | User | |
Table_name | Table_name | |
Column_name | ||
| Privilege columns | Table_priv | Column_priv |
Column_priv | ||
| Other columns | Timestamp | Timestamp |
Grantor |
The Timestamp and Grantor
columns are set to the current timestamp and the
CURRENT_USER value, respectively,
but are otherwise unused.
For verification of requests that involve stored routines, the
server may consult the procs_priv table, which
has the columns shown in the following table.
Table 4.4 procs_priv Table Columns
| Table Name | procs_priv |
|---|---|
| Scope columns | Host |
Db | |
User | |
Routine_name | |
Routine_type | |
| Privilege columns | Proc_priv |
| Other columns | Timestamp |
Grantor |
The Routine_type column is an
ENUM column with values of
'FUNCTION' or 'PROCEDURE' to
indicate the type of routine the row refers to. This column
enables privileges to be granted separately for a function and a
procedure with the same name.
The Timestamp and Grantor
columns are unused.
The proxies_priv table was added in MySQL 5.5.7
and records information about proxy accounts. It has these
columns:
For an account to be able to grant the
PROXY privilege to other accounts,
it must have a row in the proxies_priv table
with With_grant set to 1 and
Proxied_host and
Proxied_user set to indicate the account or
accounts for which the privilege can be granted. For example, the
'root'@'localhost' account created during MySQL
installation has a row in the proxies_priv
table that enables granting the
PROXY privilege for
''@'', that is, for all users and all hosts.
This enables root to set up proxy users, as
well as to delegate to other accounts the authority to set up
proxy users. See Section 5.7, “Proxy Users”.
Scope columns in the grant tables contain strings. The default value for each is the empty string. The following table shows the number of characters permitted in each column.
Table 4.5 Grant Table Scope Column Lengths
| Column Name | Maximum Permitted Characters |
|---|---|
Host, Proxied_host | 60 |
User, Proxied_user | 16 |
Password | 41 |
Db | 64 |
Table_name | 64 |
Column_name | 64 |
Routine_name | 64 |
For access-checking purposes, comparisons of
User, Proxied_user,
Password, Db, and
Table_name values are case sensitive.
Comparisons of Host,
Proxied_host, Column_name,
and Routine_name values are not case sensitive.
The user, db, and
host tables list each privilege in a separate
column that is declared as ENUM('N','Y') DEFAULT
'N'. In other words, each privilege can be disabled or
enabled, with the default being disabled.
The tables_priv,
columns_priv, and procs_priv
tables declare the privilege columns as
SET columns. Values in these
columns can contain any combination of the privileges controlled
by the table. Only those privileges listed in the column value are
enabled.
Table 4.6 Set-Type Privilege Column Values
| Table Name | Column Name | Possible Set Elements |
|---|---|---|
tables_priv | Table_priv | 'Select', 'Insert', 'Update', 'Delete', 'Create', 'Drop',
'Grant', 'References', 'Index', 'Alter', 'Create View',
'Show view', 'Trigger' |
tables_priv | Column_priv | 'Select', 'Insert', 'Update', 'References' |
columns_priv | Column_priv | 'Select', 'Insert', 'Update', 'References' |
procs_priv | Proc_priv | 'Execute', 'Alter Routine', 'Grant' |
Only the user table specifies administrative
privileges, such as RELOAD and
SHUTDOWN. Administrative operations
are operations on the server itself and are not database-specific,
so there is no reason to list these privileges in the other grant
tables. Consequently, the server need consult only the
user table to determine whether a user can
perform an administrative operation.
The FILE privilege also is
specified only in the user table. It is not an
administrative privilege as such, but a user's ability to read or
write files on the server host is independent of the database
being accessed.
The server reads the contents of the grant tables into memory when
it starts. You can tell it to reload the tables by issuing a
FLUSH PRIVILEGES
statement or executing a mysqladmin
flush-privileges or mysqladmin reload
command. Changes to the grant tables take effect as indicated in
Section 4.6, “When Privilege Changes Take Effect”.
When you modify an account, it is a good idea to verify that your
changes have the intended effect. To check the privileges for a
given account, use the SHOW GRANTS
statement. For example, to determine the privileges that are
granted to an account with user name and host name values of
bob and pc84.example.com,
use this statement:
SHOW GRANTS FOR 'bob'@'pc84.example.com';
MySQL account names consist of a user name and a host name. This enables creation of accounts for users with the same name who can connect from different hosts. This section describes how to write account names, including special values and wildcard rules.
In SQL statements such as CREATE
USER, GRANT, and
SET PASSWORD, account names follow
these rules:
Account name syntax is
'.
user_name'@'host_name'
An account name consisting only of a user name is equivalent
to
'.
For example, user_name'@'%''me' is equivalent to
'me'@'%'.
The user name and host name need not be quoted if they are
legal as unquoted identifiers. Quotes are necessary to specify
a user_name string containing
special characters (such as space or -), or
a host_name string containing
special characters or wildcard characters (such as
. or %); for example,
'test-user'@'%.com'.
Quote user names and host names as identifiers or as strings,
using either backticks (`), single
quotation marks ('), or double quotation
marks ("). For string-quoting and
identifier-quoting guidelines, see
String Literals, and
Schema Object Names.
The user name and host name parts, if quoted, must be quoted
separately. That is, write
'me'@'localhost', not
'me@localhost'; the latter is actually
equivalent to 'me@localhost'@'%'.
A reference to the CURRENT_USER
or CURRENT_USER() function is
equivalent to specifying the current client's user name and
host name literally.
MySQL stores account names in grant tables in the
mysql system database using separate columns
for the user name and host name parts:
The user table contains one row for each
account. The User and
Host columns store the user name and host
name. This table also indicates which global privileges the
account has.
Other grant tables indicate privileges an account has for
databases and objects within databases. These tables have
User and Host columns to
store the account name. Each row in these tables associates
with the account in the user table that has
the same User and Host
values.
For access-checking purposes, comparisons of User values are case sensitive. Comparisons of Host values are not case sensitive.
For additional detail about grant table structure, see Section 4.2, “Grant Tables”.
User names and host names have certain special values or wildcard conventions, as described following.
The user name part of an account name is either a nonblank value
that literally matches the user name for incoming connection
attempts, or a blank value (empty string) that matches any user
name. An account with a blank user name is an anonymous user. To
specify an anonymous user in SQL statements, use a quoted empty
user name part, such as ''@'localhost'.
The host name part of an account name can take many forms, and wildcards are permitted:
A host value can be a host name or an IP address (IPv4 or
IPv6). The name 'localhost' indicates the
local host. The IP address '127.0.0.1'
indicates the IPv4 loopback interface. The IP address
'::1' indicates the IPv6 loopback
interface.
The % and _ wildcard
characters are permitted in host name or IP address values.
These have the same meaning as for pattern-matching operations
performed with the LIKE operator.
For example, a host value of '%' matches
any host name, whereas a value of
'%.mysql.com' matches any host in the
mysql.com domain.
'192.168.1.%' matches any host in the
192.168.1 class C network.
Because IP wildcard values are permitted in host values (for
example, '192.168.1.%' to match every host
on a subnet), someone could try to exploit this capability by
naming a host 192.168.1.somewhere.com. To
foil such attempts, MySQL does not perform matching on host
names that start with digits and a dot. For example, if a host
is named 1.2.example.com, its name never
matches the host part of account names. An IP wildcard value
can match only IP addresses, not host names.
For a host value specified as an IPv4 address, a netmask can be given to indicate how many address bits to use for the network number. Netmask notation cannot be used for IPv6 addresses.
The syntax is
.
For example:
host_ip/netmask
CREATE USER 'david'@'192.58.197.0/255.255.255.0';
This enables david to connect from any
client host having an IP address
client_ip for which the following
condition is true:
client_ip&netmask=host_ip
That is, for the CREATE USER
statement just shown:
client_ip & 255.255.255.0 = 192.58.197.0
IP addresses that satisfy this condition range from
192.58.197.0 to
192.58.197.255.
A netmask typically begins with bits set to 1, followed by bits set to 0. Examples:
192.0.0.0/255.0.0.0: Any host on the
192 class A network
192.168.0.0/255.255.0.0: Any host on
the 192.168 class B network
192.168.1.0/255.255.255.0: Any host on
the 192.168.1 class C network
192.168.1.1: Only the host with this
specific IP address
The server performs matching of host values in account names against the client host using the value returned by the system DNS resolver for the client host name or IP address. Except in the case that the account host value is specified using netmask notation, the server performs this comparison as a string match, even for an account host value given as an IP address. This means that you should specify account host values in the same format used by DNS. Here are examples of problems to watch out for:
Suppose that a host on the local network has a fully qualified
name of host1.example.com. If DNS returns
name lookups for this host as
host1.example.com, use that name in account
host values. If DNS returns just host1, use
host1 instead.
If DNS returns the IP address for a given host as
192.168.1.2, that will match an account
host value of 192.168.1.2 but not
192.168.01.2. Similarly, it will match an
account host pattern like 192.168.1.% but
not 192.168.01.%.
To avoid problems like these, it is advisable to check the format in which your DNS returns host names and addresses. Use values in the same format in MySQL account names.
When you attempt to connect to a MySQL server, the server accepts or rejects the connection based on your identity and whether you can verify your identity by supplying the correct password. If not, the server denies access to you completely. Otherwise, the server accepts the connection, and then enters Stage 2 and waits for requests.
Credential checking is performed using the three
user table scope columns
(Host, User, and
Password). The server accepts the connection
only if the Host and User
columns in some user table row match the client
host name and user name and the client supplies the password
specified in that row. The rules for permissible
Host and User values are
given in Section 4.3, “Specifying Account Names”.
Your identity is based on two pieces of information:
The client host from which you connect
Your MySQL user name
If the User column value is nonblank, the user
name in an incoming connection must match exactly. If the
User value is blank, it matches any user name.
If the user table row that matches an incoming
connection has a blank user name, the user is considered to be an
anonymous user with no name, not a user with the name that the
client actually specified. This means that a blank user name is
used for all further access checking for the duration of the
connection (that is, during Stage 2).
The Password column can be blank. This is not a
wildcard and does not mean that any password matches. It means
that the user must connect without specifying a password. If the
server authenticates a client using a plugin, the authentication
method that the plugin implements may or may not use the password
in the Password column. In this case, it is
possible that an external password is also used to authenticate to
the MySQL server.
Nonblank Password values in the
user table represent encrypted passwords. MySQL
does not store passwords in cleartext form for anyone to see.
Rather, the password supplied by a user who is attempting to
connect is encrypted (using the
PASSWORD() function). The encrypted
password then is used during the connection process when checking
whether the password is correct. This is done without the
encrypted password ever traveling over the connection. See
Section 5.1, “User Names and Passwords”.
From MySQL's point of view, the encrypted password is the
real password, so you should never give
anyone access to it. In particular, do not give
nonadministrative users read access to tables in the
mysql database.
The following table shows how various combinations of
User and Host values in the
user table apply to incoming connections.
User Value | Host Value | Permissible Connections |
|---|---|---|
'fred' | 'thomas.loc.gov' | fred, connecting from
thomas.loc.gov |
'' | 'thomas.loc.gov' | Any user, connecting from thomas.loc.gov |
'fred' | '%' | fred, connecting from any host |
'' | '%' | Any user, connecting from any host |
'fred' | '%.loc.gov' | fred, connecting from any host in the
loc.gov domain |
'fred' | 'x.y.%' | fred, connecting from x.y.net,
x.y.com, x.y.edu,
and so on; this is probably not useful |
'fred' | '192.168.10.177' | fred, connecting from the host with IP address
192.168.10.177 |
'fred' | '192.168.10.%' | fred, connecting from any host in the
192.168.10 class C subnet |
'fred' | '192.168.10.0/255.255.255.0' | Same as previous example |
It is possible for the client host name and user name of an
incoming connection to match more than one row in the
user table. The preceding set of examples
demonstrates this: Several of the entries shown match a connection
from thomas.loc.gov by fred.
When multiple matches are possible, the server must determine which of them to use. It resolves this issue as follows:
Whenever the server reads the user table
into memory, it sorts the rows.
When a client attempts to connect, the server looks through the rows in sorted order.
The server uses the first row that matches the client host name and user name.
The server uses sorting rules that order rows with the
most-specific Host values first. Literal host
names and IP addresses are the most specific. (The specificity of
a literal IP address is not affected by whether it has a netmask,
so 192.168.1.13 and
192.168.1.0/255.255.255.0 are considered
equally specific.) The pattern '%' means
“any host” and is least specific. The empty string
'' also means “any host” but sorts
after '%'. Rows with the same
Host value are ordered with the most-specific
User values first (a blank
User value means “any user” and is
least specific). For rows with equally-specific
Host and User values, the
order is indeterminate.
To see how this works, suppose that the user
table looks like this:
+-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+-
When the server reads the table into memory, it sorts the rows using the rules just described. The result after sorting looks like this:
+-----------+----------+- | Host | User | ... +-----------+----------+- | localhost | root | ... | localhost | | ... | % | jeffrey | ... | % | root | ... +-----------+----------+-
When a client attempts to connect, the server looks through the
sorted rows and uses the first match found. For a connection from
localhost by jeffrey, two of
the rows from the table match: the one with
Host and User values of
'localhost' and '', and the
one with values of '%' and
'jeffrey'. The 'localhost'
row appears first in sorted order, so that is the one the server
uses.
Here is another example. Suppose that the user
table looks like this:
+----------------+----------+- | Host | User | ... +----------------+----------+- | % | jeffrey | ... | thomas.loc.gov | | ... +----------------+----------+-
The sorted table looks like this:
+----------------+----------+- | Host | User | ... +----------------+----------+- | thomas.loc.gov | | ... | % | jeffrey | ... +----------------+----------+-
A connection by jeffrey from
thomas.loc.gov is matched by the first row,
whereas a connection by jeffrey from any host
is matched by the second.
It is a common misconception to think that, for a given user
name, all rows that explicitly name that user are used first
when the server attempts to find a match for the connection.
This is not true. The preceding example illustrates this, where
a connection from thomas.loc.gov by
jeffrey is first matched not by the row
containing 'jeffrey' as the
User column value, but by the row with no
user name. As a result, jeffrey is
authenticated as an anonymous user, even though he specified a
user name when connecting.
If you are able to connect to the server, but your privileges are
not what you expect, you probably are being authenticated as some
other account. To find out what account the server used to
authenticate you, use the
CURRENT_USER() function. (See
Information Functions.) It returns a value in
format that indicates the user_name@host_nameUser and
Host values from the matching
user table row. Suppose that
jeffrey connects and issues the following
query:
mysql> SELECT CURRENT_USER();
+----------------+
| CURRENT_USER() |
+----------------+
| @localhost |
+----------------+
The result shown here indicates that the matching
user table row had a blank
User column value. In other words, the server
is treating jeffrey as an anonymous user.
Another way to diagnose authentication problems is to print out
the user table and sort it by hand to see where
the first match is being made.
After you establish a connection, the server enters Stage 2 of
access control. For each request that you issue through that
connection, the server determines what operation you want to
perform, then checks whether you have sufficient privileges to do
so. This is where the privilege columns in the grant tables come
into play. These privileges can come from any of the
user, db,
host, tables_priv,
columns_priv, or procs_priv
tables. (You may find it helpful to refer to
Section 4.2, “Grant Tables”, which lists the columns present in
each of the grant tables.)
The user table grants privileges that are
assigned to you on a global basis and that apply no matter what
the default database is. For example, if the
user table grants you the
DELETE privilege, you can delete
rows from any table in any database on the server host! It is wise
to grant privileges in the user table only to
people who need them, such as database administrators. For other
users, you should leave all privileges in the
user table set to 'N' and
grant privileges at more specific levels only. You can grant
privileges for particular databases, tables, columns, or routines.
The db and host tables grant
database-specific privileges. Values in the scope columns of these
tables can take the following forms:
A blank User value in the
db table matches the anonymous user. A
nonblank value matches literally; there are no wildcards in
user names.
The wildcard characters % and
_ can be used in the
Host and Db columns of
either table. These have the same meaning as for
pattern-matching operations performed with the
LIKE operator. If you want to use
either character literally when granting privileges, you must
escape it with a backslash. For example, to include the
underscore character (_) as part of a
database name, specify it as \_ in the
GRANT statement.
A '%' Host value in the
db table means “any host.” A
blank Host value in the
db table means “consult the
host table for further information”
(a process that is described later in this section).
A '%' or blank Host
value in the host table means “any
host.”
A '%' or blank Db value
in either table means “any database.”
The server reads the db and
host tables into memory and sorts them at the
same time that it reads the user table. The
server sorts the db table based on the
Host, Db, and
User scope columns, and sorts the
host table based on the Host
and Db scope columns. As with the
user table, sorting puts the most-specific
values first and least-specific values last, and when the server
looks for matching rows, it uses the first match that it finds.
The tables_priv,
columns_priv, and procs_priv
tables grant table-specific, column-specific, and routine-specific
privileges. Values in the scope columns of these tables can take
the following forms:
The wildcard characters % and
_ can be used in the
Host column. These have the same meaning as
for pattern-matching operations performed with the
LIKE operator.
A '%' or blank Host
value means “any host.”
The Db, Table_name,
Column_name, and
Routine_name columns cannot contain
wildcards or be blank.
The server sorts the tables_priv,
columns_priv, and procs_priv
tables based on the Host,
Db, and User columns. This
is similar to db table sorting, but simpler
because only the Host column can contain
wildcards.
The server uses the sorted tables to verify each request that it
receives. For requests that require administrative privileges such
as SHUTDOWN or
RELOAD, the server checks only the
user table row because that is the only table
that specifies administrative privileges. The server grants access
if the row permits the requested operation and denies access
otherwise. For example, if you want to execute mysqladmin
shutdown but your user table row does
not grant the SHUTDOWN privilege to
you, the server denies access without even checking the
db or host tables. (They
contain no Shutdown_priv column, so there is no
need to do so.)
For database-related requests
(INSERT,
UPDATE, and so on), the server
first checks the user's global privileges by looking in the
user table row. If the row permits the
requested operation, access is granted. If the global privileges
in the user table are insufficient, the server
determines the user's database-specific privileges by checking the
db and host tables:
The server looks in the db table for a
match on the Host, Db,
and User columns. The
Host and User columns
are matched to the connecting user's host name and MySQL user
name. The Db column is matched to the
database that the user wants to access. If there is no row for
the Host and User,
access is denied.
If there is a matching db table row and its
Host column is not blank, that row defines
the user's database-specific privileges.
If the matching db table row's
Host column is blank, it signifies that the
host table enumerates which hosts should be
permitted access to the database. In this case, a further
lookup is done in the host table to find a
match on the Host and Db
columns. If no host table row matches,
access is denied. If there is a match, the user's
database-specific privileges are computed as the intersection
(not the union!) of the privileges in the
db and host table rows;
that is, the privileges that are 'Y' in
both rows. (This way you can grant general privileges in the
db table row and then selectively restrict
them on a host-by-host basis using the host
table rows.)
After determining the database-specific privileges granted by the
db and host table rows, the
server adds them to the global privileges granted by the
user table. If the result permits the requested
operation, access is granted. Otherwise, the server successively
checks the user's table and column privileges in the
tables_priv and columns_priv
tables, adds those to the user's privileges, and permits or denies
access based on the result. For stored-routine operations, the
server uses the procs_priv table rather than
tables_priv and
columns_priv.
Expressed in boolean terms, the preceding description of how a user's privileges are calculated may be summarized like this:
global privileges OR (database privileges AND host privileges) OR table privileges OR column privileges OR routine privileges
It may not be apparent why, if the global user
row privileges are initially found to be insufficient for the
requested operation, the server adds those privileges to the
database, table, and column privileges later. The reason is that a
request might require more than one type of privilege. For
example, if you execute an
INSERT INTO ...
SELECT statement, you need both the
INSERT and the
SELECT privileges. Your privileges
might be such that the user table row grants
one privilege and the db table row grants the
other. In this case, you have the necessary privileges to perform
the request, but the server cannot tell that from either table by
itself; the privileges granted by the rows in both tables must be
combined.
The host table is not affected by the
GRANT or
REVOKE statements, so it is unused
in most MySQL installations. If you modify it directly, you can
use it for some specialized purposes, such as to maintain a list
of secure servers on the local network that are granted all
privileges.
You can also use the host table to indicate
hosts that are not secure. Suppose that you
have a machine public.your.domain that is
located in a public area that you do not consider secure. You can
enable access to all hosts on your network except that machine by
using host table rows like this:
+--------------------+----+- | Host | Db | ... +--------------------+----+- | public.your.domain | % | ... (all privileges set to 'N') | %.your.domain | % | ... (all privileges set to 'Y') +--------------------+----+-
When mysqld starts, it reads all grant table contents into memory. The in-memory tables become effective for access control at that point.
If you modify the grant tables indirectly using account-management
statements such as GRANT,
REVOKE, SET
PASSWORD, or RENAME USER,
the server notices these changes and loads the grant tables into
memory again immediately.
If you modify the grant tables directly using statements such as
INSERT,
UPDATE, or
DELETE, your changes have no effect
on privilege checking until you either restart the server or tell
it to reload the tables. If you change the grant tables directly
but forget to reload them, your changes have no
effect until you restart the server. This may leave you
wondering why your changes seem to make no difference!
To tell the server to reload the grant tables, perform a
flush-privileges operation. This can be done by issuing a
FLUSH PRIVILEGES
statement or by executing a mysqladmin
flush-privileges or mysqladmin reload
command.
A grant table reload affects privileges for each existing client connection as follows:
Table and column privilege changes take effect with the client's next request.
Database privilege changes take effect the next time the
client executes a USE
statement.
db_name
Client applications may cache the database name; thus, this effect may not be visible to them without actually changing to a different database or flushing the privileges.
Global privileges and passwords are unaffected for a connected client. These changes take effect only for subsequent connections.
If the server is started with the
--skip-grant-tables option, it does
not read the grant tables or implement any access control. Anyone
can connect and do anything, which is
insecure. To cause a server thus started to read the
tables and enable access checking, flush the privileges.
If you encounter problems when you try to connect to the MySQL server, the following items describe some courses of action you can take to correct the problem.
Make sure that the server is running. If it is not, clients cannot connect to it. For example, if an attempt to connect to the server fails with a message such as one of those following, one cause might be that the server is not running:
shell>mysqlERROR 2003: Can't connect to MySQL server on 'host_name' (111) shell>mysqlERROR 2002: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
It might be that the server is running, but you are trying to
connect using a TCP/IP port, named pipe, or Unix socket file
different from the one on which the server is listening. To
correct this when you invoke a client program, specify a
--port option to indicate the
proper port number, or a
--socket option to indicate
the proper named pipe or Unix socket file. To find out where
the socket file is, you can use this command:
shell> netstat -ln | grep mysql
Make sure that the server has not been configured to ignore
network connections or (if you are attempting to connect
remotely) that it has not been configured to listen only
locally on its network interfaces. If the server was started
with --skip-networking, it will
not accept TCP/IP connections at all. If the server was
started with
--bind-address=127.0.0.1, it
will listen for TCP/IP connections only locally on the
loopback interface and will not accept remote connections.
Check to make sure that there is no firewall blocking access to MySQL. Your firewall may be configured on the basis of the application being executed, or the port number used by MySQL for communication (3306 by default). Under Linux or Unix, check your IP tables (or similar) configuration to ensure that the port has not been blocked. Under Windows, applications such as ZoneAlarm or the Windows XP personal firewall may need to be configured not to block the MySQL port.
The grant tables must be properly set up so that the server
can use them for access control. For some distribution types
(such as binary distributions on Windows, or RPM distributions
on Linux), the installation process initializes the MySQL data
directory, including the mysql database
containing the grant tables. For distributions that do not do
this, you must initialize the data directory manually. For
details, see Chapter 3, Postinstallation Setup and Testing.
To determine whether you need to initialize the grant tables,
look for a mysql directory under the data
directory. (The data directory normally is named
data or var and is
located under your MySQL installation directory.) Make sure
that you have a file named user.MYD in
the mysql database directory. If not,
initialize the data directory. After doing so and starting the
server, test the initial privileges by executing this command:
shell> mysql -u root
The server should let you connect without error.
After a fresh installation, you should connect to the server and set up your users and their access permissions:
shell> mysql -u root mysql
The server should let you connect because the MySQL
root user has no password initially. That
is also a security risk, so setting the password for the
root accounts is something you should do
while you're setting up your other MySQL accounts. For
instructions on setting the initial passwords, see
Section 3.4, “Securing the Initial MySQL Accounts”.
If you have updated an existing MySQL installation to a newer version, did you run the mysql_upgrade script? If not, do so. The structure of the grant tables changes occasionally when new capabilities are added, so after an upgrade you should always make sure that your tables have the current structure. For instructions, see mysql_upgrade — Check and Upgrade MySQL Tables.
If a client program receives the following error message when it tries to connect, it means that the server expects passwords in a newer format than the client is capable of generating:
shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
For information on how to deal with this, see Section 2.2.4, “Password Hashing in MySQL”, and Client does not support authentication protocol.
Remember that client programs use connection parameters
specified in option files or environment variables. If a
client program seems to be sending incorrect default
connection parameters when you have not specified them on the
command line, check any applicable option files and your
environment. For example, if you get Access
denied when you run a client without any options,
make sure that you have not specified an old password in any
of your option files!
You can suppress the use of option files by a client program
by invoking it with the
--no-defaults option. For
example:
shell> mysqladmin --no-defaults -u root version
The option files that clients use are listed in Using Option Files. Environment variables are listed in MySQL Program Environment Variables.
If you get the following error, it means that you are using an
incorrect root password:
shell> mysqladmin -u root -pxxxx ver
Access denied for user 'root'@'localhost' (using password: YES)
If the preceding error occurs even when you have not specified
a password, it means that you have an incorrect password
listed in some option file. Try the
--no-defaults option as
described in the previous item.
For information on changing passwords, see Section 5.5, “Assigning Account Passwords”.
If you have lost or forgotten the root
password, see How to Reset the Root Password.
If you change a password by using SET
PASSWORD, INSERT, or
UPDATE, you must encrypt the
password using the PASSWORD()
function. If you do not use
PASSWORD() for these
statements, the password will not work. For example, the
following statement assigns a password, but fails to encrypt
it, so the user is not able to connect afterward:
SET PASSWORD FOR 'abe'@'host_name' = 'eagle';
Instead, set the password like this:
SET PASSWORD FOR 'abe'@'host_name' = PASSWORD('eagle');
The PASSWORD() function is
unnecessary when you specify a password using the
CREATE USER or
GRANT statements or the
mysqladmin password command. Each of those
automatically uses PASSWORD()
to encrypt the password. See
Section 5.5, “Assigning Account Passwords”, and
CREATE USER Syntax.
localhost is a synonym for your local host
name, and is also the default host to which clients try to
connect if you specify no host explicitly.
You can use a --host=127.0.0.1
option to name the server host explicitly. This will make a
TCP/IP connection to the local mysqld
server. You can also use TCP/IP by specifying a
--host option that uses the
actual host name of the local host. In this case, the host
name must be specified in a user table row
on the server host, even though you are running the client
program on the same host as the server.
The Access denied error message tells you
who you are trying to log in as, the client host from which
you are trying to connect, and whether you were using a
password. Normally, you should have one row in the
user table that exactly matches the host
name and user name that were given in the error message. For
example, if you get an error message that contains
using password: NO, it means that you tried
to log in without a password.
If you get an Access denied error when
trying to connect to the database with mysql -u
, you may have a
problem with the user_nameuser table. Check this by
executing mysql -u root mysql and issuing
this SQL statement:
SELECT * FROM user;
The result should include a row with the
Host and User columns
matching your client's host name and your MySQL user name.
If the following error occurs when you try to connect from a
host other than the one on which the MySQL server is running,
it means that there is no row in the user
table with a Host value that matches the
client host:
Host ... is not allowed to connect to this MySQL server
You can fix this by setting up an account for the combination of client host name and user name that you are using when trying to connect.
If you do not know the IP address or host name of the machine
from which you are connecting, you should put a row with
'%' as the Host column
value in the user table. After trying to
connect from the client machine, use a SELECT
USER() query to see how you really did connect. Then
change the '%' in the
user table row to the actual host name that
shows up in the log. Otherwise, your system is left insecure
because it permits connections from any host for the given
user name.
On Linux, another reason that this error might occur is that
you are using a binary MySQL version that is compiled with a
different version of the glibc library than
the one you are using. In this case, you should either upgrade
your operating system or glibc, or download
a source distribution of MySQL version and compile it
yourself. A source RPM is normally trivial to compile and
install, so this is not a big problem.
If you specify a host name when trying to connect, but get an error message where the host name is not shown or is an IP address, it means that the MySQL server got an error when trying to resolve the IP address of the client host to a name:
shell> mysqladmin -u root -pxxxx -h some_hostname ver
Access denied for user 'root'@'' (using password: YES)
If you try to connect as root and get the
following error, it means that you do not have a row in the
user table with a User
column value of 'root' and that
mysqld cannot resolve the host name for
your client:
Access denied for user ''@'unknown'
These errors indicate a DNS problem. To fix it, execute mysqladmin flush-hosts to reset the internal DNS host cache. See DNS Lookup Optimization and the Host Cache.
Some permanent solutions are:
Determine what is wrong with your DNS server and fix it.
Specify IP addresses rather than host names in the MySQL grant tables.
Put an entry for the client machine name in
/etc/hosts on Unix or
\windows\hosts on Windows.
Start mysqld with the
--skip-name-resolve option.
Start mysqld with the
--skip-host-cache option.
On Unix, if you are running the server and the client on
the same machine, connect to localhost.
For connections to localhost, MySQL
programs attempt to connect to the local server by using a
Unix socket file, unless there are connection parameters
specified to ensure that the client makes a TCP/IP
connection. For more information, see
Connecting to the MySQL Server.
On Windows, if you are running the server and the client
on the same machine and the server supports named pipe
connections, connect to the host name .
(period). Connections to . use a named
pipe rather than TCP/IP.
If mysql -u root works but mysql
-h
results in your_hostname -u rootAccess denied (where
your_hostname is the actual host
name of the local host), you may not have the correct name for
your host in the user table. A common
problem here is that the Host value in the
user table row specifies an unqualified
host name, but your system's name resolution routines return a
fully qualified domain name (or vice versa). For example, if
you have a row with host 'pluto' in the
user table, but your DNS tells MySQL that
your host name is 'pluto.example.com', the
row does not work. Try adding a row to the
user table that contains the IP address of
your host as the Host column value.
(Alternatively, you could add a row to the
user table with a Host
value that contains a wildcard; for example,
'pluto.%'. However, use of
Host values ending with
% is insecure and is
not recommended!)
If mysql -u
works but
user_namemysql -u does not, you
have not granted access to the given user for the database
named user_name
some_dbsome_db.
If mysql -u
works when
executed on the server host, but user_namemysql -h
does not work
when executed on a remote client host, you have not enabled
access to the server for the given user name from the remote
host.
host_name -u
user_name
If you cannot figure out why you get Access
denied, remove from the user
table all rows that have Host values
containing wildcards (rows that contain '%'
or '_' characters). A very common error is
to insert a new row with
Host='%' and
User=',
thinking that this enables you to specify
some_user'localhost to connect from the same machine.
The reason that this does not work is that the default
privileges include a row with
Host='localhost' and
User=''. Because that
row has a Host value
'localhost' that is more specific than
'%', it is used in preference to the new
row when connecting from localhost! The
correct procedure is to insert a second row with
Host='localhost' and
User=',
or to delete the row with
some_user'Host='localhost' and
User=''. After deleting
the row, remember to issue a
FLUSH
PRIVILEGES statement to reload the grant tables. See
also Section 4.4, “Access Control, Stage 1: Connection Verification”.
If you are able to connect to the MySQL server, but get an
Access denied message whenever you issue a
SELECT ... INTO
OUTFILE or
LOAD DATA
INFILE statement, your row in the
user table does not have the
FILE privilege enabled.
If you change the grant tables directly (for example, by using
INSERT,
UPDATE, or
DELETE statements) and your
changes seem to be ignored, remember that you must execute a
FLUSH
PRIVILEGES statement or a mysqladmin
flush-privileges command to cause the server to
reload the privilege tables. Otherwise, your changes have no
effect until the next time the server is restarted. Remember
that after you change the root password
with an UPDATE statement, you
will not need to specify the new password until after you
flush the privileges, because the server will not know you've
changed the password yet!
If your privileges seem to have changed in the middle of a session, it may be that a MySQL administrator has changed them. Reloading the grant tables affects new client connections, but it also affects existing connections as indicated in Section 4.6, “When Privilege Changes Take Effect”.
If you have access problems with a Perl, PHP, Python, or ODBC
program, try to connect to the server with mysql -u
or user_name
db_namemysql
-u . If you are able
to connect using the mysql client, the
problem lies with your program, not with the access
privileges. (There is no space between user_name
-pyour_pass
db_name-p and
the password; you can also use the
--password=
syntax to specify the password. If you use the
your_pass-p or
--password option with no
password value, MySQL prompts you for the password.)
For testing purposes, start the mysqld
server with the
--skip-grant-tables option.
Then you can change the MySQL grant tables and use the
mysqlaccess script to check whether your
modifications have the desired effect. When you are satisfied
with your changes, execute mysqladmin
flush-privileges to tell the
mysqld server to reload the privileges.
This enables you to begin using the new grant table contents
without stopping and restarting the server.
If you get the following error, you may have a problem with
the db or host table:
Access to database denied
If the row selected from the db table has
an empty value in the Host column, make
sure that there are one or more corresponding rows in the
host table specifying which hosts the
db table row applies to. This problem
occurs infrequently because the host table
is rarely used.
If everything else fails, start the mysqld
server with a debugging option (for example,
--debug=d,general,query). This
prints host and user information about attempted connections,
as well as information about each command issued. See
The DBUG Package.
If you have any other problems with the MySQL grant tables and
feel you must post the problem to the mailing list, always
provide a dump of the MySQL grant tables. You can dump the
tables with the mysqldump mysql command. To
file a bug report, see the instructions at
How to Report Bugs or Problems. In some cases, you may need to
restart mysqld with
--skip-grant-tables to run
mysqldump.