联系:手机/微信(+86 17813235971) QQ(107644445)
标题:Postgres数据库truncate表无有效备份恢复
作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]
创建一个Postgres表,并插入数据
postgres=# CREATE TABLE "PeisInterfaceLog" ( postgres(# "PeisInterfaceLogId" text, postgres(# "PeisDepartmentId" text, postgres(# "PeisDepartmentName" text, postgres(# "PeisInterfaceSubjectType" text, postgres(# "PeisInterfaceSubjectId" text, postgres(# "PeisInterfaceNo" text, postgres(# "PeisInterfaceName" text, postgres(# "PeisInterfaceDirection" text, postgres(# "PeisInterfaceCallAddress" text, postgres(# "PeisInterfaceLogStartTime" timestamp , postgres(# "PeisInterfaceInputContent" json, postgres(# "PeisInterfaceInputTranscodeContent" json, postgres(# "PeisInterfaceOutContent" json, postgres(# "PeisInterfaceOutTranscodeContent" json, postgres(# "PeisInterfaceSuccessSign" int4, postgres(# "PeisInterfaceLogStatusCode" text, postgres(# "PeisInterfaceLogNote" text, postgres(# "PeisInterfaceLogTimestamp" timestamp , postgres(# "PeisInterfaceLogInfo" text, postgres(# "PeisPatientRegisterId" text postgres(# ); CREATE TABLE postgres=# \i /postgres/COPY/public_copy.sql SET COPY 722957 postgres=# select count (1) from "PeisInterfaceLog" ; count -------- 722957 (1 row) |
验证truncate操作,引起Postgres中oid的变化
postgres=# checkpoint ; CHECKPOINT postgres=# show data_directory; data_directory ---------------- /pgdata (1 row) postgres=# select oid, datname from pg_database ; oid | datname -------+----------- 13676 | postgres 1 | template1 13675 | template0 (3 rows ) postgres=# select relname, relowner, relfilenode from pg_class where relowner = 10 and relname like '%PeisInterfaceLog%' ; relname | relowner | relfilenode ------------------+----------+------------- PeisInterfaceLog | 10 | 16384 (1 row) postgres=# truncate table "PeisInterfaceLog" ; TRUNCATE TABLE postgres=# select count (1) from "PeisInterfaceLog" ; count ------- 0 (1 row) postgres=# select relname, relowner, relfilenode from pg_class where relowner = 10 and relname like '%PeisInterfaceLog%' ; relname | relowner | relfilenode ------------------+----------+------------- PeisInterfaceLog | 10 | 16394 (1 row) |
使用工具进行初始化字典信息
PDU.public= # b; 开始初始化... -pg_database:< /pgdata/global/1262 > 数据库:postgres -pg_schema:< /pgdata/base/13676/2615 > -pg_class:< /pgdata/base/13676/1259 > 共88行 -pg_attribute:< /pgdata/base/13676/1249 > 共2950行 模式: ▌ public 1张表 PDU.public= # use postgres; ┌────────────────────────────────────────┐ │ 模式 │ 表数量 │ ├────────────────────────────────────────┤ │ public │ 1 │ └────────────────────────────────────────┘ postgres.public= # set public; ┌──────────────────────────────────────────────────┐ │ 表名 │ 表大小 │ ├──────────────────────────────────────────────────┤ │ PeisInterfaceLog │ 0 │ └──────────────────────────────────────────────────┘ 仅显示表大小排名前 1 的表名 postgres.public= # \d PeisInterfaceLog; ┌──────────────────────────────────────────────────────────────┐ │ 列类型 │ └──────────────────────────────────────────────────────────────┘ text,text,text,text,text,text,text,text,text,timestamp,json,json,json,json,int4,text,text,timestamp,text,text |
配置软件磁盘扫描操作(pdu.ini中配置)
#dropScan需要扫描的磁盘 DISK_PATH= /data/test . dd #dropScan时跳跃的数据块数量,数值越小覆盖磁盘越全面,速度越慢 BLOCK_INTERVAL=5 |
启用磁盘扫描操作
PDU.public= # p idxmode off; ┌─────────────────────────────────────────────────────────────────┐ │ 参数 │ 当前值 │ ├─────────────────────────────────────────────────────────────────┤ │ startwal │ │ │ endwal │ │ │ startlsnt │ │ │ endlsnt │ │ │ starttime │ │ │ endtime │ │ │ resmode(Data Restore Mode) │ TIME │ │ exmode(Data Export Mode) │ CSV │ │ encoding │ UTF8 │ │ restype(Data Restore Type) │ DELETE │ ----------------------DropScan---------------------- │ dsoff(DropScan startOffset) │ 0 │ │ blkiter(Block Intervals) │ 5 │ │ itmpcsv(Items Per Csv) │ 100 │ │ idxmode │ off │ └─────────────────────────────────────────────────────────────────┘ PDU.public= # ds; ▌全量扫描恢复模式 ▌数据文件扫描 ┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ 表名 │ 结果 ├────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ PeisInterfaceLog 99.976 %(21469593600) 数据页: 71158 成功: 722947 (疑似乱码: 2809 ) 失败: 0 耗时 15.28 秒 └────────────────────────────────────────────────────────────────────────────────────────────────────┘ 扫描完毕,文件目录如下: restore /dropscan/PeisInterfaceLog PDU.public= # ds copy; 已导出: /restore/dropscan/PeisInterfaceLog/COPY .sql PDU.public= # [root@xifenfei PeisInterfaceLog] # more COPY.sql [root@xifenfei PeisInterfaceLog] # cat /restore/dropscan/PeisInterfaceLog/COPY.sql COPY PeisInterfaceLog FROM '/restore/dropscan/PeisInterfaceLog/09-28-21:29:55_226738176_32760blks_336787items.csv' ; COPY PeisInterfaceLog FROM '/restore/dropscan/PeisInterfaceLog/09-28-21:30:01_595968000_32767blks_330416items.csv' ; COPY PeisInterfaceLog FROM '/restore/dropscan/PeisInterfaceLog/09-28-21:30:04_1116061696_5631blks_55744items.csv' ; |
把恢复数据导入到Postgres数据中
[root@xifenfei ~]# su - postgres [postgres@xifenfei ~]$ psql psql (12.8) Type "help" for help. postgres=# \i /restore/dropscan/PeisInterfaceLog/COPY.sql COPY 336787 COPY 330416 COPY 55744 postgres=# select count (1) from "PeisInterfaceLog" ; count -------- 722947 (1 row) |
经过上述扫描测试证明该工具实现了在Postgres中truncate数据的绝大部分数据恢复(这里的乱码不是由于没有扫描到数据,主要是由于个别字符串由于类型判断关系识别不对导致乱码抛弃).
如果你遇到Postgres 数据库由于drop/truncate等误操作,而且无有效备份进行恢复,面临数据丢失风险,请第一时间保护现场(数据文件所在分区尽可能不要有写入操作),联系我们提供专业恢复技术支持:
电话/微信:17813235971 Q Q:107644445 E-Mail:dba@xifenfei.com