通過外表導入至湖倉版
AnalyticDB for MySQL企業版、基礎版及湖倉版支持通過外表讀取并導入外部數據。導入數據時,您可以選擇常規導入和彈性導入兩種方式。彈性導入相較于常規導入,可以大幅減少資源的消耗,降低導入過程中對在線讀寫業務的影響。本文介紹如何通過外表查詢OSS數據,并將OSS的數據導入AnalyticDB for MySQL集群。
前提條件
AnalyticDB for MySQL集群的產品系列為企業版、基礎版或湖倉版。
AnalyticDB for MySQL集群與OSS存儲空間位于相同地域。
已將數據文件上傳至OSS目錄中。具體操作,請參見上傳文件。
示例數據說明
本文示例將數據文件person
上傳至OSS中的testBucketName/adb/dt=2023-06-15
目錄,數據行分隔符為換行符,列分隔符為英文逗號(,)。person
中的示例數據如下:
1,james,10,2023-06-15
2,bond,20,2023-06-15
3,jack,30,2023-06-15
4,lucy,40,2023-06-15
操作步驟
進入SQL開發編輯器。
登錄云原生數據倉庫AnalyticDB MySQL控制臺,在左上角選擇集群所在地域。在左側導航欄,單擊集群列表,在企業版、基礎版或湖倉版頁簽下,單擊目標集群ID。
在左側導航欄,單擊 。
導入數據。
數據導入方式分為常規導入(默認)和彈性導入。常規導入在計算節點中讀取源數據,然后在存儲節點中構建索引,消耗計算資源和存儲資源。彈性導入在Serverless Spark Job中讀取源數據和構建索引,消耗Job型資源組的資源。僅內核版本3.1.10.0及以上且已創建Job型資源組的企業版、基礎版及湖倉版集群支持彈性導入數據。更多內容,請參見數據導入方式介紹。
常規導入
創建外部數據庫。
CREATE EXTERNAL DATABASE adb_external_db;
創建外表。使用CREATE EXTERNAL TABLE語句在外部數據庫
adb_external_db
中創建OSS外表。本文以adb_external_db.person為例。說明AnalyticDB for MySQL外表的字段名稱、字段數量、字段順序、字段類型需要與和OSS文件相同。
創建OSS非分區外表
CREATE EXTERNAL TABLE adb_external_db.person ( id INT, name VARCHAR(1023), age INT, dt VARCHAR(1023) ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE LOCATION 'oss://testBucketName/adb/dt=2023-06-15/';
創建OSS分區外表
創建OSS分區外表,并添加分區,才能查詢出OSS分區外表的數據。
創建OSS分區外表
CREATE EXTERNAL TABLE adb_external_db.person ( id INT, name VARCHAR(1023) , age INT ) PARTITIONED BY (dt STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS TEXTFILE LOCATION 'oss://testBucketName/adb/';
添加分區。您可以通過ALTER TABLE ADD PARTITION手動添加分區,也可以通過MSCK REPAIR TABLE自動識別并添加分區。
ALTER TABLE adb_external_db.person ADD PARTITION (dt='2023-06-15') LOCATION 'oss://testBucketName/adb/dt=2023-06-15/';
說明增加或刪除OSS外表的分區,請參見ALTER TABLE(外表)。
自動同步OSS外表的分區,請參見MSCK REPAIR TABLE。
OSS外表的語法說明,請參見CREATE EXTERNAL TABLE。
查詢數據。
數據表創建成功后,您可以在AnalyticDB for MySQL中通過SELECT語句查詢OSS的數據。
SELECT * FROM adb_external_db.person;
返回結果如下:
+------+-------+------+-----------+ | id | name | age | dt | +------+-------+------+-----------+ | 1 | james | 10 |2023-06-15 | | 2 | bond | 20 |2023-06-15 | | 3 | jack | 30 |2023-06-15 | | 4 | lucy | 40 |2023-06-15 | +------+-------+------+-----------+ 4 rows in set (0.35 sec)
在AnalyticDB for MySQL中創建數據庫。如果有已創建的數據庫,可以忽略本步驟。示例如下:
CREATE DATABASE adb_demo;
在AnalyticDB for MySQL中創建表用于存儲從OSS中導入的數據。示例如下:
說明創建的內表和步驟b中創建的外表的字段名稱、字段數量、字段順序、字段類型必須相同。
CREATE TABLE IF NOT EXISTS adb_demo.adb_import_test( id INT, name VARCHAR(1023), age INT, dt VARCHAR(1023) ) DISTRIBUTED BY HASH(id);
向表中導入數據。
方法一:使用
INSERT INTO
語句導入數據,當主鍵重復時會自動忽略當前寫入數據,數據不做更新,作用等同于INSERT IGNORE INTO
,更多信息,請參見INSERT INTO。示例如下:INSERT INTO adb_demo.adb_import_test SELECT * FROM adb_external_db.person;
方法二:使用
INSERT OVERWRITE INTO
語句同步導入數據,會覆蓋表中原有的數據。示例如下:INSERT OVERWRITE INTO adb_demo.adb_import_test SELECT * FROM adb_external_db.person;
方法三:使用
INSERT OVERWRITE INTO
語句異步導入數據,更多信息,請參見異步寫入。示例如下:SUBMIT JOB INSERT OVERWRITE adb_demo.adb_import_test SELECT * FROM adb_external_db.person;
彈性導入
創建數據庫。如果有已創建的數據庫,可以忽略本步驟。示例如下:
CREATE DATABASE adb_demo;
創建外表。
說明AnalyticDB for MySQL外表的字段名稱、字段數量、字段順序、字段類型需要與和OSS文件相同。
彈性導入僅支持
CREATE TABLE
語句創建外表。
CREATE TABLE oss_import_test_external_table ( id INT(1023), name VARCHAR(1023), age INT, dt VARCHAR(1023) ) ENGINE='OSS' TABLE_PROPERTIES='{ "endpoint":"oss-cn-hangzhou-internal.aliyuncs.com", "url":"oss://<bucket-name>/adb/oss_import_test_data.csv", "accessid":"LTAI5t8sqJn5GhpBVtN8****", "accesskey":"HlClegbiV5mJjBYBJHEZQOnRF7****", "delimiter":"," }';
重要創建外表時,CSV、Parquet、ORC格式的外表支持設置的TABLE_PROPERTIES參數不同:
CSV格式:僅支持設置
endpoint
、url
、accessid
、accesskey
、format
、delimiter
、null_value
和partition_column
參數。Parquet格式:僅支持設置
endpoint
、url
、accessid
、accesskey
、format
和partition_column
參數。ORC格式:僅支持設置
endpoint
、url
、accessid
、accesskey
、format
和partition_column
參數。
查詢數據。
數據表創建成功后,您可以在AnalyticDB for MySQL中通過SELECT語句查詢OSS的數據。
SELECT * FROM oss_import_test_external_table;
返回結果如下:
+------+-------+------+-----------+ | id | name | age | dt | +------+-------+------+-----------+ | 1 | james | 10 |2023-06-15 | | 2 | bond | 20 |2023-06-15 | | 3 | jack | 30 |2023-06-15 | | 4 | lucy | 40 |2023-06-15 | +------+-------+------+-----------+ 4 rows in set (0.35 sec)
在AnalyticDB for MySQL中創建表用于存儲從OSS中導入的數據。示例如下:
說明創建的內表和步驟b中創建的外表的字段名稱、字段數量、字段順序、字段類型必須相同。
CREATE TABLE adb_import_test ( id INT, name VARCHAR(1023), age INT, dt VARCHAR(1023) ) DISTRIBUTED BY HASH(id);
導入數據。
重要彈性導入僅支持通過
INSERT OVERWRITE INTO
語句導入數據。方法一:執行INSERT OVERWRITE INTO彈性導入數據,會覆蓋表中原有的數據。示例如下:
/+*elastic_load=true, elastic_load_configs=[adb.load.resource.group.name=resource_group]*/ INSERT OVERWRITE INTO adb_demo.adb_import_test SELECT * FROM adb_demo.oss_import_test_external_table;
方法二:異步執行INSERT OVERWRITE INTO彈性導入數據。通常使用
SUBMIT JOB
提交異步任務,由后臺調度。/*+elastic_load=true, elastic_load_configs=[adb.load.resource.group.name=resource_group]*/ SUBMIT JOB INSERT OVERWRITE INTO adb_demo.adb_import_test SELECT * FROM adb_demo.oss_import_test_external_table;
重要異步提交彈性導入任務時,不支持設置優先級隊列。
返回結果如下:
+---------------------------------------+ | job_id | +---------------------------------------+ | 2023081517195102101701907203151****** |
使用
SUBMIT JOB
提交異步任務后,返回結果僅表示異步任務提交成功。您可以通過job_id終止異步任務或查詢異步任務狀態,判斷任務是否執行成功。具體操作,請參見異步提交導入任務。Hint參數說明:
elastic_load:是否使用彈性導入方式。取值:true或false(默認值)。
elastic_load_configs:彈性導入方式支持配置的參數。參數需使用方括號([ ])括起來,且多個參數之間以豎線(|)分隔,支持配置的參數如下表所示:
參數
是否必填
說明
adb.load.resource.group.name
是
執行彈性導入任務的Job資源組名稱。
adb.load.job.max.acu
否
單個彈性導入任務最多使用的資源。單位為ACU,最小值為5 ACU。默認值為集群Shard個數+1。
執行如下語句可查詢集群Shard個數:
SELECT count(1) FROM information_schema.kepler_meta_shards;
spark.driver.resourceSpec
否
Spark driver的資源規格。默認值為small。取值范圍,請參見Spark資源規格列表的型號列。
spark.executor.resourceSpec
否
Spark executor的資源規格。默認值為large。取值范圍,請參見Spark資源規格列表的型號列。
spark.adb.executorDiskSize
否
Spark executor的磁盤容量,取值范圍為(0,100],單位為GiB,默認值為10 Gi。更多信息,請參見指定Driver和Executor資源。
(可選)查看已提交的導入任務是否為彈性導入任務。
SELECT job_name, (job_type = 3) AS is_elastic_load FROM INFORMATION_SCHEMA.kepler_meta_async_jobs where job_name = "2023081818010602101701907303151******";
返回結果如下:
+---------------------------------------+------------------+ | job_name | is_elastic_load | +---------------------------------------+------------------+ | 2023081517195102101701907203151****** | 1 | +---------------------------------------+------------------+
is_elastic_load
的返回值為1,表示已提交的導入任務是彈性導入任務;若為0,則表示已提交的導入任務是常規導入任務。