O flashback nativo permite consultar ou restaurar dados para um ponto específico no tempo por meio de instruções SQL, permitindo a recuperação rápida de operações acidentais.
Visão geral
Operações acidentais durante a manutenção do banco de dados podem afetar gravemente os seus negócios. Os métodos tradicionais de recuperação, como o Binlog Flashback, são complexos, propensos a erros e demorados. A restauração a partir de um conjunto de backups consome recursos adicionais do sistema, e o tempo de recuperação torna-se imprevisível para grandes volumes de dados.
O AliSQL introduz o flashback nativo para o motor InnoDB, eliminando operações complexas de recuperação. Com instruções SQL simples, você pode consultar ou restaurar dados históricos anteriores a uma operação acidental, reduzindo o tempo de recuperação e minimizando o impacto nos negócios.
Pré-requisitos
Sua instância deve executar uma das seguintes versões do banco de dados. Se a versão secundária do motor não atender aos requisitos, você pode atualizá-la.
MySQL 8.4
MySQL 8.0 com versão secundária do motor 20210930 ou posterior.
Limitações
Há suporte apenas para tabelas do motor InnoDB.
Este recurso consome espaço adicional de tablespace de undo. Você pode limitar o tamanho máximo com o parâmetro innodb_undo_space_supremum_size.
Uma consulta de flashback nativo retorna dados do ponto no tempo mais próximo ao carimbo de data/hora especificado. Não há garantia de correspondência exata.
Não há suporte para consulta e restauração de dados históricos que abranjam operações DDL. Por exemplo, você não pode usar o flashback nativo para consultar o conteúdo de uma tabela excluída.
Sintaxe
O flashback nativo introduz a cláusula AS OF para especificar o ponto no tempo para consulta ou restauração. A sintaxe é a seguinte:
SELECT ... FROM <table_name>
AS OF TIMESTAMP <expression>;
A expressão especifica o ponto no tempo de destino e aceita vários formatos. Exemplos:
SELECT ... FROM tablename
AS OF TIMESTAMP '2020-11-11 00:00:00';
SELECT ... FROM tablename
AS OF TIMESTAMP now();
SELECT ... FROM tablename
AS OF TIMESTAMP (SELECT now());
SELECT ... FROM tablename
AS OF TIMESTAMP DATE_SUB(now(), INTERVAL 1 minute);
Parâmetros
Os seguintes parâmetros controlam o comportamento do flashback nativo:
|
Parâmetro |
Descrição |
|
innodb_rds_flashback_task_enabled |
Nota
Ao desativar o recurso de flashback nativo, defina também o parâmetro innodb_undo_retention como 0. |
|
innodb_undo_retention |
Nota
|
|
innodb_undo_space_supremum_size |
|
|
innodb_undo_space_reserved_size |
Nota
Um valor alto pode causar o acúmulo excessivo de registros de undo, o que impacta o desempenho da instância. Mantenha esse parâmetro em 0, a menos que seja necessário. |
Exemplos
# Get the current timestamp.
MySQL [mytest]> select now();
+---------------------+
| now() |
+---------------------+
| 2020-10-14 15:44:09 |
+---------------------+
1 row in set (0.00 sec)
# View the data.
MySQL [mytest]> select * from mt1;
+----+------+
| id | c1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.00 sec)
# Run an update operation without a WHERE clause.
MySQL [mytest]> update mt1 set c1 = 100;
Query OK, 5 rows affected (0.00 sec)
Rows matched: 5 Changed: 5 Warnings: 0
MySQL [mytest]> select * from mt1;
+----+------+
| id | c1 |
+----+------+
| 1 | 100 |
| 2 | 100 |
| 3 | 100 |
| 4 | 100 |
| 5 | 100 |
+----+------+
5 rows in set (0.00 sec)
# Query the historical data at the specified point in time. The query returns the expected result.
MySQL [mytest]> select * from mt1 AS OF timestamp '2020-10-14 15:44:09';
+----+------+
| id | c1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.00 sec)
# If the specified time is outside the retention window for historical data, the query fails.
MySQL [mytest]> select * from mt1 AS OF timestamp '2020-10-13 14:44:09';
ERROR 7545 (HY000): The snapshot to find is out of range
# Start the data recovery.
MySQL [mytest]> create table mt1_tmp like mt1; # Create a temporary table with the same structure as the original table.
Query OK, 0 rows affected (0.03 sec)
MySQL [mytest]> insert into mt1_tmp
-> select * from mt1 AS OF
-> TIMESTAMP '2020-10-14 15:44:09'; # Insert the historical data from the original table into the temporary table.
Query OK, 5 rows affected (0.01 sec)
Records: 5 Duplicates: 0 Warnings: 0
MySQL [mytest]> select * from mt1_tmp; # Verify that the data in the temporary table is correct.
+----+------+
| id | c1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.00 sec)
MySQL [mytest]> rename table mt1 to mt1_bak,
-> mt1_tmp to mt1; # (Before you perform this operation, stop all read and write operations on the table.) Rename the original table to mt1_bak and the temporary table to mt1 to complete the data recovery.
Query OK, 0 rows affected (0.02 sec)
MySQL [mytest]> select * from mt1; # Verify the restored data.
+----+------+
| id | c1 |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
| 4 | 4 |
| 5 | 5 |
+----+------+
5 rows in set (0.01 sec)