【问题标题】:Creating MySQL function requires SUPER privileges创建 MySQL 函数需要 SUPER 权限
【发布时间】:2014-06-25 14:33:36
【问题描述】:

我有一个用于比较版本的简单 MySQL 函数:

CREATE FUNCTION `compareVersions` (
  versionA VARCHAR(50),
  versionB VARCHAR(50)) RETURNS INT DETERMINISTIC NO SQL
BEGIN
  DECLARE a1 INT;
  DECLARE b1 INT;
   DECLARE c1 INT;
    DECLARE d1 INT;
  DECLARE a2 INT;
  DECLARE b2 INT;
   DECLARE c2 INT;
    DECLARE d2 INT;  SET a1 = SUBSTRING_INDEX( `versionA` , '.', 1 );
  SET b1 = SUBSTRING_INDEX(SUBSTRING_INDEX( `versionA` , '.', 2 ),'.',-1);
  SET c1 = SUBSTRING_INDEX(SUBSTRING_INDEX( `versionA` , '.', -2 ),'.',1);
  SET d1 = SUBSTRING_INDEX( `versionA` , '.', -1 );
  SET a2 = SUBSTRING_INDEX( `versionB` , '.', 1 );
  SET b2 = SUBSTRING_INDEX(SUBSTRING_INDEX( `versionB` , '.', 2 ),'.',-1);
  SET c2 = SUBSTRING_INDEX(SUBSTRING_INDEX( `versionB` , '.', -2 ),'.',1);
  SET d2 = SUBSTRING_INDEX( `versionB` , '.', -1 ); 
  IF (a1 > a2) THEN 
    RETURN -1;
  ELSEIF ((a1 = a2) AND (b1 > b2)) THEN
    RETURN -1;
  ELSEIF ((a1 = a2) AND (b1 = b2) AND (c1 > c2)) THEN
    RETURN -1;
  ELSEIF ((a1 = a2) AND (b1 = b2) AND (c1 = c2) AND (d1 > d2)) THEN
    RETURN -1;
  ELSEIF ((a1 = a2) AND (b1 = b2) AND (c1 = c2) AND (d1 = d2)) THEN  
    RETURN 0;
  ELSE
    RETURN 1;
  END IF;
END $$

它的创建失败

您没有 SUPER 权限并且启用了二进制日志记录(您 可能想要使用不太安全的 log_bin_trust_function_creators 变量)

这与this question 几乎相同,但我的函数不读取任何 SQL 数据,它很简单,具有确定性,我认为它没有理由需要任何额外的权限。从文档中我不清楚创建所有函数是否需要 SUPER 权限(这很荒谬,使许多用户无法使用存储的函数,每个无权访问其数据库配置的人)。我什至不知道该函数是否有效,这是首先想到的,但语法应该是正确的(分隔符在 PHPMyAdmin 中设置)。可以从数据库中获取所有数据并在 PHP 应用程序中进行比较,但我认为这样做最容易。是否可以?有没有人有更好的比较版本的解决方案?

【问题讨论】:

  • 您运行它的用户是否具有 EXECUTE 权限? (或创建/alter_routine 权限)
  • 我不确定,但我想是这样... SHOW GRANTS FOR 'user'@'localhost' 会产生两行:GRANT USAGE 和 GRANT ALL PRIVILEGES

标签: php mysql phpmyadmin create-function


【解决方案1】:

您可以为此调整全局变量:

/* allows to create functions as not root */
SET GLOBAL log_bin_trust_function_creators = 1;

我在 setup-sql 文件中使用它来初始化数据库以恢复转储。

【讨论】:

  • 我无法更改全局变量,因为我没有 root 权限。问题部分与此有关:我需要全局 root 权限来创建存储函数吗?
  • 您需要 CREATE ROUTINE 和可选的 ALTER ROUTINE 权限来创建存储过程。但通常你应该拥有这些特权。请检查一下 SHOW GRANTS FOR CURRENT_USER();为你出现。
  • 如上所述,我在数据库上有 GRANT USAGE 和 GRANT ALL PRIVILEGES。它包括创建例程吗?我想是的,但是函数创建失败了。
  • 不表示你可以将unsage权限和gran talk权限授予其他用户
  • 您能提供一些参考吗?文档说 ALL 分配指定级别(在我的情况下是数据库级别)除 GRANT OPTION 之外的所有可用权限,并且 CREATE ROUTINE 在数据库级别可用。
【解决方案2】:

我通过在 PHP 中进行长而丑陋的数据库查询来规避这个问题。也许使用存储过程而不是函数会更好。经过搜索我在文档中发现here这个说法:

MySQL 5.5 中存储函数的使用现状可以 总结如下。 [...] 要创建或更改存储的函数, 除了 CREATE ROUTINE 之外,您还必须拥有 SUPER 权限 或通常需要的 ALTER ROUTINE 权限。

确实,如果启用了二进制日志记录,您确实需要 SUPER 权限才能创建存储函数。这严重限制了存储函数在更大的服务器上的使用,并且在我看来降低了整个 DBMS 的价值。看起来像经典的“它不是错误,它是一个功能”。如果在将二进制日志记录更改为 on 后重新启动数据库服务器,我担心存储函数会发生什么。

【讨论】:

  • 正如我之前提到的,ET GLOBAL log_bin_trust_function_creators = 1;将允许您在没有超级权限的情况下创建 SP 和函数。我曾多次在共享托管系统上创建存储过程和函数,但我没有 root 权限。所以通常一个认真的主机应该启用上述选项。
  • 正如我所提到的,我对此没有权利,并且它没有在我使用的系统上设置错误。关于托管商我不能说什么,但有问题的服务器不用于托管,如果我是任何数据库服务器的管理员,除非强烈要求,否则我不会隐式设置一些标记为“潜在不安全”的设置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-06
  • 2021-07-09
  • 2012-08-18
  • 2014-02-17
  • 2021-06-30
相关资源
最近更新 更多