Flashback table
When a DELETE or UPDATE accidentally overwrites production data, the flashback table feature lets you recover table data to a specific point in time—without restoring the entire database. It works by restoring table data to a new table, using page snapshots saved to flashback logs and transaction information retained in the fast recovery area.
Prerequisites
Before you begin, make sure that:
-
Your cluster runs PolarDB for PostgreSQL (Compatible with Oracle) 1.0, revision version 1.1.22 or later. Run the following command to check your revision version:
show polar_version; -
Flashback logging and the fast recovery area are enabled. See Enable flashback table.
How it works
When the flashback table feature is enabled, two background processes (bgwriter and bginserter) continuously write page snapshots to flashback logs. When you run a FLASHBACK TABLE statement, PolarDB reads those logs to reconstruct the table's state at the target timestamp and writes the result to a new table named polar_flashback_<table_OID>. The original table is not modified.
Enable flashback table
Enabling the flashback table feature requires two parameters and a cluster restart.
-
Set
polar_enable_flashback_logtoonandpolar_enable_fast_recovery_areatoonin your cluster's parameter configuration. -
Restart the cluster for the changes to take effect.
Enabling this feature increases memory and disk usage and causes a small performance overhead (less than 5% in most scenarios). Review Resource impacts before enabling in production.
Flash back a table
Syntax
FLASHBACK TABLE
[ schema. ]table
TO TIMESTAMP expr;
| Parameter | Description |
|---|---|
[ schema. ]table |
The name of the table to flash back |
expr |
The target timestamp to restore data to |
Example: recover accidentally deleted data
The following steps show how to recover a table whose rows were accidentally deleted.
Step 1: Record the initial state.
CREATE TABLE test(id int);
INSERT INTO test SELECT * FROM generate_series(1, 10000);
SELECT count(1) FROM test;
Output:
count
-------
10000
(1 row)SELECT sum(id) FROM test;
Output:
sum
----------
50005000
(1 row)
Step 2: Simulate accidental deletion.
SELECT pg_sleep(10);
DELETE FROM test;
SELECT * FROM test;
Output:
id
----
(0 rows)
Step 3: Flash back the table to 10 seconds ago.
FLASHBACK TABLE test TO TIMESTAMP now() - interval'10s';
Output:
NOTICE: Flashback the relation test to new relation polar_flashback_65566, please check the data
FLASHBACK TABLE
The recovered data is in a new table named polar_flashback_65566. Only the table data is restored to the specified point in time—indexes are not included.
Step 4: Verify the recovered data.
SELECT count(1) FROM polar_flashback_65566;
Output:
count
-------
10000
(1 row)SELECT sum(id) FROM polar_flashback_65566;
Output:
sum
----------
50005000
(1 row)
After verifying the data, copy the missing rows back to the original table as needed.
Limitations
Supported table types
The flashback table feature supports only regular (heap) tables. It cannot restore the following:
-
Indexes
-
TOAST tables
-
Materialized views
-
Partitioned tables and child partitioned tables
-
System tables
-
Foreign tables
-
Tables that contain child TOAST tables
DDL restrictions
A table cannot be flashed back if any of the following DDL statements were executed between the target timestamp and the current time:
-
DROP TABLE -
TRUNCATE TABLE -
ALTER TABLE SET WITH OIDS -
ALTER TABLE SET WITHOUT OIDS -
Modifying a column's data type where the old and new types are not implicitly convertible and no
USINGclause with a secure forced conversion is provided -
Changing the table to
UNLOGGEDorLOGGED -
Adding a column as
IDENTITY -
Adding a column where only limited data types can be selected
-
Adding a column where the default value expression contains volatile functions
To recover a table dropped with DROP TABLE, use the flashback delete feature of PolarDB for PostgreSQL (Compatible with Oracle).
Resource impacts
Memory
Enabling flashback logging increases shared memory by:
-
polar_flashback_log_buffersx 8 KB -
polar_flashback_logindex_mem_sizeMB -
polar_flashback_logindex_queue_buffersMB
Enabling the fast recovery area increases shared memory by approximately 32 KB.
Disk
Flashback logs, WAL logs, and their LogIndex files must all be retained for the target time window. The polar_fast_recovery_area_rotation parameter controls how long transaction information is kept: for example, setting it to 300 retains 5 hours of history.
As a rough estimate, flashback logs consume about 1/20 of the WAL log volume (a 1:20 ratio). For example, if 20 GB of WAL logs are generated in five hours, approximately 1 GB of flashback logs are generated. This ratio increases with write-heavy workloads and decreases with larger values of polar_flashback_point_segments and polar_flashback_point_timeout.
For flashback point configuration, follow these guidelines:
-
Set
polar_flashback_point_segmentsto a multiple ofmax_wal_size. -
Set
polar_flashback_point_timeoutto a multiple ofcheckpoint_timeout.
Performance
The flashback logging feature adds two background processes (bgwriter and bginserter) that consume additional CPU. To reduce CPU overhead, increase the working intervals using polar_flashback_log_bgwrite_delay and polar_flashback_log_insert_list_delay—though this may reduce throughput. The default values work well for most workloads.
Because flashback log flushing occurs before page flushing, you may observe a performance overhead of less than 5% in most scenarios. During a flashback operation, the table's pages are swapped in and out of the shared memory pool, which may cause brief access jitter on other databases.
Best practices
-
Find the right timestamp first. Check your audit logs to identify when the accidental operation occurred before running
FLASHBACK TABLE. -
Run during off-peak hours. During flashback, an exclusive lock is held on the table, making it read-only. Page swapping during the operation can also cause brief access jitter on other databases.
-
Speed up large table flashbacks. Increase
polar_workers_per_flashback_tableto enable parallel flashback for large tables. -
Validate before merging. After the flashback completes, compare the recovered table (
polar_flashback_<OID>) with the original table using theNOTICEoutput. Create indexes as needed, then copy missing data back to the original table.
Parameters
| Parameter | Default | Valid values | Unit | Takes effect |
|---|---|---|---|---|
polar_enable_flashback_log |
off |
on, off |
— | After SIGHUP |
polar_enable_fast_recovery_area |
off |
on, off |
— | After SIGHUP |
polar_flashback_log_keep_segments |
8 |
3–2147483647 | — (256 MB per file) | After SIGHUP |
polar_fast_recovery_area_rotation |
180 |
1–14400 | minutes | After SIGHUP |
polar_flashback_point_segments |
16 |
1–2147483647 | WAL files (1 GB each) | After SIGHUP |
polar_flashback_point_timeout |
300 |
1–86400 | seconds | After SIGHUP |
polar_flashback_log_buffers |
2048 |
4–262144 | KB | After cluster restart |
polar_flashback_logindex_mem_size |
64 |
3–1073741823 | MB | After cluster restart |
polar_flashback_logindex_bloom_blocks |
512 |
8–1073741823 | — | After cluster restart |
polar_flashback_log_insert_locks |
8 |
1–2147483647 | — | After cluster restart |
polar_workers_per_flashback_table |
5 |
0–1024 | — | Immediately |
polar_flashback_log_bgwrite_delay |
100 |
1–10000 | ms | After SIGHUP |
polar_flashback_log_flush_max_size |
5120 |
0–2097152 | KB | After SIGHUP |
polar_flashback_log_insert_list_delay |
10 |
1–10000 | ms | After SIGHUP |
polar_flashback_log_size_limit |
20480 |
0–2147483647 | — | N/A |
Parameter notes:
-
polar_flashback_log_keep_segments: Flashback log files are reusable. Each file is 256 MB. -
polar_workers_per_flashback_table: Set to0to disable parallel flashback. Set to a higher value to speed up large table flashbacks. -
polar_flashback_log_flush_max_size: Set to0to remove the per-flush size limit. -
polar_flashback_log_size_limit: Set to0for no size limit. When the flashback log size exceeds this value, recycling is triggered.