O native flashback permite consultar ou restaurar dados em um ponto específico no tempo usando instruções SQL, o que facilita a recuperação rápida após operações acidentais.
Visão geral
Operações acidentais durante a manutenção do banco de dados podem impactar severamente seus negócios. 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 backup consome recursos adicionais do sistema, e o tempo de recuperação torna-se imprevisível para grandes volumes de dados.
O AliSQL introduziu o native flashback para o mecanismo InnoDB, eliminando procedimentos complexos de recuperação. Com instruções SQL simples, você consulta ou restaura 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 mecanismo não atender aos requisitos, atualize-a.
MySQL 8.4
MySQL 8.0 com versão secundária do mecanismo 20210930 ou posterior.
Limitações
Há suporte apenas para tabelas do mecanismo InnoDB.
Este recurso consome espaço adicional de undo tablespace. Limite o tamanho máximo com o parâmetro innodb_undo_space_supremum_size.
Uma consulta de native flashback retorna dados do ponto no tempo mais próximo do timestamp especificado. Não há garantia de correspondência exata.
Não há suporte para consulta e restauração de dados históricos que envolvam operações DDL. Por exemplo, não use o native flashback para consultar o conteúdo de uma tabela excluída.
Sintaxe
O native flashback introduz a cláusula AS OF para especificar o ponto no tempo a ser consultado ou restaurado. A sintaxe é:
SELECT ... FROM <table_name>
AS OF TIMESTAMP <expression>;
A expressão define o ponto alvo no tempo e aceita diversos 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 parâmetros abaixo controlam o comportamento do native flashback:
|
Parâmetro |
Descrição |
|
innodb_rds_flashback_task_enabled |
Nota
Ao desativar o native flashback, 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 elevado pode causar acúmulo excessivo de registros de undo e afetar o desempenho da instância. Mantenha este parâmetro em 0, a menos que seja estritamente 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)