ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Vastbase G100 V2.2实施手册:连接、存储、分区与备份验收

Vastbase G100 V2.2实施手册:连接、存储、分区与备份验收

简介:VASTDATA Vastbase G100 V2.2用户手册面向信创数据库方向的DBA、运维工程师与参与国产化替代项目的开发人员,提供海量数据基于openGauss研发的Vastbase G100数据库的系统性官方文档级指引。压缩包内为1个PDF文件,体积约8.76MB,章节结构清晰:从数据库逻辑结构图、数据查询请求处理过程、管理事务与相关概念等基础内容,延伸到连接数据库时的服务端远程连接配置、vsql连接与应用程序接口调用,以及关闭数据库、创建和管理数据库、规划存储模型、列存数据压缩、表空间管理等实操环节,并附有版权、商标与服务声明说明。目前已有199人学习,适合作为入门上手和日常翻阅的工作手册。读者可据此理清G100的整体架构脉络,掌握从建库建表到存储模型选型的完整流程,遇到OCR扫描导致的个别字词缺漏时亦能结合上下文理解,减少独自摸索的成本。

1. 拿到一份 2.2 版手册,先别急着翻目录

信创数据库走到实施阶段,最尴尬的局面往往不是缺文档,而是文档只有一页产品彩页:库装好了、服务起来了,但第一条连接该发什么、第一张分区表怎么切、参数改哪一行,全靠猜。《Vastbase G100 V2.2 用户手册》属于另一类——它把数据库逻辑结构图、查询请求处理过程、vsql 连接、表空间与分区表、JDBC/ODBC 接口、客户端认证与 SSL 证书管理串成一条能照着做的线,是一份可以当操作手册用的数据库解决方案文档。

它适合三类人:刚接手国产数据库迁移、需要把 Oracle 或 MySQL 的建表语句翻译过来的后端;做信创数据库选型比对、要评估分区与列存能力的架构岗;以及需要给团队沉淀一份内部操作规范的人。不适合谁:只想看产品对比参数、不打算动手的人,翻两页就会觉得枯燥。下面按“怎么连上、怎么建、怎么调、坑在哪、怎么验”的顺序拆。

2. 连接链路拆解:从 listen_addresses 到 pg_hba.conf 的四道关

2.1 逻辑结构与查询请求处理:连不上时先看哪两张图

手册第 2 章开头放了两张图:数据库逻辑结构图和数据查询请求处理过程。多数人直接跳过,等到客户端连不上、SQL 卡住不动才回头翻。这两张图真正的价值,是把“一次连接”和“一条 SQL”拆成可定位的环节:客户端发起 TCP 连接 → 服务端监听进程接受 → 分配会话线程 → 认证 → 解析 → 优化 → 执行 → 返回结果集。链路一拆开,报错就能对上号——connection refused卡在第一环,no pg_hba.conf entry卡在认证环,statement timeout卡在执行环,不会一锅乱炖。

同一章还讲了管理事务,也就是显式事务的边界、提交与回滚。这一块容易被忽略,但它直接决定了后面表空间、分区表这些 DDL 能不能回滚。常见做法是把一个 DDL 单独包在事务里,失败了立刻回滚,不要和执行数据的语句混在同一个长事务里:

-- 建表与建索引分开事务,失败只回滚当前一段 BEGIN; CREATE TABLE t_order_2024 ( order_id bigint NOT NULL, user_id bigint NOT NULL, created_at date NOT NULL, amount numeric(12,2) ); COMMIT; BEGIN; CREATE INDEX idx_order_2024_user ON t_order_2024 (user_id); COMMIT;

逻辑说明:DDL 长事务会持有表级锁,期间其他会话的查询会被挂住。参数说明:这里没有需要调的参数,关键在于事务粒度——一次事务只干一件结构变更的事,出问题时能精准回滚到上一个稳定点,而不是整段重来。

2.2 打开远程接入:listen_addresses、端口与 vb_ctl reload

新装实例默认只监听本机回环地址,应用服务器连过来必然是拒绝。手册“配置服务端远程连接”一节给的就是这个场景。改配置前先确认数据目录,$PGDATA环境变量在多数部署脚本里已经设好,没有的话手动指到实例的数据目录。

# 先看实例状态,确认数据目录与进程号 vb_ctl status -D $PGDATA # 改之前备份一份配置,出问题能直接回退 cp $PGDATA/postgresql.conf $PGDATA/postgresql.conf.bak # 监听地址放开到所有网卡,端口改成规划值 sed -i "s/^#\?listen_addresses.*/listen_addresses = '*'/" $PGDATA/postgresql.conf sed -i "s/^#\?port.*/port = 5432/" $PGDATA/postgresql.conf # listen_addresses 和 port 属于 reload 生效项,不用重启 vb_ctl reload -D $PGDATA # 从应用服务器验证端口是否真的通了 nc -zv 10.0.0.11 5432

逻辑说明:listen_addresses决定服务端在哪些网卡上接受连接,port决定监听端口;这两项都是 SIGHUP 级别参数,reload即可,不需要停库,生产上能避免一次不必要的停机窗口。参数说明:-D指向数据目录;'*'表示全部网卡,如果机器有多块网卡、只想对业务网段开放,就写成具体 IP,别图省事全放开。改完一定从对端用nc或telnet验一次端口,光看配置文件改没改是不够的,中间还有防火墙和负载均衡两层。

2.3 pg_hba.conf 五列规则:认证方式选错是最常见的翻车点

端口通了但连不上,十有八九是pg_hba.conf没放行。这个文件是逐行匹配、首条命中即生效,不是“最优匹配”。五列分别是连接类型、数据库、用户、来源地址、认证方式,写错任何一列都表现为认证失败,但日志里的提示词不一样。

# TYPE DATABASE USER ADDRESS METHOD # 本机运维走本地 socket,只对操作系统同用户免密 local all all trust # 业务网段走密码认证,sha256 与服务端口令加密方式保持一致 host appdb app_user 10.0.0.0/24 sha256 # 只读报表账号单独一条,限定库和来源 host appdb rpt_user 10.0.1.0/24 sha256 # 兜底拒绝,必须放最后,否则前面规则形同虚设 host all all 0.0.0.0/0 reject

逻辑说明:匹配从上往下走,第一条命中的规则决定结果。把reject或者宽泛的0.0.0.0/0放在前面,后面的精细规则全部失效,这是血泪经验里出现频率最高的一种。参数说明:METHOD的取值要与服务端口令加密方式对齐——服务端按 md5 存口令、客户端按 sha256 协商,就会出现“密码明明对却认证失败”。改完这个文件同样用vb_ctl reload生效,不用重启。

注意:pg_hba.conf改完必须 reload,且改之前先cp一份带时间戳的备份。曾经有人在生产上直接覆盖,回滚时找不到原文件,只能从别的节点反推规则。

2.4 vsql 与 JDBC 两条入口:命令行验证与连接池落地

排障第一步永远是用vsql从命令行连,把认证、网络、权限三层问题摘干净,再去怀疑应用代码。手册“使用 vsql 连接”一节列的元命令值得记住几个:\l看库、\dn看 schema、\d+ 表名看表结构与分布、\timing开耗时。

# 密码走环境变量,脚本里不要明文写死;生产环境建议改用 .pgpass 或证书 export PGPASSWORD="$(cat /etc/db/app_user.pwd)" vsql -h 10.0.0.11 -p 5432 -d appdb -U app_user -W # 连进去后先看三样:库、schema、当前会话参数 \l \dn SHOW search_path;

逻辑说明:-h走 TCP,不写-h走本地 socket,两条路径的认证规则不同,排障时要分清自己走的是哪条。参数说明:-W强制提示输入密码,避免脚本里带上密码参数被ps看到;-d指定库名,不指定会默认连与用户同名的库,连不上时报错信息很含糊。

应用侧接入分 JDBC 和 ODBC 两条。手册 4.2 节给的是 JDBC 的完整流程:类路径、加载驱动、连接、执行、游标、连接池;4.3 节是 ODBC 的 openGauss/unixODBC 安装、驱动替换、数据源配置、环境变量、测试。

// 最小可运行骨架,驱动类名与连接串格式以手册 4.2.3 列出的为准 Class.forName("org.postgresql.Driver"); String url = "jdbc:postgresql://10.0.0.11:5432/appdb" + "?currentSchema=app&connectTimeout=5&socketTimeout=30"; Properties props = new Properties(); props.setProperty("user", "app_user"); props.setProperty("password", System.getenv("DB_PASS")); try (Connection conn = DriverManager.getConnection(url, props); PreparedStatement ps = conn.prepareStatement( "select order_id, amount from t_order where user_id = ?")) { ps.setLong(1, 1001L); try (ResultSet rs = ps.executeQuery()) { while (rs.next()) { // 按列名取值,别按序号,后面加字段不会错位 } } }

逻辑说明:连接串里显式指定currentSchema,省掉每条 SQL 都带 schema 前缀,也避免search_path被会话级改动带偏。参数说明:connectTimeout控制建连超时,socketTimeout控制读写超时,两个值必须设,否则网络抖动时应用线程会一直挂着不释放。连接池侧的重点是最大连接数要与max_connections留出余量,池子加起来超过实例上限,高峰期就是一批too many clients。

3. 存储模型选型:行存、列存压缩与分区表的三组参数

3.1 行存还是列存:从查询形态倒推 ORIENTATION

手册“规划存储模型”一节把选择权交回给业务形态,而不是让你背概念。判断标准很朴素:一次查询要返回整行、且以点查和频繁更新为主,走行存;一次查询只碰少数几列、但要扫大量行做聚合,走列存。列存按列连续存放,同样的聚合扫描读的页数少一个量级,但代价是更新路径比行存复杂。

-- 行存:订单主表,点查多、状态频繁变更 CREATE TABLE t_order ( order_id bigint NOT NULL, user_id bigint NOT NULL, status varchar(16) NOT NULL, created_at date NOT NULL, amount numeric(12,2) ) WITH (ORIENTATION = ROW); -- 列存:明细流水,宽表、只追加、按维度聚合 CREATE TABLE t_order_detail ( order_id bigint NOT NULL, sku_id bigint NOT NULL, channel varchar(32), province varchar(32), pay_amount numeric(12,2), pay_time timestamp ) WITH (ORIENTATION = COLUMN);

逻辑说明:ORIENTATION在建表时定死,后期改只能重建表再迁数据,所以这张表未来三年的访问形态要在建表前想清楚。参数说明:ROW是默认值,不写也是行存;COLUMN走列存引擎。我一般会建议把“会不会经常改这一行”当成第一判断条件——会频繁更新的表别上列存,否则后面要么改表结构,要么业务侧绕一大圈。

3.2 列存压缩级别:COMPRESSION 的收益边界

手册 3.6 节单独讲了列存下的数据压缩。列存本身已经把同类型数据聚在一起,压缩比天然比行存高,再加一级压缩往往能把存储降到原来的三分之一到一半,但压缩级别不是越高越好,解压要 CPU。

-- 高压缩:历史归档、查询频次低的宽表 CREATE TABLE t_log_archive ( log_id bigint, biz_date date, payload text ) WITH (ORIENTATION = COLUMN, COMPRESSION = HIGH); -- 中压缩:在线明细,读写都有,折中 CREATE TABLE t_order_detail_online ( order_id bigint, sku_id bigint, pay_amount numeric(12,2) ) WITH (ORIENTATION = COLUMN, COMPRESSION = MIDDLE);

逻辑说明:压缩在写入时完成、读取时解压,收益是 IO 和存储,成本是 CPU。归档表几乎不查、只做合规留存,直接上最高级;在线明细表要兼顾写入吞吐和查询延迟,取中间档更稳。参数说明:COMPRESSION的可用取值以手册 3.6 节列出的为准,不同部署形态支持的档位可能不同,建表前先确认,别照抄别人脚本。压缩级别调整通常要重建表或走数据重分布,别指望后期一条ALTER就改掉。

3.3 表空间规划:路径、配额与扩容时的搬迁

表空间解决的是“数据和日志抢同一块盘”的问题。手册“创建和管理表空间”一节给了相对路径和绝对路径两种写法,我更倾向相对路径——它挂在数据目录下,备份和迁移时一起带走,不会出现恢复后路径对不上的情况。

-- 相对路径:落在数据目录下的 tablespace/ts_hot CREATE TABLESPACE ts_hot RELATIVE LOCATION 'tablespace/ts_hot'; CREATE TABLESPACE ts_cold RELATIVE LOCATION 'tablespace/ts_cold'; -- 热表放 SSD 对应的表空间 CREATE TABLE t_order_hot (...) TABLESPACE ts_hot; -- 归档表放容量盘 CREATE TABLE t_order_cold (...) TABLESPACE ts_cold; -- 单表搬迁:先确认目标表空间剩余空间足够 ALTER TABLE t_order_detail SET TABLESPACE ts_cold;

逻辑说明:ALTER TABLE ... SET TABLESPACE会重写整张表并持有排他锁,必须放在维护窗口里做,且执行前用pg_tablespace_location核对目标路径的剩余空间。参数说明:RELATIVE LOCATION的路径相对于数据目录,迁移实例时不会断链;绝对路径适合挂独立存储卷,但要记住恢复时得手工映射。高频写入的小表放 SSD 表空间,压缩归档放容量盘,这是最省钱的一种分层方式。

3.4 分区表与 default 分区:切分键、分区数与前缀索引

手册 3.8.8 是整本里最厚的一节,范围、列表、哈希三种分区方式加上 default 分区。落地时真正要决策的只有三个:切分键选谁、分多少个、default 分区要不要留。

-- 按月范围分区,最后一档用 MAXVALUE 兜底,避免越界插入直接失败 CREATE TABLE t_order_p ( order_id bigint NOT NULL, user_id bigint NOT NULL, created_at date NOT NULL, amount numeric(12,2) ) PARTITION BY RANGE (created_at) ( PARTITION p202401 VALUES LESS THAN ('2024-02-01'), PARTITION p202402 VALUES LESS THAN ('2024-03-01'), PARTITION p202403 VALUES LESS THAN ('2024-04-01'), PARTITION p_default VALUES LESS THAN (MAXVALUE) ); -- 查某个月的数据,确认分区裁剪是否生效 EXPLAIN (COSTS OFF) SELECT count(*) FROM t_order_p WHERE created_at >= '2024-02-01' AND created_at < '2024-03-01';

逻辑说明:切分键必须出现在查询条件里,否则分区裁剪不生效,扫描会退化成全表。分区键尽量选时间或枚举型字段,别选高基数的业务主键,否则分区数量失控,元数据管理本身就成了负担。参数说明:VALUES LESS THAN是上界,不含边界值;MAXVALUE那一档就是手册里的 default 分区,专门接住未来月份的数据。做增量插入时,正常流程应该是提前建好下个月分区,把 default 分区里的数据搬到正式分区,而不是让它长期堆积。

3.5 闪回表与全局临时表:两个容易当成后悔药的特性

手册 3.8.6 的闪回表和 3.8.7 的全局临时表,是两个看起来很好用、但边界必须先读清楚的功能。闪回是把表回到某个时间点的状态,前提是回收站相关配置开着、且数据还在保留窗口内;全局临时表是元数据共享、数据会话隔离,会话断开数据就没了。

-- 闪回:把表退回到指定时间点,执行前先确认保留窗口 TIMECAPSULE TABLE t_order_hot TO TIMESTAMP to_timestamp('2024-03-01 09:00:00', 'YYYY-MM-DD HH24:MI:SS'); -- 全局临时表:会话内可见,提交时删除行 CREATE GLOBAL TEMPORARY TABLE tmp_calc ( id bigint, val numeric(18,4) ) ON COMMIT DELETE ROWS;

逻辑说明:闪回不是备份替代品,它只能应对误删误改,一旦超过保留窗口或者实例做过清理,就彻底没有后悔药了。全局临时表的ON COMMIT DELETE ROWS表示提交即清空,PRESERVE ROWS则是会话结束时清。参数说明:闪回依赖的保留参数要提前调大,默认值往往撑不住一次大规模误操作;全局临时表虽然名字带“全局”,数据是按会话隔离的,别把它当普通表往里灌持久数据。

4. 对象与参数落地:schema、索引、约束、序列的写法清单

4.1 schema 与 search_path:隔离边界与越权访问

手册 3.11.1 讲 schema 创建与管理。多租户或者多业务共用一个库时,schema 是最省事的隔离手段,但一定要处理public的默认权限——新建用户默认能在public下建对象,这是很多人事后才发现的安全漏洞。

-- 建业务 schema 并授权给业务账号 CREATE SCHEMA app AUTHORIZATION app_user; -- 回收 public 的建对象权限,只保留只读 REVOKE CREATE ON SCHEMA public FROM PUBLIC; -- 数据库级默认搜索路径,新建会话自动生效 ALTER DATABASE appdb SET search_path TO app, public; -- 会话级临时改,只影响当前连接 SET search_path TO app;

逻辑说明:ALTER DATABASE ... SET search_path写进库级配置,应用连接串就不用每条都带 schema 前缀;SET只影响当前会话,适合排障时临时切。参数说明:REVOKE CREATE ON SCHEMA public FROM PUBLIC这行强烈建议执行,否则任何能连库的账号都能在public下建同名表做伪装。授权顺序是先建 schema 再授权,顺序反了会报对象不存在。

4.2 索引三选一:普通、部分、表达式

手册 3.11.2 讲索引创建与管理。生产上最常见的错误不是没建索引,而是建了一堆用不上的索引,拖慢写入。三种索引各管一类场景:普通 B-tree 管等值和范围,部分索引管“只查少数状态”的业务,表达式索引管对列做函数运算后的查询。

-- 普通联合索引,注意字段顺序:区分度高的在前 CREATE INDEX idx_order_user_time ON t_order (user_id, created_at); -- 部分索引:只对未支付订单建,索引体积能降一个量级 CREATE INDEX idx_order_unpaid ON t_order (created_at) WHERE status = 'UNPAID'; -- 表达式索引:查询里用了 lower(),索引也必须是 lower() CREATE INDEX idx_user_email_lower ON t_user (lower(email)); -- 查索引是否真被用上 EXPLAIN (ANALYZE, COSTS OFF) SELECT * FROM t_order WHERE user_id = 1001 ORDER BY created_at DESC LIMIT 10;

逻辑说明:联合索引遵循最左前缀,(user_id, created_at)能撑住按用户查、按用户加时间排序,但撑不住单独按created_at查。部分索引要保证查询条件里带上同样的谓词,否则用不上。参数说明:表达式索引要求查询写法和索引表达式完全一致,写成lower(email)就不能用email = ?命中。建完索引必须跑一次EXPLAIN ANALYZE确认走的是索引扫描,不能建完就完事。

4.3 约束的启用禁用:批量导入期的开关

手册 3.11.5 把检查、非空、唯一、主键、外键逐条列了一遍,还专门有一节讲约束启用禁用。这个开关是数据迁移期的救命稻草:全量导入几百万行时,每条都校验外键,性能会被拖到无法接受。

-- 导入前禁用约束(仅限维护窗口,且需业务停写) ALTER TABLE t_order_detail DISABLE CONSTRAINT fk_detail_order; -- 批量导入 -- COPY t_order_detail FROM '/data/stage/detail.dat' WITH (FORMAT 'text'); -- 导入后必须重新启用,并验证脏数据 ALTER TABLE t_order_detail ENABLE CONSTRAINT fk_detail_order; -- 找出违反外键的孤儿行,先修数据再启用 SELECT d.order_id FROM t_order_detail d LEFT JOIN t_order o ON o.order_id = d.order_id WHERE o.order_id IS NULL LIMIT 100;

逻辑说明:禁用约束期间写入的数据没有人校验,启用时若存在脏数据会直接失败,所以顺序必须是“禁用 → 导入 → 查孤儿行 → 修数据 → 启用”。参数说明:DISABLE CONSTRAINT支持按单个约束名操作,别用整表级别的禁用,粒度太粗容易漏掉关键约束。这个操作必须在维护窗口做,业务写入期间禁用唯一约束会直接产生重复数据。

4.4 序列与自增:CACHE 与跳号的关系

手册 3.11.4 讲序列。单机场景下CACHE值调大能明显减少序列争用,但代价是实例重启或会话异常退出时会跳掉一批号。订单号这种要求连续的字段,别用序列直接生成。

CREATE SEQUENCE seq_order_id START WITH 1 INCREMENT BY 1 CACHE 50 NO CYCLE; -- 取下一个值 SELECT nextval('seq_order_id'); -- 查看当前值与缓存情况 SELECT last_value, is_called FROM seq_order_id; -- 表上使用:只作为默认值来源,不保证连续 CREATE TABLE t_order_seq ( order_id bigint DEFAULT nextval('seq_order_id') PRIMARY KEY, amount numeric(12,2) );

逻辑说明:序列的CACHE是按会话预分配的,会话一断,预分配但没用的号就永久丢失,所以“跳号”是设计特性而不是 bug。参数说明:NO CYCLE防止到达上限后回绕产生重复值;INCREMENT BY在双写或多实例场景可以设置不同步长做号段隔离,避免冲突。如果业务真的要求单号连续,正确做法是单独一张号段表加行锁,而不是把序列的CACHE设成 1——那会把并发直接压垮。

4.5 参数三层改动:会话、数据库、实例

手册 3.10 讲配置数据库参数。参数有明确的作用域层级:会话级只影响当前连接,数据库级影响连到该库的所有会话,实例级影响全部。改错层级是常见事故来源——本来只想给一个报表任务放宽内存,结果改到实例级,把整机内存吃满。

-- 会话级:只影响当前连接,连接断开即失效 SET work_mem = '64MB'; -- 数据库级:连到 appdb 的新会话都生效,不需要重启 ALTER DATABASE appdb SET work_mem = '64MB'; -- 查当前生效值、来源和单位 SELECT name, setting, unit, source FROM pg_settings WHERE name IN ('work_mem', 'max_connections', 'shared_buffers');

逻辑说明:source字段能直接告诉你这个值是来自会话、库级配置还是配置文件,排障时比猜快得多。参数说明:work_mem是单次排序或哈希操作可用的内存,不是会话总内存,并发高时要按“并发数 × work_mem”估算总量;max_connections和shared_buffers属于需要重启才生效的项,改之前评估停机窗口。实例级参数走配置文件加vb_ctl reload,重启生效项要单独标记,别和 reload 项混在一起批量执行。

5. 五类高频翻车现场:从认证失败到表空间路径错位

5.1 现象是密码认证失败,但密码确实没错

现象:应用报password authentication failed for user "app_user",用vsql手工连同样的账号密码却提示一样,但换成本地 socket 又能进去。原因通常有三个:pg_hba.conf首条命中的规则不是期望那条;服务端口令按 md5 存、客户端按 sha256 协商;账号被锁定或口令已过期。解决顺序是先看规则顺序再看加密方式,最后查账号状态。

# 看实际生效的规则顺序,不要看备份文件 grep -vE '^\s*#|^\s*$' $PGDATA/pg_hba.conf # 查服务端口令加密方式,要和客户端认证方式对齐 vsql -d appdb -c "SHOW password_encryption_type;" # 重置口令,让服务端按当前加密方式重新存一份 vsql -d appdb -c "ALTER USER app_user IDENTIFIED BY 'NewPass@2024';"

逻辑说明:改pg_hba.conf后必须 reload,且改的是数据目录下那份,不是安装包里的模板。参数说明:password_encryption_type决定新口令的存储格式,历史账号可能还是旧格式,重置一次即可对齐。账号锁定和口令有效期在手册 5.2.9 账户安全策略里有配置项,排查时一并看。

5.2 列存表上的更新和删除报错或慢到不可接受

现象:对列存表执行UPDATE或DELETE,要么直接报不支持,要么执行时间从毫秒级变成分钟级。原因是列存按列组织,行级变更要走额外的增量路径,代价远高于行存。解决方式取决于这张表到底该不该是列存:更新频繁就重建为行存;确实要保列存,就改成“只追加 + 定期批量重写”。

-- 确认表的存储朝向 SELECT relname, reloptions FROM pg_class WHERE relname IN ('t_order_detail', 't_order_hot'); -- 方案一:重建为行存,适合更新频繁的表 CREATE TABLE t_order_detail_row (LIKE t_order_detail) WITH (ORIENTATION = ROW); INSERT INTO t_order_detail_row SELECT * FROM t_order_detail;

逻辑说明:reloptions里能看到orientation=column这类标识,先确认再动手。参数说明:重建期间原表可读但不可写,务必在维护窗口做,并且用INSERT ... SELECT分批提交,避免一个超大事务撑爆日志空间。这张表原本被选成列存,多半是当初只看了“宽表适合列存”这一条,忽略了更新频率。

5.3 default 分区没接住数据,插入直接失败

现象:插入一条下个月的数据,报找不到匹配分区。原因是分区定义只建到当前月,没有MAXVALUE兜底档,或者兜底档被放在了中间位置。解决是先补一个 default 分区,再把它里面的数据搬到正式分区。

-- 补一个兜底分区 ALTER TABLE t_order_p ADD PARTITION p_default VALUES LESS THAN (MAXVALUE); -- 从 default 分区里把数据搬到新月份分区(先建好目标分区) ALTER TABLE t_order_p ADD PARTITION p202404 VALUES LESS THAN ('2024-05-01');

逻辑说明:ADD PARTITION属于 DDL,会短暂持有锁,低峰期执行。参数说明:MAXVALUE分区只能有一个,且必须是最后一档;已经有兜底分区时再加会报冲突。日常运维应该做成定时任务,每月提前建下个月分区,把 default 分区长期保持为空,它只是保险丝,不是常规存放区。

5.4 JDBC 驱动与 JDK 版本对不上,报类版本错误

现象:应用启动报UnsupportedClassVersionError或者No suitable driver found,换台机器又能跑。原因是驱动 jar 的编译目标版本与运行 JDK 不匹配,或者容器镜像里打了两个版本的驱动、类加载加载到了旧的那个。手册 4.2.2 专门有一节讲 JDBC 与 JDK 的兼容性,先查矩阵再定驱动版本。

# 看驱动 jar 的编译目标版本 unzip -p vastbase-jdbc.jar META-INF/MANIFEST.MF | head -20 # 应用启动时打印类加载来源,确认加载的是哪个 jar java -verbose:class -jar app.jar 2>&1 | grep -i jdbc

逻辑说明:-verbose:class会打出每个类从哪个 jar 加载,是定位“多版本共存”的最快手段。参数说明:连接池通常在启动时初始化,如果两个驱动同时在类路径上,先加载的那个生效,后面那个静默失效,所以清理类路径比升级驱动更关键。容器化部署时把驱动打进镜像并锁定版本,别依赖基础镜像自带的驱动。

5.5 表空间备份恢复后实例起不来

现象:用vb_basebackup按 tar 格式备份,恢复后实例启动失败,日志提示表空间目录不存在。原因是 tar 格式下主数据包和表空间包是分开的,恢复时只解了主包,pg_tblspc下的链接指向空目录。解决是按顺序解包,并核对每个表空间的目录映射。

# 备份:tar 格式 + 压缩,表空间会单独打包 vb_basebackup -D /backup/full_20240301 \ -h 127.0.0.1 -p 5432 -U backup_user \ -F t -z -P -l "full backup 20240301" # 恢复:先解主包,再逐个解表空间包到对应位置 mkdir -p /pgdata/restore tar -xzf /backup/full_20240301/base.tar.gz -C /pgdata/restore ls /backup/full_20240301/*.tar.gz # 逐个确认表空间包 # 启动前核对链接指向的目录是否真实存在 ls -l /pgdata/restore/pg_tblspc/

逻辑说明:pg_tblspc下的条目是软链接,指向表空间的实际目录,恢复时目录没建好,链接就是断的。参数说明:-F t指定 tar 格式,-z开压缩,-P显示进度,-l打标签方便日后按时间点识别。恢复完成后先不要急着起库,用ls -l逐个核对链接目标,比对着日志一行行猜快得多。

6. 备份与安全加固的验收动作:三张检查表把风险压到底

备份能不能用,只有恢复过才算数。我一般把vb_basebackup的验收拆成三步:备份包能不能列全、恢复能不能起来、起来后数据对不对得上。

# 第一步:确认备份包完整性,主包和每个表空间包都要能列出内容 for f in /backup/full_20240301/*.tar.gz; do echo "== $f"; tar -tzf "$f" | head -3 done # 第二步:对照实例里实际的表空间数量,数量对不上说明漏包 vsql -d postgres -c "SELECT spcname FROM pg_tablespace;" # 第三步:解包到隔离目录试启,不要直接覆盖生产目录 mkdir -p /pgdata/restore_test tar -xzf /backup/full_20240301/base.tar.gz -C /pgdata/restore_test

逻辑说明:tar -tzf做的是只读校验,不解压,几百 G 的包也能几分钟跑完,适合放在备份后的自动巡检里。参数说明:隔离目录试启是最关键的一步,很多人备份跑了半年,第一次恢复才发现少了表空间包。试启成功后连进去核对关键表的行数和最新时间戳,才算真正闭环。

SSL 和三权分立这两项,验收靠的是“反向验证”——用错误的证书、用越权的账号去试,能挡住才算配对了。

验收项检查点通过标准
备份包完整性tar -tzf逐个列出主包与表空间包数量与pg_tablespace一致
恢复可启动隔离目录解包后vb_ctl start日志无表空间缺失、无 FATAL
数据一致性关键表行数与最大时间戳与备份时刻的监控快照对得上
SSL 强制连接串sslmode=verify-full换成错误 CA 后连接被拒
三权分立三个管理员账号分别登录系统管理员改不了审计策略
连接数水位pg_stat_activity计数稳定低于max_connections的 80%

三权分立这块,手册 5.2.3 讲得比较细:系统管理员、安全管理员、审计管理员各自职责分离,验收时不能只看账号建没建,要实际拿系统管理员账号去改审计相关配置,确认被拒绝。SSL 同理,配了ssl=on不等于强制,连接串里不写sslmode照样明文跑,必须把客户端侧也锁死。

提示:证书和私钥文件的权限要单独收紧,属主是数据库运行用户,权限 600,别跟着数据目录一起被复制到备份里再散出去。

从那以后我每次交付前都强制走一遍这套动作:先tar -tzf点数,再隔离目录试启,最后拿越权账号撞一次权限。这三步加起来不到半小时,但能挡住后面几个通宵。希望帮到你。

本文还有配套的精品资源,点击获取

返回列表