Chapter 5 Initializing the Data Directory

Table of Contents

5.1 Initializing the Data Directory Manually Using mysqld
5.2 Initializing the Data Directory Manually Using mysql_install_db
5.3 Problems Running mysql_install_db

After installing MySQL, you must initialize the data directory, including the tables in the mysql system database. For some MySQL installation methods, data directory initialization may be done automatically, as described in Postinstallation Setup and Testing. For other installation methods, including installation from generic binary and source distributions, you must initialize the data directory yourself.

This section describes how to initialize the data directory on Unix and Unix-like systems. (For Windows, see Windows Postinstallation Procedures.) For some suggested commands that you can use to test whether the server is accessible and working properly, see Testing the Server.

In the examples shown here, the server runs under the user ID of the mysql login account. This assumes that such an account exists. Either create the account if it does not exist, or substitute the name of a different existing login account that you plan to use for running the server. For information about creating the account, see Creating a mysql System User and Group, in Chapter 1, Installing MySQL on Unix/Linux Using Generic Binaries.

  1. Change location into the top-level directory of your MySQL installation, represented here by BASEDIR:

    shell> cd BASEDIR
    

    BASEDIR is likely to be something like /usr/local/mysql or /usr/local. The following steps assume that you have changed location to this directory.

    You will find several files and subdirectories in the BASEDIR directory. The most important for installation purposes are the bin and scripts subdirectories, which contain the server as well as client and utility programs.

  2. Create a directory that provides a location to use as the value of the secure_file_priv system variable that limits import/export operations to a specific directory. See Server System Variables.

    shell> mkdir mysql-files
    shell> chmod 750 mysql-files
    
  3. If necessary, ensure that the distribution contents are accessible to mysql. If you installed the distribution as mysql, no further action is required. If you installed the distribution as root, its contents will be owned by root. Change its ownership to mysql by executing the following commands as root in the installation directory. The first command changes the owner attribute of the files to the mysql user. The second changes the group attribute to the mysql group.

    shell> chown -R mysql .
    shell> chgrp -R mysql .
    
  4. If necessary, initialize the data directory, including the mysql database containing the initial MySQL grant tables that determine how users are permitted to connect to the server.

    Typically, data directory initialization need be done only the first time you install MySQL. If you are upgrading an existing installation, you should run mysql_upgrade instead (see mysql_upgrade — Check and Upgrade MySQL Tables). However, the command that initializes the data directory does not overwrite any existing privilege tables, so it should be safe to run in any circumstances.

    As of MySQL 5.7.6, use the server to initialize the data directory:

    shell> bin/mysqld --initialize --user=mysql
    

    Before MySQL 5.7.6, use mysql_install_db:

    shell> bin/mysql_install_db --user=mysql
    

    For more information, see Section 5.1, “Initializing the Data Directory Manually Using mysqld”, or Section 5.2, “Initializing the Data Directory Manually Using mysql_install_db”, depending on which command you use.

  5. If you want the server to be able to deploy with automatic support for secure connections, use the mysql_ssl_rsa_setup utility to create default SSL and RSA files:

    shell> mysql_ssl_rsa_setup
    

    For more information, see mysql_ssl_rsa_setup — Create SSL/RSA Files.

  6. After initializing the data directory, you can establish the final installation ownership settings. To leave the installation owned by mysql, no action is required here. Otherwise, most of the MySQL installation can be owned by root if you like. The exception is that the data directory and the mysql-files directory must be owned by mysql. To accomplish this, run the following commands as root in the installation directory. For some distribution types, the data directory might be named var rather than data; adjust the second command accordingly.

    shell> chown -R root .
    shell> chown -R mysql data mysql-files
    

    If the plugin directory (the directory named by the plugin_dir system variable) is writable by the server, it may be possible for a user to write executable code to a file in the directory using SELECT ... INTO DUMPFILE. This can be prevented by making the plugin directory read only to the server or by setting the secure_file_priv system variable at server startup to a directory where SELECT writes can be performed safely. (For example, set it to the mysql-files directory created earlier.)

  7. To specify options that the MySQL server should use at startup, put them in a /etc/my.cnf or /etc/mysql/my.cnf file. You can use such a file, for example, to set the secure_file_priv system variable. See Server Configuration Defaults. If you do not do this, the server starts with its default settings.

  8. If you want MySQL to start automatically when you boot your machine, see Starting and Stopping MySQL Automatically.

Data directory initialization creates time zone tables in the mysql database but does not populate them. To do so, use the instructions in MySQL Server Time Zone Support.

5.1 Initializing the Data Directory Manually Using mysqld

This section describes how to initialize the data directory using mysqld, the MySQL server.

Note

The procedure described here is available for all platforms as of MySQL 5.7.6. Prior to 5.7.6, use mysql_install_db on Unix and Unix-like systems (see Section 5.2, “Initializing the Data Directory Manually Using mysql_install_db”). Prior to MySQL 5.7.7, Windows distributions include a data directory with prebuilt tables in the mysql database.

The following instructions assume that your current location is the MySQL installation directory, represented here by BASEDIR:

shell> cd BASEDIR

To initialize the data directory, invoke mysqld with the --initialize or --initialize-insecure option, depending on whether you want the server to generate a random initial password for the 'root'@'localhost' account.

On Windows, use one of these commands:

C:\> bin\mysqld --initialize
C:\> bin\mysqld --initialize-insecure

On Unix and Unix-like systems, it is important to make sure that the database directories and files are owned by the mysql login account so that the server has read and write access to them when you run it later. To ensure this, run mysqld as root and include the --user option as shown here:

shell> bin/mysqld --initialize --user=mysql
shell> bin/mysqld --initialize-insecure --user=mysql

Otherwise, execute the program while logged in as mysql, in which case you can omit the --user option from the command.

Regardless of platform, use --initialize for secure by default installation (that is, including generation of a random initial root password). In this case, the password is marked as expired and you will need to choose a new one. With the --initialize-insecure option, no root password is generated; it is assumed that you will assign a password to the account in timely fashion before putting the server into production use.

It might be necessary to specify other options such as --basedir or --datadir if mysqld does not identify the correct locations for the installation directory or data directory. For example (enter the command on one line):

shell> bin/mysqld --initialize --user=mysql
         --basedir=/opt/mysql/mysql
         --datadir=/opt/mysql/mysql/data

Alternatively, put the relevant option settings in an option file and pass the name of that file to mysqld. For Unix and Unix-like systems, suppose that the option file name is /opt/mysql/mysql/etc/my.cnf. Put these lines in the file:

[mysqld]
basedir=/opt/mysql/mysql
datadir=/opt/mysql/mysql/data

Then invoke mysqld as follows (enter the command on a single line with the --defaults-file option first):

shell> bin/mysqld --defaults-file=/opt/mysql/mysql/etc/my.cnf
         --initialize --user=mysql

On Windows, suppose that C:\my.ini contains these lines:

[mysqld]
basedir=C:\\Program Files\\MySQL\\MySQL Server 5.7
datadir=D:\\MySQLdata

Then invoke mysqld as follows (the --defaults-file option must be first):

C:\> bin/mysqld --defaults-file=C:\my.ini --initialize

When invoked with the --initialize or --initialize-insecure option, mysqld performs the following initialization sequence.

Note

The server writes any messages to its standard error output. This may be redirected to the error log, so look there if you do not see the messages on your screen. For information about the error log, including where it is located, see The Error Log.

On Windows, use the --console option to direct messages to the console.

  1. The server checks for the existence of the data directory as follows:

    • If no data directory exists, the server creates it.

    • If a data directory exists and is not empty (that is, it contains files or subdirectories), the server exits after producing an error message:

      [ERROR] --initialize specified but the data directory exists. Aborting.
      

      In this case, remove or rename the data directory and try again.

      As of MySQL 5.7.11, an existing data directory is permitted to be nonempty if every entry either has a name that begins with a period (.) or is named using an --ignore-db-dir option.

  2. Within the data directory, the server creates the mysql system database and its tables, including the grant tables, server-side help tables, and time zone tables. For a complete listing and description of the grant tables, see The MySQL Access Privilege System.

  3. The server initializes the system tablespace and related data structures needed to manage InnoDB tables.

    Note

    After mysqld sets up the InnoDB system tablespace, changes to some tablespace characteristics require setting up a whole new instance. This includes the file name of the first file in the system tablespace and the number of undo logs. If you do not want to use the default values, make sure that the settings for the innodb_data_file_path and innodb_log_file_size configuration parameters are in place in the MySQL configuration file before running mysqld. Also make sure to specify as necessary other parameters that affect the creation and location of InnoDB files, such as innodb_data_home_dir and innodb_log_group_home_dir.

    If those options are in your configuration file but that file is not in a location that MySQL reads by default, specify the file location using the --defaults-extra-file option when you run mysqld.

  4. The server creates a 'root'@'localhost' superuser account. The server's action with respect to a password for this account depends on how you invoke it:

    • With --initialize but not --initialize-insecure, the server generates a random password, marks it as expired, and writes a message displaying the password:

      [Warning] A temporary password is generated for root@localhost:
      iTag*AfrH5ej
      
    • With --initialize-insecure, (either with or without --initialize because --initialize-insecure implies --initialize), the server does not generate a password or mark it expired, and writes a warning message:

      Warning] root@localhost is created with an empty password ! Please
      consider switching off the --initialize-insecure option.
      
  5. The server populates the server-side help tables if content is available (in the fill_help_tables.sql file). The server does not populate the time zone tables; to do so, see MySQL Server Time Zone Support.

  6. If the --init-file option was given to name a file of SQL statements, the server executes the statements in the file. This option enables you to perform custom bootstrapping sequences.

    When the server operates in bootstrap mode, some functionality is unavailable that limits the statements permitted in the file. These include statements that relate to account management (such as CREATE USER or GRANT), replication, and global transaction identifiers.

  7. The server exits.

After you initialize the data directory by starting the server with --initialize or --initialize-insecure, start the server normally (that is, without either of those options) and assign the 'root'@'localhost' account a new password:

  1. Start the server. For instructions, see Starting the Server.

  2. Connect to the server:

    • If you used --initialize but not --initialize-insecure to initialize the data directory, connect to the server as root using the random password that the server generated during the initialization sequence:

      shell> mysql -u root -p
      Enter password: (enter the random root password here)
      

      Look in the server error log if you do not know this password.

    • If you used --initialize-insecure to initialize the data directory, connect to the server as root without a password:

      shell> mysql -u root --skip-password
      
  3. After connecting, assign a new root password:

    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
    
Note

The data directory initialization sequence performed by the server does not substitute for the actions performed by mysql_secure_installation or mysql_ssl_rsa_setup. See mysql_secure_installation — Improve MySQL Installation Security, and mysql_ssl_rsa_setup — Create SSL/RSA Files.

5.2 Initializing the Data Directory Manually Using mysql_install_db

This section describes how to initialize the data directory using mysql_install_db.

Note

The procedure described here is used on Unix and Unix-like systems prior to MySQL 5.7.6. (For Windows, MySQL distributions include a data directory with prebuilt tables in the mysql database.) As of MySQL 5.7.6, mysql_install_db is deprecated. To initialize the data directory, use the procedure described at Section 5.1, “Initializing the Data Directory Manually Using mysqld”.

The following instructions assume that your current location is the MySQL installation directory, represented here by BASEDIR:

shell> cd BASEDIR

To initialize the data directory, invoke mysql_install_db. This program might be located under the base directory in either bin or scripts, depending on your version of MySQL. If it is in scripts, adjust the following commands appropriately.

shell> bin/mysql_install_db --user=mysql

It is important to make sure that the database directories and files are owned by the mysql login account so that the server has read and write access to them when you run it later. To ensure this, run mysql_install_db as root and include the --user option as shown. Otherwise, execute the program while logged in as mysql, in which case you can omit the --user option from the command.

The mysql_install_db command creates the server's data directory. Under the data directory, it creates directories for the mysql database that holds the grant tables and (prior to MySQL 5.7.4) a test database that you can use to test MySQL. The program also creates privilege table entries for the initial account or accounts. For a complete listing and description of the grant tables, see The MySQL Access Privilege System.

It might be necessary to specify other options such as --basedir or --datadir if mysql_install_db does not identify the correct locations for the installation directory or data directory. For example:

shell> bin/mysql_install_db --user=mysql \
         --basedir=/opt/mysql/mysql \
         --datadir=/opt/mysql/mysql/data

If mysql_install_db generates a random password for the root account, start the server and assign a new password:

  1. Start the server (use the first command if your installation includes mysqld_safe, the second it if includes systemd support):

    shell> bin/mysqld_safe --user=mysql &
    shell> systemctl start mysqld
    

    Substitute the appropriate service name if it differs from mysqld; for example, mysql on SLES systems.

  2. Look in the $HOME/.mysql_secret file to find the random password that mysql_install_db wrote there. Then connect to the server as root using that password:

    shell> mysql -u root -h 127.0.0.1 -p
    Enter password: (enter the random password here)
    
  3. After connecting, assign a new root password:

    mysql> SET PASSWORD FOR 'root'@'localhost' = PASSWORD('new_password');
    

    After resetting the password, remove the .mysql_secret file; otherwise, if you run mysql_secure_installation, that command may see the file and expire the root password again as part of ensuring secure deployment.

If mysql_install_db did not generate a random password, you should still assign one. For instructions, see Securing the Initial MySQL Accounts. That section also describes how to remove the test database, if mysql_install_db created one and you do not want it.

If you have trouble with mysql_install_db at this point, see Section 5.3, “Problems Running mysql_install_db”.

5.3 Problems Running mysql_install_db

The purpose of the mysql_install_db program is to initialize the data directory, including the tables in the mysql system database. It does not overwrite existing MySQL privilege tables, and it does not affect any other data.

To re-create your privilege tables, first stop the mysqld server if it is running. Then rename the mysql directory under the data directory to save it, and run mysql_install_db. Suppose that your current directory is the MySQL installation directory and that mysql_install_db is located in the bin directory and the data directory is named data. To rename the mysql database and re-run mysql_install_db, use these commands.

shell> mv data/mysql data/mysql.old
shell> bin/mysql_install_db --user=mysql

When you run mysql_install_db, you might encounter the following problems:

  • mysql_install_db fails to install the grant tables

    You may find that mysql_install_db fails to install the grant tables and terminates after displaying the following messages:

    Starting mysqld daemon with databases from XXXXXX
    mysqld ended
    

    In this case, you should examine the error log file very carefully. The log should be located in the directory XXXXXX named by the error message and should indicate why mysqld did not start. If you do not understand what happened, include the log when you post a bug report. See How to Report Bugs or Problems.

  • There is a mysqld process running

    This indicates that the server is running, in which case the grant tables have probably been created already. If so, there is no need to run mysql_install_db at all because it needs to be run only once, when you first install MySQL.

  • Installing a second mysqld server does not work when one server is running

    This can happen when you have an existing MySQL installation, but want to put a new installation in a different location. For example, you might have a production installation, but you want to create a second installation for testing purposes. Generally the problem that occurs when you try to run a second server is that it tries to use a network interface that is in use by the first server. In this case, you should see one of the following error messages:

    Can't start server: Bind on TCP/IP port:
    Address already in use
    Can't start server: Bind on unix socket...
    

    For instructions on setting up multiple servers, see Running Multiple MySQL Instances on One Machine.

  • You do not have write access to the /tmp directory

    If you do not have write access to create temporary files or a Unix socket file in the default location (the /tmp directory) or the TMPDIR environment variable, if it has been set, an error occurs when you run mysql_install_db or the mysqld server.

    You can specify different locations for the temporary directory and Unix socket file by executing these commands prior to starting mysql_install_db or mysqld, where some_tmp_dir is the full path name to some directory for which you have write permission:

    shell> TMPDIR=/some_tmp_dir/
    shell> MYSQL_UNIX_PORT=/some_tmp_dir/mysql.sock
    shell> export TMPDIR MYSQL_UNIX_PORT
    

    Then you should be able to run mysql_install_db and start the server with these commands:

    shell> bin/mysql_install_db --user=mysql
    shell> bin/mysqld_safe --user=mysql &
    

    See How to Protect or Change the MySQL Unix Socket File, and Environment Variables.

There are some alternatives to running the mysql_install_db program provided in the MySQL distribution:

  • If you want the initial privileges to be different from the standard defaults, use account-management statements such as CREATE USER, GRANT, and REVOKE to change the privileges after the grant tables have been set up. In other words, run mysql_install_db, and then use mysql -u root mysql to connect to the server as the MySQL root user so that you can issue the necessary statements. (See Account Management Statements.)

    To install MySQL on several machines with the same privileges, put the CREATE USER, GRANT, and REVOKE statements in a file and execute the file as a script using mysql after running mysql_install_db. For example:

    shell> bin/mysql_install_db --user=mysql
    shell> bin/mysql -u root < your_script_file
    

    This enables you to avoid issuing the statements manually on each machine.

  • It is possible to re-create the grant tables completely after they have previously been created. You might want to do this if you are just learning how to use CREATE USER, GRANT, and REVOKE and have made so many modifications after running mysql_install_db that you want to wipe out the tables and start over.

    To re-create the grant tables, stop the server if it is running and remove the mysql database directory. Then run mysql_install_db again.