13. ClustrixDB 基于时间点恢复
在不太可能发生灾难的情况下,可以在特定数据库、表或整个集群上执行ClustrixDB集群的某个时间点恢复。应该非常小心地处理这一问题。
先决条件
在你可以使用时间点恢复之前,你的集群应该有几个先决条件:
- ClustrixDB并行备份的二进制备份应该是可用的。有关此功能的更多信息,请参见ClustrixDB快速备份和恢复。https://www.cnblogs.com/yuxiaohao/p/11956565.html
- 需要启用binlogging。您可以在配置复制时找到有关启用binlog的信息。
- 确保您的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.:
步骤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. | | -- :: |
| foobin. | | -- :: |
| foobin. | | -- :: |
如果您正在寻找的事件是在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 | |
+---------------+------------+
row in set (0.01 sec)
然后把这个变量变成唯一的。
sql> SET GLOBAL server_id = '';
步骤7 -使用repserver重播Binlog
启动repserver实例,即提供的binlog播放器实用程序。这将设置一个复制主进程,将binlog送回集群。在屏幕上运行repserver是一个好主意,或者使用一个单独的终端,因为命令需要连续运行。
shell> cd /clustrix/binlogs
shell> repserver -port
应该看到如下输出:
root@node001:/clustrix/binlogs$ repserver -port
-- :: INFO mysql/replication/repserver/repserver.c: have_stat(): Use Ctrl-C to exit
-- :: INFO mysql/replication/repserver/repserver_proto.c: listen_on_port(): IPv4(0.0.0.0:)
不要关闭此终端/屏幕。最小化终端并在一个新窗口中继续下一步。
步骤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 =
, MASTER_HOST = 'localhost'
, MASTER_USER = 'root'
, MASTER_PORT = ;
步骤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>>) < '2018-02-28 12:00'
ORDER BY mysql_binlog_index.commit_id DESC LIMIT ;
+---------------------+---------------------+--------+----------+--------+
| commit_timestamp | commit_id | name | sequence | offset |
+---------------------+---------------------+--------+----------+--------+
| -- :: | | foobin | | |
+---------------------+---------------------+--------+----------+--------+
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. | grep -b10 "foobase" | less
您将看到如下输出:
-/*!*/;
-# at
-# at
-# at
-# :: server id end_log_pos Query thread_id= exec_time= error_code=
-SET TIMESTAMP=/*!*/;
-COMMIT
-/*!*/;
-# at
-# :: server id end_log_pos Query thread_id= exec_time= error_code=
:use foobase/*!*/;
-SET TIMESTAMP=/*!*/;
-SET @@session.sql_mode=/*!*/;
:drop database foobase
-/*!*/;
-# at
-# :: server id end_log_pos Xid =
-COMMIT/*!*/;
-# at
-# :: server id end_log_pos Query thread_id= exec_time= error_code=
-SET TIMESTAMP=/*!*/;
-SET @@session.sql_mode=/*!*/;
-BEGIN
-/*!*/;
因为在上面的例子中,您试图恢复的事件是一个DROP DATABASE foobase,所以您应该像这样查找这个命令:“12429583:DROP DATABASE foobase”,然后在此之前查找一个事务位置。因此,从上面的例子中,你想要的线是这样的:
-# at
“at”后面的数字是要记录的数字:45116913
下面是一个压缩的代码片段,显示了drop数据库和要提取的行。记录这些信息。
-# at
-# :: server id end_log_pos Query thread_id= exec_time= error_code=
:use foobase/*!*/;
-SET TIMESTAMP=/*!*/;
-SET @@session.sql_mode=/*!*/;
:drop database foobase
步骤11 -使用新从属节点读取binlog
现在您需要重播binlog,直到您在前面的步骤中指定的那一点,您可以通过启动新的从属节点来做到这一点,并且只启动那个从属节点。使用步骤10中提取的停止位置运行UNTIL命令。
sql> START SLAVE 'foo' UNTIL MASTER_LOG_FILE = 'foobin.000836', MASTER_LOG_POS = '';
从服务器将一直运行,直到在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 = '';
重新启用写入到binlog:
sql> SET sql_log_bin = 'true';
- 如果将集群设置为只读模式,则再次启用写操作。
sql> SET GLOBAL read_only = false;
回到运行repserver的窗口(或屏幕),用ctrl-c停止它。
13. ClustrixDB 基于时间点恢复的更多相关文章
- 7.5.1 Point-in-Time Recovery Using Event Times 使用Event Times 基于时间点恢复
7.5.1 Point-in-Time Recovery Using Event Times 使用Event Times 基于时间点恢复 表明开始和结束时间用于恢复, 指定 --start-datet ...
- 7.5 Point-in-Time (Incremental) Recovery Using the Binary Log 使用binay log 基于时间点恢复
7.5 Point-in-Time (Incremental) Recovery Using the Binary Log 使用binay log 基于时间点恢复 7.5.1 Point-in-Tim ...
- mysqlbinlog基于时间点恢复
基于时间点恢复 /data/mysq/mysqlbin.000026 #mysqlbinlog文件,恢复如下内容: 注意:按照时间点恢复时,可能同一个时间点有其他的操作,要结合上下文的时间选取~ # ...
- 【Oracle】rman基于时间点恢复
rman基于时间点恢复 场景: 由于某研究的误操作,导致财务模块的数据丢失,如何使用rman基于时间点恢复数据. 思路 1.克隆数据库的虚拟机,直接对数据库的数据进行恢复 RMAN> shutd ...
- 基于时间点恢复数据库stopat
create database newtestdb use newtestdbgo drop table t1go create table t1 (id int not null identity( ...
- xtrabackup全量备份+binlog基于时间点恢复
1.通过xtrabackup的备份恢复数据库. 2.找到start-position和binlog名称 cat xtrabackup_info 3.导出mysqlbinlog为sql文件,并确定恢复的 ...
- 1.MongoDB 2.7主从复制(master –> slave)环境基于时间点的恢复
(一)MongoDB恢复概述 对于任何类型的数据库,如果要将数据库恢复到过去的任意时间点,否需要有过去某个时间点的全备+全备之后的重做日志,MongoDB也不例外.使用全备将数据库恢复到固定时刻,然后 ...
- Oracle 基于用户管理恢复的处理
================================ -- Oracle 基于用户管理恢复的处理 --================================ Oracle支持多种 ...
- mysql 开发进阶篇系列 43 逻辑备份与恢复(mysqldump 的基于时间和位置的不完全恢复)
一. 概述 在上篇讲到了逻辑备份,使用mysqldump工具来备份一个库,并使用完全恢复还原了数据库.在结尾也讲到了误操作是不能用完全恢复的.解决办法是:我们需要恢复到误操作之前的状态,然后跳过误操作 ...
随机推荐
- 安装opencv3.3.0碰到的问题及解决方法
出处:http://osask.cn/front/ask/view/258965 CMakeError.log Compilation failed: source file: '/home/jhro ...
- python_面试题_TCP的三次握手与四次挥手问题
1.相关问题 问题1: 请详细描述三次握手和四次挥手的过程,并画出状态图 问题2: 四次挥手中TIME_WAIT状态存在的目的是什么? 问题3: TCP是通过什么机制保障可靠性的? 2.问题回答 问题 ...
- Systemd vs SysVinit
- vue,基于element的tree组件封装
封装组件代码 // 组件:树 /* 参数说明-属性: 1.treeData:展示数据(array) 2.treeEmptyText:内容为空的时候展示的文本(String) 3.treeNodeKey ...
- Synchronized及其实现原理(一)
一.Synchronized的基本使用 Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法.Synchronized的作用主要有三个:(1)确保线程互斥的访问同步 ...
- map的常见用法
map的常见用法 map 是什么? map是一组键值对的组合,通俗理解类似一种特殊的数组,a[key]=val,只不过数组元素的下标是任意一种类型,而且数组的元素的值也是任意一种类型.有点类似pyth ...
- adb 打印kernel输出的log
一. linux 内核printk机制 1.1. Android内核是基于Linxu kernel的,因此其log机制也是通用的,在Android内核中使用printk函数进行Log输出.与 ...
- laravel框架之即點即改
//控制器層 public function ajaxsex(request $request) { $id = $request->get('id'); $fd = $request-> ...
- alembic 实践操作
1. alembic [--config */alembic.ini ] current 2. alembic revision -m "add columns" 编辑生产的模板文 ...
- linux如何配置使用sendEmail发送邮件
sendEmail是一个轻量级.命令行的SMTP邮件客户端.如果你需要使用命令行发送邮件,那么sendEmail是非常完美的选择.使用简单并且功能强大.这个被设计用在php.bash.perl和web ...