13. Clustrix 基于时间点恢复

Posted yuxiaohao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了13. Clustrix 基于时间点恢复相关的知识,希望对你有一定的参考价值。

 

在不太可能发生灾难的情况下,可以在特定数据库、表或整个集群上执行ClustrixDB集群的某个时间点恢复。应该非常小心地处理这一问题。

 

先决条件

在你可以使用时间点恢复之前,你的集群应该有几个先决条件:

  1. ClustrixDB并行备份的二进制备份应该是可用的。有关此功能的更多信息,请参见ClustrixDB快速备份和恢复。https://www.cnblogs.com/yuxiaohao/p/11956565.html
  2. 需要启用binlogging。您可以在配置复制时找到有关启用binlog的信息。
  3. 确保您的binlog包含您希望恢复的时间点。

 

 

恢复到特定时间点的步骤

 

步骤1 -停止对希望恢复的数据库或表的写操作

停止任何可能与需要恢复的数据库或表交互的从属进程,并禁用binlogging。这可以确保数据库或表在恢复期间不接受任何写操作。您还不希望在设置恢复时间点时所做的任何更改复制到任何从属服务器,因此将sql_log_bin设置为false。将sql_log_bin设置为false只适用于当前事务,因此应该在修改表的每个操作之前包含该操作,以确保不会出现意外复制。还原操作本身不进行复制。

sql> STOP SLAVE slave name;
sql> SET sql_log_bin = false;

可选但强烈推荐-将集群设置为只读模式。

sql> SET GLOBAL read_only = true;

步骤2 -还原数据库或表

从最近的备份中还原数据库(或表)。您将使用最新的备份来恢复需要恢复的数据库和/或表。有两种方法。第一种方法是删除要恢复的数据库(或表),然后将数据库(或表)从备份中重新写入,如下所示:

sql> SET sql_log_bin = false;
sql> DROP DATABASE database;
sql> RESTORE database FROM ftp://username@ftp server_address/path_to_backup

如果删除并恢复一个表,那么可以在备份文件中database.table 替换 database 

 

您可以恢复多个数据库和/或表,只需用逗号分隔每个条目。例如:

sql> RESTORE foo, foo2, foo3 FROM ftp://username@ftp://server.com/backups/backupfolders/backup_file

第二种方法是还原到备用数据库(或表),并在验证数据后将表重命名为原来的表。

RESTORE database1.table1 AS database_backup.table1 FROM ftp://username@ftp server_address/path_to_backup;

Example:

sql> RESTORE foo.bar AS foo_backup.bar FROM ftp://username@server.com/backups/backupfolders/backup_file 

用您喜欢的任何方式验证数据,然后删除旧数据库并将新表重命名为它。

sql> SET sql_log_bin = false;
sql> DROP TABLE database.table;
sql> RENAME TABLE database_backup.table1 AS database.table1   

Example:

sql> SET sql_log_bin = false;
sql> DROP TABLE foo.bar; 
sql> RENAME TABLE foo_backup.bar AS foo.bar; 

只能重命名表,而不能重命名整个数据库。您可以将一个表从一个数据库重命名为另一个数据库,因此如果需要,您可以将数据库中的所有表重命名为一个新数据库,但这可能需要手工操作或使用一些脚本。

 

步骤3 -提取Binlog名称和位置

从ftp服务器上的metadata/binlogs文件夹中提取binlog文件和位置。这将指示从创建备份的位置开始的binlog的起始位置。这将在第5步和第7步中使用。

在你的FTP服务器运行:

The output will be in the format binlogname.binlogfile:binlog-position

Example:

shell> cat /ftp/backups/newestBackup/metadata/binlogs
foobin.000835:12345678

 

步骤4 -找到正确的Binlog

从指向ClustrixDB的mysql客户机使用show binlog files命令查找包含要恢复的事件的binlog。要找到正确的binlog,请在希望恢复的事件(或时间)的开始时间之前找到最近的时间戳您想要的事件应该在那个binlog中。记录这个binlog名称,因为它将在步骤5的end_logname位置中用作停止位置,在步骤10中用作logname。

要找到时间戳运行:

sql> show binlog files;  
+---------------+-----------+-----------------------+
| File          | Size      | First Event Timestamp |
+---------------+-----------+-----------------------+
| foobin.000835 | 104857600 | 2018-01-24 08:01:16   |
| foobin.000836 | 104857600 | 2018-01-24 08:30:13   |
| foobin.000837 | 104857600 | 2018-01-24 08:51:46   |

如果您正在寻找的事件是在2018-01-24 08:50:14,您将选择binlog foobin.000836作为该示例的结束点,因为它包含您的事件。foobin.000836显示8:50之前最近的时间戳和foobin.000837在那个时间之后开始。

 

步骤5 -使用repclient转储Binlog

ClustrixDB附带两个与binlog交互的工具。repclient用于转储和读取binlog,而repserver可以重新提供这些binlog,在此步骤中,您将使用repclient转储原始的binlog文件。首先,您将在/clustrix目录中创建一个新目录,然后将目录更改为新创建的目录,然后运行repclient来提取binlog的正确部分,以在步骤6中重播。您使用的是步骤3的起始位置和步骤4的结束位置。使用以下语法:

Example:

shell> mkdir /clustrix/binlogs 
shell> cd /clustrix/binlogs/ 
shell> repclient -dumpbinlog -logname foobin.000835 -end_logname foobin.000836  

这将需要一些时间来运行,具体取决于需要转储的日志数量。等待命令退出并返回bash提示符。如果成功,您将在当前工作目录中看到一组binlog文件。

如果只有一个binlog文件,那么这个进程将不会在repclient读取日志结束之前结束,因为日志还没有被记录。处理此问题的最佳方法是打开另一个窗口并监视/clustrix/binlogs/文件夹中正在创建的文件的大小。

一旦文件停止增长10秒,您可以使用ctrl-c手动停止进程。

For example:

shell> ls -lh /clustrix/binlogs/ 

 

 

步骤6 -更改server_id

改变server_id。这确保在稍后重播事件时。集群不会像主/主复制那样丢弃它们。server_id在您的基础结构中必须是唯一的。

显示集群的server_id并将其记录下来,以便您可以在以后重新设置它。

sql> SHOW GLOBAL VARIABLES LIKE %server_id%  
+---------------+------------+
| Variable_name | Value      |
+---------------+------------+
| server_id     | 1044953144 |
+---------------+------------+
1 row in set (0.01 sec)

然后把这个变量变成唯一的。

sql> SET GLOBAL server_id = 0123456789;

 

 

步骤7 -使用repserver重播Binlog

启动repserver实例,即提供的binlog播放器实用程序。这将设置一个复制主进程,将binlog送回集群。在屏幕上运行repserver是一个好主意,或者使用一个单独的终端,因为命令需要连续运行。

shell> cd /clustrix/binlogs  
shell> repserver -port 3307  

应该看到如下输出:

root@node001:/clustrix/binlogs$ repserver -port 3307
2018-01-30 22:56:22 INFO mysql/replication/repserver/repserver.c:620 have_stat(): Use Ctrl-C to exit
2018-01-30 22:56:22 INFO mysql/replication/repserver/repserver_proto.c:821 listen_on_port(): IPv4(0.0.0.0:3307) 

不要关闭此终端/屏幕。最小化终端并在一个新窗口中继续下一步。

 

步骤8 -创建一个新slave

在ClustrixDB上创建一个从repserver读取数据的新slave。MASTER_LOG_FILE和MASTER_LOG_POS来自上面的步骤3。

sql> CREATE SLAVE foo_slave
MASTER_LOG_FILE = foobin.000836
, MASTER_LOG_POS = 12345678
, MASTER_HOST = localhost
, MASTER_USER = root
, MASTER_PORT = 3307;

 

 

步骤9 -设置复制策略

如果您没有将整个集群恢复到某个时间点:您将需要设置系统。mysql_slave_replication_policy和table_replication_policy表只包含需要复制的数据库和表。为此,首先记录这些表中已经存在的所有值(稍后需要重置这些值)。如果您正在恢复整个集群,您可以直接跳到步骤10。

sql> show variables like %replication_policy%;
sql> select * from system.mysql_slave_replication_policy;
sql> select * from system.mysql_table_replication_policy;

记录这些表的输出,然后删除其中的任何数据。这样做的每个数据库和表,你想要恢复到一个时间点:

sql> DELETE from system.mysql_slave_replication_policy;
sql> DELETE from system.mysql_table_replication_policy;
sql> SET GLOBAL mysql_default_db_replication_policy = FALSE;
sql> SET GLOBAL mysql_default_table_replication_policy = FALSE;

要还原整个数据库,请遵循以下语法:

INSERT INTO system.mysql_slave_replication_policy (dbname, allow) VALUES (dbname, TRUE)

Example:

sql> INSERT INTO system.mysql_slave_replication_policy (dbname, allow) VALUES (foo, TRUE);

 

要恢复表,请遵循以下语法:

 

INSERT INTO system.mysql_table_replication_policy VALUES (slave name, dbname, tablename, TRUE)  

Example:

sql> INSERT INTO system.mysql_table_replication_policy VALUES (foo_slave, foo, bar, TRUE);

 

步骤10 -确定binlog停止的position

确定从站的停止位置。对于此步骤,不存在“一刀切”的解决方案,因为所需的信息位置可以根据所运行的查询类型或正在从中恢复的事件类型进行更改。最基本的方法是在几个表上运行联接,以获得所需的信息。需要提供的信息是binlog名称和希望恢复到的时间。此查询将使您在指定的时间之前处理500个事务。

时间戳的格式应该是“2018-02-01 14:00”,它表示您希望恢复到的时间。您还需要将binlog_name的两个实例替换为binlog的名称,在本例中是foobin。这将为您提供下一步所需的偏移量。

Example:

sql> SELECT commit_timestamp, mysql_binlog_index.commit_id, name, sequence, offset 
     FROM mysql_binlog_index 
     JOIN binlogs using(log_id) 
     JOIN _replication.foobin_replication_commits using(commit_id) 
     WHERE name=foobin 
     AND from_unixtime(mysql_binlog_index.commit_id>>32) < 2018-02-28 12:00 
     ORDER BY mysql_binlog_index.commit_id DESC LIMIT 1;  
+---------------------+---------------------+--------+----------+--------+
| commit_timestamp    | commit_id           | name   | sequence | offset |
+---------------------+---------------------+--------+----------+--------+
| 2018-02-01 01:27:31 | 5839789947966173188 | foobin |     4443 |    106 |
+---------------------+---------------------+--------+----------+--------+
1 row in set (3.13 sec)              

记录偏移列的输出。这将在步骤11中用作您的MASTER_LOG_POS。在大多数情况下,这将给你足够的信息来做你的时间点恢复,你可以进行第11步。

步骤10A -使用mysqlbinlog或repclient提取准确的Binlog停止位置

此步骤是可选的:如果您不需要恢复到准确的事务,请跳到步骤11。

强烈建议您联系CLUSTRIX支持人员,让他们执行下一个操作!

如果需要恢复到特定的事务,可以使用mysqlbinlog或repclient手动检查binlog。如果您使用基于语句的复制(SBR),这是一个相当简单的任务,但是对于基于行的复制(RBR),这可能相当棘手,因为任何非ddl事件都会以十六进制编码的形式出现在RBR中。如果您试图从DDL (ALTER, DROP, CREATE)中恢复的事件是SBR。要在RBR流中定位非DDL的特定事务,请联系Clustrix支持以获得帮助。要检查binlog,在logname参数中使用步骤4中的文件名,如下例所示:

mysqlbinlog不能解码ClustrixDB RBR事件。而是使用ClustrixDB repclient。

如果您试图从名为foobase的已删除数据库中恢复,请遵循以下示例。

shell> mysqlbinlog /clustrix/binlogs/foobin.000836 | grep -b10 "foobase" | less 

 

您将看到如下输出:

 

12429169-/*!*/;
12429176-# at 45116760
12429190-# at 45116813
12429204-# at 45116853
12429218-#130211 16:54:27 server id 2101898466  end_log_pos 45116913    Query   thread_id=1705364482    exec_time=0     error_code=0
12429331-SET TIMESTAMP=1360630467/*!*/;
12429362-COMMIT
12429369-/*!*/;
12429376-# at 45116913
12429390-#130211 16:54:40 server id 2101898466  end_log_pos 45117003    Query   thread_id=1705364482    exec_time=0     error_code=0
12429503:use foobase/*!*/;
12429521-SET TIMESTAMP=1360630480/*!*/;
12429552-SET @@session.sql_mode=0/*!*/;
12429583:drop database foobase
12429605-/*!*/;
12429612-# at 45117003
12429626-#130211 16:54:40 server id 2101898466  end_log_pos 45117030    Xid = 5843863418521626628
12429713-COMMIT/*!*/;
12429726-# at 45117030
12429740-#130211 16:54:54 server id 1044953188  end_log_pos 45117089    Query   thread_id=1658178562    exec_time=0     error_code=0
12429853-SET TIMESTAMP=1360630494/*!*/;
12429884-SET @@session.sql_mode=524288/*!*/;
12429920-BEGIN
12429926-/*!*/;

因为在上面的例子中,您试图恢复的事件是一个DROP DATABASE foobase,所以您应该像这样查找这个命令:“12429583:DROP DATABASE foobase”,然后在此之前查找一个事务位置。因此,从上面的例子中,你想要的线是这样的:

12429376-# at 45116913

“at”后面的数字是要记录的数字:45116913

下面是一个压缩的代码片段,显示了drop数据库和要提取的行。记录这些信息。

12429376-# at 45116913
12429390-#130211 16:54:40 server id 2101898466  end_log_pos 45117003    Query   thread_id=1705364482    exec_time=0     error_code=0
12429503:use foobase/*!*/;
12429521-SET TIMESTAMP=1360630480/*!*/;
12429552-SET @@session.sql_mode=0/*!*/;
12429583:drop database foobase

 

步骤11 -使用新从属节点读取binlog

现在您需要重播binlog,直到您在前面的步骤中指定的那一点,您可以通过启动新的从属节点来做到这一点,并且只启动那个从属节点。使用步骤10中提取的停止位置运行UNTIL命令。

sql> START SLAVE foo UNTIL MASTER_LOG_FILE = foobin.000836, MASTER_LOG_POS = 106; 

从服务器将一直运行,直到在binlog中找到灾难性的ALTER、DROP或CREATE之前的事务(如果LOG_POS定义正确)。

 

 

步骤12 -清理

这最后一步是清理所有的设置和之前做变化:

  • 将mysql_default_db_replication_policy和mysql_default_table_replication策略变量设置为步骤9中找到的值。
  • 停止并删除您先前创建的slave。
  • 重新启动以前运行的所有其他slave。
  • 将server_id设置回原来的值。这是在步骤1中记录的。
sql> SET GLOBAL server_id = 1044953144; 
  • 重新启用写入到binlog:

sql> SET sql_log_bin = true; 
  • 如果将集群设置为只读模式,则再次启用写操作。
sql> SET GLOBAL read_only = false; 

回到运行repserver的窗口(或屏幕),用ctrl-c停止它。

 

 

以上是关于13. Clustrix 基于时间点恢复的主要内容,如果未能解决你的问题,请参考以下文章

保存以编程方式为片段创建的视图并在 onresume 中恢复

Oraclerman基于时间点恢复

在 Fragment 中恢复 Google Maps 状态

MySQL 基于时间点与位置恢复

基于时间点恢复数据库stopat

恢复片段后android地图停止响应