> FGKDU(全称 FGEDU KingBase DUL,Data UnLoader)是一款专门面向人大金仓 KingBase 数据库的数据抽取与恢复工具,当数据库实例已经无法正常启动、传统逻辑备份与导出工具(如 `pg_dump`、`kingbase_dump`、`sys_dump`)全部失效时,仍然能够绕过数据库引擎,直接从底层物理数据文件中解析并抽取数据,把业务数据以可识别的格式导出,用于在新环境中重建数据库。
## 目录
1. [程序介绍](#1-程序介绍)
2. [程序功能与特性](#2-程序功能与特性)
3. [支持环境](#3-支持环境)
4. [程序使用](#4-程序使用)
5. [程序各种案例场景与操作过程](#5-程序各种案例场景与操作过程)
6. [常用问题与排查](#6-常用问题与排查)
7. [作者信息](#7-作者信息)
## 1. 程序介绍
### 1.1 项目概述
FGKDU(全称 FGEDU KingBase DUL,Data UnLoader)是一款专门面向人大金仓 KingBase 数据库的数据抽取与恢复工具,当数据库实例已经无法正常启动、传统逻辑备份与导出工具(如 `pg_dump`、`kingbase_dump`、`sys_dump`)全部失效时,仍然能够绕过数据库引擎,直接从底层物理数据文件中解析并抽取数据,把业务数据以可识别的格式导出,用于在新环境中重建数据库。
KingBase 是人大金仓基于 PostgreSQL 内核自主研发的关系型数据库。其数据页面格式、系统目录(pg_class、pg_attribute、pg_database 等)结构、TOAST 大字段存储机制、WAL(Write-Ahead Log)日志格式均与 PostgreSQL 保持兼容。版本对应关系如下:
| KingBase 版本 | 底层 PostgreSQL 内核 | 说明 |
|—————|———————-|——|
| KingBase V6 | PostgreSQL 8.x | 早期版本 |
| KingBase V7 | PostgreSQL 9.x | 广泛使用 |
| KingBase V8 | PostgreSQL 12 | 主流版本 |
| KingBase V8R2/R3/R4/R6 | PostgreSQL 12 衍生 | 企业级发行 |
| KingBase V9 | PostgreSQL 14 / 15 | 最新版本 |
FGKDU 正是基于上述兼容性,直接读取 KingBase 数据目录(PGDATA)下的物理数据文件,按照 PostgreSQL 页面格式(8KB 数据块)逐页解析,提取元组数据,最终输出为 SQL、DMP、CSV、TXT、BINARY 等多种格式。整个恢复过程完全脱离数据库实例,不依赖数据库在线状态,也不依赖任何 KingBase 客户端库。
### 1.2 适用场景
FGKDU 主要用于以下数据库灾难恢复场景:
– **控制文件损坏或丢失**:pg_control 文件物理损坏、校验和错误、魔数不匹配,导致数据库无法读取控制信息。
– **数据文件物理损坏**:磁盘坏道、RAID 阵列故障、存储设备异常导致部分数据文件读取失败。
– **系统目录损坏**:pg_class、pg_attribute、pg_database 等核心系统表损坏,无法定位用户表对象。
– **参数文件丢失或错误**:kingbase.conf 配置文件丢失或参数错误导致实例无法启动。
– **误操作删除数据**:DELETE 误删行、DROP TABLE 误删表、TRUNCATE 误清空表数据。
– **数据库升级失败**:版本升级过程中断、数据字典不兼容导致无法打开。
– **文件系统故障**:部分文件损坏、inode 错误、文件系统不一致。
– **VACUUM FULL 后数据丢失**:维护操作异常导致数据意外丢失。
– **主机意外断电**:异常关机后数据库无法启动,需要紧急抽取业务数据。
### 1.3 工作原理
FGKDU 的工作流程可以概括为”直接读取物理文件 → 解析页面格式 → 提取元组数据 → 解码列值 → 写入输出文件”五个阶段,具体如下:
1. **数据目录识别**:读取 PG_VERSION 文件识别 KingBase 版本,读取 pg_control 检测数据块大小(自动识别 8KB/16KB/32KB)。
2. **系统目录解析**:解析 pg_database(数据库列表)、pg_class(表对象列表)、pg_attribute(列定义)等系统表,建立 OID 到表名、列类型的映射关系。
3. **页面扫描**:按照 8KB 页面格式逐块读取数据文件(路径为 `PGDATA/base/{db_oid}/{relfilenode}`),解析页面头(PageHeaderData:pd_lower/pd_upper/pd_special/pd_pagesize_version)。
4. **元组提取**:遍历页面中的项指针数组(ItemId),定位每个堆元组(HeapTuple),解析元组头(HeapTupleHeaderData:t_xmin/t_xmax/t_infomask),判断元组的可见性与删除状态。
5. **列值解码**:按照 pg_attribute 中的列类型定义,逐列解码数据值,支持整数、浮点、字符、日期时间、BYTEA(二进制大对象)、TEXT/CLOB、JSONB、NUMERIC 等全部常见类型。
6. **输出写入**:将解码后的行数据按照指定格式(SQL INSERT 语句、DMP 二进制、CSV、TXT)写入输出文件,同时生成恢复报告。
对于损坏页面,FGKDU 会启用增强恢复引擎:跳过无法解析的坏块,对坏块启用激进原始扫描(Aggressive Raw Scan)逐字节寻找有效的元组头特征码,最大程度从损坏文件中恢复数据。
### 1.4 与传统工具的对比
| 对比项 | FGKDU | pg_dump / kingbase_dump | 物理备份恢复 |
|——–|——-|————————|————–|
| 是否需要数据库在线 | 否 | 是 | 否 |
| 是否需要完整控制文件 | 否 | 是 | 是 |
| 能否恢复已删除数据 | 是(DELETE/DROP/TRUNCATE) | 否 | 否 |
| 能否处理损坏文件 | 是(自适应扫描) | 否 | 否 |
| 输出格式 | SQL/DMP/CSV/TXT/BINARY | SQL/自定义 | 物理文件 |
| 部署方式 | 单文件零依赖 | 需安装客户端 | 需完整实例 |
| 恢复粒度 | 用户/Schema/表/文件级 | 库/表级 | 全库级 |
—
关于作者
| 联系方式 | 信息 |
| — | — |
| **作者** | 风哥 | W itpux-com |
| **官方网站** | http://www.fgedu.net.cn , http://www.itpux.com |
| **数据库教程** | https://edu.51cto.com/lecturer/8020378.html |
如果您在使用过程中遇到问题、需要商业技术支持、或希望参与贡献,欢迎通过上方联系方式与作者取得联系。
## 2. 程序功能与特性
### 2.1 核心特性概览
FGKDU 围绕”灾难场景下的最大化数据恢复”这一核心目标设计,具备以下核心特性:
#### 2.1.1 免依赖单文件可执行
采用完全静态链接编译,生成单个约 1.1MB 的可执行文件,零运行时依赖。无论是 Linux 还是 Windows 平台,编译产物拷贝到目标服务器即可直接运行,无需安装任何动态库、运行时环境或 KingBase 客户端。这极大简化了灾难恢复场景下的部署工作——运维人员只需通过 U 盘、scp 或网络传输单个文件,即可在任何目标机器上启动恢复。
– Linux:完全静态链接(glibc-static),`ldd` 检查显示”not a dynamic executable”。
– Windows:静态链接 libgcc,生成的 `fgkdu.exe` 不依赖任何 DLL,可在干净的 Windows 系统直接运行。
#### 2.1.2 多平台原生支持
原生支持主流 Linux 发行版与 Windows 操作系统,一套源码跨平台编译:
– Linux:RHEL 5/6/7/8/9/10、Oracle Enterprise Linux(OEL)、CentOS、麒麟(Kylin/NeoKylin)、欧拉(EulerOS/openEuler)、统信 UOS、Ubuntu 12.04-24.04、SUSE/openSUSE、Debian,以及任何内核 2.6.32+ 的 Linux x86_64 系统。
– Windows:Windows 7/8/10/11、Windows Server 2008 R2 – 2022,内置完整的 POSIX 兼容层(kb_wincompat.h),提供目录操作、文件 I/O、信号处理、时间函数、getopt_long 等跨平台支持。
#### 2.1.3 多版本兼容
支持 KingBase V6 到 V9 全系列版本,底层覆盖 PostgreSQL 8.x 到 15.x 内核:
– 自动从 PG_VERSION 文件识别 KingBase 大版本。
– 自动从 pg_control 文件识别 PostgreSQL 页面版本(pd_pagesize_version 字段)。
– 兼容 PG 9.2 – 15 的页面格式差异(页头结构、pd_prune_xid 字段等)。
– 兼容多版本系统目录结构变化。
#### 2.1.4 自动块大小检测
从 pg_control 控制文件自动检测数据块大小,支持 8KB(默认)、16KB、32KB 等配置。当 pg_control 不可用时,自动回退到 KingBase 默认的 8192 字节(8KB),并输出警告提示。无需用户手动指定块大小参数。
#### 2.1.5 多种恢复模式
针对不同灾难场景,提供五种恢复命令:
– **scan 全量扫描导出**:通过系统目录正常解析,导出所有有效数据行,适用于数据目录健康或轻微损坏场景。
– **recover delete**:扫描元组的 t_xmax 事务标记,恢复被 DELETE 误删的行,适用于未执行 VACUUM 的误删除恢复。
– **recover drop**:扫描孤立的 relfilenode 文件,恢复被 DROP TABLE 删除的表数据,适用于误删表场景。
– **recover truncate**:检测 relfilenode 变更,恢复被 TRUNCATE 截断的旧文件数据。
– **recover max**:忽略系统目录,直接扫描所有数据文件进行最大化恢复,是系统目录严重损坏时的终极手段。
#### 2.1.6 强大恢复引擎(v1.0 新增)
v1.0 引入了多层级的增强恢复引擎,在所有恢复场景中最大化数据恢复量:
– **激进原始扫描(Aggressive Raw Scan)**:不依赖页头和项指针,逐字节扫描整个数据文件,寻找有效的元组头模式。适用于页头严重损坏、项指针区域损坏、数据文件被部分覆盖的场景。
– **空闲空间扫描(Free Space Scan)**:扫描每个页面的空闲空间区域(pd_lower 和 pd_upper 之间),寻找尚未被 VACUUM 清理的已删除元组数据。适用于 DELETE 后未执行 VACUUM 的恢复。
– **WAL 日志恢复(WAL Recovery)**:扫描 pg_wal/ 目录下的 WAL 日志文件,从日志记录中提取已被 VACUUM 清理的历史数据。适用于主数据文件已无痕迹但 WAL 日志完好的恢复。
– **多级回退恢复(Fallback Recovery)**:按照恢复策略优先级自动级联执行:第一级正常扫描 → 第二级激进原始扫描(损坏率超 30%)→ 第三级空闲空间扫描 → 第四级激进原始扫描 → 第五级 WAL 日志恢复,最大化数据恢复量。
– **LOB/TOAST 恢复**:大字段指针解码,保留原始大小、关联 TOAST 表 OID 等元信息。
#### 2.1.7 LOB 大字段默认导出
默认支持所有大字段类型的导出,无需额外参数:
– **内联 LOB(小于 2KB)**:直接完整输出。BYTEA 输出为 `\x…` 十六进制格式,TEXT/CLOB 输出实际文本,JSONB 输出 JSON 文本,均可直接导入新库无语法错误。
– **TOAST 外部化 LOB(大于 2KB)**:输出有效占位值加 SQL 注释元数据,包括 relid(关联 TOAST 表 OID)、valueid(chunk ID)、rawsize(原始大小)、compressed(是否压缩)。注释格式示例:`NULL /* LOB BYTEA TOAST rel=28912 val=415 size=24576000 compressed=Y – manual recovery */`,可直接导入不报语法错误,后续可基于元信息人工恢复完整大字段。
#### 2.1.8 损坏容错机制
内置自适应损坏恢复扫描器,确保面对严重损坏的数据文件也不会崩溃:
– **页面安全验证**:读取每个页面前验证 pd_lower >= 24(页头最小大小)、pd_upper <= page_size、pd_lower < pd_upper、检测全零页(完全损坏)、验证项指针指向有效区域。
– **坏块跳过**:自动跳过损坏的页面头,从正常页面继续恢复。
– **边界检查**:所有内存访问前进行边界检查。
– **信号保护**:捕获 SIGSEGV/SIGBUS/SIGABRT/SIGFPE 信号(Windows 额外支持 SIGBREAK),防止程序崩溃,确保恢复过程不中断。
– **继续执行**:使用 `–continue-on-error` 选项,遇到错误时继续恢复而非退出。
#### 2.1.9 多输出格式
支持五种输出格式,满足不同恢复与迁移需求:
| 格式 | 说明 | 适用场景 |
|——|——|———-|
| SQL(默认) | 生成可执行的 INSERT 语句,含 CREATE TABLE 与注释 | 直接导入新库 |
| DMP | 二进制归档文件,每个表一个文件 | 跨库迁移、归档 |
| CSV | 逗号分隔文本 | Excel 查看、数据分析 |
| TXT | 纯文本 | 简单查看 |
| BINARY | 原始二进制 | 底层归档 |
#### 2.1.10 精细粒度恢复
支持三级粒度精确定位恢复对象:
– **按用户/数据库**(`-u`):仅恢复指定用户或数据库的所有数据。
– **按 Schema**(`-s`):仅恢复指定模式下的所有表。
– **按单表**(`-t`):仅恢复指定表,支持 `schema.table` 格式。
– 三者可组合使用,如 `-u mydb -s public -t orders` 精确到单库单模式单表。
#### 2.1.11 稳定性加固
全面的稳定性保障措施:
– 全面的边界检查与错误处理。
– 页面安全验证防止崩溃。
– 信号保护机制。
– 多段文件(relfilenode.1、relfilenode.2)自动处理。
– 实时进度显示与详细日志输出。
### 2.2 功能特性详细说明
#### 数据类型支持
FGKDU 支持全部 KingBase/PostgreSQL 常见数据类型的解码:
| 类型分类 | 支持类型 |
|———-|———-|
| 整数类型 | int2(smallint)、int4(integer)、int8(bigint)、serial、bigserial |
| 浮点类型 | float4(real)、float8(double precision) |
| 精确数值 | numeric/decimal(含高精度) |
| 字符类型 | char、varchar、text、bpchar |
| 二进制 | bytea(含内联与 TOAST) |
| 日期时间 | date、time、timestamp、timestamptz、interval |
| 布尔 | boolean |
| UUID | uuid |
| JSON | json、jsonb |
| 网络地址 | inet、cidr、macaddr |
| 位串 | bit、varbit |
| 大对象 | TEXT/CLOB、BYTEA(含 TOAST) |
#### 输出目录结构
scan 与 unload 命令会自动按数据库/模式组织输出目录,便于按库恢复:
“`
output/
├── testdb/ # testdb 数据库
│ ├── public/ # public 模式
│ │ ├── customers.sql # 各表数据
│ │ └── orders.sql
│ └── hr/ # hr 模式
│ └── employees.sql
├── business_db/ # business_db 数据库
│ └── public/
│ └── …
├── fgkdu_recovery_report.txt # 恢复报告
└── import_all.sh # 一键导入脚本
“`
#### 恢复报告
每次恢复操作完成后,FGKDU 会自动生成恢复报告,包含:
– 数据库/模式/表的处理数量。
– 总行数提取统计。
– 坏块数量与占比。
– raw scan 恢复的元组数。
– 各恢复策略(正常扫描/空闲空间/WAL)的贡献统计。
– 数据完整性统计。
– 输出目录与日志路径。
#### 实时进度显示
在 unload 等长耗时操作中,FGKDU 提供详细的实时进度显示:
– 当前处理的数据库 OID 与名称。
– 当前处理的表名与 OID。
– 每表导出行数与总计行数。
– 已扫描文件数与总文件数。
– 实时扫描进度百分比。
– 吞吐量统计(行/秒)。
—
## 3. 支持环境
### 3.1 支持的操作系统
#### Linux 平台
| 操作系统 | 支持版本 |
|———-|———-|
| Red Hat Enterprise Linux(RHEL) | 5 / 6 / 7 / 8 / 9 / 10 |
| Oracle Enterprise Linux(OEL) | 5 / 6 / 7 / 8 / 9 / 10 |
| CentOS | 5 / 6 / 7 / 8 / 9 |
| 麒麟(Kylin / NeoKylin) | 全系列 |
| 欧拉(EulerOS / openEuler) | 全系列 |
| 统信 UOS | 全系列 |
| Ubuntu | 12.04 – 24.04 |
| SUSE / openSUSE | 全系列 |
| Debian | 全系列 |
| 通用 Linux x86_64 | 内核 2.6.32 及以上 |
#### Windows 平台
| 操作系统 | 支持版本 |
|———-|———-|
| Windows 桌面 | 7 / 8 / 10 / 11(64 位) |
| Windows Server | 2008 R2 / 2012 / 2016 / 2019 / 2022 |
### 3.2 支持的 KingBase 版本
| KingBase 版本 | 底层 PostgreSQL 内核 | 支持状态 |
|—————|———————-|———-|
| KingBase V6 | PostgreSQL 8.x | 支持 |
| KingBase V7 | PostgreSQL 9.x | 支持 |
| KingBase V8 | PostgreSQL 12 | 支持 |
| KingBase V8R2 | PostgreSQL 12 衍生 | 支持 |
| KingBase V8R3 | PostgreSQL 12 衍生 | 支持 |
| KingBase V8R4 | PostgreSQL 12 衍生 | 支持 |
| KingBase V8R6 | PostgreSQL 12 衍生 | 支持 |
| KingBase V9 | PostgreSQL 14 / 15 | 支持 |
底层覆盖 PostgreSQL 8.x – 15.x 全系列内核。
### 3.3 编译要求
#### Linux 编译环境
– 编译器:GCC 4.8 及以上(推荐 GCC 7+)。
– 静态链接依赖:glibc-static(完全静态构建需要)、libstdc++-static。
– 构建工具:make。
– 操作系统:Linux x86_64,内核 2.6.32 及以上。
各发行版依赖安装命令:
“`bash
# RHEL / OEL / CentOS 系列
yum install -y gcc glibc-static libstdc++-static make
# Ubuntu / Debian 系列
apt-get update
apt-get install -y gcc libc6-dev make
# SUSE / openSUSE 系列
zypper install -y gcc glibc-devel-static make
# 欧拉 / openEuler
dnf install -y gcc glibc-static make
“`
#### Windows 编译环境
– 方式一(推荐):MinGW-w64,生成原生无依赖 exe。
– 方式二:Microsoft Visual Studio 2019/2022(通过 CMake)。
– 跨平台构建:CMake 3.5 及以上。
### 3.4 运行环境要求
– 目标服务器操作系统:见上文支持列表。
– 磁盘空间:输出目录空间至少为数据目录大小的 1.5 倍(SQL 格式约为原始数据的 1.5 倍)。
– 内存:无特殊要求,默认配置即可(大库恢复建议 1GB 以上可用内存)。
– 权限:对 KingBase 数据目录具备读权限(建议以 kingbase 用户或 root 运行)。
– 依赖:零运行时依赖(完全静态二进制)。
—
## 4. 程序使用
### 4.1 编译与部署
#### 4.1.1 Linux 平台编译
“`bash
# 进入项目源码目录
cd /path/to/FGKDU
# 查看所有构建目标
make help
# 推荐:完全静态单文件构建(零依赖,可拷贝到任何 Linux 系统运行)
make standalone
# 如果完全静态构建失败(缺少 glibc-static),使用便携版构建
make portable
“`
编译成功后生成 `build/standalone/fgkdu` 可执行文件(约 1.1MB)。
#### 4.1.2 Windows 平台编译
**方式一:MinGW-w64(推荐)**
“`cmd
:: 使用构建脚本(最简单)
build_win.bat
:: 或手动执行编译命令
gcc -std=gnu99 -O2 -Wall -Iinclude -D_WIN32 -D_CRT_SECURE_NO_WARNINGS ^
src\main.c src\cli\kb_cli.c src\io\kb_io.c src\page\kb_page.c ^
src\tuple\kb_tuple.c src\dbdict\kb_dbdict.c src\scan\kb_scan.c ^
src\output\kb_output.c src\utils\kb_utils.c src\utils\kb_getopt.c ^
src\version\kb_version.c ^
-o fgkdu.exe -static -static-libgcc -lm -s
“`
**方式二:CMake + MSVC**
“`cmd
mkdir build
cd build
cmake .. -G “Visual Studio 17 2022” -A x64
cmake –build . –config Release
“`
**方式三:CMake + MinGW**
“`cmd
mkdir build
cd build
cmake .. -G “MinGW Makefiles” -DCMAKE_BUILD_TYPE=Release
cmake –build . –config Release
“`
编译完成后生成 `fgkdu.exe`,拷贝到任何 Windows 系统即可运行,无需安装任何运行时库。
#### 4.1.3 部署到目标服务器
“`bash
# 拷贝到目标服务器(Linux)
scp build/standalone/fgkdu kingbase@target-host:/tmp/
# 设置执行权限
ssh kingbase@target-host “chmod +x /tmp/fgkdu”
# 建议部署到 /usr/local/bin 以便全局调用
sudo cp build/standalone/fgkdu /usr/local/bin/
sudo chmod 755 /usr/local/bin/fgkdu
“`
Windows 部署:将 `fgkdu.exe` 拷贝到任意目录(如 `D:\tools\`),可选加入系统 PATH。
#### 4.1.4 安装验证
“`bash
# 1. 验证版本号
fgkdu -V
# 预期输出:
# FGKDU – FGEDU KingBase DUL v1.0.0
# Version: 1.0.0 (Major: 1, Minor: 0, Patch: 0)
# Build mode: standalone static
# Author: 风哥 (QQ:113257174, WX:itpux-com)
# 2. 验证帮助信息
fgkdu -h
# 3. 验证零动态依赖(Linux)
ldd /usr/local/bin/fgkdu
# 预期输出: not a dynamic executable(不是动态可执行文件)
“`
### 4.2 命令一览
| 命令 | 说明 |
|——|——|
| `diagnose` | 诊断数据目录,检查完整性与损坏程度 |
| `list databases` | 列出所有数据库 |
| `list schemas` | 列出所有模式 |
| `list tables` | 列出所有表 |
| `scan` | 扫描导出所有表数据(全量导出) |
| `recover delete` | 恢复 DELETE 删除的数据行 |
| `recover drop` | 恢复 DROP 删除的表数据 |
| `recover truncate` | 恢复 TRUNCATE 截断的表数据 |
| `recover max` | 最大恢复(忽略系统目录,扫描所有数据文件) |
| `unload` | 全库按用户名/数据库名导出(按库分目录) |
| `scan-file <path>` | 直接扫描单个数据文件(底层恢复) |
### 4.3 选项说明
| 选项 | 说明 |
|——|——|
| `-d, –data-dir PATH` | KingBase 数据目录路径 |
| `-o, –output-dir PATH` | 输出目录路径 |
| `-f, –format FORMAT` | 输出格式:sql、csv、txt、dmp、binary |
| `-u, –user NAME` | 用户名/数据库名(按库过滤) |
| `-D, –database NAME` | 数据库名(-u 的别名) |
| `-s, –schema SCHEMA` | 模式名(按模式过滤) |
| `-t, –table TABLE` | 表名(支持 schema.table 格式) |
| `–include-deleted` | 包含已删除行 |
| `–include-updated` | 包含已更新行 |
| `-v, –verbose` | 详细输出日志 |
| `–progress` | 显示进度 |
| `–continue-on-error` | 出错继续执行 |
| `-V, –version` | 显示版本信息 |
| `-h, –help` | 显示帮助信息 |
### 4.4 命令详解
#### 4.4.1 diagnose 诊断命令
对 KingBase 数据目录进行全面健康检查,是所有恢复操作的第一步。诊断结果会指出数据目录的完好程度、可用恢复策略,为后续操作提供决策依据。
诊断检查项:
1. 数据目录存在性与权限检查。
2. PG_VERSION 文件读取与版本识别。
3. pg_control 控制文件状态(魔数、版本、校验和、块大小)。
4. 关键子目录结构(base/、global/、pg_wal/、pg_tblspc/)。
5. 系统目录可读性(pg_database、pg_class、pg_attribute)。
6. 数据块大小自动检测。
7. 典型数据文件完整性抽样检查。
8. 文件权限检查。
“`bash
# 基本诊断
fgkdu diagnose -d /opt/kingbase/data
# 详细诊断(含每个文件的可读性统计)
fgkdu diagnose -d /opt/kingbase/data -v
“`
#### 4.4.2 list 列出对象命令
“`bash
# 列出所有数据库
fgkdu list databases -d /opt/kingbase/data
# 列出所有模式
fgkdu list schemas -d /opt/kingbase/data
# 列出所有表
fgkdu list tables -d /opt/kingbase/data
# 列出指定数据库的表
fgkdu list tables -d /opt/kingbase/data -u testdb
# 列出指定模式的表
fgkdu list tables -d /opt/kingbase/data -s public
“`
#### 4.4.3 scan 全量扫描导出
通过系统目录正常解析,扫描并导出所有(或指定)表的有效数据行。适用于数据目录健康或轻微损坏场景。
“`bash
# 导出所有表为 SQL(默认格式)
fgkdu scan -d /opt/kingbase/data -o ./output
# 导出为 DMP 格式(每表一个文件)
fgkdu scan -d /opt/kingbase/data -o ./output -f dmp
# 导出为 CSV 格式
fgkdu scan -d /opt/kingbase/data -o ./output -f csv
# 按数据库过滤导出
fgkdu scan -d /opt/kingbase/data -u testdb -o ./output
# 按模式过滤导出
fgkdu scan -d /opt/kingbase/data -s public -o ./output
# 按单表导出
fgkdu scan -d /opt/kingbase/data -t public.orders -o ./output
# 遇到错误继续
fgkdu scan -d /opt/kingbase/data -o ./output –continue-on-error -v
“`
#### 4.4.4 recover delete 恢复已删除行
恢复被 DELETE 语句误删除的数据行。利用 KingBase/PostgreSQL 的 MVCC 机制:DELETE 操作不会物理删除元组,仅设置 t_xmax 事务号标记删除,在 VACUUM 之前被删除的行仍然完整存在于数据页面中。
“`bash
# 恢复所有已删除数据
fgkdu recover delete -d /opt/kingbase/data -o ./recovered
# 恢复指定表的已删除数据
fgkdu recover delete -d /opt/kingbase/data -t public.orders -o ./recovered
# 恢复指定用户/schema 的已删除数据
fgkdu recover delete -d /opt/kingbase/data -u system -s public -o ./recovered
“`
恢复原理:扫描每个数据页面的所有元组 → 检查元组头的 t_xmax 字段(非 0 表示被标记删除)→ 检查 t_infomask 标志位区分删除/更新 → 解码被删除元组的数据列输出 INSERT 语句 → 同时启用空闲空间扫描与 WAL 日志恢复。
#### 4.4.5 recover drop 恢复已删除表
恢复被 DROP TABLE 语句删除的表数据。DROP TABLE 会从 pg_class/pg_attribute 中删除表定义,但数据文件(relfilenode)可能仍存在于磁盘上成为孤立文件。
“`bash
# 恢复所有 DROP 的表数据
fgkdu recover drop -d /opt/kingbase/data -o ./recovered
“`
恢复原理:扫描 base/{db_oid}/ 目录下所有数字命名文件 → 与 pg_class 已知表 OID 匹配 → 找出孤立 relfilenode 文件 → 对每个孤立文件尝试多种策略解析 → 列名恢复为 col1..colN,类型做最佳猜测。
#### 4.4.6 recover truncate 恢复已截断表
恢复被 TRUNCATE TABLE 语句清空的数据。TRUNCATE 创建新的空 relfilenode 文件替换旧文件,旧文件不会立即被物理删除。
“`bash
# 恢复 TRUNCATE 的表数据
fgkdu recover truncate -d /opt/kingbase/data -o ./recovered
“`
#### 4.4.7 recover max 最大恢复
当系统目录严重损坏时,FGKDU 直接扫描 base/ 目录下的所有数据文件,不依赖任何目录信息,实现最大程度的数据恢复。这是最后的恢复手段,自动启用多级回退恢复策略。
“`bash
# 最大恢复(忽略系统目录,扫描所有数据文件)
fgkdu recover max -d /opt/kingbase/data -o ./recovered
# 遇到错误继续,详细日志
fgkdu recover max -d /opt/kingbase/data -o ./recovered –continue-on-error -v
“`
#### 4.4.8 unload 全库按用户名导出
当数据库无法启动时,全库抽取所有数据,并按用户名/数据库名自动生成子目录,导出所有能导出的表。与 `recover max` 不同,`unload` 会按数据库分目录组织输出,结构更清晰,便于按库恢复。
“`bash
# 全库 unload:按数据库名自动分目录导出所有表
fgkdu unload -d /opt/kingbase/data -o /tmp/unload_output
# 按用户名/数据库名 unload:仅导出指定数据库的所有表
fgkdu unload -d /opt/kingbase/data -u fgedu -o /tmp/unload_output
# 指定输出格式(默认 sql,支持 csv/txt/dmp/binary)
fgkdu unload -d /opt/kingbase/data -o /tmp/unload_output -f dmp
# 遇到错误继续(推荐,损坏场景必备)
fgkdu unload -d /opt/kingbase/data -o /tmp/unload_output –continue-on-error -v
“`
输出目录结构:
“`
/tmp/unload_output/
├── fgedudb/ # fgedudb 数据库
│ ├── 16468_recovered.sql # 各表数据(按 relfilenode 命名)
│ └── 16481_recovered.sql
├── postgres/ # postgres 数据库
│ └── *_recovered.sql
├── template1/ # template1 数据库
│ └── *_recovered.sql
└── _global/ # 全局共享系统表(pg_database 等)
└── *_recovered.sql
“`
工作原理:
1. 扫描 `base/` 目录下的每个数据库 OID 子目录。
2. 尝试从系统目录 `pg_database` 解析数据库名(best effort)。
3. 系统目录可读时:子目录名为数据库名(如 `fgedudb`)。
4. 系统目录损坏时:子目录名回退为 `oid_<OID>`(如 `oid_16384`),仍可正常导出。
5. 对每个数据库目录下的数据文件逐个扫描,导出可恢复的行。
6. 同时扫描 `global/` 目录的共享系统表,输出到 `_global/` 子目录。
7. 若指定 `-u`,仅处理匹配的数据库。
#### 4.4.9 scan-file 直接扫描文件
直接扫描指定的单个数据文件,是最底层的恢复方式。当知道具体哪个文件包含需要的数据时使用。
“`bash
# 直接扫描单个数据文件
fgkdu scan-file /opt/kingbase/data/base/16384/16521 -o ./recovered
# 指定输出格式
fgkdu scan-file /opt/kingbase/data/base/16384/16521 -o ./recovered -f dmp
“`
scan-file 命令会自动在正常扫描失败后启用激进原始扫描,从损坏文件中尽力恢复数据。
### 4.5 输出格式说明
#### 4.5.1 SQL 格式(默认)
生成可直接执行的 SQL 文件,包含 CREATE TABLE 语句(如果目录可用)、INSERT 语句、恢复报告与恢复指南。是最推荐的恢复格式,可直接导入新库。
#### 4.5.2 DMP 格式(二进制)
生成二进制 DMP 文件,每个表一个文件。包含文件头(魔数、版本、表信息)、行数据(二进制格式)、文件尾。适合跨库迁移与归档。
#### 4.5.3 CSV 格式
生成 CSV 文件,适合用 Excel 等表格工具查看,也便于数据分析与处理。
#### 4.5.4 TXT 格式
生成纯文本格式,便于简单查看。
#### 4.5.5 BINARY 格式
生成原始二进制格式,适合底层归档。
### 4.6 高级用法
#### 4.6.1 块大小自动检测
FGKDU 自动从 pg_control 文件中检测块大小。如果 pg_control 不可用,会使用默认的 8192 字节(KingBase 默认块大小),并输出警告。
#### 4.6.2 多段文件支持
KingBase 大表会分段存储(relfilenode.1、relfilenode.2 等),FGKDU 自动处理多段文件,无需用户干预。
#### 4.6.3 配置文件使用
FGKDU 支持简单的配置文件:
“`ini
# fgkdu.conf
data_dir=/opt/kingbase/data
output_dir=./output
format=sql
“`
“`bash
fgkdu scan –config fgkdu.conf
“`
#### 4.6.4 详细日志与进度
“`bash
# 启用详细输出
fgkdu scan -d /opt/kingbase/data -o ./output -v
# 显示进度
fgkdu scan -d /opt/kingbase/data -o ./output –progress
# 日志会显示每个文件的处理状态、坏块信息、恢复统计等
“`
—
## 5. 程序各种案例场景与操作过程
### 5.1 案例一:金仓KingBase数据库无法启动(控制文件损坏)完整恢复
**场景描述**:服务器意外断电后 KingBase 无法启动,日志提示 “pg_control corrupted”、”invalid page header”。控制文件损坏导致数据库无法读取控制信息,但用户数据文件大概率完好。
**恢复思路**:先诊断,后尝试常规扫描,若系统目录损坏则启用最大恢复。
**操作步骤**:
“`bash
# 步骤 0:紧急备份整个数据目录(先做备份再任何操作)
cp -a /opt/kingbase/data /data/backup/data_backup_20260808/
# 步骤 1:诊断数据目录,确认损坏范围
fgkdu diagnose -d /opt/kingbase/data -v
# 预期输出:
# [WARN] WARNING: pg_control corrupted: invalid checksum
# [OK ] base/ directory: OK (2 databases found)
# [ERR ] pg_class: partial – 89/100 blocks readable
# === Diagnostics Complete: 11% corrupted ===
# 步骤 2:先尝试常规 scan(带 continue-on-error)
fgkdu scan -d /opt/kingbase/data -o ./output –continue-on-error -v
# 如果输出目录中有大量 .sql 文件并且行数正常,则完成
# 如果 scan 退出码非 0 或输出文件极少,进入步骤 3
# 步骤 3:常规扫描失败,用最大恢复 recover max
fgkdu recover max -d /opt/kingbase/data -o ./output_max –continue-on-error -v
# 预期输出:
# Files scanned: 124
# Rows recovered: 508,231
# Bad blocks: 10
# === MAX Recovery Complete ===
# 步骤 4:验证恢复结果
ls -lh ./output_max/ # 检查输出文件数
wc -l ./output_max/*.sql # 统计行数
head -50 ./output_max/schema_table.sql # 查看恢复结果
“`
**Windows 等价命令**:
“`cmd
fgkdu.exe diagnose -d D:\kingbase\data
fgkdu.exe scan -d D:\kingbase\data -o .\output –continue-on-error
fgkdu.exe recover max -d D:\kingbase\data -o .\output_max
“`
**验证方法**:
“`bash
ls -lh ./output_max/ # 检查输出文件数
wc -l ./output_max/*.sql # 统计行数
head -50 ./output_max/*.sql # 查看恢复结果
“`
### 5.2 案例二:金仓KingBase误 DELETE 恢复误删除行
**场景描述**:开发人员误执行 `DELETE FROM public.orders WHERE status=’CANCELLED’` 删除了 2280 行订单数据,尚未执行 VACUUM,需要立即恢复。
**恢复思路**:利用 t_xmax 事务标记恢复未 VACUUM 的已删除行。
**操作步骤**:
“`bash
# 步骤 1:立即停止数据库写入(防止 VACUUM 清理已删除行)
# 在数据库层面停止相关业务写入
# 步骤 2:执行误删除行恢复(针对指定表)
fgkdu recover delete -d /opt/kingbase/data \
-u testdb -s public -t orders \
-o ./recovered_orders -v
# 预期输出:
# [INFO] Recover DELETE rows starting…
# [INFO] Strategy: t_xmax scan + free space scan + WAL fallback
# [INFO] Scanning public.orders (16450)…
# [SCAN] Normal scan: found 1,580 deleted rows via t_xmax
# [FREE SPACE] Free space area scan: found 642 additional rows
# [WAL] WAL recovery: 58 rows recovered
# [TOTAL] public.orders: 2280 rows recovered
# === RECOVER DELETE COMPLETE ===
# Total deleted rows recovered: 2,280
# 步骤 3:验证恢复结果
grep -c ‘^INSERT INTO’ ./recovered_orders/orders_deleted.sql
# 预期:2280
head -20 ./recovered_orders/orders_deleted.sql
# 查看恢复的 INSERT 语句
# 步骤 4:导入新库验证
ksql -U system -d newdb -f ./recovered_orders/orders_deleted.sql
SELECT count(*) FROM public.orders; — 验证行数
“`
### 5.3 案例三:金仓KingBase误 DROP TABLE 恢复被删表
**场景描述**:运维误执行 `DROP TABLE public.old_transactions` 删除了一张重要历史表,需要恢复。
**恢复思路**:DROP TABLE 删除了系统目录定义,但数据文件(孤立 relfilenode)仍存在于磁盘,扫描孤立文件恢复。
**操作步骤**:
“`bash
# 步骤 1:尽快停止数据库写入,防止磁盘块被重用
# 步骤 2:执行 DROP TABLE 恢复
fgkdu recover drop -d /opt/kingbase/data -o ./recovered_drop -v
# 预期输出:
# [INFO] Detected 16 orphan candidate files
# [ORPHAN] File base/16384/16800 (256 MB): valid page headers found
# [ANALYZE] 42 columns detected
# [RECOVER] orphan_16800: 52,340 rows extracted
# === RECOVER DROP COMPLETE ===
# Total rows recovered from dropped tables: 2,012,987
# 步骤 3:查看恢复的文件
ls -lhS ./recovered_drop/
# 预期:按大小排序的 SQL 文件
# 步骤 4:查看恢复报告,了解每个孤立文件的推断信息
cat ./recovered_drop/fgkdu_drop_recovery_report.txt
# 步骤 5:抽样查看恢复的数据
head -30 ./recovered_drop/dropped_table_16800.sql
# 注意:列名恢复为 col1..colN,需人工根据业务知识重命名
“`
**注意**:恢复的表列名为 col1..colN,需要人工根据业务知识重命名列。
### 5.4 案例四:金仓KingBase误 TRUNCATE 恢复被截断数据
**场景描述**:运维误执行 `TRUNCATE TABLE public.audit_log` 清空了审计日志表,需要恢复。
**恢复思路**:TRUNCATE 创建新的空 relfilenode 替换旧文件,旧文件可能仍存在,扫描旧文件恢复。
**操作步骤**:
“`bash
# 步骤 1:执行 TRUNCATE 恢复
fgkdu recover truncate -d /opt/kingbase/data -o ./recovered_truncate -v
# 步骤 2:查看恢复结果
ls -lh ./recovered_truncate/
cat ./recovered_truncate/*.sql | head -50
# 步骤 3:导入新库验证
ksql -U system -d newdb -f ./recovered_truncate/*.sql
“`
### 5.5 案例五:金仓KingBase按指定用户(数据库)导出全部数据
**场景描述**:需要把 system 用户(数据库名 sales)中的所有数据迁移到新服务器。
**操作步骤**:
“`bash
# 步骤 1:列出所有数据库,确认目标数据库 OID
fgkdu list databases -d /opt/kingbase/data
# 输出:
# OID NAME
# 1 template1
# 16384 sales <– 目标库
# 步骤 2:按数据库(-u)导出全部数据为 SQL
fgkdu scan -d /opt/kingbase/data -u sales -o ./sales_export -f sql
# 步骤 3:同时导出为 DMP(每表一个二进制文件)
fgkdu scan -d /opt/kingbase/data -u sales -o ./sales_export_dmp -f dmp
# 步骤 4:查看被恢复的表
ls -1 ./sales_export/ | head -20
# public_orders.sql
# public_customers.sql
# public_products.sql
# 步骤 5:在新库中导入
ksql -U system -d sales_new -f ./sales_export/*.sql
“`
**注意**:`-u` 参数同时接受 KingBase 用户名与数据库名(因为 KingBase 常以同名数据库+用户工作)。
### 5.6 案例六:金仓KingBase按指定 Schema 导出所有表
**场景描述**:只需要 public schema 或 hr schema 的数据。
**操作步骤**:
“`bash
# 步骤 1:列出所有 schema
fgkdu list schemas -d /opt/kingbase/data
# OID NAMESPACE
# 11 pg_catalog
# 2200 public
# 16482 hr
# 16500 report
# 步骤 2:按 schema 导出(public 全量)
fgkdu scan -d /opt/kingbase/data -s public -o ./schema_public_export
# 步骤 3:按多个 schema 逐个导出
for s in public hr report; do
fgkdu scan -d /opt/kingbase/data -s “$s” -o “./schema_${s}_export” -f dmp
done
“`
### 5.7 案例七:金仓KingBase按指定单表导出(含 LOB 字段)
**场景描述**:只需要 public.orders 表(有 BYTEA 发票字段),同时要恢复被误 DELETE 的行。
**操作步骤**:
“`bash
# 方式一:-t public.orders(推荐,schema 明确)
fgkdu scan -d /opt/kingbase/data -t public.orders -o ./table_export -f sql
# 方式二:-s public -t orders(拆分为两个参数)
fgkdu recover delete -d /opt/kingbase/data -s public -t orders -o ./orders_deleted
# 方式三:-t orders(当前 schema,public 默认)
fgkdu scan -d /opt/kingbase/data -t orders -o ./table_export -f dmp
# 验证 LOB 导出格式(BYTEA 输出为 ‘\x…’ 十六进制格式,可直接导入)
grep “orders_blob_col” ./table_export/public_orders.sql | head -5
# INSERT INTO “public”.”orders” VALUES (1, 1001, ‘\x255044462D312E340A25…’, ‘2026-01-15’);
# 检查 TOAST 大字段(被外部化的 LOB)
grep “LOB BYTEA TOAST” ./table_export/public_orders.sql
# INSERT INTO “public”.”orders” VALUES (123, 2024, NULL /* LOB BYTEA TOAST rel=28912 val=415 size=24576000 compressed=Y */);
# 新库导入
ksql -U system -d newdb -f ./table_export/public_orders.sql
SELECT count(*) FROM public.orders;
SELECT length(orders_blob_col) FROM public.orders WHERE id=1;
“`
### 5.8 案例八:金仓KingBase直接按数据文件批量导出(绕过目录)
**场景描述**:系统目录完全损坏,无法通过 OID 对应表名,但数据文件仍完好。
**操作步骤**:
“`bash
# 步骤 1:列出数据目录中的所有数据文件
ls /opt/kingbase/data/base/
# 1/ 16384/
ls -1 /opt/kingbase/data/base/16384/ | head -10
# 1259 <- pg_class
# 16385 <- 用户表1
# 16385.1 <- 用户表1的第二段(大表)
# 16386
# 16387 <- 用户表4(含LOB)
# 步骤 2:直接 scan-file 单个文件
fgkdu scan-file /opt/kingbase/data/base/16384/16387 -o ./direct_export -f sql
# 步骤 3:批量 scan-file 扫描整个数据库目录(所有文件)
mkdir -p ./all_files_export
for f in /opt/kingbase/data/base/16384/*; do
echo “Processing $f…”
fgkdu scan-file “$f” -o ./all_files_export -f sql –continue-on-error
done
# Windows 批量(cmd 批处理)
# mkdir all_files_export
# for %f in (D:\kingbase\data\base\16384\*) do (
# echo Processing %f
# fgkdu.exe scan-file “%f” -o .\all_files_export -f sql –continue-on-error
# )
# 步骤 4:检查批量恢复结果
ls -1 ./all_files_export/ | wc -l
# 87 <- 成功从87个数据文件中恢复了SQL
wc -l ./all_files_export/*.sql | tail -1
# 512034 total <- 共恢复51万行
# 步骤 5:从恢复的 SQL 中验证数据质量
head -100 ./all_files_export/*_16387.sql
“`
### 5.9 案例九:金仓KingBase数据文件严重损坏 recover max 终极恢复
**场景描述**:磁盘出现大量坏道,系统目录严重损坏,需要最大化恢复数据。
**操作步骤**:
“`bash
# 步骤 1:先诊断损坏程度
fgkdu diagnose -d /opt/kingbase/data -v
# 步骤 2:执行最大恢复(后台运行,大库耗时较长)
nohup fgkdu recover max -d /opt/kingbase/data \
-o ./max_recovery \
–continue-on-error \
-v > max_recovery.log 2>&1 &
# 步骤 3:监控进度
tail -f max_recovery.log
# 或统计已处理文件数
ls -1 ./max_recovery/*.sql 2>/dev/null | wc -l
# 步骤 4:完成后检查结果
tail -100 max_recovery.log
# 预期统计:
# Total rows extracted: 128,456,789
# Files scanned: 487
# Level 2 raw scan activated: 63 files
# Bad blocks: 1,208 (0.01%)
# 步骤 5:统计输出的 SQL 文件数与总行数
ls -1 ./max_recovery/*.sql | wc -l
grep -hc ‘^INSERT INTO’ ./max_recovery/*.sql | awk ‘{s+=$1} END {print “Total INSERT lines:”, s}’
“`
### 5.10 案例十:金仓KingBase含 LOB(BYTEA/TEXT/JSONB)表的完整导出与恢复验证
**场景描述**:数据库中存储了大量 PDF/图片(BYTEA)、日志数据(TEXT 1MB+)、JSONB 配置对象。
**操作步骤**:
“`bash
# 步骤 1:导出所有表(默认已经支持 LOB,无需额外参数)
fgkdu scan -d /opt/kingbase/data -o ./lob_full_export -f sql -v
# LOB 处理说明:
# – 内联 LOB(< 2KB): 直接完整输出 BYTEA 的 ‘\x…’ 十六进制 / TEXT 的实际文本
# – TOAST 外部化 LOB(> 2KB): 输出有效占位值 + SQL 注释
# BYTEA: NULL /* LOB BYTEA TOAST rel=28912 val=415 size=24576000 compressed=Y */
# TEXT : ” /* LOB TEXT TOAST rel=28912 val=416 size=1048576 compressed=N */
# JSONB: ‘{}’ /* LOB JSONB TOAST rel=28912 val=417 size=524288 compressed=N */
# 步骤 2:检查 SQL 文件中的 LOB 输出
grep -n “BYTEA\|\\\\x\|LOB” ./lob_full_export/*documents*.sql | head -20
# 正常的 BYTEA:
# INSERT INTO … VALUES (…, ‘\x255044462D312E340A25E2E3CFD3…’); — 内联,直接导入
# TOAST 的 BYTEA:
# INSERT INTO … VALUES (…, NULL /* LOB BYTEA TOAST rel=28912 val=415 size=24576000 compressed=Y */);
# 步骤 3:导入 KingBase 新库
ksql -U system -d newdb << ‘EOFSQL’
— 先关闭 fsync 加速导入
SET fsync = off;
SET work_mem = ‘256MB’;
SET maintenance_work_mem = ‘1GB’;
— 执行导出的 SQL 文件
\i ./lob_full_export/public_documents.sql
— 验证内联 LOB(< 2KB)
SELECT count(*), count(content) FROM public.documents;
— count | count
— ——-+——-
— 50000 | 38421 <- 38421条内联LOB成功,11579条为TOAST占位
— 验证 BYTEA 数据正确(PDF 文件头 25 50 44 46 = %PDF)
SELECT encode(content::bytea, ‘hex’) FROM public.documents WHERE id=1 LIMIT 1;
— encode
— —————————————-
— 255044462d312e340a25e2e3cfd30a…(正确)
EOFSQL
“`
### 5.11 案例十一:金仓KingBase数据库无法启动 unload 按用户名全库导出
**场景描述**:数据库因控制文件损坏无法启动,pg_dump、kingbase_dump 等工具都依赖数据库在线无法使用,需要全库抽取并按数据库名分目录导出。
**unload 与其他命令的选择**:
| 命令 | 数据库在线 | 输出结构 | 适用场景 |
|——|———–|———-|———-|
| pg_dump | 需要 | 单文件 | 数据库可正常启动 |
| scan | 不需要 | 单一目录 | 系统目录健康 |
| recover max | 不需要 | 单一目录 | 系统目录损坏 |
| unload | 不需要 | 按数据库名分目录 | 全库导出,最佳选择 |
**操作步骤**:
“`bash
# 步骤 1:诊断数据目录
fgkdu diagnose -d /opt/kingbase/data -v
# 步骤 2:全库 unload(按数据库名自动分目录,后台运行)
nohup fgkdu unload -d /opt/kingbase/data \
-o /tmp/unload_recovery \
–continue-on-error \
-v > /tmp/unload_full.log 2>&1 &
# 监控进度
tail -f /tmp/unload_full.log
# 步骤 3:按用户名/数据库名 unload(仅导出指定数据库)
fgkdu unload -d /opt/kingbase/data \
-u fgedudb \
-o /tmp/unload_fgedudb \
–continue-on-error -v
# 步骤 4:查看输出目录结构
find /tmp/unload_recovery -type d
# /tmp/unload_recovery/
# /tmp/unload_recovery/fgedudb
# /tmp/unload_recovery/postgres
# /tmp/unload_recovery/template1
# /tmp/unload_recovery/_global
# 步骤 5:统计各库恢复的文件数与行数
for db_dir in /tmp/unload_recovery/*/; do
echo “=== $db_dir ===”
ls -1 “$db_dir” | wc -l
grep -hc ‘^INSERT INTO’ “$db_dir”/*.sql 2>/dev/null | awk ‘{s+=$1} END {print “INSERT lines:”, s}’
done
# 预期输出样例:
# === Unload Complete ===
# Databases unloaded: 4
# Files scanned: 35
# Rows extracted: 156
# Bad blocks: 0
“`
### 5.12 案例十二:金仓KingBase恢复到新建库完整流程
**场景描述**:数据抽取完成后,需要在新环境中重建数据库并导入数据。
**操作步骤**:
“`bash
# 步骤 1:在新服务器上创建 KingBase 实例
# 使用 kingbase_initdb 初始化新数据目录
# 步骤 2:启动新实例
sys_ctl start -D /opt/kingbase/new_data -l /tmp/kb.log
# 步骤 3:创建目标数据库
ksql -U system -d security << ‘EOF’
CREATE DATABASE newdb WITH ENCODING ‘UTF8’;
\q
EOF
# 步骤 4:导入 SQL 格式文件(推荐)
ksql -U system -d newdb << ‘EOF’
SET fsync = off;
SET work_mem = ‘256MB’;
SET maintenance_work_mem = ‘1GB’;
\i /data/recovery/output/testdb/public/customers.sql
\i /data/recovery/output/testdb/public/orders.sql
\i /data/recovery/output/testdb/public/order_items.sql
EOF
# 步骤 5:数据验证
ksql -U system -d newdb -c “SELECT count(*) FROM public.customers;”
ksql -U system -d newdb -c “SELECT count(*) FROM public.orders;”
ksql -U system -d newdb -c “SELECT * FROM public.orders LIMIT 10;”
# 步骤 6:重建索引与约束(如导出文件不含)
ksql -U system -d newdb -f schema_indexes.sql
ksql -U system -d newdb -f schema_constraints.sql
# 步骤 7:ANALYZE 更新统计信息
ksql -U system -d newdb -c “ANALYZE;”
“`
—
## 6. 常用问题与排查
### 6.1 编译失败:完全静态构建失败
**问题**:执行 `make standalone` 报错 “Fully static build failed” 或找不到静态库。
**原因**:缺少 glibc-static 静态链接库。
**解决**:安装静态库依赖。
“`bash
# RHEL / OEL / CentOS 系列
yum install -y glibc-static libstdc++-static
# Ubuntu / Debian 系列
apt-get install -y libc6-dev
# SUSE / openSUSE 系列
zypper install -y glibc-devel-static
# 如果仍无法完全静态构建,使用半静态构建作为替代
make portable
“`
### 6.2 无法识别数据目录
**问题**:报错 “Not a valid KingBase data directory”。
**原因**:数据目录缺少 PG_VERSION 文件,或路径不正确。
**解决**:确认数据目录包含 PG_VERSION 文件。
“`bash
# 检查 PG_VERSION 文件是否存在
ls /opt/kingbase/data/PG_VERSION
# 预期:/opt/kingbase/data/PG_VERSION
# 检查内容
cat /opt/kingbase/data/PG_VERSION
# 预期:12(或 14、15 等 KingBase 对应的 PG 内核版本号)
# 确认数据目录结构完整
ls -la /opt/kingbase/data/
# 预期包含:PG_VERSION、base/、global/、pg_wal/ 等关键目录
“`
### 6.3 恢复的数据为空或行数为 0
**可能原因与解决方案**:
1. **系统目录损坏**:pg_class 无法读取,无法定位用户表。
– 解决:使用 `recover max` 命令绕过系统目录直接扫描所有数据文件。
“`bash
fgkdu recover max -d /opt/kingbase/data -o ./recovered
“`
2. **数据文件名为非数字格式**:KingBase 数据文件以 OID 数字命名,若文件名异常无法识别。
– 解决:使用 `scan-file` 直接扫描指定文件。
“`bash
fgkdu scan-file /opt/kingbase/data/base/16384/16521 -o ./recovered
“`
3. **表已被 VACUUM 清理**:已删除行被 VACUUM 物理清理后无法从主文件恢复。
– 解决:尝试 WAL 日志恢复(recover max 会自动启用 WAL 恢复策略)。
“`bash
fgkdu recover max -d /opt/kingbase/data -o ./recovered -v
# 查看日志中 [WAL] 开头的恢复记录
“`
4. **数据目录路径错误**:-d 指向了非数据目录路径。
– 解决:先用 `diagnose` 确认目录有效性。
### 6.4 权限问题
**问题**:报错 “Permission denied” 无法读取数据文件。
**原因**:当前用户对 KingBase 数据目录无读权限。
**解决**:
“`bash
# 方式一:以 kingbase 用户运行
su – kingbase -c “fgkdu scan -d /opt/kingbase/data -o ./output”
# 方式二:赋予读权限
sudo chmod -R +r /opt/kingbase/data
# 方式三:以 root 运行(需要确保安全)
sudo fgkdu scan -d /opt/kingbase/data -o ./output
“`
### 6.5 恢复的数据不完整
**问题**:恢复的行数少于预期,部分表数据缺失。
**原因与解决**:FGKDU 会在输出文件中生成恢复报告,包含恢复的行数、坏块数量、raw scan 恢复的元组数、数据完整性统计。查看报告了解恢复情况。
“`bash
# 查看恢复报告
cat ./output/fgkdu_recovery_report.txt
# 报告包含:
# – 恢复的行数
# – 坏块数量
# – raw scan 恢复的元组数
# – 数据完整性统计
# – 各恢复策略的贡献
“`
对于 raw scan 恢复的数据需要人工验证,因为列类型可能是猜测的。建议:
1. 对比原表的行数与恢复行数。
2. 抽样检查恢复的数据内容。
3. 对于列名是 col1..colN 的恢复表,根据业务知识重命名列。
### 6.6 程序崩溃或信号异常
**问题**:程序运行中收到 SIGSEGV/SIGBUS 信号退出。
**原因**:遇到严重损坏的数据文件,触发了内存访问异常。
**解决**:FGKDU 内置信号保护机制,正常情况下会捕获信号继续运行。如果仍崩溃:
“`bash
# 1. 使用 –continue-on-error 遇到错误继续
fgkdu scan -d /opt/kingbase/data -o ./output –continue-on-error -v
# 2. 改用 recover max(更强的容错)
fgkdu recover max -d /opt/kingbase/data -o ./output –continue-on-error -v
# 3. 改用 scan-file 逐个文件扫描(定位问题文件)
for f in /opt/kingbase/data/base/16384/*; do
fgkdu scan-file “$f” -o ./output –continue-on-error
done
“`
### 6.7 磁盘空间不足
**问题**:恢复过程中输出目录磁盘空间不足。
**解决**:
“`bash
# 恢复前检查磁盘空间(SQL 格式约为原始数据的 1.5 倍)
df -h /data/recovery
# 切换到空间充足的磁盘
fgkdu scan -d /opt/kingbase/data -o /data/large_disk/output
# 使用 DMP 格式(比 SQL 格式更节省空间)
fgkdu scan -d /opt/kingbase/data -o ./output -f dmp
“`
### 6.8 Windows 平台路径问题
**问题**:Windows 下路径分隔符导致命令失败。
**解决**:FGKDU 已内置路径分隔符自动转换,`\` 和 `/` 均可。如果仍有问题,统一使用反斜杠:
“`cmd
:: 推荐使用反斜杠
fgkdu.exe scan -d D:\kingbase\data -o D:\recovery\output
:: 正斜杠也可
fgkdu.exe scan -d D:/kingbase/data -o D:/recovery/output
“`
### 6.9 恢复的 TOAST 大字段为占位值
**问题**:导出的 SQL 中 TOAST 大字段(大于 2KB 的 BYTEA/TEXT/JSONB)显示为 NULL 或占位值加注释,而非完整数据。
**原因**:TOAST 大字段存储在独立的 TOAST 表中,主表中仅保存指针。FGKDU 默认输出占位值加元信息注释,保证导入不报语法错误。
**解决**:基于注释中的元信息(relid/valueid/rawsize/compressed)人工恢复:
“`sql
— 元信息示例:
— NULL /* LOB BYTEA TOAST rel=28912 val=415 size=24576000 compressed=Y */
— 1. 从原库对应的 TOAST 表(OID 28912)中按 chunk_id=415 恢复 chunk 数据
— 2. 按 chunk_seq 顺序拼接
— 3. 若 compressed=Y,需解压(PG 默认 pglz 压缩)
— 4. 拼接后即为完整的大字段原始数据
“`
### 6.10 LOB 数据验证失败
**问题**:导入新库后,BYTEA 字段长度与原库不一致。
**解决**:
“`sql
— 验证内联 LOB(< 2KB)应完整
SELECT id, length(content::bytea) FROM documents WHERE id <= 1000;
— 验证 PDF 文件头(正确应为 25504446 = %PDF)
SELECT id, encode(substring(content::bytea, 1, 4), ‘hex’) FROM documents WHERE id=1;
— 预期:25504446
— 统计内联与 TOAST 占位的数量
SELECT
count(*) AS total,
count(content) AS inline_lob,
count(*) – count(content) AS toast_placeholder
FROM documents;
“`
### 6.11 恢复速度慢
**问题**:大库恢复耗时过长。
**解决**:
“`bash
# 1. 使用 -v 查看进度,确认是否在处理大文件
fgkdu scan -d /opt/kingbase/data -o ./output -v
# 2. 指定单表恢复(比全库快)
fgkdu scan -d /opt/kingbase/data -t public.large_table -o ./output
# 3. 按数据库分批恢复
for db in db1 db2 db3; do
fgkdu scan -d /opt/kingbase/data -u $db -o ./output_$db
done
# 4. 后台运行避免终端阻塞
nohup fgkdu scan -d /opt/kingbase/data -o ./output -v > scan.log 2>&1 &
tail -f scan.log
“`
### 6.12 恢复报告查看
**问题**:需要了解恢复的详细情况。
**解决**:查看恢复报告与日志。
“`bash
# 查看恢复报告
cat ./output/fgkdu_recovery_report.txt
# 查看详细日志(需 -v)
cat scan.log | grep -E “TABLE|COMPLETE|ERROR|WARN”
# 统计各表恢复行数
grep “rows extracted” scan.log
# 统计总行数
grep -hc ‘^INSERT INTO’ ./output/*/*.sql | awk ‘{s+=$1} END {print “Total:”, s}’
# 查看坏块信息
grep “bad block” scan.log
“`
—
关于作者
| 联系方式 | 信息 |
| — | — |
| **作者** | 风哥 | W itpux-com |
| **官方网站** | http://www.fgedu.net.cn , http://www.itpux.com |
| **数据库教程** | https://edu.51cto.com/lecturer/8020378.html |
FGKDU 是一款面向人大金仓 KingBase 数据库的数据抽取与恢复工具。当 KingBase 数据库无法启动时,FGKDU 可以直接从底层数据文件中抽取数据,导出为 SQL/DMP/CSV/TXT/BINARY 等格式,用于新建库的数据恢复。完全静态链接编译,单文件零依赖,支持 Linux 与 Windows 双平台,覆盖 KingBase V6 – V9 全系列版本。
如需技术支持或有功能建议,可通过上述联系方式与作者沟通。使用前请务必备份原数据目录,恢复操作应在数据目录副本上进行,避免对原始数据造成二次损坏。
本文由风哥教程整理发布,仅用于学习测试使用,转载注明出处:http://www.fgedu.net.cn/10327.html
