AlloyDB for PostgreSQL 的直接 Iceberg 存取功能,可讓您從 AlloyDB 執行個體,查詢 Cloud Storage 中以 Apache Iceberg 資料表格式儲存的資料。您可以使用 Cloud Storage bucket URI 或 Lakehouse 執行階段目錄存取 Iceberg 資料集。為加快分析工作負載,AlloyDB 提供內建的資料欄引擎,可最佳化掃描、彙整和匯總作業。直接存取 Iceberg 功能與資料欄引擎整合,可讓您在資料湖倉執行高效能分析查詢,不必建構、管理或維護複雜的擷取、轉換和載入 (ETL) 資料管道。
您可以使用標準 SQL 指令查詢 Iceberg 資料表、將 Iceberg 資料集與 AlloyDB 中的作業資料表彙整,以及將 Iceberg 資料表填入記憶體內資料欄引擎,加快查詢速度。
優點
直接存取 Iceberg 有下列好處:
- 零 ETL Lakehouse 存取:直接查詢外部 Iceberg 資料集,不必將資料複製或移至獨立的分析系統。
- 整合交易和分析查詢:將儲存在 AlloyDB 堆積資料表中的即時營運資料,與儲存在 Cloud Storage Iceberg 資料表中的大量歷來資料彙整。
- 彈性的目錄整合:透過 Cloud Storage bucket 路徑或 Lakehouse 執行階段目錄,存取 Iceberg 資料表中繼資料。
- 資料欄查詢加速:將 Iceberg 資料表快取並填入 AlloyDB 資料欄引擎記憶體,在 1 秒內完成分析處理。
- 標準 SQL 介面:使用熟悉的 PostgreSQL 語法查詢及分析 Iceberg 資料表。
直接存取 Iceberg 的運作方式
直接存取 Iceberg 時,會使用 PostgreSQL 資料表存取方法 (TAM) 介面 (USING iceberg),並與 AlloyDB 資料欄引擎規劃工具和執行架構整合。
查詢 Iceberg 資料表時,AlloyDB 會以下列其中一種模式運作:
- 直接掃描 (用於串流讀取):AlloyDB 直接從 Cloud Storage 讀取最新的中繼資料和資料檔案。資料欄引擎會以串流方式處理資料。
- 資料欄引擎加速 (用於記憶體內快取讀取):使用
google_columnar_engine_add()函式將 Iceberg 資料表填入 AlloyDB 資料欄引擎時,資料表會載入記憶體中的資料欄儲存庫。後續查詢會從資料欄引擎記憶體讀取,盡可能提高查詢處理量並縮短延遲時間。
快照提供和快取重新整理
AlloyDB 查詢的 Iceberg 資料表快照取決於讀取模式:
直接掃描:AlloyDB 會對最新的 Iceberg 快照執行查詢。查詢開始時,AlloyDB 會判斷最新可用的 Iceberg 資料表快照,並從該快照讀取資料,即使在
REPEATABLE READ或SERIALIZABLE交易中也是如此。AlloyDB 不支援跨交易的快照固定和時間點查詢。舉例來說,使用直接掃描查詢資料表時,交易中的每個陳述式都會從最新可用的快照讀取:
BEGIN TRANSACTION ISOLATION LEVEL SERIALIZABLE; SELECT * FROM customer_orders; -- If an external process commits a new Iceberg snapshot: SELECT * FROM customer_orders; -- Returns results from the new snapshot. COMMIT;資料欄引擎加速:AlloyDB 會在資料欄引擎中填入的快照執行查詢。如果 AlloyDB 在填入資料後,將新資料寫入 Cloud Storage 中的基礎 Iceberg 資料表,查詢可能會傳回過時資料。如要在基礎資料表上執行 DML 作業後取得最新資料,請使用
google_columnar_engine_refresh()函式重新整理快取。
支援的資料類型
在 AlloyDB 定義 Iceberg 資料表時,DDL 陳述式中的資料欄名稱和資料類型,必須與基礎 Iceberg 結構定義中的類型相符。
直接存取 Iceberg 支援下列 Apache Iceberg 資料類型和對應的 AlloyDB 類型:
| Apache Iceberg 資料類型 | AlloyDB 資料類型 | 說明 |
|---|---|---|
boolean |
BOOLEAN |
向量化轉換為位元組封裝格式 |
int |
INT/INTEGER |
32 位元有正負號整數 |
long |
BIGINT |
64 位元帶正負號整數 |
float |
REAL/FLOAT4 |
32 位元單精度浮點 |
double |
DOUBLE PRECISION/FLOAT8 |
64 位元雙精度浮點數 |
decimal(P, S) |
NUMERIC(P, S)/DECIMAL(P, S) |
精確度為 P 且小數位數為 S 的定點數值 |
string |
TEXT/VARCHAR |
UTF-8 字串值 |
date |
DATE |
日曆日期 (年、月、日) |
timestamp |
TIMESTAMP |
不含時區的時間戳記 |
timestamptz |
TIMESTAMPTZ |
包含時區的時間戳記 |
限制
直接存取 Iceberg 有下列限制:
- PostgreSQL 版本可用性:AlloyDB 支援在 PostgreSQL 18 以上版本直接存取 Iceberg。
- 使用者授權:只有具備
alloydbsuperuser角色,才能建立 Iceberg 資料表。建立資料表後,您可以將SELECT權限授予其他使用者,以便查詢 Iceberg 資料表。 - 唯讀作業:AlloyDB 僅支援對 Iceberg 資料表執行
SELECT查詢 (DQL)。不支援寫入作業 (INSERT、UPDATE、DELETE、TRUNCATE)。 - Apache Iceberg 規格版本:AlloyDB 不支援 Iceberg v2 刪除檔案 (位置和等值刪除) 或 Iceberg v3 刪除向量。
- 支援的檔案格式:直接存取 Iceberg 支援 Parquet 資料檔案,以及 JSON 和 Avro 中繼資料檔案。不支援 ORC 資料檔案。
- 快照版本管理:直接掃描查詢會在最新的 Iceberg 資料表快照執行,而資料欄加速查詢則會在填入的快照執行。AlloyDB 不支援時間點查詢。
- 結構定義演變:AlloyDB 不支援對 Iceberg 資料表執行
ALTER TABLE作業。基礎 Iceberg 資料表不得經過結構定義遷移。 - 中繼資料目錄支援:直接存取 Iceberg 時,支援直接 Cloud Storage bucket 路徑 (
gs://) 和 Lakehouse 執行階段目錄路徑 (bl://)。針對 Lakehouse 執行階段目錄,AlloyDB 僅支援使用者憑證模式。不支援憑證販售模式或其他 REST 目錄。 - 要求者付費 bucket:AlloyDB 不支援使用要求者付費的 Cloud Storage bucket。
- 完整填入限制:AlloyDB 不支援部分填入 Iceberg 資料表的資料欄。資料表必須能放入資料欄引擎記憶體或 SSD 空間。
- 母體堆積記憶體:填入含有大型 Parquet 資料列群組的 Iceberg 資料表時,可能會超過每個 worker 的母體堆積記憶體限制,尤其是在 vCPU 數量較少的執行個體上。如要解決這個問題,請參閱「資料欄引擎母體堆積已滿」。
事前準備
建立及查詢 Iceberg 資料表前,請務必完成下列事項:
- 在 Google Cloud上建立執行 PostgreSQL 18 以上版本的 AlloyDB 叢集。詳情請參閱「建立叢集」。
- 在 Cloud Storage 中託管 Apache Iceberg 資料表,或在 Lakehouse 執行階段目錄中註冊:
- 如果是 Cloud Storage 路徑,bucket 目錄結構必須遵循標準 Apache Iceberg 版面配置,其中包含
data/和metadata/子目錄,包括中繼資料 JSON 檔案和version-hint.text。詳情請參閱「建立 bucket」。 - 如果是 Lakehouse 執行階段目錄,請在使用者憑證模式下建立及註冊 Iceberg 目錄。詳情請參閱「設定 Apache Iceberg REST 目錄端點」。
- 如果是 Cloud Storage 路徑,bucket 目錄結構必須遵循標準 Apache Iceberg 版面配置,其中包含
- 為具備
alloydbsuperuser角色的使用者設定資料庫憑證。詳情請參閱「alloydbsuperuser群組角色」。
必要的角色
如要讓 AlloyDB 讀取 Iceberg 資料和中繼資料,您必須將必要的 IAM 角色授予 AlloyDB 叢集服務帳戶:
- Cloud Storage 存取權:針對含有 Iceberg 資料和中繼資料的 Cloud Storage bucket,授予 Storage 物件檢視者 (
roles/storage.objectViewer) 角色。 - BigLake 存取權 (如果使用 Lakehouse 執行階段目錄):在託管 BigLake 目錄的專案中,授予 BigLake 檢視者 (
roles/biglake.viewer) 角色。
如要找出叢集服務帳戶,請執行 gcloud beta alloydb clusters describe 指令:
gcloud beta alloydb clusters describe CLUSTER_ID --region=REGION_ID更改下列內容:
CLUSTER_ID:AlloyDB 叢集 ID。REGION_ID:AlloyDB 叢集的位置。例如,us-east1。如需完整的區域清單,請參閱「AlloyDB 位置」。
輸出內容包含 serviceAccountEmail 欄位,也就是這個叢集的服務帳戶。在 Google Cloud 控制台的「Cluster overview」(叢集總覽) 頁面中,可以找到服務帳戶。
如要使用 gcloud CLI 授予 Storage 物件檢視者角色,請執行:
gcloud storage buckets add-iam-policy-binding \
gs://BUCKET_NAME \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/storage.objectViewer"如果您使用 Lakehouse 執行階段目錄,請授予 BigLake 檢視者角色:
gcloud projects add-iam-policy-binding LAKEHOUSE_PROJECT_ID \
--member="serviceAccount:SERVICE_ACCOUNT_EMAIL" \
--role="roles/biglake.viewer"更改下列內容:
BUCKET_NAME:Cloud Storage bucket 的名稱。LAKEHOUSE_PROJECT_ID:託管 Lakehouse 執行階段目錄的 Google Cloud 專案 ID。SERVICE_ACCOUNT_EMAIL:您在serviceAccountEmail欄位中找到的叢集服務帳戶電子郵件。
設定資料庫旗標
如要啟用資料欄引擎和直接存取 Iceberg,您可以在 AlloyDB 執行個體設定資料庫旗標。在執行個體上設定下列資料庫旗標:
| 資料庫旗標 | 值 | 說明 |
|---|---|---|
google_columnar_engine.enabled |
on |
啟用 AlloyDB 資料欄引擎。 |
google_columnar_engine.enable_iceberg_reads |
on |
啟用直接存取 Iceberg 的功能。您必須重新啟動執行個體,設定才會生效。 |
google_columnar_engine.memory_size_in_mb |
SIZE_IN_MB | (選用) 為資料欄引擎分配記憶體。如果打算在記憶體中填入 Iceberg 資料表,建議使用這個選項。 |
如要使用 gcloud CLI 設定這些旗標,請執行 gcloud alloydb instances update 指令:
gcloud alloydb instances update INSTANCE_ID \
--cluster=CLUSTER_ID \
--region=REGION_ID \
--database-flags=google_columnar_engine.enabled=on,google_columnar_engine.enable_iceberg_reads=on更改下列內容:
INSTANCE_ID:AlloyDB 執行個體的 ID。CLUSTER_ID:AlloyDB 叢集的 ID。REGION_ID:AlloyDB 叢集的區域 ID。
在 AlloyDB 建立 Iceberg 資料表
如要在 AlloyDB 中公開 Apache Iceberg 資料集,請以具備 alloydbsuperuser 權限的使用者身分連線。接著,使用 USING iceberg 資料表存取方法建立資料表。
CREATE TABLE TABLE_NAME (
COLUMN_NAME DATA_TYPE [, ...]
)
USING iceberg
WITH (
uri = 'LOCATION_URI'
);
更改下列內容:
TABLE_NAME:要在 AlloyDB 建立的資料表名稱。COLUMN_NAME和DATA_TYPE:欄定義。資料欄名稱和類型必須與基礎 Iceberg 資料表的結構定義相符。LOCATION_URI:Iceberg 資料表中繼資料的位置。請指定下列其中一種格式:- 直接 Cloud Storage 路徑:
gs://BUCKET_NAME/PATH_TO_ICEBERG_TABLE - Lakehouse 執行階段目錄 URI:
bl://projects/PROJECT_ID/catalogs/CATALOG_NAME/databases/DATABASE_NAME/tables/TABLE_NAME
- 直接 Cloud Storage 路徑:
範例
下列範例說明如何在 AlloyDB 中建立 Iceberg 資料表。
從 Cloud Storage 路徑建立資料表
下列範例會建立名為 customer_orders 的資料表,並以 Cloud Storage bucket 中的 Iceberg 資料集為基礎:
CREATE TABLE customer_orders (
order_id BIGINT,
customer_id INT,
order_status TEXT,
total_amount DOUBLE PRECISION,
order_date DATE,
is_completed BOOLEAN
)
USING iceberg
WITH (
uri = 'gs://my-iceberg-analytics-bucket/datasets/sales/customer_orders'
);
從 Lakehouse 執行階段目錄建立資料表
下列範例會建立資料表,並參照 Lakehouse 執行階段目錄管理的 Iceberg 資料表:
CREATE TABLE customer_orders (
order_id BIGINT,
customer_id INT,
order_status TEXT,
total_amount DOUBLE PRECISION,
order_date DATE,
is_completed BOOLEAN
)
USING iceberg
WITH (
uri = 'bl://projects/my-analytics-project/catalogs/sales_catalog/databases/retail_db/tables/customer_orders'
);
查詢 Iceberg 資料
在 AlloyDB 建立資料表後,您可以使用標準 SQL SELECT 陳述式和 alloydbsuperuser 權限查詢資料表。您也可以選擇使用 GRANT 陳述式,將讀取的權限授予沒有 alloydbsuperuser 權限的使用者。例如:GRANT SELECT ON customer_orders TO normal_user。
查詢資料
以下範例說明如何執行查詢:
SELECT
customer_id,
COUNT(order_id) AS total_orders,
SUM(total_amount) AS total_spent
FROM customer_orders
WHERE is_completed = true
AND order_date >= '2026-01-01'
GROUP BY customer_id
ORDER BY total_spent DESC
LIMIT 10;
查詢聯合 Iceberg 資料和作業資料
您可以將 AlloyDB 中的即時營運資料,與 Iceberg 中的歷來資料合併:
SELECT
c.customer_name,
c.account_tier,
COUNT(o.order_id) AS total_orders,
SUM(o.total_amount) AS historical_spend
FROM customer_orders o
JOIN customers c ON o.customer_id = c.customer_id
WHERE o.is_completed = true
GROUP BY c.customer_name, c.account_tier
ORDER BY historical_spend DESC;
將資料匯入本機資料表
如要在本機 AlloyDB 儲存空間中,建立獨立且可寫入的 Iceberg 資料副本,請執行 CREATE TABLE ... AS SELECT,如以下範例所示:
CREATE TABLE local_customer_orders AS
SELECT * FROM customer_orders
WHERE order_date >= '2026-01-01';
使用資料欄引擎加快查詢速度
如果分析工作負載需要超低延遲時間,您可以直接將 Iceberg 資料表填入 AlloyDB 資料欄引擎記憶體。
將 Iceberg 資料表填入資料欄儲存庫
如要將 Iceberg 資料表的所有資料欄填入 AlloyDB 資料欄引擎,請使用 google_columnar_engine_add() 函式。例如:
SELECT google_columnar_engine_add('customer_orders');
如要僅填入查詢使用的特定資料欄,請傳遞以半形逗號分隔的資料欄名稱清單,做為第二個引數。例如:
SELECT google_columnar_engine_add('customer_orders', 'customer_id,order_status');
詳情請參閱「使用 SQL 函式新增資料欄」。
重新整理填入的資料
如果您將新的快照寫入基礎 Iceberg 資料集,請重新整理資料表,將最新資料重新載入資料欄引擎,讓查詢傳回最新結果:
SELECT google_columnar_engine_refresh('customer_orders');
從資料欄儲存庫中移除資料表
如要從資料欄儲存庫中移除 Iceberg 資料表,並還原為直接掃描:
SELECT google_columnar_engine_drop('customer_orders');
監控及驗證查詢執行
您可以監控 AlloyDB 如何對 Iceberg 資料表執行查詢,並確認查詢是否使用記憶體內資料欄引擎。使用系統檢視表查看快取填入狀態,並使用 EXPLAIN 檢查查詢執行計畫。
驗證資料欄快取狀態
如要確認 Iceberg 資料表是否已填入資料欄引擎,請查詢 g_columnar_relations 系統檢視表:
SELECT relation_name, status
FROM g_columnar_relations
WHERE relation_name = 'customer_orders';
如果 status 值為 USABLE,表示資料表已快取至資料欄引擎記憶體。
使用 EXPLAIN 檢查查詢執行計畫
如要確認查詢是否使用資料欄引擎,請使用 EXPLAIN 陳述式:
EXPLAIN (ANALYZE, COSTS OFF)
SELECT SUM(total_amount)
FROM customer_orders
WHERE is_completed = true;
輸出內容會透過資料表上的 Custom Scan (ColumnarScan) 節點,指出資料欄執行作業:
Custom Scan (ColumnarScan) on customer_orders
Filter: (is_completed = true)
疑難排解
本節說明如何在 AlloyDB 設定及查詢 Iceberg 資料表,以及如何解決常見問題。
google_columnar_engine.enable_iceberg_reads 旗標已停用
原因:直接存取 Iceberg 的資料庫旗標已停用。
建議修正方式:在執行個體中設定資料庫旗標 google_columnar_engine.enabled=on 和 google_columnar_engine.enable_iceberg_reads=on,然後重新啟動執行個體。
權限遭拒,無法存取 Cloud Storage
原因:AlloyDB 叢集服務帳戶缺少 Cloud Storage bucket 的讀取權限。
建議修正方式:將 bucket 的 roles/storage.objectViewer 角色授予叢集服務帳戶。
權限遭拒,無法存取 Lakehouse 執行階段目錄
原因:AlloyDB 叢集服務帳戶缺少 Lakehouse 執行階段目錄的讀取權限。
建議修正方式:將 roles/biglake.viewer 角色授予託管 Lakehouse 執行階段目錄的 Google Cloud 專案中的叢集服務帳戶。
資料欄填入失敗
原因:Iceberg 資料表大小超過資料欄引擎的可用記憶體和 SSD 空間。
建議修正方式:使用執行個體的 google_columnar_engine.memory_size_in_mb 旗標,增加分配給資料欄引擎的記憶體配置,或使用 google_columnar_engine.storage_cache_size 旗標,增加資料欄引擎儲存空間快取大小。詳情請參閱「設定資料欄引擎的儲存空間快取」。
資料欄引擎填入堆積已滿
錯誤訊息:
ERROR: Columnar engine population heap is full during population. Set
google_columnar_engine.population_heap_size_in_mb to a bigger value.
原因:填入大型 Parquet 資料列群組所需的記憶體,超過每個 worker 的填入堆積限制。
建議修正方式:減少平行母體工作站數量,讓母體程序能使用較大的堆積。在填入資料表的 SQL 工作階段中,請先將 google_job_scheduler.max_parallel_workers_per_job 旗標設為 0,再呼叫 google_columnar_engine_add() 函式:
SET google_job_scheduler.max_parallel_workers_per_job = 0;
SELECT google_columnar_engine_add('TABLE_NAME');
將 TABLE_NAME 替換為 AlloyDB 中的 Iceberg 資料表名稱。
後續步驟
- 瞭解 AlloyDB 資料欄引擎。
- 瞭解如何設定資料欄引擎。
- 選擇如何從 AlloyDB 存取 BigQuery 資料。