AWS RDS 上的错误 1045 (28000) mysql 加载数据 INFILE

ERROR 1045 (28000) on AWS RDS mysql LOAD DATA INFILE

我在 AWS RDS 上使用 MySQL 8.0.16。 当我 运行 SQL 命令时:

mysql> LOAD DATA INFILE 't1.csv'  INTO TABLE t1 FIELDS TERMINATED BY ','  ENCLOSED BY '"' LINES TERMINATED BY '\n';
ERROR 1045 (28000): Access denied for user 'admin'@'%' (using password: YES)

运行 mysql从 Shell 导入:

$ mysqlimport --local --compress  -u admin -pXXXXXXX -h HOST.rds.amazonaws.com DB --verbose --lines-terminated-by="\n" --fields-terminated-by=, --fields-enclosed-by='"' t1.csv
mysqlimport: [Warning] Using a password on the command line interface can be insecure.
Connecting to HOST.rds.amazonaws.com
Selecting database empresas
Loading data from LOCAL file: t1.csv into t1
empresas.cnaes: Records: 1209  Deleted: 0  Skipped: 0  Warnings: 1
Disconnecting from HOST.rds.amazonaws.com empresas

$ mysql -u admin -pXXXXXX-h HOST.rds.amazonaws.com DB -e "select count(*) from t1"   
mysql: [Warning] Using a password on the command line interface can be insecure.
+----------+
| count(*) |
+----------+
|        0 |
+----------+

我试过:

参考:https://forums.aws.amazon.com/message.jspa?messageID=902265

总结:

当我尝试从 mysql 提示导入数据时遇到错误 1045,当我尝试使用 mysql 导入实用程序导入时没有错误,但是 mysql导入不加载任何数据。

有人知道发生了什么事吗?

谢谢

tl;dr:使用这个:

mysql [connect-options] --local-infile --execute "LOAD DATA LOCAL INFILE 'foo.csv' ...;"

LOAD DATA INFILE 用于从位于 MySQL 服务器上的文件加载数据,而 LOAD DATA LOCAL INFILE 用于从位于客户端计算机上的文件加载数据 (其中 mysql CLI) 是 运行.

因为 RDS 是一项托管服务,您无法访问该服务所在的服务器 运行,LOAD DATA INFILE 是不可能的,因此需要 LOCAL 变体。

关于 LOAD DATA LOCAL INFILE 的一个重要细节是,所有工作仍然由服务器而不是客户端完成,并且 - 在幕后 - 它实际上 完全LOAD DATA INFILE 的工作方式相同,通过处理实际位于服务器上的文件...但不同的是该文件如何在服务器上找到自己...该文件是一个临时文件客户端流式传输到服务器以供此命令使用。 (这意味着对于使用 LOCAL 加载大文件,服务器上仍然需要足够的磁盘 space 来存储原始文件和生成行的 tablespace 存储。 )

从根本上说,mysql CLI 是一个程序,它建立到服务器进程的基于套接字的连接并提供 shell 用于键入(或管道)SQL 语句,发送它们分别发送到服务器执行,并解压缩任何返回的结果...所以 LOAD DATA LOCAL INFILE -- SQL 语句 -- 需要客户端和服务器之间奇怪的相互作用,这并不像直觉所建议的那样工作.它实际上是这样工作的:

(console) mysql> LOAD DATA LOCAL INFILE 'foo.csv' ...;
(socket) (client) "Hey, server, run this query: LOAD DATA LOCAL INFILE 'foo.csv' ...
(socket) (server) "Okay, client, I parsed that query without problems, so now I need you to start streaming me your local file 'foo.csv'.
(socket) (client) "Okay, server, here is that raw file..."

所以...哎呀,服务器要求客户端流式传输文件,其名称由服务器指定。显然,如果服务器代码是恶意的或客户端正在执行不受信任的查询,则这里有多种可能的攻击。

这就是 mysql CLI 具有 --local-infile 选项的原因。如果没有此选项,客户端代码将不会交出服务器请求的文件,服务器会发现这一点,并且 returns 出错。

根据文档,在 MySQL Server 8.0 之前,这是您遇到的一般错误:

ERROR 1148 (42000): The used command is not allowed with this MySQL version.

从Server 8.0开始,应该更具体:

ERROR 3950 (42000): Loading local data is disabled; this must be enabled on both the client and server side

不清楚 MySQL 8.0 的 RDS 为什么返回旧错误。

另见 Security Issues with LOAD DATA LOCAL