MySQL 使用LOAD DATA定期同步数据到阿里云数据库

  之前有个小的测试项目需要定时同步本地的一些数据到阿里云数据库,用了最机械的脚本执行LOAD DATA来实现,这里简单介绍一下。

  LOAD DATA能够快速的将文本文件数据读入表中(导入数据使用LOAD DATA通常比使用INSERT语句快20倍 ),LOAD DATA与SELECT … INTO OUTFILE属于逆向互补功能,要将数据从表导出到文本文件,就使用 SELECT … INTO OUTFILE,反之则使用 LOAD DATA,两者的FIELDS和LINES子句的语法相同。

LOAD DATA
    [LOW_PRIORITY | CONCURRENT] [LOCAL] --LOCAL:从客户端主机读取文本文件
    INFILE 'file_name'
    [REPLACE | IGNORE] --REPLACE:输入行将替换现有重复行,IGNORE:跳过重复行
    INTO TABLE tbl_name
    [PARTITION (partition_name [, partition_name] ...)]
    [CHARACTER SET charset_name] --指定文件中的所有字段解释为具有相同的字符集,而不管字段值加载到的列的数据类型如何
    [{FIELDS | COLUMNS} --FIELDS必须在LINES之前
        [TERMINATED BY 'string'] --列字段分隔符,默认\t
        [[OPTIONALLY] ENCLOSED BY 'char'] --指定列值的包括符,默认空
        [ESCAPED BY 'char'] --转义字符,默认\
    ]
    [LINES
        [STARTING BY 'string'] --行起始符
        [TERMINATED BY 'string'] --换行符,默认\n
    ]
    [IGNORE number {LINES | ROWS}] --导入的时候跳过指定的前几行
    [(col_name_or_user_var
        [, col_name_or_user_var] ...)]
    [SET col_name={expr | DEFAULT}
        [, col_name={expr | DEFAULT}] ...]

  FIELDS ESCAPED BY控制如何读取或写入特殊字符:

  几个官方例子:
# 字段由逗号分隔,字段值用双引号引起来,数据文件第一行以列名开头,行以回车/换行符对终止。
LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
  FIELDS TERMINATED BY ',' ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n'
  IGNORE 1 LINES;
# 以回车/换行对结尾的行
LOAD DATA INFILE '/tmp/jokes.txt' INTO TABLE jokes
  FIELDS TERMINATED BY ''
  LINES TERMINATED BY '\n%%\n' (joke);

  一般情况下,都是本地的数据文件导入到本地的数据库中,弹药将客户端主机上的文件执行导入到远程MySQL数据库,就需要用到LOCAL关键字。这里说明一下:LOCAL仅当服务器和客户端都已配置为允许时才可以使用,例如,如果 mysqld是在local_infile禁用系统变量的情况下启动的,LOCAL则无法使用。

  • 如果LOCAL指定,则文件将由客户端主机上的客户端程序读取,并发送到服务器;可以将文件指定为完整路径名以指定其确切位置,如果给出为相对路径名,则相对于启动客户端程序的目录来解释该名称;
  • 如果LOCAL未指定,则该文件必须位于服务器主机上,并且可以由服务器直接读取。服务器使用以下规则来定位文件:如果文件名是绝对路径名,则服务器将按照给定的名称使用它;如果文件名是具有一个或多个前导组件的相对路径名,则服务器将搜索相对于服务器数据目录的文件;如果给出的文件名中没有前导组件,则服务器将在默认数据库的数据库目录中查找该文件。

  LOAD DATA使用LOCAL存在两个潜在的安全问题:

  • 数据库服务器会告诉客户端程序传输服务器选择的文件,而不是语句中命名的文件,数据库服务器可以访问客户端用户具有读取访问权限的客户端主机上的任何文件;
  • 在web环境中,客户从web服务器进行连接,用户可以使用LOAD DATA LOCAL来读取Web服务器进程具有读取权限的任何文件(假设用户可以针对SQL Server运行任何语句)。在这种环境下,关于MySQL服务器的客户端实际上是Web服务器,而不是由连接到Web服务器的用户运行的远程程序。
      为了避免连接到不受信任的服务器,客户端可以建立安全连接并通过使用–ssl-mode=VERIFY_IDENTITY选项和适当的CA证书进行连接来验证服务器身份;为了控制本地数据加载数据,MySQL允许启用或禁用LOCAL功能,从MySQL 8.0.21开始,MySQL客户端只能从本地指定目录中的数据文件实现加载数据功能。

  下面来看通过LOAD DATA LOCAL定时本地同步数据到阿里云的案例,定时:
[root@mysqlplus2 ~]# crontab -e

01 00 * * 1-6 /home/mysqlbak/script/bigdata_impinc.sh

  先导出需要的数据:

SELECT insId,areaNo,jointId,contractId,sold
FROM tb_jyx_ins_bizarea into outfile "/home/databak/tb_bizarea.txt" fields terminated by ',';

SELECT tb_member.mid,openid,unionid,cellPhone,nickname,
    sex,headImgUrl,country,city,province,xlanguage,privilege,
    nextMid,createDatetime,bindphoneDatetime
FROM tb_member where TO_DAYS(NOW())-TO_DAYS(createDatetime)=1 into outfile "/home/databak/tb_member.txt" fields terminated by ',';

SELECT orgID,orgname,disno,province,city,orgnum,fullname,orgtype
 FROM tb_organization into outfile "/home/databak/tb_organization.txt" fields terminated by '|';

  再看看LOAD DATA:

set autocommit=0;
set unique_checks=0;
load data local infile "/home/databak/tb_bizarea.txt" into table tb_test_bizareafields terminated by ',';
load data local infile "/home/databak/tb_member.txt" replace into table tb_test_member fields terminated by ',';
load data local infile "/home/databak/tb_organization.txt" into table tb_test_organization fields terminated by '|'(orgID,orgname,disno,province,city,orgnum,fullname,orgtype) ;
set unique_checks=1;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章