本文說明如何將資料庫從 Oracle® 線上交易處理 (OLTP) 系統遷移至 Spanner。
Spanner 使用的一些概念與其他企業資料庫管理工具不同,因此您可能需要調整應用程式,以充分利用其功能。您可能也需要以 Google Cloud 的其他服務補足 Spanner,以滿足您的需求。
遷移限制條件
將應用程式遷移到 Spanner 時,必須考量可以使用的不同特色。您可能需要重新設計應用程式架構,以符合 Spanner 的特徵集,並與其他 Google Cloud 服務整合。
內儲程序和觸發條件
Spanner 不支援在資料庫層級執行使用者程式碼,因此在遷移時,必須將資料庫層級的內儲程序和觸發條件實作的企業邏輯一起遷移到應用程式內。
序列
建議您使用 UUID 4 版做為產生主鍵值的預設方法。GENERATE_UUID()
函式 (GoogleSQL、PostgreSQL) 會將 UUID 4 版值傳回為 STRING
類型。
如果您需要產生 64 位元整數值,Spanner 支援正向位元反轉序列 (GoogleSQL、PostgreSQL),可產生在正向 64 位元數字空間中平均分配的值。您可以使用這些數字避免資源使用率不均的問題。
詳情請參閱「主鍵預設值策略」。
存取權控管
您可以使用身分與存取權管理 (IAM) 功能,控制使用者和群組對專案、Spanner 執行個體和 Spanner 資料庫層級的 Spanner 資源存取權。詳情請參閱「身分與存取權管理總覽」。
請針對存取資料庫的所有使用者和服務帳戶,依據最低權限原則審查及實施 IAM 政策。如果應用程式需要對特定資料表、資料欄、檢視畫面或變更串流實施精細存取權控管機制 (FGAC),請實作精細存取權控管機制 (FGAC)。詳情請參閱細項存取權控管總覽。
資料驗證限制條件
Spanner 可以在資料庫層支援有限的一套資料驗證限制條件。
如果您需要更複雜的資料限制條件,請在應用程式層實作。
下表討論在 Oracle® 資料庫中常見的限制條件類型,以及如何使用 Spanner 進行實作。
限制 | 使用 Spanner 實作 |
---|---|
Not null | NOT NULL 欄限制條件 |
Unique | 具有 UNIQUE 限制條件的次要索引 |
Foreign key (適用於普通資料表) | 請參閱「建立及管理外來鍵關係」。 |
外鍵 ON DELETE/ON UPDATE 動作 |
僅適用於交錯式資料表,否則在應用程式層實施。 |
透過 CHECK 限制條件或觸發條件進行值的檢查和驗證 |
在應用程式層實施 |
支援的資料類型
Oracle® 資料庫和 Spanner 支援不同的資料類型組合。下表列舉了 Oracle 資料類型和 Spanner 中與其對等的資料類型。如要進一步瞭解各 Spanner 資料類型的詳細定義,請參閱「資料類型」。
您可能也必須按照「Note」(附註) 欄的描述對資料進行額外的轉換,讓 Oracle 資料符合您的 Spanner 資料庫。
例如,您可以將大型 BLOB
儲存為 Cloud Storage 值區中的物件,而非儲存於資料庫中,將 URI 參考以 STRING
形式儲存至資料庫中的 Cloud Storage 物件。
Oracle 資料類型 | Spanner 等價 | 附註 |
---|---|---|
字元類型 (CHAR 、VARCHAR 、NCHAR 、NVARCHAR ) |
STRING
|
注意:Spanner 一律使用 Unicode 字串。 Oracle 支援的最大長度為 32,000 個位元組或字元 (取決於類型),Spanner 則最多支援 2,621,440 個字元。 |
BLOB 、LONG RAW 、BFILE
|
包含物件 URI 的 BYTES 或 STRING 。 |
小型物件 (小於 10 MiB) 可儲存為 BYTES 。請考慮使用其他 Google Cloud 產品 (例如 Cloud Storage) 來儲存較大型的物件。 |
CLOB 、NCLOB |
STRING (包含資料或指向外部物件的 URI) |
小型物件 (小於 2,621,440 個字元) 可儲存為 STRING 。請考慮使用其他 Google Cloud 產品 (例如 Cloud Storage) 來儲存較大型的物件。 |
NUMBER 、NUMERIC 、DECIMAL
|
STRING 、FLOAT64 、INT64
|
NUMBER Oracle 資料類型最多支援 38 位精確度,FLOAT64 Spanner 資料類型則最多支援 16 位精確度。如需替代機制,請參閱「儲存任意精確度數值資料」。 |
INT 、INTEGER 、SMALLINT
|
INT64
|
|
BINARY_FLOAT 、BINARY_DOUBLE
|
FLOAT64
|
|
DATE
|
DATE
|
Spanner DATE 類型的預設 STRING 表示是 yyyy-mm-dd ,與 Oracle 不同,因此自動轉換至 STRING 日期表示或從其轉換時要小心。提供 SQL 函式,將日期轉換為格式化字串。 |
DATETIME
|
TIMESTAMP
|
Spanner 儲存的時間與時區無關。如果您需要儲存時區,則需使用單獨的 STRING 欄。提供 SQL 函式,使用時區將時間戳記轉換為格式化字串。 |
XML
|
STRING (包含資料或指向外部物件的 URI) |
小型 XML 物件 (少於 2,621,440 個字元) 可儲存為 STRING 。請考慮使用其他 Google Cloud 產品 (例如 Cloud Storage) 來儲存較大型的物件。 |
URI 、DBURI 、XDBURI 、HTTPURI |
STRING
|
|
ROWID
|
PRIMARY KEY
|
Spanner 在內部使用資料表的主鍵進行排序和參照,因此在 Spanner 中,其實際上與 ROWID 資料類型相同。 |
SDO_GEOMETRY 、SDO_TOPO_GEOMETRY_SDO_GEORASTER
|
Spanner 不支援地理空間資料類型。您必須使用標準資料類型儲存此資料,並在應用程序層中實作任何搜尋和過濾邏輯。 | |
ORDAudio 、ORDDicom 、ORDDoc 、ORDImage 、ORDVideo 、ORDImageSignature |
Spanner 不支援媒體資料類型。請考慮使用 Cloud Storage 來儲存媒體資料。 |
遷移程序
遷移過程的時間表如下:
- 轉換結構定義和資料模型。
- 翻譯任何 SQL 查詢。
- 遷移應用程式,除了 Oracle 之外,還會使用 Spanner。
- 使用 Dataflow 從 Oracle 大量匯出資料,並將資料匯入 Spanner。
- 在遷移期間維持兩個資料庫之間的一致性。
- 將應用程式從 Oracle 遷移出去。
步驟 1:轉換資料庫和結構定義
您將現有的結構定義轉換成 Spanner 結構定義,以儲存您的資料。此應儘可能與現有的 Oracle 結構定義相近,以利簡化應用程式的修改。然而,由於功能的差異,您可能必須做一些變更。
使用結構定義設計的最佳做法可協助您增加總處理量,並減少 Spanner 資料庫中的熱點。
主要金鑰
在 Spanner 中,每個需要儲存一列以上的資料表都必須具有由該資料表的一欄或多欄組成的主鍵。您的資料表的主鍵將唯一識別資料表中的每一列,資料表列是按照主鍵排序的。由於 Spanner 是高度分散式,因此請務必選擇可隨著資料成長而調整的索引鍵產生技術。詳情請參閱建議的主鍵遷移策略。
請注意,指定主鍵後,除非刪除並重新建立資料表,否則無法新增或移除主鍵資料欄,也無法稍後變更主鍵值。如要進一步瞭解如何指定主鍵,請參閱「結構定義和資料模型 - 主鍵」。
交錯資料表
Spanner 有一個功能,可將兩份資料表定義為具有一對多的父項─子項關係。這樣會讓子項資料列與其父項列在儲存空間中交錯,並能有效地將資料表預先彙整,而且當同時查詢父項與子項時,可以改善資料擷取效率。
子項資料表的主鍵必須從父項資料表的主鍵欄開始。從子項列的觀點來看,父項列主鍵被稱為外部鍵。您最多可以定義六層的父項─子項關係。
您可以為子項資料表定義 on-delete 動作,以決定當父項列被刪除時,會發生什麼事:所有子項列都被刪除,或當子項列存在時,父項列刪除會被封鎖。
以下是建立交錯於先前定義的父項 Singers 資料表中 Albums 資料表的範例:
CREATE TABLE Albums (
SingerId INT64 NOT NULL,
AlbumId INT64 NOT NULL,
AlbumTitle STRING(MAX),
) PRIMARY KEY (SingerId, AlbumId)
INTERLEAVE IN PARENT (Singers)
ON DELETE CASCADE;
建立次要索引
您也可以建立次要索引,從主鍵之外索引資料表內的資料。
Spanner 使用和資料表相同的方式實作次要索引,讓欲使用為索引鍵的欄值具有和資料表主鍵相同的限制條件。這也表示索引具有和 Spanner 一樣的一致性保證。
使用次要索引進行值查詢實際上等於使用資料表彙整的查詢。您可以使用 STORING
子句,將原始資料表的欄值副本儲存於次要索引,使其成為覆蓋索引,以改善查詢效能。
當索引本身儲存了被查詢的所有欄 (覆蓋查詢) 時,Spanner 查詢最佳化器會自動僅使用次要索引。查詢原始資料表中各欄時,如要強制使用某一索引,您必須在 SQL 陳述式中使用 FORCE INDEX
指令,例如:
SELECT *
FROM MyTable@{FORCE_INDEX=MyTableIndex}
WHERE IndexedColumn=@value
您可以對某資料欄定義一個 UNIQUE
索引,以強制使該資料表欄內的值不重複。索引將阻止您新增重複的值。
以下是為 Albums 資料表建立次要索引的 DDL 陳述式範例︰
CREATE INDEX AlbumsByAlbumTitle ON Albums(AlbumTitle);
請注意,如果您在資料載入之後建立額外的索引,填入索引可能需要一些時間。您應該將新增索引的頻率限制為平均每天三次。如需建立次要索引的詳細說明,請參閱「次要索引」。如要進一步瞭解索引建立的限制,請參閱結構定義更新。
步驟 2:翻譯任何 SQL 查詢
Spanner 使用附擴充功能的 ANSI 2011 SQL 方言,而且擁有許多函式和運算子,以協助翻譯及匯總您的資料。您必須將任何使用 Oracle 特有語法、函式和類型的 SQL 查詢轉換成與 Spanner 相容。
雖然 Spanner 不支援以結構化資料做為欄定義,但 SQL 查詢中可以利用 ARRAY
和 STRUCT
類型,而使用結構化資料。
例如,您可以撰寫查詢,在單一查詢中使用 STRUCTs
的 ARRAY
(利用預先彙整的資料),傳回某位藝人的所有專輯。詳情請參閱說明文件的「關於子查詢的說明」一節。
您可以使用 Google Cloud 主控台中的 Spanner Studio 頁面來執行查詢,以分析 SQL 查詢的效能。對大型資料表進行全資料表掃描的查詢通常非常昂貴,應該謹慎使用。
如要進一步瞭解如何將 SQL 查詢最佳化,請參閱 SQL 最佳做法說明文件。
步驟 3:遷移應用程式以使用 Spanner
Spanner 提供了一組包含各種語言的用戶端程式庫,以及使用 Spanner 特定 API 呼叫、SQL 查詢和資料修改語言 (DML) 陳述式讀取或寫入資料的功能。使用 API 呼叫對於某些查詢 (例如直接依鍵值讀取列) 可能更迅速,因為不需要翻譯 SQL 陳述式。
您也可以使用 Java Database Connectivity (JDBC) 驅動程式連接到 Spanner,利用沒有本機整合的現有工具和基礎架構。
在遷移程序中,Spanner 中無法使用的功能必須在應用程式中實施。例如,驗證資料值並更新相關資料表的觸發條件必須在應用程式中使用讀取/寫入交易來實施,以讀取現有的列,驗證限制條件,然後將更新過的列寫入兩個資料表。
Spanner 提供讀寫和唯讀交易,確保資料的外部一致性。此外,讀取交易可以套用時間戳記邊界,讓您讀取在以下方式中指定的一致性資料版本︰
- 過去的精確時間 (最多 1 小時以前)。
- 在未來 (讀取將被封鎖,直至到達該時刻為止)。
- 傳回到過去某一時間的一致性資料檢視 (具有可接受的有限過時性),不需檢查另一複本上是否有較新的資料。這樣可以獲得效能益處,但代價是資料可能過時。
步驟 4:將資料從 Oracle 轉移至 Spanner
為了將資料從 Oracle 轉移到 Spanner,您需要將 Oracle 資料庫以可攜帶的檔案格式 (例如 CSV) 匯出,然後使用 Dataflow 將該資料匯入 Spanner。
從 Oracle 大量匯出
Oracle 不提供任何用於將整個資料庫匯出或卸載至可攜帶檔案格式的內建公用程式。
Oracle 常見問題中列出了執行匯出的一些選項。
其中包括:
- 使用 SQL*plus 或 SQLcl 將查詢排存至文字檔。
- 撰寫使用 UTL_FILE 的 PL/SQL 函式,將資料表平行卸載至文字檔。
- 使用 Oracle APEX 或 Oracle SQL Developer 內的功能,將資料表卸載至 CSV 或 XML 檔案。
每一個選項都有一次只能匯出一個資料表的缺點,這表示您必須暫停應用程式或停用資料庫,讓資料庫維持於匯出的一致狀態。
其他選項包括第三方工具,例如 Oracle 常見問題頁面中列出的工具,其中有些可以卸載資料庫的一致性資料檢視。
這些資料表卸載之後,您應將資料表上傳到 Cloud Storage 值區,以便將之匯入。
大量匯入至 Spanner
由於 Oracle 和 Spanner 的資料庫結構定義或許並不相同,您可能需要做一些資料轉換,這是匯入過程的一部分。
執行這些資料轉換,並匯入 Spanner 最容易的方法是使用 Dataflow。
Dataflow 是 Google Cloud 分散式擷取、轉換及載入 (ETL) 服務。此為執行使用 Apache Beam SDK 撰寫的資料管道提供一個平台,以便在多部機器上平行讀取和處理大量資料。
Apache Beam SDK 要求您撰寫一個簡單的 Java 程式,以設定讀取、轉換和寫入資料。Cloud Storage 和 Spanner 都存在 Beam 連接器,因此唯一需要撰寫的程式碼是資料轉換本身。
請參閱本文隨附的範例程式碼存放區中一個簡單的管道範例:從 CSV 檔案讀取,並寫入 Spanner。
如果您的 Spanner 結構定義中使用了父項─子項交錯資料表,則匯入過程中必須留意,讓父項列在子項列之前建立。Spanner 匯入管道程式碼會先匯入根層次的所有資料,接下來是所有第一層子項資料表,然後是所有的第二層子項資料表,依此類推,以處理這個問題。
Spanner 匯入管道可用來直接大量匯入資料,但您的資料必須使用正確的結構定義,並以 Avro 檔案形式存在。
步驟 5:維持兩個資料庫之間的一致性
許多應用程式都有可用性要求,因此無法離線匯出和匯入資料。當您將資料轉移到 Spanner 時,應用程式仍會繼續修改現有的資料庫。當應用程式執行時,您必須複製對 Spanner 資料庫的更新。
有許多方法可以維持兩個資料庫同步,包括變更資料擷取,以及在應用程式中實施同時更新。
變更資料擷取
Oracle GoldenGate 可為 Oracle 資料庫提供變更資料擷取 (CDC) 串流。Oracle LogMiner 或 Oracle XStream Out 是 Oracle 資料庫的替代介面,可用於取得不涉及 Oracle GoldenGate 的 CDC 串流。
您可以開發一套應用程式訂閱其中一個串流,並將相同的修改套用在您的 Spanner 資料庫上 (但當然要先經過資料轉換後再套用)。這類串流處理應用程式必須實作多項功能:
- 連線至 Oracle 資料庫 (來源資料庫)。
- 連線至 Spanner (目標資料庫)。
- 重複執行下列操作:
- 接收 Oracle 資料庫 CDC 串流產生的資料。
- 解讀 CDC 串流產生的資料。
- 將資料轉換為 Spanner
INSERT
陳述式。 - 執行 Spanner
INSERT
陳述式。
資料庫遷移技術是一種中介軟體技術,已將必要功能納入其功能。資料庫遷移平台會根據客戶需求,以個別元件的形式安裝在來源位置或目標位置。資料庫遷移平台只需要相關資料庫的連線設定,即可指定並開始從來源資料庫持續傳輸資料至目標資料庫。
Striim 是可在Google Cloud上使用的資料庫移轉技術平台。它可連線至 Oracle GoldenGate 和 Oracle LogMiner 以及 Oracle XStream Out 的 CDC 串流。Striim 提供圖形工具,可讓您設定資料庫連線,以及從 Oracle 轉移資料至 Spanner 所需的任何轉換規則。
您可以從 Google Cloud Marketplace 安裝 Striim,連線至來源和目標資料庫、實作任何轉換規則,並開始傳輸資料,而無須自行建構串流處理應用程式。
從應用程式同時更新兩個資料庫
另一種方法是修改應用程式,以執行對兩個資料庫的寫入。一個資料庫 (最初是 Oracle) 將會視為事實來源,而且在每一次資料庫寫入之後,會讀取一整列,進行轉換,然後寫入 Spanner 資料庫。
如此一來,應用程式將不斷地以最新資料覆寫 Spanner 列。
當您確信所有資料都已經正確轉移之後,便可將事實來源切換至 Spanner 資料庫。
如果在切換至 Spanner 時發現問題,此機制提供復原的路徑。
驗證資料一致性
當資料流入 Spanner 資料庫時,您可以定期比較 Spanner 資料和 Oracle 資料,確保資料一致。
您可以查詢兩個資料來源,並比較結果,以驗證一致性。
您可以使用 Dataflow,利用彙整轉換對大型資料集進行詳細的比較。此轉換會使用兩個具有鍵值的資料集,並依據鍵值比對各值。接下來可以比較匹配的值是否相等。
您可以定期執行此一驗證,直到一致性等級符合您的公司需求。
步驟 6:切換至 Spanner,做為應用程式的事實來源
當您對資料遷移有信心時,您可以將應用程式切換為使用 Spanner 做為事實來源。繼續將變更寫回 Oracle 資料庫,讓 Oracle 資料庫維持於最新狀態,萬一出現問題,您還可以復原。
最後,您可以停用並移除 Oracle 資料庫更新程式碼,並關閉 Oracle 資料庫。
匯出及匯入 Spanner 資料庫
您可以選擇性使用 Dataflow 範本執行匯出,將資料表從 Spanner 匯出至 Cloud Storage 值區。產生的資料夾包含一組 Avro 檔案和 JSON 資訊清單檔案,其中包含已匯出的資料表。這些檔案可以使用於各種用途,其中包括︰
- 備份資料庫,以實現資料保留政策合規性或用於災難復原。
- 將 Avro 檔案匯入 BigQuery 等其他 Google Cloud 產品。
如要進一步瞭解匯出和匯入程序,請參閱「匯出資料庫」和「匯入資料庫」。
後續步驟
- 瞭解如何最佳化 Spanner 結構定義。
- 瞭解如何將 Dataflow 用於更複雜的情況。