MySQL新版本特性之:`MySQL 8.0`的“`系统变量`:`set persist`和`set global`的区别。

MySQL 8.0 系统变量持久化:SET PERSIST vs. SET GLOBAL

大家好!今天我们来深入探讨 MySQL 8.0 中关于系统变量持久化的两个重要命令:SET PERSISTSET GLOBAL。理解它们之间的区别对于管理和配置 MySQL 服务器至关重要,尤其是在生产环境中。

在 MySQL 8.0 之前,我们主要依赖 my.cnf (或者 my.ini 在 Windows 上) 文件来配置 MySQL 服务器的各种参数。虽然这种方式有效,但它有一些明显的缺点:

  1. 需要重启服务器: 修改 my.cnf 文件后,通常需要重启 MySQL 服务器才能使更改生效。这在生产环境中是不可接受的,因为它会导致服务中断。

  2. 配置管理复杂: 管理分布在多个 my.cnf 文件中的配置信息可能变得复杂,尤其是在有多个 MySQL 实例的情况下。

  3. 缺乏动态性: 无法在运行时动态地更改某些系统变量,这限制了我们根据服务器负载或应用程序需求进行调整的能力。

MySQL 8.0 通过引入 SET PERSIST 命令,显著改善了这些问题。让我们首先了解一下 SET GLOBALSET PERSIST 的基本概念和用法,然后深入探讨它们之间的差异。

SET GLOBAL:运行时变量修改

SET GLOBAL 命令允许我们在 MySQL 服务器运行时修改全局系统变量的值。这些更改会立即生效,影响所有的连接。现有的连接不受影响,直到它们重新连接服务器。

语法:

SET GLOBAL system_variable = value;

示例:

SET GLOBAL max_connections = 200;

这个命令将 max_connections 全局变量设置为 200。这意味着所有新建立的连接将被允许,直到达到 200 个连接的限制。

需要 SUPER 权限: 执行 SET GLOBAL 命令需要 SUPER 权限。

作用范围: 更改只在当前 MySQL 服务器实例的生命周期内有效。当服务器重启时,全局变量将恢复为它们在配置文件 (my.cnf 或其他配置文件) 中定义的值,或者如果配置文件中没有定义,则恢复为它们的默认值。

使用场景:

  • 临时调整服务器参数,例如在高峰期增加 max_connections
  • 在测试环境中快速更改配置以进行实验。
  • 在脚本中自动化一些配置更改。

SET PERSIST:持久化变量修改

SET PERSIST 命令是 MySQL 8.0 引入的新特性,它允许我们不仅在运行时修改全局系统变量的值,而且还可以将这些更改持久化mysqld-auto.cnf 文件中。这意味着即使服务器重启,更改后的值仍然有效。

语法:

SET PERSIST system_variable = value;

示例:

SET PERSIST innodb_buffer_pool_size = 2147483648;  -- 2GB

这个命令将 innodb_buffer_pool_size 全局变量设置为 2GB,并将这个值保存到 mysqld-auto.cnf 文件中。下次服务器启动时,innodb_buffer_pool_size 将自动设置为 2GB。

需要 SUPER 权限: 执行 SET PERSIST 命令同样需要 SUPER 权限。

作用范围: 更改不仅在当前 MySQL 服务器实例的生命周期内有效,而且还会被写入 mysqld-auto.cnf 文件,从而在服务器重启后仍然生效。

mysqld-auto.cnf 文件:

  • 这个文件位于 MySQL 数据目录下。
  • 它是一个 JSON 格式的文件,用于存储通过 SET PERSIST 命令持久化的系统变量。
  • 不应该手动编辑这个文件。应该始终使用 SET PERSIST 命令来修改其中的内容。

使用场景:

  • 永久性地更改服务器参数,例如调整 innodb_buffer_pool_size 以提高性能。
  • 确保关键配置在服务器重启后仍然有效。
  • 简化配置管理,避免手动编辑 my.cnf 文件。

SET PERSIST_ONLY:安全地持久化变量

SET PERSIST_ONLY 命令是 SET PERSIST 的一个变体,它只将变量写入 mysqld-auto.cnf 文件,而不立即更改当前运行的服务器实例中的变量值。这意味着,只有在下次服务器启动时,这个变量才会生效。

语法:

SET PERSIST_ONLY system_variable = value;

示例:

SET PERSIST_ONLY default_authentication_plugin = 'mysql_native_password';

这个命令将 default_authentication_plugin 的值写入 mysqld-auto.cnf 文件,但当前运行的服务器实例仍然使用其旧值。只有在下次服务器启动时,default_authentication_plugin 才会设置为 mysql_native_password

需要 SUPER 权限: 执行 SET PERSIST_ONLY 命令同样需要 SUPER 权限。

作用范围: 更改只写入 mysqld-auto.cnf 文件,不影响当前运行的服务器实例。

使用场景:

  • 在服务器重启前提前配置好一些参数,例如在升级 MySQL 版本后更改 default_authentication_plugin
  • 避免立即更改可能影响服务器稳定性的参数。
  • 在计划维护期间进行配置更改。

RESET PERSIST:恢复默认值

RESET PERSIST 命令用于将通过 SET PERSISTSET PERSIST_ONLY 持久化的系统变量恢复为它们的默认值。它会从 mysqld-auto.cnf 文件中删除相应的条目。

语法:

RESET PERSIST system_variable;

示例:

RESET PERSIST innodb_buffer_pool_size;

这个命令将从 mysqld-auto.cnf 文件中删除 innodb_buffer_pool_size 变量的条目。下次服务器启动时,innodb_buffer_pool_size 将恢复为其默认值或者在 my.cnf 中配置的值。

需要 SUPER 权限: 执行 RESET PERSIST 命令同样需要 SUPER 权限。

作用范围:mysqld-auto.cnf 文件中删除变量条目,下次服务器启动时恢复默认值。

使用场景:

  • 撤销之前使用 SET PERSISTSET PERSIST_ONLY 所做的更改。
  • 恢复到默认配置,以便进行故障排除或测试。
  • 清理不再需要的持久化配置。

详细对比:SET GLOBAL vs. SET PERSIST vs. SET PERSIST_ONLY

为了更清晰地理解这三个命令之间的区别,我们使用表格进行对比:

特性 SET GLOBAL SET PERSIST SET PERSIST_ONLY
作用范围 当前会话以及之后的新会话 当前会话以及之后的新会话,并持久化到 mysqld-auto.cnf 持久化到 mysqld-auto.cnf,不影响当前会话
生效时间 立即生效 立即生效,并持久化 下次服务器启动时生效
是否持久化 是,写入 mysqld-auto.cnf 是,写入 mysqld-auto.cnf
重启后是否生效 否,恢复为配置文件或默认值 是,从 mysqld-auto.cnf 读取 是,下次启动时从 mysqld-auto.cnf 读取
配置文件影响 写入 mysqld-auto.cnf 写入 mysqld-auto.cnf
使用场景 临时调整参数,测试环境快速配置 永久性更改参数,确保重启后配置有效 在重启前提前配置参数,避免立即生效的影响
权限要求 SUPER SUPER SUPER

优先级:配置文件 vs. mysqld-auto.cnf vs. SET GLOBAL

当系统变量在多个地方定义时,MySQL 使用以下优先级规则来确定最终值:

  1. SET GLOBAL (最高优先级): 通过 SET GLOBAL 命令设置的值具有最高优先级。它们会覆盖配置文件和 mysqld-auto.cnf 文件中的设置,但只在当前服务器实例的生命周期内有效。

  2. mysqld-auto.cnf 通过 SET PERSISTSET PERSIST_ONLY 命令设置的值存储在 mysqld-auto.cnf 文件中,具有第二高的优先级。它们会覆盖配置文件中的设置,并在服务器重启后仍然有效。

  3. 配置文件 (my.cnf 等): 在配置文件中定义的系统变量具有较低的优先级。如果一个变量没有通过 SET GLOBALSET PERSIST 命令设置,则使用配置文件中的值。

  4. 默认值 (最低优先级): 如果一个变量既没有通过 SET GLOBALSET PERSIST 命令设置,也没有在配置文件中定义,则使用 MySQL 的默认值。

总结: SET GLOBAL > mysqld-auto.cnf > 配置文件 > 默认值

实际案例:调整 innodb_buffer_pool_size

假设我们需要将 innodb_buffer_pool_size 设置为 4GB。以下是一些不同的方法以及它们的效果:

方法 1:修改 my.cnf 文件

  1. 打开 my.cnf 文件(通常位于 /etc/my.cnf/etc/mysql/my.cnf)。

  2. [mysqld] 部分添加或修改以下行:

    innodb_buffer_pool_size = 4G
  3. 保存文件并重启 MySQL 服务器。

效果: innodb_buffer_pool_size 将在服务器重启后设置为 4GB。

方法 2:使用 SET GLOBAL 命令

SET GLOBAL innodb_buffer_pool_size = 4294967296;  -- 4GB

效果: innodb_buffer_pool_size 将立即设置为 4GB,影响所有新的连接。但是,当服务器重启时,它将恢复为配置文件或默认值。

方法 3:使用 SET PERSIST 命令

SET PERSIST innodb_buffer_pool_size = 4294967296;  -- 4GB

效果: innodb_buffer_pool_size 将立即设置为 4GB,影响所有新的连接,并且这个值会被写入 mysqld-auto.cnf 文件。当服务器重启时,它将自动设置为 4GB。

方法 4:使用 SET PERSIST_ONLY 命令

SET PERSIST_ONLY innodb_buffer_pool_size = 4294967296;  -- 4GB

效果: innodb_buffer_pool_size 的值会被写入 mysqld-auto.cnf 文件,但当前运行的服务器实例仍然使用其旧值。只有在下次服务器启动时,innodb_buffer_pool_size 才会设置为 4GB。

推荐方法: 对于永久性更改,推荐使用 SET PERSIST 命令。这确保了配置在服务器重启后仍然有效,并且简化了配置管理。

风险与注意事项

  • 权限管理: SET GLOBALSET PERSISTSET PERSIST_ONLY 命令都需要 SUPER 权限。应该谨慎授予这些权限,以防止未经授权的配置更改。

  • 配置冲突: 避免在多个地方定义同一个系统变量,例如同时在 my.cnf 文件和 mysqld-auto.cnf 文件中定义。这可能导致配置冲突和难以预测的行为。

  • 验证更改: 在进行任何配置更改后,应该始终验证更改是否生效,并且服务器是否按预期运行。可以使用 SHOW GLOBAL VARIABLES LIKE 'variable_name'; 命令来查看当前系统变量的值。

  • mysqld-auto.cnf 文件损坏: 虽然不应该手动编辑 mysqld-auto.cnf 文件,但如果文件损坏,可能会导致服务器启动失败或配置错误。应该定期备份这个文件,以便在需要时进行恢复。

  • 回滚配置: 如果配置更改导致问题,可以使用 RESET PERSIST 命令来恢复到默认配置。

代码示例:自动化配置管理

以下是一个使用 Python 和 MySQL Connector/Python 库来自动化配置管理的示例:

import mysql.connector

def set_global_variable(variable_name, value):
    """使用 SET GLOBAL 命令设置全局变量。"""
    try:
        mydb = mysql.connector.connect(
            host="localhost",
            user="root",
            password="your_password",
            database="mysql"
        )
        mycursor = mydb.cursor()
        sql = f"SET GLOBAL {variable_name} = %s"
        val = (value,)
        mycursor.execute(sql, val)
        mydb.commit()
        print(f"成功使用 SET GLOBAL 设置 {variable_name} 为 {value}")
    except mysql.connector.Error as err:
        print(f"设置 {variable_name} 失败: {err}")
    finally:
        if mydb:
            mycursor.close()
            mydb.close()

def set_persist_variable(variable_name, value):
    """使用 SET PERSIST 命令设置全局变量并持久化。"""
    try:
        mydb = mysql.connector.connect(
            host="localhost",
            user="root",
            password="your_password",
            database="mysql"
        )
        mycursor = mydb.cursor()
        sql = f"SET PERSIST {variable_name} = %s"
        val = (value,)
        mycursor.execute(sql, val)
        mydb.commit()
        print(f"成功使用 SET PERSIST 设置 {variable_name} 为 {value}")
    except mysql.connector.Error as err:
        print(f"设置 {variable_name} 失败: {err}")
    finally:
        if mydb:
            mycursor.close()
            mydb.close()

def reset_persist_variable(variable_name):
    """使用 RESET PERSIST 命令重置全局变量为默认值。"""
    try:
        mydb = mysql.connector.connect(
            host="localhost",
            user="root",
            password="your_password",
            database="mysql"
        )
        mycursor = mydb.cursor()
        sql = f"RESET PERSIST {variable_name}"
        mycursor.execute(sql)
        mydb.commit()
        print(f"成功使用 RESET PERSIST 重置 {variable_name}")
    except mysql.connector.Error as err:
        print(f"重置 {variable_name} 失败: {err}")
    finally:
        if mydb:
            mycursor.close()
            mydb.close()

# 示例用法
set_global_variable("max_connections", 300)
set_persist_variable("innodb_buffer_pool_size", 8589934592)  # 8GB
reset_persist_variable("max_connections")

这个脚本演示了如何使用 SET GLOBALSET PERSISTRESET PERSIST 命令来自动化配置管理。

总结:持久化是关键,谨慎使用,自动化管理

SET PERSIST 命令是 MySQL 8.0 中一个强大的特性,它允许我们持久化系统变量的更改,从而简化配置管理并确保关键配置在服务器重启后仍然有效。 但是,需要谨慎使用,确保理解其作用范围和优先级。 结合自动化脚本,可以更有效地管理 MySQL 服务器的配置。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注