【问题标题】:How to set sql_mode in my.cnf in MySQL 8?如何在 MySQL 8 的 my.cnf 中设置 sql_mode?
【发布时间】:2026-01-18 10:40:02
【问题描述】:

我正在运行 MySQL 8.0.11 社区版。我需要将 sql_mode 设置为在 my.cnf 中排除 ONLY_FULL_GROUP_BY ,以便安全重启。我尝试了以下变体:

sql_mode= STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
sql-mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

无论变量名为“sql_mode”还是“sql-mode”,它们都以相同的方式失败:

mysqld --verbose --help | grep "sql[-_]mode"
2018-06-19T15:22:51.667734Z 0 [ERROR] [MY-011071] [Server] /usr/sbin/mysqld: Error while setting value 'STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' to 'sql_mode'
    --sql-mode=name     Syntax: sql-mode=mode[,mode[,mode...]]. See the manual
2018-06-19T15:22:51.675498Z 0 [ERROR] [MY-010119] [Server] Aborting

sql模式

似乎 mysqld 处理 my.cnf 并将 'sql_mode' 或 'sql-mode' 转换为 'sql_mode',然后它会拒绝!

问题是如何解决这个问题?

【问题讨论】:

    标签: mysql mysql-8.0 sql-mode


    【解决方案1】:

    SQL 模式NO_AUTO_CREATE_USER 在 MySQL 8.0 中被移除,不再被识别。

    https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html#mysql-nutshell-deprecations 说:

    删除了以下与帐户管理相关的功能:

    • 使用GRANT 创建用户。相反,请使用CREATE USER。按照这种做法,NO_AUTO_CREATE_USER SQL 模式对于 GRANT 语句,所以它也被删除了。

    将您的 sql_mode 更改为“STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION”。我在我的 8.0.11 沙盒实例上对此进行了测试,并且成功了。

    sql-mode 或 sql_mode 的拼写都可以。

    使用引号或省略引号都可以。

    【讨论】:

    【解决方案2】:

    假设“安全重启”只是意味着永久,语法是:

    sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
    

    来自Setting the SQL Mode

    要在服务器启动时设置 SQL 模式,请使用 --sql-mode="modes" 命令行中的选项,或选项文件中的sql-mode="modes" 例如 my.cnf(Unix 操作系统)或 my.ini(Windows)。 modes 是用逗号分隔的不同模式的列表。

    如果它对您不起作用,则可能是您将其放在错误的部分下。对于需要为[mysqld]的服务器设置,如:

    [mysqld]
    sql-mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
    

    【讨论】:

      【解决方案3】:

      步骤1.检查sql模式:

      mysql -u root -p -e "SELECT @@GLOBAL.sql_mode;"
      

      步骤2.在/etc/mysql/conf.d/目录下新建配置文件:

      sudo nano /etc/mysql/conf.d/disable_strict_mode.cnf 
      

      在编辑器上输入以下文本:

      [mysqld]
      
      sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
      

      步骤 3. 重启 MySQL:

      sudo service mysql restart
      

      第 4 步。确认更改:

      mysql -u root -p -e "SELECT @@GLOBAL.sql_mode;"
      

      NO_AUTO_CREATE_USER SQL 模式已在 MySQL 8.0 中移除,请查看full list of SQL modes 的参考手册。

      【讨论】:

      • 我可以确认这适用于 Ubuntu 20.04 和 MySQL 8.0。
      【解决方案4】:

      我没有找到使用 my.cnf 解决问题的方法。为了安全重启mysqld,我需要避免这样做:

      SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
      

      我发现解决这个问题的唯一方法是设置一个环境变量:

      sudo systemctl set-environment MYSQLD_OPTS="--sql-mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"
      sudo systemctl restart mysqld
      

      欢迎提供更好的解决方案。

      【讨论】:

        【解决方案5】:

        在最新版本的 Ubuntu/Debian 中,就我而言,我正在修改文件 /lib/systemd/system/mysql.service

        ExecStart=/usr/sbin/mysqld --sql-mode=NO_ENGINE_SUBSTITUTION
        

        之后,再执行:

        systemctl daemon-reload
        systemctl restart mysql
        

        *.cnf 文件的更改没有任何作用。

        【讨论】:

        • 检查您的 my.cnf 文件中是否存在设置 sql_mode 的冗余行。文件中设置该变量的 last 行优先。所以看起来对文件的更改似乎什么也没做,实际发生的情况可能是您的更改被后面的行覆盖。
        • 在最新的 Linux 和 MySQL8.x 环境中,sql_mode 的行为存在一些限制。
        【解决方案6】:

        编辑my.cnf 不适用于 MySQL 8。所以我开发了一个解决方法。我在 Ubuntu 20.04 中使用 MySQL 8

        我创建了一个文件/etc/mysql/mysqlmode.sql

        SET GLOBAL sql_mode = (SELECT REPLACE(@@sql_mode, 'ONLY_FULL_GROUP_BY', ''));
        

        接下来,我编辑了/etc/mysql/my.cnf,并在最后添加了这几行代码:

        [mysqld]
        init-file="/etc/mysql/mysqlmode.sql"
        

        【讨论】:

          【解决方案7】:

          对于 MacOs Catalina,我使用 MysqlWorkbench 将“服务器/状态和../ =>系统变量并搜索 sql_mode”中的“持久”复选框关闭 如果没有该操作,它将忽略 my.cnf 设置/

          那是我的: [mysqld] sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

          【讨论】:

            【解决方案8】:

            我只是发现该选项与 my.cnf 中的“NO_AUTO_CREATE_USER”不兼容。这可能与某些设置冲突。

            以下行在 MySQL 8 中适用于我。

            [mysqld] sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

            【讨论】: