MySQL 有关用户密码




  • MySQL 介绍

    MySQL 是由Oracle Corporation 开发和发行的最流行的数据库管理系统。MySQL 网站地址为: www.mysql.com,提供最新的MySQL软件包及相关工具的下载。MySQL 是一个数据库管理系统,数据库是由数据的集合构成。MySQL 是关系型数据库,关系型数据库存储数据在单独的一系列表中,而不是将数据存储在一个大的存储空间中。数据库的结构是被组织在快速的优化后的物理文件中。逻辑模型和对象如数据库、表、视图、行和列,提供了灵活的编程环境。MySQL 的 SQL 部分是标准的 "Structured Query Language"。SQL 是用来访问数据库的最标准的语言。当然,取决于你的编程环境。

    安装

    MySQL 使用 rpm 或者 yum 方式安装将会自动创建一个 mysql 普通操作系统用户。在当前 redhat 家族操作系统中,已经不再提供 mysql 安装包了,如果使用 yum 方式安装,需要自己手动创建一个 mysql 仓库。yum 安装的好处在于自动解决依赖。以下是使用 yum 安装的过程:

    复制代码
    #创建归档包路径 /opt/software 和解包后存放文件路径 /mnt/mysql
    [root@node01 ~]# mkdir -p /opt/software  /mnt/mysql
    
    #上传已下载的 MySQL 包到 /opt/software 目录下
    [root@node01 ~]# cd /opt/software/
    [root@node01 software]# ls
    mysql-5.7.34-1.el7.x86_64.rpm-bundle.tar
    
    #解包到 /mnt目录下的 mysql 目录
    [root@node01 ~]# tar -xf /opt/software/mysql-5.7.34-1.el7.x86_64.rpm-bundle.tar -C /mnt/mysql/
    
    #删除安装包归档文件 mysql-5.7.34-1.el7.x86_64.rpm-bundle.tar
    [root@node01 ~]# ls /mnt/mysql/
    mysql-community-client-5.7.34-1.el7.x86_64.rpm
    mysql-community-common-5.7.34-1.el7.x86_64.rpm
    mysql-community-devel-5.7.34-1.el7.x86_64.rpm
    mysql-community-embedded-5.7.34-1.el7.x86_64.rpm
    mysql-community-embedded-compat-5.7.34-1.el7.x86_64.rpm
    mysql-community-embedded-devel-5.7.34-1.el7.x86_64.rpm
    mysql-community-libs-5.7.34-1.el7.x86_64.rpm
    mysql-community-libs-compat-5.7.34-1.el7.x86_64.rpm
    mysql-community-server-5.7.34-1.el7.x86_64.rpm
    mysql-community-test-5.7.34-1.el7.x86_64.rpm
    
    #安装 createrepo
    #该命令是用来生成 rpm 包元数据仓库的命令工具
    [root@node01 ~]# yum install -y createrepo
    
    #使用 createrepo 生成元数据仓库信息
    [root@node01 ~]# createrepo  /mnt/mysql/ #创建的快慢取决于你的CPU核心数
    
    #配置 mysql yum 仓库
    [root@node01 ~]# cat >/etc/yum.repos.d/mysql.repo<<EOF
    [mysql]
    name=mysql
    baseurl=file:///mnt/mysql
    enabled=1
    gpgcheck=0
    EOF
    [root@node01 ~]# cat /etc/yum.repos.d/mysql.repo 
    [mysql]
    name=mysql
    baseurl=file:///mnt/mysql
    enabled=1
    gpgcheck=0
    
    #查看已经配置好的 mysql 仓库
    [root@node01 ~]# yum repolist enabled | grep mysql
    mysql                   mysql                                                 10
    
    #安装 mysql-community-server
    [root@node01 ~]# yum install -y mysql-community-server
    
    #验证
    [root@node01 ~]# rpm -ql mysql-community-server | wc -l
    150
    
    #修改配置文件内容如下
    [root@node01 ~]# cat /etc/my.cnf
    [mysqld]
    datadir=/data1/mysqldata
    socket=/data1/mysql/mysql.sock
    symbolic-links=0
    log-error=/data1/log/mysqld.log
    pid-file=/data1/mysqld/mysqld.pid
    
    #创建配置文件中需要的目录并授权
    [root@node01 ~]# mkdir -p /data1/{mysql/log,mysqldata,log,mysqld}
    [root@node01 mysql]# ll /data1/
    total 0
    drwxr-xr-x. 2 root root  6 Aug 13 15:49 log
    drwxr-xr-x. 3 root root 17 Aug 13 15:49 mysql
    drwxr-xr-x. 2 root root  6 Aug 13 15:49 mysqld
    drwxr-xr-x. 2 root root  6 Aug 13 15:49 mysqldata
    
    
    [root@node01 ~]# chown mysql.mysql -R /data1/
    
    #服务启动配置文件
    [root@node01 ~]# egrep -v "^$|^#" /usr/lib/systemd/system/mysqld.service
    [Unit]
    Description=MySQL Server
    Documentation=man:mysqld(8)
    Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
    After=network.target
    After=syslog.target
    [Install]
    WantedBy=multi-user.target
    [Service]
    User=mysql
    Group=mysql
    Type=forking
    PIDFile=/data1/mysqld/mysqld.pid
    TimeoutSec=0
    PermissionsStartOnly=true
    ExecStartPre=/usr/bin/mysqld_pre_systemd
    ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/data1/mysqld/mysqld.pid $MYSQLD_OPTS
    EnvironmentFile=-/etc/sysconfig/mysql
    LimitNOFILE = 5000
    Restart=on-failure
    RestartPreventExitStatus=1
    PrivateTmp=false
    
    #加载配置文件
    [root@node01 ~]# systemctl  daemon-reload
    
    #启动 mysql 服务(该过程将会自动初始化数据库集群并生成临时用户登录密码)
    [root@node01 ~]# systemctl  status mysqld
    ● mysqld.service - MySQL Server
       Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
       Active: active (running) since Fri 2021-08-13 15:56:33 CST; 4s ago
         Docs: man:mysqld(8)
               http://dev.mysql.com/doc/refman/en/using-systemd.html
      Process: 4237 ExecStart=/usr/sbin/mysqld --daemonize --pid-file=/data1/mysqld/mysqld.pid $MYSQLD_OPTS (code=exited, status=0/SUCCESS)
      Process: 4188 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
     Main PID: 4240 (mysqld)
       CGroup: /system.slice/mysqld.service
               └─4240 /usr/sbin/mysqld --daemonize --pid-file=/data1/mysqld/mysqld.pid
    
    Aug 13 15:56:29 node01 systemd[1]: Starting MySQL Server...
    Aug 13 15:56:33 node01 systemd[1]: Started MySQL Server.
    复制代码

     

    首次登录

    首次登录需要使用密码,当然也可以通过 skip-grant-tables 选项来跳过密码登录。在首次启动 MySQL 数据库后,将会生成一个临时密码。临时密码位于日志文件中,默认的日志文件是 /var/log/mysqld.log ,这里在配置文件 /etc/my.cnf 中指定的是 /data1/log/mysqld.log

    复制代码
    [root@node01 ~]# cat /data1/log/mysqld.log  | grep password | awk  '{print $NF}' 
    _rDRCIajo3D.
    
    #使用上面输出的密码来登录(由于 socket 路径已变更,因此需要特殊指定 socket 文件的路径)
    [root@node01 ~]# mysql -uroot -p -S /data1/mysql/mysql.sock
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.34
    
    Copyright (c) 2000, 2021, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql> show databases;
    ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
    
    #可以看到由于第一次登录,需要修改密码才能使用数据库
    mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@123';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | sys                |
    +--------------------+
    4 rows in set (0.00 sec)
    复制代码

     

    用户密码

    在 MySQL 中,密码采用 hash 方式加密。密码表为 mysql 数据库下的 user,也叫授权表。每个用户都对应一个密码, user 表不以明文的方式存储密码,存储的是明文进行hash运算后的哈希值,表中存储密码的字段为 authentication_string。如下:

    复制代码
    --生成的密码 hash 值
    mysql>SELECT
        PASSWORD('MySQL@123')
    ;
    +-------------------------------------------+
    | password('MySQL@123')                     |
    +-------------------------------------------+
    | *42D97F0078E96A9A0589554CCEB3E1E095B7DF69 |
    +-------------------------------------------+
    1 row in set, 1 warning (0.00 sec)
    
    --user 表中存储的 hash 值
    mysql>SELECT
        AUTHENTICATION_STRING
    FROM
        MYSQL.USER
    WHERE
        USER    =   'root'
    AND HOST    =   'localhost'
    ;
    +-------------------------------------------+
    | authentication_string                     |
    +-------------------------------------------+
    | *42D97F0078E96A9A0589554CCEB3E1E095B7DF69 |
    +-------------------------------------------+
    1 row in set (0.00 sec)
    复制代码

     

    忘记密码后的解决方法

    跳过授权表

    在实际使用过程中,有可能会出现忘记密码的问题,如果在 MySQL 中忘记了密码,该如何处理呢?
    通过跳过密码授权表的方式可以免密登录到数据库中,但是需要重新启动数据库。可以在 mysqld.service 服务启动配置文件中添加参数 --skip-grant-tables ,也可以通过在 my.cnf 模块 [mysqld] 中添加 skip-grant-tables 的方式跳过密码表,我们以后一种方式进行配置。如下:

    复制代码
    #停止数据库
    [root@node01 ~]# systemctl  stop mysqld
    
    #在 /etc/my.cnf 中添加 skip-grant-tables
    [root@node01 ~]# cat /etc/my.cnf
    [mysqld]
    skip-grant-tables
    datadir=/data1/mysqldata
    socket=/data1/mysql/mysql.sock
    symbolic-links=0
    log-error=/data1/log/mysqld.log
    pid-file=/data1/mysqld/mysqld.pid
    
    #重新启动数据库
    [root@node01 ~]# systemctl  start mysqld
    [root@node01 ~]# systemctl  status mysqld | grep running
       Active: active (running) since Fri 2021-08-13 16:33:40 CST; 13s ago
    
    
    #登录数据库
    [root@node01 ~]# mysql -uroot -p -S /data1/mysql/mysql.sock
    Enter password: (此处只需要再按一次回车键即可,而不需要输入密码)
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.34 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2021, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    复制代码

     

    但是通过 skip-grant-tables 跳过授权表,需要注意一些问题,只要通过该方式登录到数据库,并执行了 flush privileges 或者使用 **mysqladmin flush-privileges **命令后,退出后,再次登录必须要使用密码才能登录,如果想再次通过以跳过密码的方式登录,必须重新启动数据库。

    通过该方式登录到数据库,是无法通过 ALTER USER 的方式修改密码的,如下:

    mysql> ALTER USER 'root'@'localhsot' IDENTIFIED BY 'MySQL@123';
    ERROR 1290 (HY000): The MySQL server is running with the --skip-grant-tables option so it cannot execute this statement

     

    更新密码表

    既然无法通过 ALTER USER 命令行的方式修改密码,那么只能采用更新密码授权表 user 中的 authentication_string 字段来更新密码,如下:

    复制代码
    mysql> UPDATE
        MYSQL.USER
    SET
        AUTHENTICATION_STRING   =PASSWORD('NewPass@123')
    WHERE
        USER    =   'root'
    AND HOST    =   'localhost'
    ;
    Query OK, 1 row affected, 1 warning (0.00 sec)
    Rows matched: 1  Changed: 1  Warnings: 1
    
    mysql> show warnings;
    +---------+------+-------------------------------------------------------------------+
    | Level   | Code | Message                                                           |
    +---------+------+-------------------------------------------------------------------+
    | Warning | 1681 | 'PASSWORD' is deprecated and will be removed in a future release. |
    +---------+------+-------------------------------------------------------------------+
    1 row in set (0.00 sec)
    
    #查看新密码
    mysql>SELECT
        AUTHENTICATION_STRING
    FROM
    USER
    WHERE
        USER    =   'root'
    AND HOST    =   'localhost'
    ;
    +-------------------------------------------+
    | authentication_string                     |
    +-------------------------------------------+
    | *303EC79A0669B1C7233BB0E885A363B18A69900B |
    +-------------------------------------------+
    1 row in set (0.00 sec)
    复制代码

    修改 user 表完成后,那么再次将 /etc/my.cnf中的 skip-grant-tables 删除,然后重启服务器就可以使用新密码登录到数据了

    复制代码
    [root@node01 ~]# mysql -uroot -pNewPass@123 -S /data1/mysql/mysql.sock
    mysql: [Warning] Using a password on the command line interface can be insecure.
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 2
    Server version: 5.7.34 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2021, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    复制代码

     

    避免输入密码和用户名登录数据库

    有时候为了方便维护程序运行,不需要输入密码和用户名要登录到数据库中,那么可以配置免用户名和密码来登录到数据库中。该免密登录的方式是通过 mysql_config_editor 命令生成一个 .mylogin.cnf 的隐藏文件,该文件加密存储。mysql 在执行登录时访问该隐藏文件既可实现免密登录,如下:

    复制代码
    #生成隐藏文件 .mylogin.cnf
    [root@node01 ~]# mysql_config_editor set --user=root --port=3306 --host=localhost --password
    Enter password: (输入密码)
    .mylogin.cnf    .mysql_history  
    [root@node01 ~]# ls .mylogin.cnf 
    .mylogin.cnf
    
    #直接使用 mysql 登录
    [root@node01 ~]# mysql -S /data1/mysql/mysql.sock
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 3
    Server version: 5.7.34 MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2021, Oracle and/or its affiliates.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    mysql>
    复制代码

     

    如验证 MySQL 服务器是否连接成功

    复制代码
    [root@node01 ~]# cat testconn.sh 
    #!/bin/bash
    SOCKET=/data1/mysql/mysql.sock
    myconn=`mysql mysql -S ${SOCKET} -s -e "SELECT 1" | tail -1`
    if [ "${myconn}" == "1" ];then
        echo "Connection successfully"
    else
        echo "Connection Failure"
    fi
    
    [root@node01 ~]# sh testconn.sh 
    Connection successfully
    复制代码

     

    以上就是 MySQL 数据库有关密码的内容,如果有更其他方式,可以投稿指出。

    Speak Your Mind

    *