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;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章