PostgreSQL数据DML误操作恢复方法

 更新时间:2024年12月10日 10:28:04   作者:施嘉伟  
PostgreSQL是一种开源的对象关系型数据库管理系统,其DML(Data Manipulation Language)负责数据的操作和管理,那么如何DML误操作了如何恢复,所以本文介绍了PostgreSQL数据DML误操作恢复方法,需要的朋友可以参考下

第一部分 文档描述

本文档适用数据表数据被DML类型的语句误操作情况下的重置恢复,需要满足数据库或数据表未被vacuum或者vacuum full

第二部分 操作步骤

2.1 创建测试表

创建测试表novels,

dbtest=# create table novels (name varchar(200), id int);
CREATE TABLE
dbtest=# insert into novels select md5(random()::text),generate_series(1,10);
INSERT 0 10

2.2 安装pageinspect扩展

安装pageinspect扩展获取元组记录信息

dbtest=# create extension pageinspect ;
CREATE EXTENSION

2.3 查询表的事务操作记录

使用扩展pageinspect中的函数查询当前表的事务操作记录

dbtest=# select * from heap_page_items(get_raw_page('novels','main', 0));
 lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid |     
                                  t_data                                       
----+--------+----------+--------+--------+--------+----------+--------+-------------+------------+--------+--------+-------+-----
-------------------------------------------------------------------------------
  1 |   8128 |        1 |     64 |    651 |      0 |        0 | (0,1)  |           2 |       2050 |     24 |        |       | \x43
613731663139343239303330323262313732613039383366633066396562663600000001000000
  2 |   8064 |        1 |     64 |    651 |      0 |        0 | (0,2)  |           2 |       2050 |     24 |        |       | \x43
386633363838333134386434323539306265613033636434386536393232383400000002000000
  3 |   8000 |        1 |     64 |    651 |      0 |        0 | (0,3)  |           2 |       2050 |     24 |        |       | \x43
363535323364663966616531663935666538383632646239383166633962623600000003000000
  4 |   7936 |        1 |     64 |    651 |      0 |        0 | (0,4)  |           2 |       2050 |     24 |        |       | \x43
333763383035386564303434316133366438656133333764613837626362616600000004000000
  5 |   7872 |        1 |     64 |    651 |      0 |        0 | (0,5)  |           2 |       2050 |     24 |        |       | \x43
663833356234353939623566336661336662376630323234363133663139663800000005000000
  6 |   7808 |        1 |     64 |    651 |      0 |        0 | (0,6)  |           2 |       2050 |     24 |        |       | \x43
626336623539373031316565396437333236363965313937323265373736333100000006000000
  7 |   7744 |        1 |     64 |    651 |      0 |        0 | (0,7)  |           2 |       2050 |     24 |        |       | \x43
646633323365396535356166376538386632376139666431643739303736356600000007000000
  8 |   7680 |        1 |     64 |    651 |      0 |        0 | (0,8)  |           2 |       2050 |     24 |        |       | \x43
393865616338366430323137363466626462616539333831636436646137333200000008000000
  9 |   7616 |        1 |     64 |    651 |      0 |        0 | (0,9)  |           2 |       2050 |     24 |        |       | \x43
333766383764653134633235666664643563663832313836643064326138653600000009000000
 10 |   7552 |        1 |     64 |    651 |      0 |        0 | (0,10) |           2 |       2050 |     24 |        |       | \x43
32333636613934363930393830316562376564366537376630366231626362610000000a000000
(10 rows)

2.4 模拟删除表数据

删除id为5的数据,再次查看该表的事务操作记录,可以看到标红处id为5的记录其删除事务号为652

dbtest=# delete from novels where id = 5;
DELETE 1
dbtest=# select * from heap_page_items(get_raw_page('novels','main', 0));
 lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_field3 | t_ctid | t_infomask2 | t_infomask | t_hoff | t_bits | t_oid |     
                                  t_data                                       
----+--------+----------+--------+--------+--------+----------+--------+-------------+------------+--------+--------+-------+-----
-------------------------------------------------------------------------------
  1 |   8128 |        1 |     64 |    651 |      0 |        0 | (0,1)  |           2 |       2306 |     24 |        |       | \x43
613731663139343239303330323262313732613039383366633066396562663600000001000000
  2 |   8064 |        1 |     64 |    651 |      0 |        0 | (0,2)  |           2 |       2306 |     24 |        |       | \x43
386633363838333134386434323539306265613033636434386536393232383400000002000000
  3 |   8000 |        1 |     64 |    651 |      0 |        0 | (0,3)  |           2 |       2306 |     24 |        |       | \x43
363535323364663966616531663935666538383632646239383166633962623600000003000000
  4 |   7936 |        1 |     64 |    651 |      0 |        0 | (0,4)  |           2 |       2306 |     24 |        |       | \x43
333763383035386564303434316133366438656133333764613837626362616600000004000000
  5 |   7872 |        1 |     64 |    651 |    652 |        0 | (0,5)  |        8194 |        258 |     24 |        |       | \x43
663833356234353939623566336661336662376630323234363133663139663800000005000000
  6 |   7808 |        1 |     64 |    651 |      0 |        0 | (0,6)  |           2 |       2306 |     24 |        |       | \x43
626336623539373031316565396437333236363965313937323265373736333100000006000000
  7 |   7744 |        1 |     64 |    651 |      0 |        0 | (0,7)  |           2 |       2306 |     24 |        |       | \x43
646633323365396535356166376538386632376139666431643739303736356600000007000000
  8 |   7680 |        1 |     64 |    651 |      0 |        0 | (0,8)  |           2 |       2306 |     24 |        |       | \x43
393865616338366430323137363466626462616539333831636436646137333200000008000000
  9 |   7616 |        1 |     64 |    651 |      0 |        0 | (0,9)  |           2 |       2306 |     24 |        |       | \x43
333766383764653134633235666664643563663832313836643064326138653600000009000000
 10 |   7552 |        1 |     64 |    651 |      0 |        0 | (0,10) |           2 |       2306 |     24 |        |       | \x43
32333636613934363930393830316562376564366537376630366231626362610000000a000000
(10 rows)

2.5 关闭表级别的autovacuum

解析被删除的数据之前首先查询表在删除时间点之后是否被vacuum(包括手动vacuum和autovacuum)

dbtest=# \x
Expanded display is on.
dbtest=# select * from pg_stat_all_tables where relname = 'novels';
-[ RECORD 1 ]-------+------------------------------
relid               | 24783
schemaname          | public
relname             | novels
seq_scan            | 13
seq_tup_read        | 44
idx_scan            | 
idx_tup_fetch       | 
n_tup_ins           | 28
n_tup_upd           | 0
n_tup_del           | 22
n_tup_hot_upd       | 0
n_live_tup          | 6
n_dead_tup          | 18
n_mod_since_analyze | 50
n_ins_since_vacuum  | 24
last_vacuum         | 2022-02-09 11:27:30.501748+08
last_autovacuum     | 
last_analyze        | 
last_autoanalyze    | 
vacuum_count        | 1
autovacuum_count    | 0
analyze_count       | 0
autoanalyze_count   | 0

如果没有被vacuum,则关闭表级别的autovacuum并开始解析步骤

dbtest=# alter table novels set (autovacuum_enabled = off);

2.6 关闭数据库重置事务id

关闭数据库服务,使用pg_resetwal工具重置事务id,使得下一个事务id从652开始

[postgres@VM-4-13-centos ~]$ pg_ctl stop
[postgres@VM-4-13-centos data]$ pg_resetwal -x 652 -D $PGDATA
Write-ahead log reset

2.7 启动数据库

启动数据库,查看数据是否找回,并重建表导出导入数据

[postgres@VM-4-13-centos ~]$ pg_ctl start
waiting for server to start....2022-02-09 14:56:51.938 CST [27058] LOG:  redirecting log output to logging collector process
2022-02-09 14:56:51.938 CST [27058] HINT:  Future log output will appear in directory "log".
 done
server started
[postgres@VM-4-13-centos ~]$ psql -ddbtest
psql (13.4)
Type "help" for help.

dbtest=# 
dbtest=# select xmin,xmax,id from novels ;
 xmin | xmax | id 
------+------+----
  651 |    0 |  1
  651 |    0 |  2
  651 |    0 |  3
  651 |    0 |  4
  651 |  652 |  5
  651 |    0 |  6
  651 |    0 |  7
  651 |    0 |  8
  651 |    0 |  9
  651 |    0 | 10
(10 rows)

可以使用pg_dump/pg_restore重建表

[postgres@VM-4-13-centos ~]$ pg_dump -Fc -U postgres -t novels -f novels.sql -d dbtest

导出表数据后重命名原表

dbtest=# alter table novels rename to novelsbak;

pg_restore恢复数据

[postgres@VM-4-13-centos ~]$ pg_restore -d dbtest novels.sql -c --if-exists

最后,验证数据完整性

dbtest=# select * from novels ;
               name               | id 
----------------------------------+----
 a63e2f63c5dbec9065a788f6e774b9ce |  1
 092465fb1c7b58adea3b35b4a5de5fd9 |  2
 1559907b48d5e8efaeddbdace55efad2 |  3
 3f47e858647d8ef838fbaa7e87b3bc07 |  4
 430f91a034857bf996f51cbe1dc6bef3 |  5
 56d65c982438ed56724e3dae4c5e7933 |  6
 4dbecc8fb3d3a8acca631ed359685011 |  7
 98023e6140984d125cc19ee4ba33608f |  8
 f2570c845be93fdf36e9d7c3f4d34ccf |  9
 7d9d3a65770df1573ec58c349d3216f0 | 10
(10 rows)

到此这篇关于PostgreSQL数据DML误操作恢复方法的文章就介绍到这了,更多相关PostgreSQL DML误操作恢复内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • PostgreSQL中实现自增的三种方式举例

    PostgreSQL中实现自增的三种方式举例

    很多小伙伴在把mysql数据库里面的表导入pgsql数据库的时候,会遇到新增数据的时候id不自增,这篇文章主要给大家介绍了关于PostgreSQL中实现自增的三种方式,需要的朋友可以参考下
    2024-02-02
  • 浅谈PostgreSQL消耗的内存计算方法

    浅谈PostgreSQL消耗的内存计算方法

    这篇文章主要介绍了浅谈PostgreSQL消耗的内存计算方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • postgres 实现查询某条数据的排名

    postgres 实现查询某条数据的排名

    这篇文章主要介绍了postgres 实现查询某条数据的排名,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • PGSQL查询最近N天的数据及SQL语句实现替换字段内容

    PGSQL查询最近N天的数据及SQL语句实现替换字段内容

    PostgreSQL提供了WITH语句,允许你构造用于查询的辅助语句,下面这篇文章主要给大家介绍了关于PGSQL查询最近N天的数据及SQL语句实现替换字段内容的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • PostgreSQL中的OID和XID 说明

    PostgreSQL中的OID和XID 说明

    在PostgreSQL中经常碰到OID和XID,刚才不明白这些东西是干什么的。
    2009-09-09
  • postgresql 实现更新序列的起始值

    postgresql 实现更新序列的起始值

    这篇文章主要介绍了postgresql 实现更新序列的起始值,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 浅谈Postgresql默认端口5432你所不知道的一点

    浅谈Postgresql默认端口5432你所不知道的一点

    这篇文章主要介绍了浅谈Postgresql默认端口5432你所不知道的一点,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • postgresql 中的加密扩展插件pgcrypto用法说明

    postgresql 中的加密扩展插件pgcrypto用法说明

    这篇文章主要介绍了postgresql 中的加密扩展插件pgcrypto用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • PostgreSQL的日期时间差DATEDIFF实例详解

    PostgreSQL的日期时间差DATEDIFF实例详解

    PostgreSQL是一款简介而又性能强大的数据库应用程序,其在日期时间数据方面所支持的功能也都非常给力,下面这篇文章主要给大家介绍了关于PostgreSQL的日期时间差DATEDIFF的相关资料,需要的朋友可以参考下
    2023-04-04
  • PostgreSQL psql 常用命令总结

    PostgreSQL psql 常用命令总结

    psql是PostgreSQL的一个命令行交互式客户端工具,它具有非常丰富的功能,类似于Oracle的命令行工具sqlplus,本文给大家总结下PostgreSQL 中常用 psql 常用命令以便后续查阅,感兴趣的朋友跟随小编一起看看吧
    2023-07-07

最新评论