【问题标题】:MySQL DROP DATABASE equivalent w/o root access or DROP privilegesMySQL DROP DATABASE 等效无 root 访问或 DROP 权限
【发布时间】:2009-12-20 19:26:19
【问题描述】:

我正在协调一些 PHP 开发项目。我已经设置了一个工作流程,开发人员都使用一个 Subversion 存储库。当他们准备好在登台服务器上查看他们的应用程序时,上传 MySQL 数据库转储并创建标签。

我已经配置了一个 shell 脚本,它会自动将 PHP 代码部署到 DocumentRoot 并配置适当的权限。我现在需要编写加载数据库快照的脚本。

当我第一次配置一个新的应用程序时,我会创建一个数据库和用户帐户,如下所示:

CREATE DATABASE foodb;
GRANT ALL ON foodb.* TO user1@localhost IDENTIFIED BY 'password';

现在,当开发人员将新版本的 MySQL 转储检查到 Subversion 时,我需要删除旧数据库并恢复新快照。我目前正在使用以下工作流程。

1.) 以 root 身份登录 MySQL

DROP DATABASE foodb;
CREATE DATABASE foodb;
GRANT ALL ON foodb.* TO user1@localhost IDENTIFIED BY 'password';

2.) 登录 MySQL“user1”

mysql -h localhost -u user1 --password="drumitFed" foodb << new-db-dump-from-subversion.sql

我想合并上面的步骤 1 和 2。我想它看起来像这样。代码不仅应该删除表,还应该删除视图、索引和存储过程。

请注意,它必须以数据库用户而非超级用户身份运行,并且数据库用户没有 DROP DATABASE 或 CREATE DATABASE 权限。

mysql -h localhost -u user1 --password="password" foodb << delete-all-tables-and-views.sql
mysql -h localhost -u user1 --password="password" foodb << new-db-dump-from-subversion.sql

【问题讨论】:

  • 特定数据库上的 MySQL CREATE 和 DROP 权限还使该用户能够删除和重新创建数据库本身。因此,您可以安全地提供它,而不会影响数据库之外的任何内容。

标签: mysql svn workflow


【解决方案1】:

我没有时间对此进行测试,但尝试授予用户 CREATE 权限 MySQL 范围内,然后创建每个数据库的用户应该有权删除他们创建的内容,如果没有,您可以授予他们删除该数据库的权限?

【讨论】:

  • 好主意。我认为这会让我做我想做的事情。它还允许用户创建其他数据库,但这是可以接受的风险。
【解决方案2】:

您的选择是:

  1. 以 root 身份运行脚本
  2. 如果可能,通过角色向数据库用户授予适当的权限。
  3. 让用户能够为脚本提供转储,该脚本以 root 身份运行

数据库不会允许您绕过访问控制。

【讨论】:

    【解决方案3】:

    首先,超级用户与否在这里没有直接关系。 mysql 通常有一个“root”用户,但不必与 root 登录相关联。

    您的问题似乎是“我如何以 mysql 用户的身份执行 X,并使该用户不必获得执行 X 的权限”,这导致了“您不能”的答案。因此,您的问题似乎还有其他问题。为什么要对所有事情都使用同一个用户?

    不知何故,您需要拥有更大的权限才能设置环境。这可以做到 通过拥有一个单独的 mysql 用户或单独的 mysql 服务器,或者在设置期间临时关闭 mysql 服务器并使用 --skip-grant-tables 运行它的单独实例。

    【讨论】:

      【解决方案4】:

      您可以使用 information_schema 来生成执行该工作的 SQL 查询。我对您正在使用的脚本解决方案了解不多,因此我无法为此提出任何建议,但这里有一个示例 SQL 脚本,它可以在 MySQL 内部完成所有操作:

      DELIMITER go
      
      DROP PROCEDURE IF EXISTS p_drop_all_tables;
      go
      
      CREATE PROCEDURE p_drop_all_tables()
      BEGIN
          DECLARE v_table_type VARCHAR(64);
          DECLARE v_table_name VARCHAR(64);
          DECLARE v_not_found TINYINT(1) DEFAULT FALSE;
          DECLARE csr_tables CURSOR FOR
              SELECT  CASE table_type
                          WHEN 'BASE TABLE' THEN 'TABLE'
                          ELSE table_type
                      END table_type
              ,       table_name
              FROM    information_schema.TABLES
              WHERE   table_schema = SCHEMA()
              AND     table_type IN ('BASE TABLE', 'VIEW')
              ;
          DECLARE CONTINUE HANDLER FOR NOT FOUND 
              SET v_not_found := TRUE;
      
          SET @@foreign_key_checks := OFF;
          OPEN csr_tables;
          table_loop: LOOP
      
              FETCH   csr_tables 
              INTO    v_table_type
              ,       v_table_name
              ;
              IF v_not_found THEN
                  CLOSE csr_tables;
                  LEAVE table_loop;
              END IF;
      
              SET @stmt := CONCAT(
                  'DROP '
              ,   v_table_type
              ,   ' `', v_table_name, '`'
              );
              PREPARE stmt FROM @stmt;
              EXECUTE stmt;
              DEALLOCATE PREPARE stmt;
      
          END LOOP;
          SET @@foreign_key_checks := ON;
      END;
      go
      
      CALL p_drop_all_tables();
      go
      
      DROP PROCEDURE p_drop_all_tables;
      go
      
      DELIMITER; 
      

      【讨论】:

        【解决方案5】:

        你也许可以作弊。

        如果您可以安排脚本以 root 或 mysql 用户身份运行,您可以让脚本安装具有适当数据库权限和“空白”模式设置的数据库。

        关闭mysql

        复制 -rp .../clean/* /var/lib/mysql/

        启动mysql

        所以,数据库的干净副本有创建的数据库和授权语句,但没有数据。

        -丹尼尔

        【讨论】:

          【解决方案6】:

          您可以向用户授予全局权限。这不是最安全的,但它确实保护了 root 用户密码,如果这是一个删除数据库是常见操作的系统,那么数据完整性似乎就不那么重要了。

          您可以在 mysqldump 中使用 --add-drop-database 标志在导入转储之前删除数据库:

          --add-drop-database Add a 'DROP DATABASE' before each create.
          

          【讨论】:

            【解决方案7】:

            为什么不这样做?

            mysql -h localhost -u root --password="xxx" foodb << delete-all-tables-and-views.sql
            mysql -h localhost -u user1 --password="yyy" foodb << new-db-dump-from-subversion.sql
            

            脚本本身不需要以 root 身份运行。 MySQL“root”和系统的“root”是分开的。

            【讨论】:

              猜你喜欢
              • 2016-09-18
              • 2014-06-02
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多