AWS RDS mysql LOAD DATA INFILE上的错误1045(28000)

时间:2019-12-28 18:09:53

标签: mysql load amazon-rds mysqlimport

我在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)

从Shell运行mysqlimport:

$ 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 |
+----------+

我尝试过:

  • 参数‘log_bin_trust_function_creators’= 1

  • 更改主密码

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

摘要:

当我尝试从mysql提示符下导入数据时出现错误1045,而当我尝试使用mysqlimport实用程序进行导入时我没有错误,但是mysqlimport不会加载任何数据。

有人知道发生了什么吗?

谢谢

1 个答案:

答案 0 :(得分:0)

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加载大文件,服务器上仍需要足够的磁盘空间来存储原始文件和所生成行的表空间。)

从根本上讲,mysql CLI是一个程序,该程序建立与服务器进程的基于套接字的连接,并提供用于键入(或管道传递)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选项的原因。如果没有此选项,则客户端代码将不会移交服务器请求的文件,服务器会发现并返回错误。

根据文档,在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