MySQL 安装

一、版本说明

1. 版本区别

  • alpha - 内测版本(CB):以展示新特性为目的,稳定性差,会持续添加新特性。
  • beta - 公测版本:对所有用户公开的测试版本。
  • rc - 正式发布候选版本:在 beta 版本基础上修改,作为正式发布前的候选版本。
  • GA(General Availability)- 稳定版:无后缀时,通常为可用版本或产品版本,适合学习、测试及生产环境。

2. 社区版和企业版

(1)社区版(MySQL Community)

(2)企业版(MySQL Enterprise Edition)

二、安装方式

1. Docker 安装

(1)重要目录和文件

  • 客户端程序和脚本:/usr/bin
  • mysqld 服务器:/usr/sbin
  • 配置文件:/etc/my.cnf
  • 数据目录:/var/lib/mysql
  • 错误日志:/var/log/mysqld.log
  • secure_file_priv:/var/lib/mysql-files
  • System V 初始脚本:/etc/init.d/mysqld
  • PID 文件:/var/run/mysql/mysqld.pid
  • Socket:/var/lib/mysql/mysql.sock

(2)安装步骤

  • 拉取镜像

    docker pull container-registry.oracle.com/mysql/community-server:8.4
    
  • 启动容器

    # 启动临时容器(自动创建不存在的主机目录)
    docker run -d \
    --name=mysql-8.4 \
    -p 3306:3306 \
    -v /data/mysql/datadir:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=mysql123456 \
    container-registry.oracle.com/mysql/community-server:8.4
    
    # 导出配置文件
    docker cp mysql-8.4:/etc/my.cnf /data/mysql/
    
    # 删除临时容器
    docker stop mysql-8.4 && docker rm mysql-8.4
    
    # 重新启动完整容器
    docker run -d \
    --name=mysql-8.4 \
    -p 3306:3306 \
    -v /data/mysql/my.cnf:/etc/my.cnf \
    -v /data/mysql/datadir:/var/lib/mysql \
    -e MYSQL_ROOT_PASSWORD=mysql123456 \
    container-registry.oracle.com/mysql/community-server:8.4
    

    可根据生产环境修改配置文件

  • 首次登录

    docker exec -it mysql-8.4 mysql -u root -p
    
  • 授予远程登录权限(可选)

    create user 'root'@'%' identified by 'mysql123456' password expire never;
    grant all privileges on *.* to 'root'@'%' with grant option;
    flush privileges;
    
  • 远程登录验证

    # 在容器外执行
    mysql -h 192.168.17.50 -P 3306 -u root -p
    

2. 二进制文件安装

(1)安装单实例

以 MySQL 8.0.23 二进制社区 GA 版为例。

  • 规划

    • 用户和用户组:mysql.mysql
    • 启动方式:systemd
    • 端口:默认 3306
    • server_id:默认 1
    • 目录规划
      • 安装目录:/opt/mysql
      • 数据目录:/mdata/data
      • 配置文件:/etc/my.cnf
      • socket 文件:/tmp/mysql.sock
      • 其他文件(二进制日志、中继日志等):默认目录
  • 准备工作

    • 卸载系统自带版本

      rpm -qa | grep "mysql|mariadb" | yum remove -y
      
    • 安装依赖(参考官方文档:https://dev.mysql.com/doc/refman/8.0/en/binary-installation.html)

      yum install -y libaio ncurses-compat-libs
      

      Note:EL8 系统默认无 /lib64/libtinfo.so.5,需手动安装 ncurses-compat-libs

    • 创建用户/用户组

      groupadd -g 888 mysql
      useradd -M -u 888 -g 888 -s /sbin/nologin mysql
      

      Note:简单创建可使用 useradd mysql -M -s /sbin/nologin

    • 创建目录

      mkdir -p /mdata/data
      chown -R mysql.mysql /opt/mysql*
      chown -R mysql.mysql /mdata
      chmod 750 /mdata
      
  • 安装软件

    • 下载 & 解压(下载地址:https://downloads.mysql.com/archives/community/)

      wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.23-linux-glibc2.12-x86_64.tar.xz
      tar -xvf mysql-8.0.23-linux-glibc2.12-x86_64.tar.xz -C /opt/
      
    • 创建软链接(便于后续升级)

      ln -s /opt/mysql-8.0.23-linux-glibc2.12-x86_64 /opt/mysql
      
    • 添加环境变量
      编辑 /etc/profile,添加:

      MYSQL_HOME=/opt/mysql
      export PATH=$PATH:$MYSQL_HOME/bin
      

      使生效:

      source /etc/profile
      
    • 验证

      mysql -V
      # 预期输出:mysql  Ver 8.0.23 for Linux on x86_64 (MySQL Community Server - GPL)
      
  • 初始化数据目录

    • 不同版本初始化命令

      • 5.6 版本:

        /opt/mysql/scripts/mysql_install_db --user=mysql --basedir=/opt/mysql --datadir=/mdata/data
        
      • 5.7 以上版本(两种方式,区别在于是否生成随机临时密码):

        • 无临时密码:

          mysqld --initialize-insecure --user=mysql --basedir=/opt/mysql --datadir=/mdata/data
          
        • 生成随机临时密码(含密码复杂度定制、180 天过期):

          mysqld --initialize --user=mysql --basedir=/opt/mysql --datadir=/mdata/data
          
    • 初始化后的数据目录文件(部分关键文件):

      • auto.cnf(UUID)、ca-key.pem(CA 私钥)、ca.pem(自签名 CA 证书)
      • ibdata1(系统表空间文件)、ib_logfile0/1(redo 日志)
      • mysql(常规日志和慢查询日志目录)、performance_schema(性能库)
      • undo_001/002(undo 日志)等

      Note:MySQL 5.7 以上默认开启 SSL 连接,数据目录会生成 .pem 相关文件

    • 扩展

      • 多次初始化:失败时可删除数据目录文件后重新初始化

      • –defaults-file 选项:初始化配置可写入文件,命令中指定(与启动配置文件区分)

        # 创建初始化配置文件
        cat /mdata/my.cnf << EOF
        [mysqld]
        user=mysql
        basedir=/opt/mysql
        datadir=/mdata/data
        EOF
        # 初始化命令
        mysqld --defaults-file=/mdata/my.cnf --initialize-insecure
        
      • 认证插件演进:MySQL 8.0 默认插件为 caching_sha2_password;8.0.34 起弃用 mysql_native_password,8.4.0 默认禁用,9.0.0 移除。查看方式:

        select user,host,plugin,authentication_string from mysql.user;
        
  • 启动服务

    • 编辑配置文件 /etc/my.cnf

      cat /etc/my.cnf << EOF
      [mysqld]
      user=mysql
      basedir=/opt/mysql
      datadir=/mdata/data
      server_id=1
      port=3306
      socket=/tmp/mysql.sock
      EOF
      
    • 启动方式

      • 直接启动:

        mysqld_safe --defaults-file=/etc/my.cnf &
        

        Note:不指定 --defaults-file 时,自动读取 /etc/my.cnf;命令行选项优先级高于配置文件

      • sys-v 方式:

        # 复制启动文件
        cp /opt/mysql/support-files/mysql.server /etc/init.d/mysqld
        # 管理服务
        service mysqld start | stop | status
        
      • systemd 方式(推荐):

        # 创建服务文件
        cat /usr/lib/systemd/system/mysqld.service << EOF
        [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
        
        [Service]
        User=mysql
        Group=mysql
        ExecStart=/opt/mysql/bin/mysqld --defaults-file=/etc/my.cnf
        LimitNOFILE=5000
        
        [Install]
        WantedBy=multi-user.target
        EOF
        # 管理服务
        systemctl daemon-reload
        systemctl start | enable | stop | status mysqld
        
    • 启动故障排查

      • 查看错误日志(默认数据目录下 host_name.err)
      • 日志输出到屏幕:/opt/mysql/bin/mysqld --defaults-file=/etc/my.cnf
      • 杀掉进程:pkill mysqld
    • 停止服务

      mysqladmin -u root -p shutdown
      
  • 修改 root 密码及验证

    • 首次登录

      mysql -uroot -p -S /tmp/mysql.sock
      

      Note:有临时密码时使用临时密码;本地登录默认用 Unix socket,可不指定 -S

    • 查看现有账户

      select host,user,plugin,authentication_string from mysql.user;
      
    • 修改密码

      ALTER USER root@localhost IDENTIFIED BY 'root';
      
    • 授予远程登录权限(可选)

      create user 'root'@'%' identified by 'mysql123456' password expire never;
      grant all privileges on *.* to 'root'@'%' with grant option;
      flush privileges;
      
    • 登录验证

      # 本地 socket 登录
      mysql -uroot -p -S /tmp/mysql.sock
      # TCP/IP 登录(需指定 127.0.0.1)
      mysql -uroot -p -h127.0.0.1 -P3306
      

(2)安装多实例

  • 规划

    • 目录规划
      image-1765794950199
  • 准备工作

    • 创建目录

      mkdir -p /mdata/{3301..3309}/{data,log,binlog}
      chown -R mysql.mysql /mdata
      chmod 750 /mdata
      
    • 修改配置文件(以 3301 端口为例)

      cat /mdata/3301/my.cnf << EOF
      [mysqld]
      user=mysql
      port=3301
      
      basedir=/opt/mysql
      datadir=/mdata/3301/data
      socket=/mdata/3301/mysql.sock
      
      # 错误日志
      log_error=/mdata/3301/log/mysql.err
      
      # 二进制日志
      server_id=1
      log_bin=/mdata/3301/binlog/mysql-bin
      
      autocommit=0
      
      # GTID
      gtid_mode=on
      enforce_gtid_consistency=true
      log_slave_updates=1
      
      # 慢日志
      slow_query_log=on
      slow_query_log_file=/mdata/3301/log/mysql-slow.log
      long_query_time=5
      log_queries_not_using_indexes=on
      
      # 存储引擎
      default_storage_engine=InnoDB
      innodb_autoextend_increment=64
      
      # 允许导入/导出数据
      secure_file_priv=/tmp
      EOF
      
  • 初始化数据目录(以 3301 端口为例)

    mysqld --initialize-insecure --user=mysql --basedir=/opt/mysql --datadir=/mdata/3301/data
    
  • 启动服务(以 3301 端口为例)

    • 创建 systemd 服务文件

      cat /usr/lib/systemd/system/mysqld@3301.service << EOF
      [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
      
      [Service]
      User=mysql
      Group=mysql
      ExecStart=/opt/mysql/bin/mysqld --defaults-file=/mdata/3301/my.cnf
      LimitNOFILE=5000
      
      [Install]
      WantedBy=multi-user.target
      EOF
      
    • 启动服务

      systemctl daemon-reload
      systemctl start mysqld@3301
      systemctl enable mysqld@3301
      
  • 验证

    mysql -S /mdata/3301/mysql.sock -e "select @@server_id"
    

    Note:本地登录非默认端口需指定 -S,否则使用默认 socket 文件

  • 安装脚本(批量创建 3301 - 3309 实例)

    #!/bin/bash
    
    # 创建目录
    mkdir -p /mdata/{3301..3309}/{data,log,binlog}
    
    # 清理目录
    rm -rf /mdata/{3301..3309}/{data,log,binlog}/*
    
    # 修改配置文件
    for i in {1..9}
    do
    	port=330$i
    
    cat /mdata/$port/my.cnf << EOF
    [mysqld]
    user=mysql
    port=$port
    
    basedir=/opt/mysql
    datadir=/mdata/$port/data
    socket=/mdata/$port/mysql.sock
    
    # 错误日志
    log_error=/mdata/$port/log/mysql.err
    
    # 二进制日志
    server_id=$i
    log_bin=/mdata/$port/binlog/mysql-bin
    
    autocommit=0
    
    # GTID
    gtid_mode=on
    enforce_gtid_consistency=true
    log_slave_updates=1
    
    # 慢日志
    slow_query_log=on
    slow_query_log_file=/mdata/$port/log/mysql-slow.log
    long_query_time=5
    log_queries_not_using_indexes=on
    
    # 存储引擎
    default_storage_engine=InnoDB
    innodb_autoextend_increment=64
    
    # 允许导入/导出数据
    secure_file_priv=/tmp
    EOF
    
    # 创建 systemd 服务文件
    cat /usr/lib/systemd/system/mysqld@$port.service << EOF
    [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
    
    [Service]
    User=mysql
    Group=mysql
    ExecStart=/opt/mysql/bin/mysqld --defaults-file=/mdata/$port/my.cnf
    LimitNOFILE=5000
    
    [Install]
    WantedBy=multi-user.target
    EOF
    done
    
    # 重新加载 systemd
    systemctl daemon-reload
    
    # 授权
    chown -R mysql.mysql /mdata
    chmod 750 /mdata
    
    # 初始化数据目录
    for port in {3301..3309}
    do
    	if [ ! -f /mdata/$port/data/ibdata1 ]; then
        	mysqld --initialize-insecure --user=mysql --basedir=/opt/mysql --datadir=/mdata/$port/data &>/dev/null
    		echo -e "mysql@$port: initialize end."	
    	fi
    done
    
    # 启动实例
    for port in {3301..3309}
    do
    	s_active=`systemctl is-active mysqld@$port`
    	[ $s_active != 'active' ] && systemctl start mysqld@$port; mysql -uroot -S /mdata/$port/mysql.sock -e "select @@server_id"
    	
    	s_enable=`systemctl is-enabled mysqld@$port`
    	[ $s_enable = 'disabled' ] && systemctl enable mysqld@$port >/dev/null
    done
    

三、重置管理员密码

  • 跳过授权表启动
# 停止服务
systemctl stop mysqld

# 跳过授权表启动
# --defaults-file 需作为第一个选项传入。--skip-grant-tables 跳过 mysql.user 授权表加载;--skip-networking 禁止 TCP/IP 连接,仅用本地 socket。
mysqld_safe --defaults-file=/etc/my.cnf --skip-grant-tables --skip-networking &

# 无密码登录
mysql -uroot -p -S /tmp/mysql.sock
  • 修改密码
flush privileges;  -- 刷新权限,重新加载授权表
alter user root@localhost identified by 'new_password';
  • 正常启动服务
# 启动
mysqladmin -uroot -p shutdown
systemctl start mysqld

# 登录验证
mysql -uroot -p -S /tmp/mysql.sock

四、错误汇总

1. 使用 --defaults-file 初始化数据目录报错

  • 报错信息

    $ mysqld --initialize-insecure --defaults-file=/pdata/3307/my.cnf
    2021-01-15T10:20:59.791546Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
    2021-01-15T10:20:59.792611Z 0 [ERROR] --initialize specified but the data directory has files in it. Aborting.
    2021-01-15T10:20:59.792639Z 0 [ERROR] Aborting
    
  • 原因:配置文件有多余设置;数据目录非空。

  • 解决方法

    # 方法 1:不指定 --defaults-file,直接指定必要参数
    mysqld --initialize-insecure --user=mysql --basedir=/opt/mysql --datadir=/mdata/3307/data
    # 方法 2:清空数据目录
    

2. 初始化数据目录无反应

  • 原因:存在 /etc/my.cnf 文件,初始化时自动读取导致冲突。

  • 解决方法

    rm -rf /etc/my.cnf
    

3. 配置 ibdata2 共享表空间启动报错

  • 报错场景:配置文件添加 innodb_data_file_path=ibdata1:512M;ibdata2:512M:autoextend 后启动失败。
  • 原因:ibdata1 实际大小未达到 512M,不满足创建 ibdata2 条件。
  • 解决方法:暂时移除该配置,待 ibdata1 增长到指定大小后再添加;或使用 ALTER INSTANCE 语句扩展系统表空间。