m6米乐安卓版下载-米乐app官网下载
1

mogdb异常恢复研究-m6米乐安卓版下载

范计杰 2022-09-05
207

[[toc]]

在异常恢复场景中,如磁盘故障、文件系统固定,仅能找回部分文件,如pgdata/base/{待恢复用户数据库目录}时,通过创建新的cluster,创建空库,使用{待恢复用户数据库目录}替换到新的pgdata/base/{新建空库},来读取数据是可行的。 主要有以下几点依据 1、pgdata/base/{database oid}下包含本库的数据字典
2、$pgdata/base/{database oid}下包含用户数据文件
3、读取数据可见性依赖的clog、csnlog,可以人工重建(会丢失部分事务信息)
4、读取数据可见性依赖的控制文件中记录的nextxid,nextoid等主要信息,也可以人工更改

1、环境描述
要恢复的cluster目录
/opt/ogdata/pdata

新建的空的cluster目录
/home/omm/data

2、待恢复库准备测试数据
准备好数据后直接kill数据库进程,模拟异常终止

生成测试数据
\c test
create table t1(id int,c varchar(100));
insert into t1 select i,'test'||i from generate_series(1,100) i;
create table t2(id int,c varchar(100));
insert into t2 select i,'test'||i from generate_series(1,100) i;
delete from t2 where id<50;
checkpoint

3、初始划一个空的cluster,并创建一个空库

$ gs_initdb -d /home/omm/data --nodename test -e utf8
$ gs_ctl start -d /home/omm/data -z single_node -l logfile

4、创建空库,并查看database oid

postgres=# create database test;
create database
postgres=# select oid from pg_database where datname='test';
  oid
-------
 16385
(1 row)

确定该库目录为$pgdata/base/16385

5、停止新库,复制替换数据库
$ gs_ctl stop -d ~/data
$ cp -rp /opt/ogdata/pdata/base/16389/* ~/data/base/16385/

6、尝试从旧的cluster目录找到控制文件信息
pg_controldata /opt/ogdata/pdata/

找到重要的几个信息,用于新cluster pg_resetxlog
latest checkpoint’s nextxid: 21378 <<<<
latest checkpoint’s nextoid: 24581 <<<<
latest checkpoint’s nextmultixactid: 2 <<<<
latest checkpoint’s nextmultioffset: 0

7、pg_resetxlog重置新库控制文件
$ pg_resetxlog -o 24581 -x 21378 -m 2 -o 0 ./data
transaction log reset

8、人工生成clog
根据当前的nextxid,判断生成多少个clog文件,256k一个

手工生成committed状态的clog日志,默认认为还没冻结或设置t_informask xmin,xmax提交状态的tuple上的事务都是已提交的
提示:正常情况下abort事务较少,多数为commited
=======4种事务状态===========
#define transaction_status_in_progress 0x00
#define transaction_status_committed 0x01
#define transaction_status_aborted 0x02
#define transaction_status_sub_committed 0x03
#define clog_bits_per_xact 2 #使用2bit保存事务状态
#define clog_xacts_per_byte 4 #每字节可以保存4个事务的事务状态
0x55为4个commit事务状态。
in [4]: bin(0x55)
out[4]: ‘0b1010101’
echo -e -n “\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55” > clog.dat
每次1k,可以通过dd方式生成更多clog
$ ls -l clog.dat
-rw-r–r-- 1 postgres dba 1024 6月 20 16:31 clog.dat
$ hexdump clog.dat
0000000 5555 5555 5555 5555 5555 5555 5555 5555
*
0000400
for((i=1;i<=255;i  ));
do
dd if=clog.dat of=data/pg_clog/000000000000 bs=1024 count=1 seek=$i conv=notrunc
done
[omm@centos7 ~]$ ls -l data/pg_clog/000000000000
-rw-r–r–. 1 omm dbgrp 262144 jun 20 17:59 data/pg_clog/000000000000

10、生成csnlog
根据当前的nextxid,判断生成多少个csnlog,每个文件256k。

dd if=/dev/zero of=data2/pg_csnlog/000000000000 bs=1024 count=256

提示:
只有在 latestcompletedxid<=>nextxid 之间的事务才需要csn判断可见性
重启库后,latestcompletedxid=nextxid,历史数据不太可能需要csn判断可见性

9、启动新库,验证数据
起库,验证数据可读
$ gs_ctl start -d ./data

如果验证可读后,导出数据备份
然后验证数据库可读写,可以使用,但推荐创建新库,导入数据,防止留坑。

中间的一点小波折

第一次没有生成提交状态的clog,导致读取不到数据。

表存在,但数据没查到,奇怪
test=# select count(*) from t1;
 count
-------
     0
(1 row)
mog_filedump 查看数据是存在的,但infomask 加了标志位,xmin_invalid,怀疑为第一次查询时,因为tuple中不能确定事务状态,是clog中查找xid 23100的事务,查找不到,被标记为xmin_invalid
mog_filedump -o -i -d int,varchar ~/data/base/16385/32773
copy: 98        test98
 item  14 -- length:   35  offset: 7632 (0x1dd0)  flags: normal
  xmin: 23100  xmax: 0  cid|xvac: 0
  block id: 1  linp index: 14   attributes: 2   size: 24
  infomask: 0x0a02 (hasvarwidth|xmin_invalid|xmax_invalid)
copy: 99        test99
 item  15 -- length:   36  offset: 7592 (0x1da8)  flags: normal
  xmin: 23100  xmax: 0  cid|xvac: 0 <<<

1、只要数据字典存在,数据文件存在,通过复制目录恢复数据就是可行的
2、过程中主要难点在于,判断最大的xid,生成clog
3、如果数据字典丢失或损坏,理论找到表结构,重建,重命名数据文件也能读取数据,但一难数据文件无法判断是哪个表!!!

「喜欢文章,快来给作者赞赏墨值吧」
【米乐app官网下载的版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论

网站地图