このトピックでは、OracleデータベースをPolarDBクラスターに移行する前に考慮する必要がある重要なポイントについて説明します。 スムーズな移行プロセスを確保するために、移行前にこのトピックをよくお読みください。
シーケンス値の同期
質問
移行中に、移行元Oracleデータベースのシーケンス値が移行先のPolarDBクラスターに自動的に同期されますか。 OracleデータベースからPolarDBクラスターにシーケンス値を同期するにはどうすればよいですか。
分析
PolarDBは、ソースデータベースのシーケンス値を自動的に同期しません。 PolarDBは、PostgreSQLプロトコルで定義された論理レプリケーション機能を完全にサポートしています。 ただし、シーケンス値はPostgreSQLプロトコルの論理レプリケーションスコープには含まれません。
最初のスキーマ移行中に、移行時のシーケンス値 (Q1など) の1回限りのスナップショットがPolarDBクラスターに同期されます。 最初の移行後、データは引き続きOracleデータベースに追加または更新されます。 Oracleデータベースのシーケンス値はQ2に増加する可能性がありますが、PolarDBクラスターのシーケンス値はQ1のままです。 ただし、ターゲットPolarDBクラスターのテーブルデータは、ソースOracleデータベースとリアルタイムで同期されます。
Q1の値を使用して新しいレコードをPolarDBクラスターに挿入すると、Oracleデータベースで同じシーケンス番号が使用されているため、重複キーエラーが発生します。
ソリューション
解決策1: データ送信サービス (DTS) を使用してシーケンスを同期する
DTSインスタンスの [増分書き込み] ページで、[シーケンスの同期] をクリックします。 このようにして、DTSはシーケンス値を同期するためのシーケンス同期ステートメントを生成します。 詳細については、「ターゲットデータベースのシーケンスの値の更新」をご参照ください。
解決策2: シーケンス値を手動で同期する
OracleデータベースからPolarDBクラスターにシーケンス値を手動で同期する方法については、「自己管理OracleデータベースからPolarDB For PostgreSQL (Compatible with Oracle) クラスターへのデータの移行」をご参照ください。
エンコード設定
質問
OracleデータベースはGBKまたはUTF-8エンコーディングを使用できます。 PolarDBクラスターにはどのエンコーディングを使用しますか?
解決策
Oracleデータベースでは、GBKまたはUTF-8文字セットを使用できます。 OracleデータベースをPolarDBクラスターに移行するには、PolarDBクラスターのUTF-8文字セットを指定することを推奨します。 UTF-8文字セットは互換性が高く、次の利点があります。
エンコードの競合のリスクを回避する: PolarDBクラスターの文字セットとしてGBKを使用しないことを推奨します。 GBKには、ASCIIコードと同じエンコード範囲を共有する特定の文字があります。 これにより、データ移行中にエンコーディングエラーが発生する可能性があります。
文字化けのコード挿入の防止: オラクルは、無効なGBKエンコーディングの挿入を許可します。これにより、データが読み戻されるときに文字化けのテキストが発生する可能性があります。 PolarDBは、無効なGBKエンコーディングの挿入をサポートしていません。 無効なGBKエンコーディングをPolarDBに挿入しようとすると、データが拒否される可能性があります。
したがって、OracleデータベースからPolarDBクラスターへのスムーズでエラーのない移行を保証するために、UTF-8エンコードを使用することを推奨します。
テーブル名の大文字と小文字の区別
質問
デフォルトでは、テーブル名と列名はOracleデータベースでは大文字、PolarDBクラスターでは小文字です。 OracleデータベースからPolarDBクラスターにデータを移行する際の大文字と小文字の区別の違いに対処するにはどうすればよいですか。
解決策
デフォルトでは、スキーマ名、テーブル名、列名など、引用符で囲まれていないすべての名前が大文字に変換されます。 デフォルトでは、PolarDB for PostgreSQL (Compatible with Oracle) は引用されていないすべての名前を小文字に変換します。 OracleデータベースからPolarDB for PostgreSQL (Compatible with Oracle) クラスターにデータを移行する場合、DTSはビジネス要件に基づいて次のデフォルトのソリューションを使用します。
引用符なしの名前を大文字から小文字に変換する
適用シナリオ: Oracleデータベースのスキーマ名、テーブル名、および列名は引用されません。
解決策: DTSは、PolarDB for PostgreSQL (Compatible with Oracle) クラスターへの移行中に、引用符なしの名前をすべて小文字に自動的に変換します。 移行後も、引き続き二重引用符なしで名前を使用できます。 変更や特別な設定は必要ありません。
引用された名前の元のケースを保持する
適用可能なシナリオ: 表名と列名は混合ケースを使用し、Oracleデータベースでは二重引用符で囲まれています。
解決策: DTSは、移行中に名前の元の大文字小文字を保持します。 特定のマッピングを無効にしてください。 PolarDB for PostgreSQL (Compatible with Oracle) クラスターへの移行後も、引き続き二重引用符付きの名前を使用できます。 変更や特別な設定は必要ありません。
大文字と小文字を区別しないクエリを許可する
デフォルトでは、PolarDBクラスター内の名前が大文字または小文字のテーブル名を使用して、名前が大文字のテーブルを照会できます。
CHARおよびVARCHARデータ長セマンティクス
質問
VARCHAR (20) はOracleとPolarDBで同じデータ長を指定しますか。
分析
VARCHAR(20) データ型は、OracleとPolarDBで異なる方法で実装されます。
Oracleデータベースでは、
CHARとVARCHARのデータ型は長さをバイト単位で指定します。PolarDB for PostgreSQL (Compatible with Oracle) クラスターでは、
CHARおよびVARCHARデータ型はデフォルトで長さを文字単位で指定します。PolarDB for PostgreSQL (Compatible with Oracle) クラスターでは、
polar_default_char_length_semanticsパラメーターを使用して、CHARおよびVARCHARデータ型のデフォルトの長さのセマンティクスを変更できます。 デフォルトでは、パラメーター値はOFFで、CHARおよびVARCHARデータ型の長さは文字単位で測定されます。 パラメーターをONに設定した場合、CHARおよびVARCHARのデータ型の長さはバイト単位で測定されます。説明PolarDBコンソールで
polar_default_char_length_semanticsパラメーターを設定できます。 詳細は、「クラスターパラメーターの設定」をご参照ください。
解決策
polar_default_char_length_semanticsパラメーターがONに設定されている場合:シナリオ: Oracleデータベースでは、
CHAR(10)列にGBK文字が使用されます。 PolarDB for PostgreSQL (Compatible with Oracle) クラスターでは、対応するCHAR(10)列にUTF-8文字セットが使用されます。問題: OracleデータベースからPolarDB for PostgreSQL (Compatible with Oracle) クラスターへの順方向同期中に、OracleデータベースのCHAR(10) 列に "文字列" が書き込まれます。 文字列は
2 × 5 = 10バイトを占めます。これはまさに列の最大バイト数です。 ただし、PolarDB for PostgreSQL (Oracleと互換) クラスターでは、文字列「文字列」が15文字を占め、列の最大バイト数を超えています。 エラーが報告されます。解決策
解決策1: 移行中に関連するエラーが発生しないように、
polar_default_char_length_semanticsパラメーターをOFFに設定します。解決策2: PolarDB for PostgreSQL (Compatible with Oracle) クラスターの列の長さをより大きなサイズに変更します。
polar_default_char_length_semanticsパラメーターがOFFに設定されている場合:シナリオ: Oracleデータベースでは、
CHAR(10)列にGBK文字が使用されます。 PolarDB for PostgreSQL (Compatible with Oracle) クラスターでは、対応するCHAR(10)列にUTF-8文字セットが使用されます。問題: PolarDB for PostgreSQL (Compatible with Oracle) クラスターからOracleデータベースへの逆同期中に、PolarDB for PostgreSQL (Compatible with Oracle) クラスターのCHAR(10) 列に文字列「」が書き込まれます。 実際の占有文字数は
2 + 8 = 10です。 文字列がバイトに変換されると、文字列は2 × 3 + 8 = 14バイトを占め、これはOracleデータベースのCHAR(10) 列の長さを超えます。 データ切り捨てエラーが報告されます。解決策
解決策1: Oracleデータベースの列の長さをより大きなサイズに変更します。
解決策2: DTSで抽出、変換、読み込み (ETL) タスクを設定して、余分な文字を切り捨てます。 詳細については、「データ移行または同期タスクでのETLの設定」をご参照ください。
主キーまたは一意キーのないテーブル
質問
主キーまたは一意キーのないテーブルがOracleデータベースに存在する場合はどうすればよいですか? データ検証は影響を受けますか?
解決策
テーブルにプライマリキーまたは一意のキーがない場合、移行プロセス中にデータの一貫性を保証できないため、移行先クラスターにエントリが重複する可能性があります。 ビジネス要件に基づいて、次のいずれかのソリューションを使用できます。
データの一貫性がビジネスにとって重要でない場合、または移行後に重複排除を実行する予定がある場合は、移行プロセスを続行できます。
データの一貫性がビジネスにとって重要な場合は、Oracleデータベースの
ROWID列をターゲット・クラスターの隠し主キー (空でない一意のキー) として使用できます。 DTSコンソールにログインし、プライマリキーのないテーブル /一意のキーのないテーブルの隠しプライマリキーの追加パラメーターをYesに設定します。 詳細については、「自己管理型OracleデータベースからPolarDB For PostgreSQL (Compatible with Oracle) クラスターへのデータの移行」をご参照ください。 移行タスクが完了したら、対応するボタンをクリックして、隠しプライマリキーを削除します。 次に、データ検証を実行できます。 主キーのないテーブルはデータ検証をサポートしないことに注意してください。
\0文字の処理
質問
Oracleデータベースで非表示の \0文字を処理するにはどうすればよいですか?
解決策
PolarDB for PostgreSQL (Oracleと互換) は \0文字をサポートしていません。 DTSは、移行プロセス中に \0文字を削除します。
共通フィールドに \0文字が含まれている場合、文字を削除すると、移行の前後でデータの不一致が発生する可能性があります。
主キーフィールドに
\0文字が含まれている場合、文字を削除するとデータが競合する可能性があります。 たとえば、プライマリキー値がdts\0とdtsの2つのレコードがあるとします。 移行後、2つのキー値はdtsに変換され、データの競合が発生します。
空の文字列
質問
Oracleデータベースでは、空の文字列 ('') はNULL値として扱われます。 PolarDBはこの動作をサポートしていますか?
解決策
SQL標準によれば、空の文字列はNULL値とは区別される。 ただし、Oracleは空の文字列をNULL値として扱います。 PolarDBは、polar_empty_string_is_null_enableパラメーターを使用して、Oracleのこの動作をサポートします。 デフォルトでは、パラメーターはONに設定され、空の文字列はPolarDBクラスターでNULL値として扱われます。 この機能が不要になった場合は、PolarDBコンソールで無効にできます。 詳細は、「クラスターパラメーターの設定」をご参照ください。
タイムゾーンの設定
質問
PolarDBクラスターのタイムゾーンを設定するにはどうすればよいですか。 タイムゾーン設定の影響は何ですか?
解決策
デフォルトでは、PolarDBクラスターのタイムゾーン値はUTCです。 UTCは協定世界時の略です。 クラスターから保存または取得されるすべてのタイムスタンプはUTCに基づいています。
たとえば、2024年12月3日18:13:34 (UTC + 8) にクラスターの現在のデータと時刻を照会します。
SELECT * FROM now();次の応答が返されます。
now
--------------------------------
2024-12-03 10:13:34.018557 +00
(1 row)PolarDBクラスターでUTC + 8時刻を使用する場合は、PolarDBコンソールでtimezoneパラメーターをPRCに設定します。 詳細は、「クラスターパラメーターの設定」をご参照ください。 現在の時刻を照会します。
SELECT * FROM now();次の応答が返されます。
now
--------------------------------
2024-12-03 18:14:34.841027 +08
(1 row)INTEGERデータ型の精度
質問
Oracleデータベースでは、INTEGER型はNUMBER(38) で、最大38桁の整数を格納できます。 PolarDB for PostgreSQL (Compatible with Oracle) クラスターでは、INTEGER型は32ビット整数です。 ソースOracleデータベースとターゲットPolarDBクラスター間のINTEGERデータ型の精度の違いに対処するにはどうすればよいですか?
解決策
PolarDBクラスターのout of integerエラーを防ぐには、クエリのCAST(val AS INTEGER) をCAST(val AS NUMBER(38)) に置き換えます。
次の例では、99999999999数がPolarDB for PostgreSQL (Compatible with Oracle) クラスターの32ビット整数の制限を超えています。 これにより、PolarDB for PostgreSQL (Oracleと互換) クラスターでout of integerエラーが発生します。 対照的に、Oracleデータベースは番号を正しく処理できます。
SELECT CAST(99999999999 AS INTEGER) FROM dual;Oracleデータベースのサンプル結果:
CAST(99999999999ASINTEGER) _____________________________ 99999999999PolarDB for PostgreSQL (Oracle互換) クラスターのサンプル結果:
ERROR: integer out of range
PolarDB for PostgreSQL (Compatible with Oracle) クラスターのクエリを変更します。
SELECT CAST(99999999999 AS NUMBER(38)) FROM dual;PolarDB for PostgreSQL (Oracle互換) クラスターのサンプル結果:
numeric
-------------
99999999999
(1 row)