全部產品
Search
文件中心

PolarDB:閃回查詢

更新時間:Aug 27, 2025

通過閃回查詢(Flashback Query)功能,您可以高效查詢叢集、資料庫、資料表在過去某個時間點的資訊。

前提條件

  • PolarDB叢集版本需滿足如下條件之一:

    • PolarDB MySQL版8.0.2版本且修訂版本為8.0.2.2.21及以上

    • PolarDB MySQL版8.0.1版本且修訂版本為8.0.1.1.32及以上

    • PolarDB MySQL版5.7版本且修訂版本為5.7.1.0.25及以上

    • PolarDB 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、子查詢)使用閃回查詢。

  • 推薦使用主鍵來進行閃回查詢,目前不支援使用二級索引來進行閃回查詢。若使用二級索引來進行閃回查詢,會轉換為全表掃描,查詢效能會比較慢。

  • 由於Undo日誌保留了部分歷史差值資料,在配置的innodb_backquery_window時間視窗內,開啟閃回查詢功能會使得Undo資料表空間增長。除此之外,在BLOB情境下也可能會存在資料表空間增長的情況,且在資料表空間增長的過程中,寫入效能會略有下降。

  • 開始閃回查詢後,Undo日誌數量將會增加,被標記為DELETE的記錄可能無法及時刪除。因此,在某些情況下,這可能會導致查詢速度變慢。

  • 單條記錄的歷史版本上限是10萬次。超過該上限後,若閃回查詢該記錄,系統將會報錯record undo history version exceed limit

  • 在執行DDL操作後,之前的資料不能進行閃回查詢,若閃回查詢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及以上的隔離等級下是加鎖讀 */
    /* READ-COMMITTED隔離劑層級下是快照讀 */
    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

閃回的時間戳記,為時間字串或者其他時間函數,僅支援常量運算式,不能包含列名。樣本如下:

  • 時間字串:'2021-08-31 14:00:00'。

  • 時間函數:FROM_UNIXTIMESTAMP(unix_timestamp('2024-01-01 00:00:00'))CONVERT(unix_timestamp('2024-01-01 00:00:00'), DATETIME)

alias

alias1

alias2

alias3

表的別名。

join_cond1

join_cond2

JOIN條件。

參數說明

PolarDB提供了以下參數來更精確地控制閃回功能:

參數名稱

資料類型

說明

loose_innodb_backquery_enable

BOOL

開啟或者關閉閃回查詢功能。取值:

  • ON:開啟

  • OFF:關閉(預設)

loose_innodb_backquery_window

ULONG

閃回查詢支援的時間長度。

  • 取值範圍:1~604800。

  • 單位:秒。

  • 預設值:86400。

loose_innodb_backquery_capacity_limit

ULONG

閃回查詢支援的undo日誌容量。當undo日誌容量大於或等於該值時,將會縮短閃回查詢支援的時間長度。

  • 取值範圍:100~200000000。

  • 單位:MB。

  • 預設值:100000000。

樣本

以單表閃回為例。

  1. 準備測試資料:

    2021-08-31 13:51建立products表,並插入資料。

    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());
    
                            
  2. 查詢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)
  3. 更新測試資料:

    2021-08-31 14:18products表資料進行了更新。

    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)
  4. 執行閃回查詢:

    查看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)