Red Hat Training

A Red Hat training course is available for RHEL 8

7.3. 使用 MySQL

MySQL 服务器是一个开源、快速且强大的数据库服务器。MySQL 是一个关系型数据库,其将数据转换为结构化的信息,并提供 SQL 接口来访问数据。它包括多种存储引擎和插件,以及地理信息系统(GIS)和 JavaScript 对象表示法(JSON)功能。

了解如何在 RHEL 系统上安装和配置 MySQL,如何备份 MySQL 数据、如何从较早的 MySQL 版本迁移,以及如何复制 MySQL

7.3.1. 安装 MySQL

在 RHEL 8 中,MySQL 8.0 服务器是作为 mysql:8.0 模块流提供的。

要安装 MySQL,请使用以下流程。

流程

  1. mysql 模块中选择 8.0 流(版本),并指定 服务器 配置文件来安装 MySQL 服务器软件包:

    # yum module install mysql:8.0/server
  2. 启动 mysqld 服务:

    # systemctl start mysqld.service
  3. 在引导时启用 mysqld 服务:

    # systemctl enable mysqld.service
  4. 建议:要在安装 MySQL 时提高安全性,请运行以下命令:

    $ mysql_secure_installation

    此命令启动一个完全交互的脚本,该脚本会提示过程中的每一步。该脚本可让您通过以下方法提高安全性:

    • 为 root 帐户设置密码
    • 删除匿名用户
    • 禁止远程 root 登录(在本地主机之外)
注意

由于 RPM 软件包冲突,MySQLMariaDB 数据库服务器无法在 RHEL 8 中并行安装。在 RHEL 7 的红帽软件集合中可以并行安装组件。在 RHEL 8 中,可在容器中使用不同版本的数据库服务器。

7.3.2. 配置 MySQL

要为网络配置 MySQL 服务器,请使用以下流程。

流程

  1. 编辑 /etc/my.cnf.d/mysql-server.cnf 文件的 [mysqld] 部分。您可以设置以下配置指令:

    • bind-address - 是服务器监听的地址。可能的选项有:

      • 主机名
      • IPv4 地址
      • IPv6 地址
    • skip-networking - 控制服务器是否监听 TCP/IP 连接。可能的值有:

      • 0 - 监听所有客户端
      • 1 - 只监听本地客户端
    • 端口 - MySQL 侦听 TCP/IP 连接的端口。
  2. 重启 mysqld 服务:

    # systemctl restart mysqld.service

7.3.3. 在 MySQL 服务器上设置 TLS 加密

默认情况下,MySQL 使用未加密的连接。对于安全连接,请在 MySQL 服务器上启用 TLS 支持,并将您的客户端配置为建立加密连接。

7.3.3.1. 将 CA 证书、服务器证书和私钥放在 MySQL 服务器上

MySQL 服务器上启用 TLS 加密前,请将证书颁发机构(CA)证书、服务器证书和私钥存储在 MySQL 服务器上。

先决条件

  • 以下 Privacy Enhanced Mail(PEM)格式的文件已复制到服务器:

    • 服务器的私钥:server.example.com.key.pem
    • 服务器证书:server.example.com.crt.pem
    • 证书颁发机构(CA)证书:ca.crt.pem

    有关创建私钥和证书签名请求(CSR),以及从 CA 请求证书的详情,请查看您的 CA 文档。

流程

  1. 将 CA 和服务器证书存储在 /etc/pki/tls/certs/ 目录中:

    # mv <path>/server.example.com.crt.pem /etc/pki/tls/certs/
    # mv <path>/ca.crt.pem /etc/pki/tls/certs/
  2. 在 CA 和服务器证书上设置权限,以使 MySQL 服务器能够读取文件:

    # chmod 644 /etc/pki/tls/certs/server.example.com.crt.pem /etc/pki/tls/certs/ca.crt.pem

    由于证书是建立安全连接前通信的一部分,因此任何客户端都可以在不需要身份验证的情况下检索它们。因此,您不需要对 CA 和服务器证书文件设置严格的权限。

  3. 将服务器的私钥存储在 /etc/pki/tls/private/ 目录中:

    # mv <path>/server.example.com.key.pem /etc/pki/tls/private/
  4. 对服务器的私钥设置安全权限:

    # chmod 640 /etc/pki/tls/private/server.example.com.key.pem
    # chgrp mysql /etc/pki/tls/private/server.example.com.key.pem

    如果未授权的用户可以访问私钥,则到 MySQL 服务器的连接不再是安全的。

  5. 恢复 SELinux 上下文:

    # restorecon -Rv /etc/pki/tls/

7.3.3.2. 在 MySQL 服务器上配置 TLS

要提高安全性,请在 MySQL 服务器上启用 TLS 支持。因此,客户端可以使用 TLS 加密与服务器传输数据。

先决条件

  • 您已安装了 MySQL 服务器。
  • mysqld 服务正在运行。
  • 服务器上存在 Privacy Enhanced Mail(PEM)格式的以下文件,并可由 mysql 用户读取:

    • 服务器的私钥:/etc/pki/tls/private/server.example.com.key.pem
    • 服务器证书:/etc/pki/tls/certs/server.example.com.crt.pem
    • 证书颁发机构(CA)证书 /etc/pki/tls/certs/ca.crt.pem
  • 主题可识别名称(DN)或服务器证书中的主题备用名称(SAN)字段与服务器的主机名相匹配。

流程

  1. 创建 /etc/my.cnf.d/mysql-server-tls.cnf 文件:

    1. 添加以下内容来配置到私钥、服务器和 CA 证书的路径:

      [mysqld]
      ssl_key = /etc/pki/tls/private/server.example.com.key.pem
      ssl_cert = /etc/pki/tls/certs/server.example.com.crt.pem
      ssl_ca = /etc/pki/tls/certs/ca.crt.pem
    2. 如果您有证书撤销列表(CRL),请配置 MySQL 服务器来使用它:

      ssl_crl = /etc/pki/tls/certs/example.crl.pem
    3. 可选:拒绝没有加密的连接尝试。要启用此功能,请附加:

      require_secure_transport = on
    4. 可选:设置服务器应支持的 TLS 版本。例如,要支持 TLS 1.2 和 TLS 1.3,请附加:

      tls_version = TLSv1.2,TLSv1.3

      默认情况下,服务器支持 TLS 1.1、TLS 1.2 和 TLS 1.3。

  2. 重启 mysqld 服务:

    # systemctl restart mysqld

验证

要简化故障排除,请在将本地客户端配置为使用 TLS 加密前在 MySQL 服务器上执行以下步骤:

  1. 验证 MySQL 现在是否启用了 TLS 加密:

    # mysql -u root -p -h <MySQL_server_hostname> -e "SHOW session status LIKE 'Ssl_cipher';"
    +---------------+------------------------+
    | Variable_name | Value                  |
    +---------------+------------------------+
    | Ssl_cipher    | TLS_AES_256_GCM_SHA384 |
    +---------------+------------------------+
  2. 如果您将 MySQL 服务器配置为只支持特定的 TLS 版本,请显示 tls_version 变量:

    # mysql -u root -p -e "SHOW GLOBAL VARIABLES LIKE 'tls_version';"
    +---------------+-----------------+
    | Variable_name | Value           |
    +---------------+-----------------+
    | tls_version   | TLSv1.2,TLSv1.3 |
    +---------------+-----------------+
  3. 验证服务器是否使用正确的 CA 证书、服务器证书和私钥文件:

    # mysql -u root -e "SHOW GLOBAL VARIABLES WHERE Variable_name REGEXP '^ssl_ca|^ssl_cert|^ssl_key';"
    +-----------------+-------------------------------------------------+
    | Variable_name   | Value                                           |
    +-----------------+-------------------------------------------------+
    | ssl_ca          | /etc/pki/tls/certs/ca.crt.pem                   |
    | ssl_capath      |                                                 |
    | ssl_cert        | /etc/pki/tls/certs/server.example.com.crt.pem   |
    | ssl_key         | /etc/pki/tls/private/server.example.com.key.pem |
    +-----------------+-------------------------------------------------+

7.3.3.3. 对特定的用户帐户需要 TLS 加密连接

可以访问敏感数据的用户应始终使用 TLS 加密连接,以避免通过网络发送未加密的数据。

如果您无法在服务器上配置所有连接都需要安全传输(require_secure_transport = on),请将单个用户帐户配置为需要 TLS 加密。

先决条件

  • MySQL 服务器启用了 TLS 支持。
  • 您配置为需要安全传输的用户已存在。
  • CA 证书存储在客户端上。

流程

  1. 以管理用户身份连接到 MySQL 服务器:

    # mysql -u root -p -h server.example.com

    如果您的管理用户没有远程访问服务器的权限,请在 MySQL 服务器上执行命令,并连接到 localhost

  2. 使用 REQUIRE SSL 子句强制用户必须使用 TLS 加密连接进行连接:

    MySQL [(none)]> ALTER USER 'example'@'%' REQUIRE SSL;

验证

  1. 使用 TLS 加密,以 example 用户身份连接到服务器:

    # mysql -u example -p -h server.example.com
    ...
    MySQL [(none)]>

    如果没有显示错误,且您可以访问交互式 MySQL 控制台,则与 TLS 的连接成功。

    默认情况下,如果服务器提供了,客户端会自动使用 TLS 加密。因此,--ssl-ca=ca.crt.pem--ssl-mode=VERIFY_IDENTITY 选项不是必需的,但可以提高安全性,使用这些选项,客户端可以验证服务器的身份。

  2. 尝试以禁用 TLS 的 example 用户身份进行连接:

    # mysql -u example -p -h server.example.com --ssl-mode=DISABLED
    ERROR 1045 (28000): Access denied for user 'example'@'server.example.com' (using password: YES)

    服务器拒绝登录尝试,因为此用户需要 TLS,但禁用了(--ssl-mode=DISABLED)。

7.3.4. 在 MySQL 客户端中使用 CA 证书验证全局启用 TLS 加密

如果您的 MySQL 服务器支持 TLS 加密,请将您的客户端配置为仅建立安全连接,并验证服务器证书。这个流程描述了如何为服务器上的所有用户启用 TLS 支持。

7.3.4.1. 将 MySQL 客户端配置为默认使用 TLS 加密

在 RHEL 上,您可以全局配置 MySQL 客户端使用 TLS 加密,并验证服务器证书中的通用名称(CN)是否与用户连接的主机名匹配。这可防止中间人攻击。

先决条件

  • MySQL 服务器启用了 TLS 支持。
  • CA 证书存储在客户端上的 /etc/pki/tls/certs/ca.crt.pem 文件中。

流程

  • 使用以下内容创建 /etc/my.cnf.d/mysql-client-tls.cnf 文件:

    [client]
    ssl-mode=VERIFY_IDENTITY
    ssl-ca=/etc/pki/tls/certs/ca.crt.pem

    这些设置定义 MySQL 客户端使用 TLS 加密,并且客户端将主机名与服务器证书中的 CN 进行比较(ssl-mode=VERIFY_IDENTITY)。另外,它还指定到 CA 证书的路径(ssl-ca)。

验证

  • 使用主机名连接到服务器,并显示服务器的状态:

    # mysql -u root -p -h server.example.com -e status
    ...
    SSL:        Cipher in use is TLS_AES_256_GCM_SHA384

    如果 SSL 条目中包含 Cipher in use is…​,则连接是加密的。

    请注意,您在这个命令中使用的用户具有远程身份验证的权限。

    如果您连接的主机名与服务器的 TLS 证书中的主机名不匹配,则 ssl-mode=VERIFY_IDENTITY 参数会导致连接失败。例如,如果您连接到 localhost

    # mysql -u root -p -h localhost -e status
    ERROR 2026 (HY000): SSL connection error: error:0A000086:SSL routines::certificate verify failed

其它资源

  • mysql(1) 手册页中的 --ssl* 参数描述。

7.3.5. 备份 MySQL 数据

在 Red Hat Enterprise Linux 8 中,备份 MySQL 数据库数据有两个主要方法:

  • 逻辑备份
  • 物理备份

逻辑备份 由恢复数据所需的 SQL 语句组成。这种类型的备份以纯文本文件的形式导出信息和记录。

与物理备份相比,逻辑备份的主要优势在于可移植性和灵活性。数据可以在其他硬件配置、MySQL 版本或数据库管理系统(DBMS)上恢复,而这些数据无法进行物理备份。

请注意,如果 mysqld.service 正在运行,也可以执行逻辑备份。逻辑备份不包括日志和配置文件。

物理备份由保存内容的文件和目录副本组成。

与逻辑备份相比,物理备份具有以下优点:

  • 输出更为紧凑。
  • 备份的大小会较小。
  • 备份和恢复速度更快。
  • 备份包括日志和配置文件。

请注意,当 mysqld.service 没有运行或数据库中的所有表被锁住时,才能执行物理备份,以防在备份过程中数据有更改。

您可以使用以下 MySQL 备份方法之一从 MySQL 数据库备份数据:

  • 使用 mysqldump 的逻辑备份
  • 文件系统备份
  • 作为备份解决方案复制

7.3.5.1. 使用 mysqldump 执行逻辑备份

mysqldump 客户端是一种备份实用程序,可用于转储数据库或数据库集合,用于备份或传输到其他数据库服务器。mysqldump 的输出通常包含 SQL 语句,用于重新创建服务器表结构、给它填充数据或两者兼而有之。mysqldump 也可以以其他格式生成文件,包括 XML 和分隔的文本格式,如 CSV。

要执行 mysqldump 备份,您可以使用以下一种选项:

  • 备份一个或多个所选的数据库
  • 备份所有数据库
  • 从一个数据库备份表子集

流程

  • 要转储单个数据库,请运行:

    # mysqldump [options] --databases db_name > backup-file.sql
  • 要一次转储多个数据库,请运行:

    # mysqldump [options] --databases db_name1 [db_name2 ...] > backup-file.sql
  • 要转储所有数据库,请运行:

    # mysqldump [options] --all-databases > backup-file.sql
  • 要将一个或多个转储的完整数据库加载回服务器,请运行:

    # mysql < backup-file.sql
  • 要将数据库加载到远程 MySQL 服务器,请运行:

    # mysql --host=remote_host < backup-file.sql
  • 要从一个数据库中转储表的字面子集,请在 mysqldump 命令末尾添加所选表的列表:

    # mysqldump [options] db_name [tbl_name ...​] > backup-file.sql
  • 要加载从一个数据库转储的表的字面子集,请运行:

    # mysql db_name < backup-file.sql
    注意

    此时,db_name 数据库必须存在。

  • 要查看 mysqldump 支持的选项列表,请运行:

    $ mysqldump --help

7.3.5.2. 执行文件系统备份

要创建 MySQL 数据文件的文件系统备份,请将 MySQL 数据目录的内容复制到您的备份位置。

要同时备份当前的配置或日志文件,请使用以下流程的可选步骤:

流程

  1. 停止 mysqld 服务:

    # systemctl stop mysqld.service
  2. 将数据文件复制到所需位置:

    # cp -r /var/lib/mysql /backup-location
  3. (可选)将配置文件复制到所需位置:

    # cp -r /etc/my.cnf /etc/my.cnf.d /backup-location/configuration
  4. (可选)将日志文件复制到所需位置:

    # cp /var/log/mysql/* /backup-location/logs
  5. 启动 mysqld 服务:

    # systemctl start mysqld.service
  6. 将备份位置的备份数据加载到 /var/lib/mysql 目录时,请确保 mysql:mysql/var/lib/mysql 中所有数据的所有者:

    # chown -R mysql:mysql /var/lib/mysql

7.3.5.3. 作为备份解决方案复制

复制是源服务器的一个替代的备份解决方案。如果源服务器复制到副本服务器,备份可以在副本上运行,而不会对源造成任何影响。当您关闭副本,并从副本备份数据时,源仍然可以运行。

有关如何复制 MySQL 数据库的说明,请参阅 复制 MySQL

警告

复制本身并不是一个足够的备份解决方案。复制可以防止源服务器出现硬件故障,但它不能确保防止数据的丢失。建议您将对副本的任何其他备份解决方案与此方法一起使用。

其它资源

7.3.6. 迁移到 MySQL 8.0 的 RHEL 8 版本

RHEL 7 包含 MariaDB 5.5 ,来作为 MySQL 数据库系列的服务器的默认实现。RHEL 7 的 Red Hat Software Collections 提供了 MySQL 8.0 和几个 MariaDB 版本。RHEL 8 提供了 MySQL 8.0MariaDB 10.3MariaDB 10.5

此流程描述了使用 mysql_upgrade 工具从 MySQL 8.0 的 Red Hat Software Collections 版本迁移到 MySQL 8.0 的 RHEL 8 版本。mysql_upgrade 工具由 mysql-server 软件包提供。

注意

MySQL 的 Red Hat Software Collections 版本中,源数据目录为 /var/opt/rh/rh-mysql80/lib/mysql/。在 RHEL 8 中,MySQL 数据存储在 /var/lib/mysql/ 目录中。

先决条件

  • 在进行升级前,请备份存储在 MySQL 数据库中的所有数据。

流程

  1. 确定在 RHEL 8 系统上安装了 mysql-server 软件包:

    # yum install mysql-server
  2. 确保在复制数据时 mysqld 服务不在源或目标系统上运行:

    # systemctl stop mysqld.service
  3. 将 RHEL 7 源系统上 /var/opt/rh/rh-mysql80/lib/mysql/ 目录中的数据复制到 RHEL 8 目标系统上的 /var/lib/mysql/ 目录中。
  4. 对目标系统上复制的文件设置适当的权限和 SELinux 上下文:

    # restorecon -vr /var/lib/mysql
  5. 确保 mysql:mysql/var/lib/mysql 目录中所有数据的所有者:

    # chown -R mysql:mysql /var/lib/mysql
  6. 在目标系统上启动 MySQL 服务器:

    # systemctl start mysqld.service

    注意:在 MySQL 的早期版本中,需要 mysql_upgrade 命令来检查和修复内部表。现在,当您启动服务器时会自动完成此操作。

7.3.7. 复制 MySQL

MySQL 为复制提供各种配置选项,范围从基本到高级。这部分描述了使用全局事务标识符(GTID)在新安装的 MySQL 服务器上在 MySQL 中进行复制的一种基于事务的方法。使用 GTID 简化了事务识别和一致性验证。

要在 MySQL 中设置复制,您必须:

重要

如果要使用现有的 MySQL 服务器进行复制,您必须首先同步数据。如需更多信息,请参阅 上游文档

7.3.7.1. 配置 MySQL 源服务器

您可以设置 MySQL 源服务器所需的配置选项,来正确运行并复制数据库服务器上所做的所有更改。

先决条件

  • 源服务器已安装。

流程

  1. 包括 /etc/my.cnf.d/mysql-server.cnf 文件中 [mysqld] 部分下的以下选项:

    • bind-address=source_ip_adress

      从副本到源的连接需要这个选项。

    • server-id=id

      id 必须是唯一的。

    • log_bin=path_to_source_server_log

      此选项定义 MySQL 源服务器的二进制日志文件的路径。例如:log_bin=/var/log/mysql/mysql-bin.log

    • gtid_mode=ON

      此选项在服务器上启用全局事务标识符(GTID)。

    • enforce-gtid-consistency=ON

      服务器通过仅允许执行可使用 GTID 进行安全记录的语句来强制实施 GTID 一致性。

    • 可选: binlog_do_db=db_name

      如果您只想复制所选的数据库,则使用这个选项。要复制多个所选的数据库,请分别指定每个数据库:

      binlog_do_db=db_name1
      binlog_do_db=db_name2
      binlog_do_db=db_name3
    • 可选: binlog_ignore_db=db_name

      使用此选项从复制中排除特定的数据库。

  2. 重启 mysqld 服务:

    # systemctl restart mysqld.service

7.3.7.2. 配置 MySQL 副本服务器

您可以设置 MySQL 副本服务器所需的配置选项,以确保成功复制。

先决条件

  • 副本服务器已安装。

流程

  1. 包括 /etc/my.cnf.d/mysql-server.cnf 文件中 [mysqld] 部分下的以下选项:

    • server-id=id

      id 必须是唯一的。

    • relay-log=path_to_replica_server_log

      中继日志是在复制过程中由 MySQL 副本服务器创建的一组日志文件。

    • log_bin=path_to_replica_sever_log

      此选项定义了 MySQL 副本服务器的二进制日志文件的路径。例如:log_bin=/var/log/mysql/mysql-bin.log

      副本中不需要这个选项,但强烈建议使用。

    • gtid_mode=ON

      此选项在服务器上启用全局事务标识符(GTID)。

    • enforce-gtid-consistency=ON

      服务器通过仅允许执行可使用 GTID 进行安全记录的语句来强制实施 GTID 一致性。

    • log-replica-updates=ON

      这个选项可确保从源服务器接收的更新记录在副本的二进制日志中。

    • skip-replica-start=ON

      此选项可确保在副本服务器启动时不启动复制线程。

    • 可选: binlog_do_db=db_name

      如果您只想复制某些数据库,则使用这个选项。要复制多个数据库,请分别指定每个数据库:

      binlog_do_db=db_name1
      binlog_do_db=db_name2
      binlog_do_db=db_name3
    • 可选: binlog_ignore_db=db_name

      使用此选项从复制中排除特定的数据库。

  2. 重启 mysqld 服务:

    # systemctl restart mysqld.service

7.3.7.3. 在 MySQL 源服务器上创建复制用户

您必须创建一个复制用户,并授予这个用户所需的复制流量的权限。此流程演示了如何创建具有适当权限的复制用户。仅在源服务器上执行这些步骤。

先决条件

流程

  1. 创建复制用户:

    mysql> CREATE USER 'replication_user'@'replica_server_ip' IDENTIFIED WITH mysql_native_password BY 'password';
  2. 授予用户复制权限:

    mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication_user'@'replica_server_ip';
  3. 重新载入 MySQL 数据库中的授权表:

    mysql> FLUSH PRIVILEGES;
  4. 将源服务器设置为只读状态:

    mysql> SET @@GLOBAL.read_only = ON;

7.3.7.4. 将副本服务器连接到源服务器

MySQL 副本服务器上,您必须配置凭证和源服务器的地址。使用以下流程实现副本服务器。

先决条件

流程

  1. 将副本服务器设置为只读状态:

    mysql> SET @@GLOBAL.read_only = ON;
  2. 配置复制源:

    mysql> CHANGE REPLICATION SOURCE TO
        -> SOURCE_HOST='source_ip_address',
        -> SOURCE_USER='replication_user',
        -> SOURCE_PASSWORD='password',
        -> SOURCE_AUTO_POSITION=1;
  3. MySQL 副本服务器中启动副本线程:

    mysql> START REPLICA;
  4. 在源和目标服务器上取消只读状态的设置:

    mysql> SET @@GLOBAL.read_only = OFF;
  5. 可选: 检查复制服务器的状态以进行调试:

    mysql> SHOW REPLICA STATUS\G;
    注意

    如果复制服务器启动或连接失败,您可以跳过 SHOW MASTER STATUS 命令的输出中显示的二进制日志文件位置后的某些事件。例如,从定义的位置跳过第一个事件:

    mysql> SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;

    尝试再次启动副本服务器。

  6. 可选: 停止副本服务器中的副本线程:

    mysql> STOP REPLICA;

7.3.7.5. 验证步骤

  1. 在源服务器上创建一个示例数据库:

    mysql> CREATE DATABASE test_db_name;
  2. 验证 test_db_name 数据库是否在副本服务器上进行复制。
  3. 在源或副本服务器上执行以下命令,显示 MySQL 服务器的二进制日志文件的状态信息:

    mysql> SHOW MASTER STATUS;

    Executed_Gtid_Set 列,针对在源上执行的事务显示一组 GTID,它不能为空。

    注意

    当在副本服务器上使用 SHOW SLAVE STATUS 时,Executed_Gtid_Set 行中会显示相同的 GTID。

7.3.7.6. 其它资源

7.3.8. 开发 MySQL 客户端应用程序

红帽建议针对 MariaDB 客户端库开发 MySQL 客户端应用程序。客户端和服务器之间的通信协议在 MariaDBMySQL 之间兼容。MariaDB 客户端库适用于最常见的 MySQL 场景,但特定于 MySQL 实现的有限数量的功能除外。

针对 MariaDB 客户端库构建应用程序所需的开发文件和程序由 mariadb-connector-c-devel 软件包提供。

不使用直接库名称,而是使用 mariadb_config 程序,该程序在 mariadb-connector-c-devel 软件包中分发。此程序确保返回正确的构建标志。