Column-store snapshots let you access data as it existed at a specific point in time. Use them to:
-
Recover data accidentally deleted or overwritten
-
Audit historical records at a specific point in time
-
Clone data from a past state for analysis or testing
Prerequisites
Before you begin, ensure that you have:
-
A PolarDB for Xscale instance running version 5.4.20 or later
-
An instance using the MySQL 5.7 or MySQL 8.0 engine
For release notes, see Release notes. To check your instance version, see View and update the version of an instance.
Usage notes
-
Schema changes affect historical queries. Column-store snapshot queries always return results using the current table structure, not the structure that existed when the snapshot was created. For example, if you add a column to a table and then query a snapshot taken before that column was added, the result includes the new column based on the post-change table structure.
-
autocommitis required for transactional restores. TheINSERT ... SELECTstatement can restore data within a transaction only whenautocommit=trueis set on the database. -
Avoid complex queries in
INSERT ... SELECT. Complex subqueries in theSELECTclause may degrade performance significantly.
Query historical data from a snapshot
To query data at a specific snapshot point, use the AS OF TSO clause with FORCE INDEX in a SELECT statement:
SELECT * FROM <table_name> AS OF TSO <TSO> FORCE INDEX(<snapshot_name>);
| Clause | Description |
|---|---|
AS OF TSO <TSO> |
Specifies the Timestamp Oracle (TSO) value that identifies the snapshot point. Place this clause directly after the table name. |
FORCE INDEX(<snapshot_name>) |
Forces the query to read from the named column-store snapshot. Place this clause after AS OF TSO. |
To get a TSO value, run CALL polardbx.columnar_flush(). For details, see Generate snapshot points.
Example:
-- FORCE INDEX must come after AS OF TSO.
SELECT * FROM tb1 AS OF TSO 7206138458723582016 FORCE INDEX(cci);
Restore data from a snapshot
To copy historical data from a snapshot into another table, use INSERT ... SELECT with the same AS OF TSO and FORCE INDEX clauses:
INSERT INTO <target_table> SELECT * FROM <source_table> AS OF TSO <TSO> FORCE INDEX(<snapshot_name>);
Example:
INSERT INTO tmp SELECT * FROM tb1 AS OF TSO 7206138458723582016 FORCE INDEX(cci);
End-to-end example
The following example walks through creating a table, generating snapshots at different points, and querying or restoring data from each snapshot.
Step 1: Create the database and table.
CREATE DATABASE test_columnar_snapshot MODE=AUTO;
USE test_columnar_snapshot;
CREATE TABLE tb1 (
id INT PRIMARY KEY,
a INT,
gmt_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
gmt_modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) PARTITION BY KEY(id);
Step 2: Create a column-store snapshot named cci on tb1.
CREATE CLUSTERED COLUMNAR INDEX cci ON tb1(a)
PARTITION BY KEY(id)
columnar_options='{
"type":"snapshot",
"snapshot_retention_days":"7",
"auto_gen_columnar_snapshot_interval":"30"
}';
Step 3: Insert data and generate snapshot points.
INSERT INTO tb1 (id, a) VALUES (0, 0);
CALL polardbx.columnar_flush (test_columnar_snapshot, 'tb1', 'cci'); -- CCI-level snapshot; record the returned TSO as TSO1
INSERT INTO tb1 (id, a) VALUES (1, 1);
CALL polardbx.columnar_flush(); -- Instance-level snapshot; record the returned TSO as TSO2
INSERT INTO tb1 (id, a) VALUES (2, 2);
Step 4: Query data at each snapshot point.
-- Query at TSO1 (after inserting row 0).
SELECT * FROM tb1 AS OF TSO {TSO1} FORCE INDEX(cci) ORDER BY id;
Expected output:
+----+------+
| id | a |
+----+------+
| 0 | 0 |
+----+------+-- Query at TSO2 (after inserting rows 0 and 1).
SELECT * FROM tb1 AS OF TSO {TSO2} FORCE INDEX(cci) ORDER BY id;
Expected output:
+----+------+
| id | a |
+----+------+
| 0 | 0 |
| 1 | 1 |
+----+------+-- Query the latest data (all three rows).
SELECT * FROM tb1 FORCE INDEX(cci) ORDER BY id;
Expected output:
+----+------+
| id | a |
+----+------+
| 0 | 0 |
| 1 | 1 |
| 2 | 2 |
+----+------+
Step 5: Restore data from a snapshot.
CREATE TABLE tb1_tmp (
id INT PRIMARY KEY,
a INT,
gmt_created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
gmt_modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) PARTITION BY KEY(id);
-- Restore data from the TSO1 snapshot into tb1_tmp.
INSERT INTO tb1_tmp SELECT * FROM tb1 AS OF TSO {TSO1} FORCE INDEX(cci);
SELECT * FROM tb1_tmp ORDER BY id;
Expected output:
+----+------+
| id | a |
+----+------+
| 0 | 0 |
+----+------+