我最近在 MySQL 5.5.x 中尝试过这个:
GRANT
SELECT, INSERT, UPDATE, DELETE, TRUNCATE ON crawler.*
TO 'my_user'@'localhost' WITH GRANT OPTION;
这会导致错误:
ERROR 1064 (42000):您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,了解在“TRUNCATE ON 爬虫”附近使用的正确语法。* TO 'my_user'@'localhost' with GRANT OPTION' 在第 2 行
这在我添加
TRUNCATE
之前曾经有效,所以经过一番研究后我发现MySQL不支持这一点。
原因是
TRUNCATE
被归类为DDL操作,因此它内部不使用DELETE
,而是使用DROP
。好吧,所以我想限制该用户删除表(如果发生安全漏洞,至少恶意用户必须确定表的名称并单独删除它们)。
但是,事实证明我需要授予该用户
DROP
权限,该权限也允许用户删除整个数据库。鉴于没有为单个表提供资助,还有其他方法可以做到这一点吗?我想我可以将其交给另一个用户的另一个进程,但对于这么小的问题感觉有点麻烦。
暂时我会坚持使用
DELETE
,尽管它相当慢! (在我的笔记本电脑上,删除 160 万小行需要大约 55 秒,截断相同的小行只需不到一秒的时间)。然而,如果有更快、更安全的替代方案,我会洗耳恭听。
要将特定数据库中特定表的 DROP 权限授予 MySQL 中的特定用户,可以使用如下的 GRANT 语句。 (这假设表
fi
存在于数据库 fee
中,并且这是您希望允许用户 'fo'@'%'
能够 TRUNCATE 的表):
GRANT DROP ON TABLE fee.fi TO 'fo'@'%'
要查看用户有权截断该特定表:
SHOW GRANTS FOR 'fo'@'%' ;
并以用户
'fo'@'%'
身份连接进行测试:
TRUNCATE TABLE fee.fi ;
(显然,用户也有权限删除同一个表。但这就是 MySQL 中的方式。)
作为替代方案,允许用户仅对该特定表执行 TRUNCATE 操作,而不授予用户
DROP
对该表的权限...
创建一个执行
TRUNCATE fee.fi;
的存储过程(由于它是 DDL,因此可能需要动态执行。)该过程需要使用 DEFINER
权限创建,并由具有所需权限的用户创建。
然后您可以将过程的执行权限授予用户:
GRANT EXECUTE ON fee.truncate_table_fee_fi TO 'fo'@'%';
编辑
注意:上面的语法可能有错误,并且可能需要包含关键字 PROCEDURE。无论需要什么语句来允许 fo 调用该过程
将程序费用.truncate_table_fee_fi 上的执行授予 'fo'@'%';
然后用户
'fo'@'%'
可以
CALL fee.truncate_table_fee_fi