フラッシュバッククエリ機能を使用すると、過去の特定の時点に存在していたクラスター、データベース、およびテーブルからデータを効率的に取得できます。
前提条件
PolarDB クラスターは、次のいずれかのバージョンである必要があります:
PolarDB for MySQL 8.0.2、リビジョンバージョン 8.0.2.2.21 以降。
PolarDB for MySQL 8.0.1、リビジョンバージョン 8.0.1.1.32 以降。
PolarDB for MySQL 5.7、リビジョンバージョン 5.7.1.0.25 以降。
PolarDB for MySQL 5.6、リビジョンバージョン 5.6.1.0.36 以降。
詳細については、「バージョン番号のクエリ」をご参照ください。
フラッシュバッククエリ機能は、innodb_backquery_enable パラメーターに依存します。このパラメーターはデフォルトで無効になっています。この機能を使用するには、PolarDB クラスターの パラメーター で innodb_backquery_enable パラメーターを有効にする必要があります。
説明innodb_backquery_enable パラメーターを有効にする前にフラッシュバッククエリを実行すると、システムは次のエラーを返します:
ERROR 1815 (HY000): Internal error: the backquery_time set is out of range, too old。
注意事項
フラッシュバッククエリは、単一テーブルのシナリオで使用してください。JOIN やサブクエリを含むような複雑なクエリシナリオでは使用しないでください。
フラッシュバッククエリではプライマリキーを使用してください。セカンダリインデックスはフラッシュバッククエリではサポートされていません。フラッシュバッククエリでセカンダリインデックスを使用すると、クエリは全表スキャンに変換され、クエリのパフォーマンスが低下します。
フラッシュバッククエリ機能を有効にすると、
innodb_backquery_windowパラメーターで指定されたタイムウィンドウ内の既存データを UNDO ログが保持するため、UNDO 表領域が増加します。表領域は BLOB シナリオでも増加する可能性があります。表領域が増加している間、書き込みパフォーマンスがわずかに低下する可能性があります。フラッシュバッククエリ機能が有効になっていると、UNDO ログの数が増加します。削除対象としてマークされたレコードが迅速に削除されない場合があります。これにより、場合によってはクエリのパフォーマンスが低下する可能性があります。
1 つのレコードには、最大 100,000 の履歴バージョンを保持できます。この制限を超えるレコードに対してフラッシュバッククエリを実行すると、システムは次のエラーを返します:
record undo history version exceed limit。DDL 操作を実行した後は、操作前の時点のデータを取得するためにフラッシュバッククエリを使用することはできません。そうしようとすると、システムは次のエラーを返す可能性があります:
Backquery primary key invisible。削除されたテーブルを表示するためにフラッシュバッククエリを使用できるのは、テーブルが削除される前にこの機能が有効になっていた場合のみです。
フラッシュバッククエリは、スナップショット読み取り (Snapshot Read) シナリオでのみ有効です。ロッキング読み取り (Lock Read) を使用すると、This query in backquery is not a consistent read, please check. というエラーが返されます。以下は、一般的なロッキング読み取り文です:
SELECT * FROM your_table WHERE condition LOCK IN SHARE MODE; SELECT * FROM your_table WHERE condition FOR UPDATE; /* REPEATABLE-READ 以上の分離レベルでは、ロッキング読み取り (Lock Read) が使用されます。 */ /* READ-COMMITTED 分離レベルでは、スナップショット読み取り (Snapshot Read) が使用されます。 */ INSERT INTO ... SELECT ...;
構文
単一テーブルのフラッシュバッククエリの構文
SELECT column_name_list FROM table_name AS OF TIMESTAMP time_expr alias WHERE...;複数テーブルのフラッシュバッククエリの構文
SELECT column_name_list FROM table1_name AS OF TIMESTAMP time_expr alias1,table2_name AS OF TIMESTAMP time_expr alias2 WHERE... ;複数テーブルの JOIN フラッシュバッククエリの構文
SELECT column_name_list FROM table1_name AS OF TIMESTAMP time_expr alias1 JOIN table2_name AS OF TIMESTAMP time_expr alias2 ON join_cond1 JOIN table3_name AS OF TIMESTAMP time_expr alias3 ON join_cond2 WHERE...;
次の表にパラメーターを示します。
パラメーター | 必須 | 説明 |
column_name_list | はい | クエリする列の名前。 |
table_name table1_name table2_name table3_name | はい | テーブルの名前。 |
time_expr | はい | フラッシュバックのタイムスタンプ。これは時間文字列または時間関数にすることができます。定数式のみがサポートされます。式に列名を含めることはできません。例:
|
alias alias1 alias2 alias3 | いいえ | テーブルのエイリアス。 |
join_cond1 join_cond2 | はい | JOIN 条件。 |
パラメーター
PolarDB は、フラッシュバック機能を制御するために次のパラメーターを提供します:
パラメーター | データ型 | 説明 |
loose_innodb_backquery_enable | BOOL | フラッシュバッククエリ機能を有効にするかどうかを指定します。 有効値:
|
loose_innodb_backquery_window | ULONG | フラッシュバッククエリがサポートされるタイムウィンドウ。
|
loose_innodb_backquery_capacity_limit | ULONG | フラッシュバッククエリでサポートされる UNDO ログの容量。UNDO ログの容量がこの値以上の場合、フラッシュバッククエリでサポートされるタイムウィンドウは短縮されます。
|
例
この例では、単一テーブルに対してフラッシュバッククエリを実行する方法を示します。
テストデータを準備します。
productsテーブルを作成し、2021-08-31 13:51にデータを挿入します。create table products ( prod_id bigint(10) primary key NOT NULL, prod_name varchar(20) NOT NULL, cust_id bigint(10) NULL, createtime datetime NOT NULL DEFAULT NOW() ); INSERT INTO products(prod_id,prod_name,cust_id,createtime) values (101,'Book',1,NOW()),(102,'Apple',1,NOW()),(103,'Beef',2,NOW()),(104,'Bread',3,NOW()),(105,'Cheese',4,NOW());productsテーブルのデータをクエリします。SELECT * FROM products; +---------+-----------+---------+---------------------+ | prod_id | prod_name | cust_id | createtime | +---------+-----------+---------+---------------------+ | 101 | Book | 1 | 2021-08-31 13:51:22 | | 102 | Apple | 1 | 2021-08-31 13:51:24 | | 103 | Beef | 2 | 2021-08-31 13:51:26 | | 104 | Bread | 3 | 2021-08-31 13:51:27 | | 105 | Cheese | 4 | 2021-08-31 13:51:29 | +---------+-----------+---------+---------------------+ 5 rows in set (0.00 sec)テストデータを更新します。
productsテーブルのデータを2021-08-31 14:18に更新します。UPDATE products SET prod_id = 110, createtime = NOW() WHERE prod_name = "Book"; UPDATE products SET prod_id = 119, createtime = NOW() WHERE prod_name = "Apple"; SELECT * FROM products; +---------+-----------+---------+---------------------+ | prod_id | prod_name | cust_id | createtime | +---------+-----------+---------+---------------------+ | 103 | Beef | 2 | 2021-08-31 13:51:26 | | 104 | Bread | 3 | 2021-08-31 13:51:27 | | 105 | Cheese | 4 | 2021-08-31 13:51:29 | | 110 | Book | 1 | 2021-08-31 14:18:21 | | 119 | Apple | 1 | 2021-08-31 14:18:22 | +---------+-----------+---------+---------------------+ 5 rows in set (0.00 sec)フラッシュバッククエリを実行します。
productsテーブルに2021-08-31 14:00:00の時点で存在していたデータをクエリします。SELECT * FROM products AS of TIMESTAMP '2021-08-31 14:00:00'; +---------+-----------+---------+---------------------+ | prod_id | prod_name | cust_id | createtime | +---------+-----------+---------+---------------------+ | 101 | Book | 1 | 2021-08-31 13:51:22 | | 102 | Apple | 1 | 2021-08-31 13:51:24 | | 103 | Beef | 2 | 2021-08-31 13:51:26 | | 104 | Bread | 3 | 2021-08-31 13:51:27 | | 105 | Cheese | 4 | 2021-08-31 13:51:29 | +---------+-----------+---------+---------------------+ 5 rows in set (0.00 sec)