当前主流数据库版本服务支持周期-202503

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:当前主流数据库版本服务支持周期-202503

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

在最新的”当前数据库版本的发行时间表 (Doc ID 1626244.1)”文档中,oracle官方更新的数据库产品的支持周期,最重要的一点就是oracle 19c标准服务延期到2029年12月31日
DBROADMAP12-2-2024

版本 补丁结束日期 注意和例外
 23ai

Long Term Release

Premier Support – 2032年12月31日

Extended Support - 时间待定

  • 由于此次发布中突破性人工智能技术的重要性,我们将其从 Oracle 数据库 23c 重新命名为 Oracle 数据库 23ai
  • 现在可在云上、Oracle Exadata 和 Oracle Database Appliance 中使用。请参阅下方的 Oracle 数据库日程表中的详细信息
  • Premier Support将于 2031 年 12 月 31 日结束
  • 通过扩展支持或者ULA进行错误修正/补丁的截止日期待定
21c

Innovation Release

 2027年7月31日
  • 错误更正/补丁 有效期至2027年7月31日
  • 21c没有资格申请 Extended Support(ES)
  • 21c只提供 Release Updates (RUs) 补丁
  • 21c不适用于Exadata Database Service

 

19c

Long Term Release

2029年12月31日,没有ES/ULA

2032年12月31日,有ES/ULA

 

  • Premier Support(PS)将于2029年12月31日结束。扩展支持(ES)将从2030年1月1日持续到2032年12月31日。
  • 错误更正/补丁,付费的ES可到2032年12月31日;没有付费的ES,有效期到2029年12月31日
  • 从 2022 年 10 月的补丁周期开始,19.17.0 及更高版本将不再提供 19c RUR。在 2023 年 1 月交付 Oracle Database 19c RUR 19.16.2 之后,不会在任何平台上交付额外的 RUR。更多细节请参考文档 Sunsetting of 19c RURs and FAQ (Doc ID 2898381.1))
  • 为了让客户更频繁地访问推荐和经过良好测试的补丁集合,Oracle 从 2022 年 11 月开始推出 Monthly Recommended Patches (MRP)。 MRP 仅支持 Linux x86-64 平台。(更多细节请参考文档 Introducing Monthly Recommended Patches (MRPs) and FAQ (Doc ID 2898740.1))
18c

Innovation Release

 

2021年6月30日
  • 错误更正/补丁 有效期至2021年6月30日,18c已进入 Sustaining Support 阶段。
  • 18c没有资格申请 Extended Support(ES)
  • 18c 在 Exadata Database Service、Base Database Service 或 Exadata Cloud@Customer 上不受支持。
12.2.0.1

 

2022年3月31日

Upgrade Support (Restricted Availability) Jan 1, 2024- Dec 31, 2025 - 具体请联系 CSS

  • 这个版本的错误更正/补丁已经结束
  • 12.2.0.1 没有资格申请 Extended Support(ES)
  • 在 Exadata Database Service、Base Database Service 或 Exadata Cloud@Customer 上运行 12.2.0.1 需要购买 Upgrade Support (Restricted Availability)(旧称MDS) 服务
12.1.0.2

最终版本

2022年7月31日,有付费的ES, ULA, 或者减免费用的 EBS

Dec 31, 2025 (Upgrade Support (Restricted Availability)- 具体请联系 CSS)

  • 这个版本的错误更正/补丁已经结束
  • Premier Support(PS)截止至2018年7月31日,为期一年的免费 Extended Support(ES)有效期至2019年7月31日
  • 从 2019年8月1日 至 2022年7月31日,需要ES费用或ULA. 没有付费的 ES or ULA, 补丁截止于 2019年7月31日
  • 我们为电子商务客户提供全球ES uplift 费用减免,详情和到期日期见: Extended Support Fee Waiver for Oracle Database 12.1 and 11.2 for Oracle E-Business Suite (Doc ID 2522948.1) 或技术支持政策文件
  • Apple Macintosh 平台 补丁结束日期为2021年7月31日 
  • 微软Windows平台: 对于 12.1.0.2 Database, Oracle 在 Microsoft Windows 2008 上运行 12.1.0.2 Database。 这个平台的 end-of-life support 是 January 14, 2020。 甲骨文做出了合理的努力,在2022年7月之前为Windows上的数据库12.1.0.2提供补丁,但这种支持已经过期。
  • 在 Exadata Database Service、Base Database Service 或 Exadata Cloud@Customer 上运行 12.1.0.2 需要购买 Upgrade Support (Restricted Availability)(旧称MDS) 服务
12.1.0.1 2016年8月31日
  • 这个版本的错误更正/补丁已经结束
  • 12.1.0.1 没有资格申请 Extended Support (ES)
  • 12.1.0.1 是 Standard Edition (SE) 和 Standard Edition One (SE1) 的最后一个版本
11.2.0.4

最终版本 for 11.2

  • 2020年12月31日(有偿扩展支持 或 ULA扩展支持 或 减免费用的EBS)
  • 2025年12月31日(Upgrade Support (Restricted Availability) - 具体请联系 CSS)
  • 2021年12月31日 适用于OpenVMS平台

 

  • Premier Support (PS)截止到2015年1月31日,而为期一年的免费Extended Support(ES)持续到2018年12月31日。
  • 从2019年1月1日开始到2020年12月31日,将需要ES费用或ULA。
  • Oracle为电子商务客户提供全球ES uplift 费用减免,详情和到期日期见: Extended Support Fee Waiver for Oracle Database 12.1 and 11.2 for Oracle E-Business Suite (Doc ID 2522948.1) 或技术支持政策文件。
  • 第1代 ExaCC, OCC DBCS, and ODA 将拥有额外3个月的支持周期. 这些平台上的数据库的支持周期截止到: 2021年3月31日。可以创建新实例,直到扩展支持终止为止。但是,Oracle不承诺在支持终止后任何11.2.0.4 DBCS实例将继续运行。
  • 市场驱动支持(Market Driven Support)提供以下数据库云服务:第1代和第2代ExaCC,OCC DBCS,OCI DBCS,OCI ExaCS。 直到市场驱动支持终止(2021年12月31日),可以创建新实例。 Oracle不承诺在Upgrade Support(旧称MDS)支持终止后任何11.2.0.4 DBCS实例将继续运行。 市场驱动支持不适用于PSM-based OCI DBCS,OCI-C DBCS和OCI-C ExaCS。
  • 在 Exadata Database Service、Base Database Service 或 Exadata Cloud@Customer 上运行 11.2.0.4 需要购买 Upgrade Support (Restricted Availability)(旧称MDS) 服务
  • 11.2.0.4是OpenVMS上的最终版本。 在2021日历年中,除了标准的专业支持费用之外无需其他费用,客户能够收到重要度1的修复程序和安全更新。涵盖范围不包括新认证,第三方产品或任何Java/JDK功能(包括数据库中嵌入的Java组件)。涵盖范围还不包括与加密和网络加密有关的任何更新。 此供应不包括标准的安全补丁更新(SPU)。

 


pg启动报invalid checkpoint record处理

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:pg启动报invalid checkpoint record处理

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

pg库启动报PANIC: could not locate a valid checkpoint record错误

2025-03-09 10:59:10.365 EDT [73013] LOG:  starting PostgreSQL 16.8 on x86_64-pc-linux-gnu, 
                                          compiled by gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5), 64-bit
2025-03-09 10:59:10.365 EDT [73013] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-03-09 10:59:10.365 EDT [73013] LOG:  listening on IPv6 address "::", port 5432
2025-03-09 10:59:10.367 EDT [73013] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2025-03-09 10:59:10.401 EDT [73018] LOG:  database system was interrupted; last known up at 2025-03-09 10:54:43 EDT
2025-03-09 10:59:11.506 EDT [73018] LOG:  invalid checkpoint record
2025-03-09 10:59:11.508 EDT [73018] PANIC:  could not locate a valid checkpoint record
2025-03-09 10:59:12.004 EDT [73013] LOG:  startup process (PID 73018) was terminated by signal 6: Aborted
2025-03-09 10:59:12.004 EDT [73013] LOG:  aborting startup due to startup process failure
2025-03-09 10:59:12.006 EDT [73013] LOG:  database system is shut down

从报错信息中看,是有无法读取到有效的checkpoint记录导致,初步怀疑是wal异常,检查pg_wal目录,发现wal日志为空

[root@localhost pg_wal]# ls -ltr
total 16388
drwx------  2 postgres postgres        6 Mar  6 08:10 archive_status
[root@localhost pg_wal]# 

进一步检查系统操作命令rm删除wal日志命令

cd pg_wal
rm -rf 0000000*

初步确认是由于wal日志被意外删除导致pg库无法启动,尝试重置wal,由于库不是干净关闭,无法直接重置成功

[postgres@localhost log]$ pg_resetwal $PGDATA
The database server was not shut down cleanly.
Resetting the write-ahead log might cause data to be lost.
If you want to proceed anyway, use -f to force reset.

使用pg_resetwal -f强制重置

[postgres@localhost log]$ pg_resetwal -f $PGDATA
Write-ahead log reset

尝试启动pg库成功

[postgres@localhost log]$ pg_ctl start 
waiting for server to start....2025-03-09 11:02:02.609 EDT [73088] LOG:  
redirecting log output to logging collector process
2025-03-09 11:02:02.609 EDT [73088] HINT:  Future log output will appear in directory "log".
 done
server started
2025-03-09 11:02:02.609 EDT [73088] LOG:  starting PostgreSQL 16.8 on x86_64-pc-linux-gnu, 
                                          compiled by gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5), 64-bit
2025-03-09 11:02:02.609 EDT [73088] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2025-03-09 11:02:02.609 EDT [73088] LOG:  listening on IPv6 address "::", port 5432
2025-03-09 11:02:02.610 EDT [73088] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2025-03-09 11:02:02.645 EDT [73092] LOG:  database system was shut down at 2025-03-09 11:01:53 EDT
2025-03-09 11:02:02.650 EDT [73088] LOG:  database system is ready to accept connections

删除redo导致ORA-00313 ORA-00312故障处理

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:删除redo导致ORA-00313 ORA-00312故障处理

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

有客户由于误操作直接rm 删除了redo文件,导致数据库启动报ORA-00313 ORA-00312错

2025-03-07T14:49:16.325723+08:00
ALTER DATABASE OPEN
2025-03-07T14:50:00.124620+08:00
Ping without log force is disabled:
  instance mounted in exclusive mode.
2025-03-07T14:50:00.198907+08:00
Crash Recovery excluding pdb 2 which was cleanly closed.
2025-03-07T14:50:00.238450+08:00
Beginning crash recovery of 1 threads
 parallel recovery started with 15 processes
 Thread 1: Recovery starting at checkpoint rba (logseq 2966 block 74686), scn 0
2025-03-07T14:50:00.325246+08:00
Started redo scan
2025-03-07T14:50:00.341193+08:00
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2681.trc:
ORA-00313: open failed for members of log group 2 of thread 1
ORA-00312: online log 2 thread 1: '/u01/app/oracle/oradata/orcl/redo02.log'
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory
Additional information: 7
2025-03-07T14:50:00.372632+08:00
Slave encountered ORA-10388 exception during crash recovery
…………
2025-03-07T14:50:00.385698+08:00
Slave encountered ORA-10388 exception during crash recovery
2025-03-07T14:50:00.388594+08:00
Aborting crash recovery due to error 313
2025-03-07T14:50:00.388739+08:00
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2681.trc:
ORA-00313: open failed for members of log group 2 of thread 1
ORA-00312: online log 2 thread 1: '/u01/app/oracle/oradata/orcl/redo02.log'
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory
Additional information: 7
2025-03-07T14:50:00.389243+08:00
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2681.trc:
ORA-00313: open failed for members of log group 2 of thread 1
ORA-00312: online log 2 thread 1: '/u01/app/oracle/oradata/orcl/redo02.log'
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory
Additional information: 7
ORA-313 signalled during: ALTER DATABASE OPEN...

然后客户把历史的redo文件拷贝过来,尝试恢复数据库,报ORA-00314 ORA-00312错误

2025-03-07T15:07:30.784759+08:00
ALTER DATABASE OPEN
Ping without log force is disabled:
  instance mounted in exclusive mode.
2025-03-07T15:07:30.808497+08:00
Crash Recovery excluding pdb 2 which was cleanly closed.
2025-03-07T15:07:30.838664+08:00
Beginning crash recovery of 1 threads
 parallel recovery started with 15 processes
 Thread 1: Recovery starting at checkpoint rba (logseq 2966 block 74686), scn 0
2025-03-07T15:07:30.897547+08:00
Started redo scan
2025-03-07T15:07:30.898222+08:00
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4106.trc:
ORA-00314: log 2 of thread 1, expected sequence# 2966 doesn't match 1646
ORA-00312: online log 2 thread 1: '/u01/app/oracle/oradata/orcl/redo02.log'
2025-03-07T15:07:30.930089+08:00
Slave encountered ORA-10388 exception during crash recovery
…………
2025-03-07T15:07:30.940051+08:00
Slave encountered ORA-10388 exception during crash recovery
2025-03-07T15:07:30.942274+08:00
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_mz00_4138.trc:
ORA-00312: online log 1 thread 1: '/u01/app/oracle/oradata/orcl/redo01.log'
2025-03-07T15:07:30.945509+08:00
Slave encountered ORA-10388 exception during crash recovery
2025-03-07T15:07:30.945512+08:00
Slave encountered ORA-10388 exception during crash recovery
2025-03-07T15:07:30.948369+08:00
Aborting crash recovery due to error 314
2025-03-07T15:07:30.948488+08:00
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4106.trc:
ORA-00314: log 2 of thread 1, expected sequence# 2966 doesn't match 1646
ORA-00312: online log 2 thread 1: '/u01/app/oracle/oradata/orcl/redo02.log'
2025-03-07T15:07:30.949390+08:00
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_4106.trc:
ORA-00314: log 2 of thread 1, expected sequence# 2966 doesn't match 1646
ORA-00312: online log 2 thread 1: '/u01/app/oracle/oradata/orcl/redo02.log'
ORA-314 signalled during: ALTER DATABASE OPEN...

使用Oracle数据库异常恢复检查脚本(Oracle Database Recovery Check)脚本收集信息之后数据文件头状态和所需要redo信息
df_header


数据库需要sequence#为2966的redo日志,但是当前已经被删除,基于当前情况,只能进行强制非一致性恢复,尝试强制打开库

SQL> recover database;                 
ORA-00283: recovery session canceled due to errors
ORA-00314: log 2 of thread 1, expected sequence# 2966 doesn't match 1646
ORA-00312: online log 2 thread 1: '/u01/app/oracle/oradata/orcl/redo02.log'

QL> select group#,status,sequence# from v$log;

	  GROUP# STATUS 		 SEQUENCE#
---------------- ---------------- ----------------
	       1 UNUSED 			 0
	       3 CURRENT		      2967
	       2 ACTIVE 		      2966

SQL> 
SQL> 
SQL> recover database until cancel;
ORA-00279: change 163033183 generated at 03/07/2025 14:04:20 needed for thread 1
ORA-00289: suggestion : /u01/app/oracle/recovery_area/orcl/archivelog/2025_03_08/o1_mf_1_2966_%u_.arc
ORA-00280: change 163033183 for thread 1 is in sequence #2966


Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
cancel
ORA-01547: warning: RECOVER succeeded but OPEN RESETLOGS would get error below
ORA-01194: file 1 needs more recovery to be consistent
ORA-01110: data file 1: '/u01/app/oracle/oradata/orcl/system01.dbf'


ORA-01112: media recovery not started


SQL> alter database open resetlogs;

Database altered.

运气不错,直接打开数据库成功,然后逻辑导出数据,完成此处恢复.这个让我想起来了一些类似案例:
Oracle 23ai rm redo*.log恢复
清空redo,导致ORA-27048: skgfifi: file header information is invalid
由于默认情况下oracle的redo文件扩展名是.log,然后被当做是不重要文件从而被清理导致数据库故障,在oracle服务器上清理数据之前建议查询v$datafile,v$logfile,v$tempfile,v$controlfile来确认是否是数据库文件

Navicat连接postgresql时出现column “datlastsysoid” does not exist错误解决

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:Navicat连接postgresql时出现column “datlastsysoid” does not exist错误解决

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

使用Navicat Premium 15访问PostgreSQL 16版本的库,报如下错误

ERROR:  column "datlastsysoid" does not exist
LINE 1: SELECT DISTINCT datlastsysoid FROM pg_database;

QQ20250308-105201
QQ20250308-105222


登录pg库查看

postgres=# SELECT DISTINCT datlastsysoid FROM pg_database;
2025-03-07 22:09:03.569 EST [62553] ERROR:  column "datlastsysoid" does not exist at character 17
2025-03-07 22:09:03.569 EST [62553] STATEMENT:  SELECT DISTINCT datlastsysoid FROM pg_database;
ERROR:  column "datlastsysoid" does not exist
LINE 1: SELECT DISTINCT datlastsysoid FROM pg_database;
                        ^
postgres=# \d pg_database;
               Table "pg_catalog.pg_database"
     Column     |   Type    | Collation | Nullable | Default 
----------------+-----------+-----------+----------+---------
 oid            | oid       |           | not null | 
 datname        | name      |           | not null | 
 datdba         | oid       |           | not null | 
 encoding       | integer   |           | not null | 
 datlocprovider | "char"    |           | not null | 
 datistemplate  | boolean   |           | not null | 
 datallowconn   | boolean   |           | not null | 
 datconnlimit   | integer   |           | not null | 
 datfrozenxid   | xid       |           | not null | 
 datminmxid     | xid       |           | not null | 
 dattablespace  | oid       |           | not null | 
 datcollate     | text      | C         | not null | 
 datctype       | text      | C         | not null | 
 daticulocale   | text      | C         |          | 
 daticurules    | text      | C         |          | 
 datcollversion | text      | C         |          | 
 datacl         | aclitem[] |           |          | 
Indexes:
    "pg_database_oid_index" PRIMARY KEY, btree (oid), tablespace "pg_global"
    "pg_database_datname_index" UNIQUE CONSTRAINT, btree (datname), tablespace "pg_global"
Tablespace: "pg_global"

确认没有了datlastsysoid列,通过查看文档确认从Postgres 15版本开始 pg_database表中删除了 datlastsysoid,但是可以通过查询dattablespace替代,使用二进制工具修改libcc.dll文件中的SELECT DISTINCT datlastsysoid部分语句为:SELECT DISTINCT dattablespace
QQ20250308-105427
QQ20250308-105455


然后重新启动Navicat,访问pg库正常
QQ20250308-111555

当然这个问题如果使用高版本的Navicat或者访问低版本的PostgreSQL库不会出现

aix磁盘损坏oracle数据库恢复

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:aix磁盘损坏oracle数据库恢复

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

客户aix环境硬盘异常导致系统无法启动,初步判断是数据文件存放在本地磁盘的空间中(本地两个盘都异常,系统无法启动),通过硬件恢复厂商镜像出来,但是通过aix文件系统直接挂载提示需要fsck,但是做fsck之后,提示大量文件丢失(最关键的数据文件和备份文件都被自动删除)
dmp-remove
fsck-remove


基于这种情况,采用镜像主机挂载的方式肯定不行,考虑直接采用软件直接解析,能够看到软件,可惜由于大量的文件系统元数据损坏,解析出来的数据文件和dmp也不可用(大量损坏和空块)
QQ20250307-122939

基于上述情况,只能采用碎片级别恢复出来数据文件
QQ20250307-123123

然后使用dul工具把数据恢复到表中,实现最大限度抢救客户数据
QQ20250307-123653

对于数据库级别恢复,这个是理论上的终极恢复方法

pg误删除数据恢复(PostgreSQL delete数据恢复)

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:pg误删除数据恢复(PostgreSQL delete数据恢复)

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

应用维护人员通过应用程序误删除了一些数据,希望对其进行恢复.通过咨询确认是PostgreSQL数据,wal和arch文件都在,取客户删除数据时间点相关wal文件
QQ20250306-231208


然后让客户提供具体涉及误删除的相关的库和表信息
QQ20250306-230846

通过工具解析wal日志,比较顺利的获取到了undo sql语句

Switch wal to 0000000300000525000000B0 on time 2025-03-05 22:23:14.263661+08
Switch wal to 0000000300000525000000B1 on time 2025-03-05 22:23:14.423082+08
Switch wal to 0000000300000525000000B2 on time 2025-03-05 22:23:15.983833+08
Switch wal to 0000000300000525000000B3 on time 2025-03-05 22:23:17.802107+08
Switch wal to 0000000300000525000000B4 on time 2025-03-05 22:23:18.942125+08
Switch wal to 0000000300000525000000B5 on time 2025-03-05 22:23:20.293585+08
Switch wal to 0000000300000525000000B6 on time 2025-03-05 22:23:21.531484+08
Switch wal to 0000000300000525000000B7 on time 2025-03-05 22:23:24.217501+08
Switch wal to 0000000300000525000000B8 on time 2025-03-05 22:23:27.504164+08
Switch wal to 0000000300000525000000B9 on time 2025-03-05 22:23:29.260754+08
Switch wal to 0000000300000525000000BA on time 2025-03-05 22:23:33.544486+08
Switch wal to 0000000300000525000000BB on time 2025-03-05 22:23:35.568116+08
Switch wal to 0000000300000525000000BC on time 2025-03-05 22:23:37.329659+08
Switch wal to 0000000300000525000000BD on time 2025-03-05 22:23:38.971834+08
Switch wal to 0000000300000525000000BE on time 2025-03-05 22:23:39.922353+08
Switch wal to 0000000300000525000000BF on time 2025-03-05 22:23:40.897294+08

QQ20250306-231657


然后把这些sql语句反向插入到生产库,完成这些误操作数据的恢复
QQ20250306-231935

如果此类的数据库(oracle,mysql,sql server,PostgreSQL)等恢复请求,需要专业恢复技术支持,请联系我们:
电话/微信:17813235971    Q Q:107644445QQ咨询惜分飞    E-Mail:dba@xifenfei.com

PostgreSQL表文件损坏恢复—pdu恢复损坏的表文件

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:PostgreSQL表文件损坏恢复—pdu恢复损坏的表文件

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

在某些情况下,由于PostgreSQL表文件损坏导致无法正常访问,可以通过pdu把好的block中的数据恢复出来
准备一张测试表,里面有97条记录

his5_dms=# \d hiscrm.t_sys_oper_log;
                                            Table "hiscrm.t_sys_oper_log"
       Column       |          Type          | Collation | Nullable |Default                     
--------------------+------------------------+-----------+----------+------------
 id                 | bigint                 |           | not null | 
 module             | character varying(50)  |           |          | 
 title              | character varying(50)  |           |          | 
 alias              | character varying(50)  |           |          | 
 business_type      | integer                |           |          | 0
 method             | character varying(200) |           |          | 
 request_method     | character varying(10)  |           |          | 
 operator_type      | integer                |           |          | 0
 oper_name          | character varying(50)  |           |          | 
 dept_name          | character varying(50)  |           |          | 
 oper_url           | character varying(255) |           |          | 
 oper_ip            | character varying(50)  |           |          | 
 oper_location      | character varying(255) |           |          | 
 oper_param         | text                   |           |          | 
 json_result        | text                   |           |          | 
 status             | integer                |           |          | 0
 error_msg          | text                   |           |          | 
 oper_time          | date                   |           |          | 
 create_id          | bigint                 |           |          | 
 create_time        | bigint                 |           |          | 
 clinic_id          | bigint                 |           |          | 
 group_id           | bigint                 |           |          | 
 patient_id         | bigint                 |           |          | 
 is_patient_related | integer                |           |          | 
 business_content   | json                   |           |          | 

his5_dms=# select count(1) from hiscrm.t_sys_oper_log;
 count 
-------
    97
(1 row)

查询表对应的具体文件

his5_dms=# SELECT oid,relfilenode FROM pg_class WHERE relname='t_sys_oper_log';
  oid  | relfilenode 
-------+-------------
 16850 |       16850
(1 row)

his5_dms=# SELECT pg_relation_filepath('hiscrm.t_sys_oper_log');
 pg_relation_filepath 
----------------------
 base/16386/16850
(1 row)

his5_dms=# SHOW data_directory;
     data_directory     
------------------------
 /var/lib/pgsql/12/data
(1 row)

使用dd对文件进行破坏

[postgres@xifenfeidg ~]$ ls -l  /var/lib/pgsql/12/data/base/16386/16850
-rw-------. 1 postgres postgres 90112 Sep  5 20:26 /var/lib/pgsql/12/data/base/16386/16850
[postgres@xifenfeidg ~]$ dd if=/dev/zero of=/var/lib/pgsql/12/data/base/16386/16850 bs=512 count=1 conv=notrunc
1+0 records in
1+0 records out
512 bytes copied, 0.000158756 s, 3.2 MB/s

重启pg库

[postgres@xifenfeidg bin]$ ./pg_ctl -m fast -D /var/lib/pgsql/12/data/ stop
waiting for server to shut down.... done
server stopped
[postgres@xifenfeidg bin]$ ./pg_ctl -D /var/lib/pgsql/12/data/ start
waiting for server to start....2025-03-02 19:02:11.395 HKT [64515] LOG:  
  starting PostgreSQL 12.20 on x86_64-pc-linux-gnu, 
  compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-22), 64-bit
2025-03-02 19:02:11.396 HKT [64515] LOG:  listening on IPv6 address "::1", port 5432
2025-03-02 19:02:11.396 HKT [64515] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2025-03-02 19:02:11.396 HKT [64515] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2025-03-02 19:02:11.397 HKT [64515] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2025-03-02 19:02:11.403 HKT [64515] LOG:  redirecting log output to logging collector process
2025-03-02 19:02:11.403 HKT [64515] HINT:  Future log output will appear in directory "log".
 done
server started

查询数据报错

[postgres@xifenfeidg bin]$ psql
psql (16.8, server 12.20)
Type "help" for help.

postgres=# \c his5_dms;
psql (16.8, server 12.20)
You are now connected to database "his5_dms" as user "postgres".
his5_dms=#  select count(1) from hiscrm.t_sys_oper_log;
ERROR:  invalid page in block 0 of relation base/16386/16850

通过pdu进行恢复
跳过了坏块,把好的block中数据均恢复出来

his5_dms.hiscrm=# unload tab t_sys_oper_log;
正在解析表 <t_sys_oper_log>. 已解析数据页: 0, 已解析数据: 0 条
        |-块号0 空页面或页面已损坏,已跳过
正在解析表 <t_sys_oper_log>. 已解析数据页: 11, 已解析数据: 86 条
表名<t_sys_oper_log>-</var/lib/pgsql/12/data/base/16386/16850> 
    解析完成, 11 个数据页 ,共计 86 条数据. 成功 86 条; 失败【0】条 
COPY文件路径为:<his5_dms/hiscrm/t_sys_oper_log.csv>

导入pg库中

his5_dms=# truncate table hiscrm.t_sys_oper_log;
TRUNCATE TABLE
his5_dms=# \i his5_dms/COPY/hiscrm_copy.sql
SET
COPY 86
his5_dms=# 

linux rm -rf 删除数据文件恢复

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:linux rm -rf 删除数据文件恢复

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

有客户由于误操作删除了oracle的部分数据文件(rm -rf 方式删除),然后自己尝试进行恢复操作,对部分文件执行了offline,导致比较麻烦的后果
jb
offline-file


接手故障之后,第一时间对其进行了镜像(因为有部分文件句柄已经释放,为了方式覆盖进一步破坏),对于没有释放的句柄可以通过类似方法进行恢复,参考以前类似恢复:
Oracle误删除数据文件恢复
Solaris rm datafile recovery—利用句柄误删除数据文件恢复

!cp  269  /u01/app/oracle/oradata/orcl/XXXXXX_DATA01.dbf
alter database datafile 12 offline;
recover datafile 12;
alter database datafile 12 online;

对于删除文件,而且句柄已经释放的文件,通过文件系统层面反删除进行恢复,参考以前类似恢复:
rm -rf误删Oracle数据库恢复
记录一次rm -rf 删除数据文件异常恢复
rm -rf 删除数据文件恢复方法—文件系统反删除+oracle碎片重组
rm


在这个恢复过程中,由于客户linux是物理机,而且本地空间不足,无法对其进行镜像,采用dd命令直接写镜像到其他的linux机器上(通过nfs方式),然后在win机器上直接挂载该nfs,记录下win上挂载nfs操作
nfs
mount-nfs

PostgreSQL恢复工具—pdu恢复单个表文件

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:PostgreSQL恢复工具—pdu恢复单个表文件

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

在某些情况下,比如我们需要对单个的PostgreSQL库的表文件进行恢复(比如文件系统损坏,drop库/表,truncate表等原因,然后找到了部分oid文件),可以使用pdu对其进行完美恢复(相比pg_filedump也方便很多),具体操作步骤:
1. 由于只有单个表文件,无法获取字典信息,因此需要应用厂商/客户提供具体表创建语句

his5_dms=#    CREATE TABLE t_xff (
his5_dms(#         id                       bigint,
his5_dms(#         hospital_id              bigint,
his5_dms(#         parent_id                bigint,
his5_dms(#         disease_code             varchar(60),
his5_dms(#         disease_name             varchar(60),
his5_dms(#         type                     smallint,
his5_dms(#         py                       varchar(60),
his5_dms(#         wb                       varchar(60),
his5_dms(#         sc                       varchar(20),
his5_dms(#         order_no                 int,
his5_dms(#         state                    smallint,
his5_dms(#         create_datetime          timestamp(6),
his5_dms(#         create_id                bigint,
his5_dms(#         edit_datetime            timestamp(6),
his5_dms(#         edit_id                  bigint,
his5_dms(#         search_path              varchar(300),
his5_dms(#         diagnosis_sort           int,
his5_dms(#         category_name            varchar(40),
his5_dms(#         input_option             varchar(40),
his5_dms(#         category_class           smallint,
his5_dms(#         memo1                    varchar(300),
his5_dms(#         memo2                    varchar(300),
his5_dms(#         other_code               varchar(60),
his5_dms(#         other_name               varchar(60),
his5_dms(#         special_disease_flag     smallint
his5_dms(#    );
CREATE TABLE

2. 把oid文件pdu放到restore库中

[root@xifenfeidg public]# pwd
/tmp/pdu/restore/public
[root@xifenfeidg public]# ls -l
total 7144
-rw-r--r--. 1 root root 7315456 Mar  2 21:04 123456
[root@xifenfeidg public]# 

3. 使用add语句在pdu加载数据类型

restore.public=# add 123456 t_xff bigint,bigint,bigint,varchar,varchar,smallint,varchar,varchar,varchar,
int,smallint,timestamp,bigint,timestamp,bigint,varchar,int,varchar,varchar,
smallint,varchar,varchar,varchar,varchar,smallint;
添加完成,请用\dt;查看可unload的表
restore.public=# \dt;
|--------------------------------------------------|
|               表名                  |  表大小    |
|--------------------------------------------------|
|    t_xff                            |  6.98 MB   |
|--------------------------------------------------|

        仅显示表大小排名前 1 的表名

4.使用pdu恢复表数据

restore.public=# unload t_xff;
正在解析表 <t_xff>. 已解析数据页: 893, 已解析数据: 46998 条
<t_xff>-<restore/public/123456> 解析完成, 894 个数据页 ,共计 46998 条数据. 成功 46998 条; 失败【0】条 
 COPY文件路径为:<restore/public/t_xff.csv>
restore.public=# unload COPY;

COPY命令导出完成, 文件路径: restore/COPY/public_copy.sql

5.导入数据到pg库中

his5_dms=# \i restore/COPY/public_copy.sql
SET
COPY 46998
his5_dms=# select count(1) from t_xff;
 count 
-------
 46998
(1 row)
his5_dms=# \x
Expanded display is on.
his5_dms=# select * from t_xff limit 1;
-[ RECORD 1 ]--------+---------------------------
id                   | 323839
hospital_id          | 0
parent_id            | 301
disease_code         | 57.8900x003
disease_name         | 腹腔镜下膀胱颈悬吊术
type                 | 2
py                   | fqjxpgjxds
wb                   | eeqgeeceks
sc                   | 
order_no             | 0
state                | 1
create_datetime      | 2022-09-29 15:22:58.588492
create_id            | 
edit_datetime        | 
edit_id              | 
search_path          | 301,
diagnosis_sort       | 
category_name        | 
input_option         | 
category_class       | 3
memo1                | 
memo2                | 
other_code           | 
other_name           | 
special_disease_flag | 0

PostgreSQL恢复工具—pdu工具介绍

联系:手机/微信(+86 17813235971) QQ(107644445)QQ咨询惜分飞

标题:PostgreSQL恢复工具—pdu工具介绍

作者:惜分飞©版权所有[未经本人同意,不得以任何形式转载,否则有进一步追究法律责任的权利.]

张晨同学开发了一个PostgreSQL数据恢复工具PDU(PDU: Postgresql Data Rescue Tool),我这边配合做一些测试
使用帮助命令

PDU.public=# ;

PDU数据拯救工具 | 命令帮助
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
**基础操作**
b;                                      │ 初始化数据库元信息
exit;                                   │ 退出工具

**数据库切换**
use <db>;                               │ 指定目标数据库 (例: use logs;)
set <schema>;                           │ 指定操作模式 (例: set recovery;)

**元数据展示**
\l;                                     │ 列出所有数据库
\dn;                                    │ 显示当前数据库模式
\dt;                                    │ 列出当前模式下的表
\d+ <table>;                            │ 查看表结构详情 (例: \d+ users;)
\d <table>;                             │ 查看表列类型 (例: \d users;)

**数据导出**
unload <table>;                         │ 导出表数据 → ./<表名>.csv (例: unload orders;)
unload SCH;                             │ 导出当前模式所有数据
unload DDL;                             │ 生成模式结构定义文件
unload COPY;                            │ 生成PSQL COPY语句脚本

**误删数据恢复**
scan t1;                                │ 扫描被误删的表
restore del <Tx Number>;                │ 通过事务号恢复被误删的数据
--------------------------------------------------------------------------------------
scan drop;                              │ 扫描wal日志中的drop事务
restore drop <Tx Number>;               │ 通过事务号恢复被drop的表
add <oid> <tablename> <attibutes>;      │ 将表信息手动添加到restore库中
例如: <add 12345 t1 varchar,varchar,timestamp,varchar,numeric,varchar,varchar,varchar,numeric;>

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
语法规则
◈ 指令后缀必须带 `;`

加载PostgreSQL元数据

PDU.public=# b;
开始初始化...
 -pg_database:</var/lib/pgsql/12/data/global/1262>
    【postgres】
      -pg_schema:</var/lib/pgsql/12/data/base/14399/2615>
      -pg_class:</var/lib/pgsql/12/data/base/14399/1259>,共55行
      -pg_attribute:</var/lib/pgsql/12/data/base/14399/1249>,共2913行
      模式:
        -->public,2张表
    【his5_dms】
      -pg_schema:</var/lib/pgsql/12/data/base/16386/2615>
      -pg_class:</var/lib/pgsql/12/data/base/16386/1259>,共793行
      -pg_attribute:</var/lib/pgsql/12/data/base/16386/1249>,共31329行
      模式:
        -->public,660张表
        -->hiscrm,55张表
        -->pgagent,8张表
        -->report,7张表
        -->statistics,10张表

查看当前有哪些库

PDU.public=# \l;
|------------------|
|     数据库名     |
|------------------|
|    postgres      |
|    template1     |
|    template0     |
|    his5_dms      |
|    restore       |
|------------------|

      5 rows selected

进入某个库

PDU.public=# use his5_dms;
|----------------------------------------|
|          模式             |  表数量    |
|----------------------------------------|
|    public                 |  660       |
|    hiscrm                 |  55        |
|    pgagent                |  8         |
|    report                 |  7         |
|    statistics             |  10        |
|----------------------------------------|

进入某个模式

his5_dms.public=# set hiscrm;
|--------------------------------------------------|
|               表名                  |  表大小    |
|--------------------------------------------------|
|    t_patient_other                  |  600.00 KB |
|    t_sys_oper_log                   |  88.00 KB  |
|    t_auth                           |  88.00 KB  |
|    t_setting_user                   |  56.00 KB  |
|    t_field_define                   |  32.00 KB  |
|    t_oper_log                       |  16.00 KB  |
|    t_role                           |  16.00 KB  |
|    t_sys_login_log                  |  8.00 KB   |
|    t_appointment_item               |  8.00 KB   |
|    t_clinic                         |  8.00 KB   |
|    t_dept                           |  8.00 KB   |
|    t_employee                       |  8.00 KB   |
|    t_menu                           |  8.00 KB   |
|    t_patient_label                  |  8.00 KB   |
|    t_patient_label_detail_tpl       |  8.00 KB   |
|    t_patient_source_ref             |  8.00 KB   |
|    t_return_visit_tpl               |  8.00 KB   |
|    t_setting_clinic                 |  8.00 KB   |
|    t_setting_notify                 |  8.00 KB   |
|    t_sms_template_category          |  8.00 KB   |
|--------------------------------------------------|

        仅显示表大小排名前 50 的表名

显示部分表

his5_dms.hiscrm=# \dt;
|--------------------------------------------------|
|               表名                  |  表大小    |
|--------------------------------------------------|
|    t_patient_other                  |  600.00 KB |
|    t_sys_oper_log                   |  88.00 KB  |
|    t_auth                           |  88.00 KB  |
|    t_setting_user                   |  56.00 KB  |
|    t_field_define                   |  32.00 KB  |
|    t_oper_log                       |  16.00 KB  |
|    t_role                           |  16.00 KB  |
|    t_sys_login_log                  |  8.00 KB   |
|    t_appointment_item               |  8.00 KB   |
|    t_clinic                         |  8.00 KB   |
|    t_dept                           |  8.00 KB   |
|    t_employee                       |  8.00 KB   |
|    t_menu                           |  8.00 KB   |
|    t_patient_label                  |  8.00 KB   |
|    t_patient_label_detail_tpl       |  8.00 KB   |
|    t_patient_source_ref             |  8.00 KB   |
|    t_return_visit_tpl               |  8.00 KB   |
|    t_setting_clinic                 |  8.00 KB   |
|    t_setting_notify                 |  8.00 KB   |
|    t_sms_template_category          |  8.00 KB   |
|--------------------------------------------------|

        仅显示表大小排名前 50 的表名

显示某个表的信息

his5_dms.hiscrm=# \d+ t_auth;
----------------------------------------------------------------
|                            建表语句                           |
----------------------------------------------------------------
   CREATE TABLE t_auth (
        id                       bigint,
        clinic_id                bigint,
        group_id                 bigint,
        parient_id               varchar(64),
        menu_id                  varchar(64),
        auth_key                 varchar(60),
        auth_name                varchar(64),
        uris                     varchar,
        rely                     varchar(255),
        state                    bigint,
        sort                     bigint,
        tag                      bigint,
        explain                  varchar(255),
        desc                     varchar(255)
   );
----------------------------------------------------------------
|                                                              |
----------------------------------------------------------------
his5_dms.hiscrm=# \d t_auth;
----------------------------------------------------------------
|                            列类型                             |
----------------------------------------------------------------
bigint,bigint,bigint,varchar,varchar,varchar,varchar,varchar,varchar,bigint,bigint,bigint,varchar,varchar

恢复表数据

his5_dms.hiscrm=# unload t_auth;
正在解析表 <t_auth>. 已解析数据页: 11, 已解析数据: 492 条
<t_auth>-</var/lib/pgsql/12/data/base/16386/16895> 解析完成, 12 个数据页 ,共计 492 条数据. 成功 492 条; 失败【0】条 
 COPY文件路径为:<his5_dms/hiscrm/t_auth.csv>

确认恢复表的数据情况

[root@xifenfeidg hiscrm]# wc -l t_auth.csv
492 t_auth.csv

QQ20250228-224837


PostgreSQL中查询表实际数据情况

his5_dms=# select count(1) from hiscrm.t_auth;
 count 
-------
   492
(1 row)
is5_dms=# \d hiscrm.t_auth;
                                Table "hiscrm.t_auth"
   Column   |          Type          | Collation | Nullable |         Default         
------------+------------------------+-----------+----------+-------------------------
 id         | bigint                 |           | not null | 
 clinic_id  | bigint                 |           |          | 
 group_id   | bigint                 |           |          | 
 parient_id | character varying(64)  |           | not null | 
 menu_id    | character varying(64)  |           | not null | 
 auth_key   | character varying(60)  |           | not null | 
 auth_name  | character varying(64)  |           | not null | 
 uris       | text                   |           | not null | 
 rely       | character varying(255) |           |          | NULL::character varying
 state      | bigint                 |           | not null | 
 sort       | bigint                 |           | not null | 
 tag        | bigint                 |           |          | '0'::bigint
 explain    | character varying(255) |           |          | NULL::character varying
 desc       | character varying(255) |           |          | NULL::character varying

truncate表

his5_dms=# truncate table hiscrm.t_auth;
TRUNCATE TABLE
his5_dms=# select count(1) from hiscrm.t_auth;
 count 
-------
     0
(1 row)

导入数据,并验证恢复效果

his5_dms=# \i /tmp/pdu/his5_dms/COPY/hiscrm_copy.sql 
SET
COPY 492
his5_dms=# select count(1) from  hiscrm.t_auth;
 count 
-------
   492
(1 row)

通过验证pdu可以在数据库离线的情况下,恢复PostgreSQL数据库中表的数据,更加方便和灵活的实现替代pg_filedump功能,而且pdu还在不断完善和新功能更新中