GBase 8c 表空间规划和对象迁移
GBase 8c 表空间规划和对象迁移我最近看 GBase 8c 资料时越来越强烈的一个感觉是很多现场不是不会建表空间而是把表空间用得太晚、太散、太随意。真正落到现场时最常见的现象通常不是“不会执行CREATE TABLESPACE”而是业务已经跑了一段时间默认表空间所在磁盘开始吃紧热点表、归档表、临时排序、历史索引全堆在一起最后才想到把对象往别的路径挪。这个时候事情就不再是“加一个目录”这么简单了而是变成了对象盘点、变更窗口、I/O 冲击、回退方案一起上。我自己理解下来GBase 8c 里的表空间更像是存储布局的控制点。它能解决“对象落到哪里”的问题但解决不了“规划混乱”本身。要是前期没想清楚后面迁移对象时不仅麻烦还容易把影响面低估。我实际排查时先看的不是建不建表空间很多人一上来就问默认表空间满了要不要赶紧新建一个。但我最近整理下来觉得先别急着建先把下面几件事想清楚这次是容量问题还是冷热数据混放问题。需要移动的是表、索引还是临时文件压力。这批对象是后续持续新增还是只需要一次性搬迁。当前环境是不是适合自定义表空间而不是继续沿用默认表空间。先把这四个问题分开后面的动作才不会乱。现场现象我更倾向于先判断什么常见误区默认路径空间告急是单个大对象膨胀还是很多对象混放直接新建表空间但不盘点对象查询高峰时 I/O 抖动明显是热点索引和归档数据抢盘还是排序临时文件压力只搬表不搬索引新系统即将上线是不是应该在建库建表阶段就定好落盘位置等上线后再慢慢挪云化或标准化部署环境是否真的适合使用自定义表空间默认把“多表空间”当最佳实践从落地角度看表空间最怕的不是没建而是只建不用规则、只迁不做分层。我对 GBase 8c 表空间边界的理解GBase 8c 的数据最终由 DN 节点落盘表空间本质上是文件系统里的目录用来承载数据库对象的数据文件。系统自带的两个表空间是pg_default和pg_global。我自己更关注的是这两个内置表空间的边界pg_default默认承载非共享系统表、用户表、用户表索引、临时表、临时表索引、内部临时表。pg_global承载共享系统表空间不是业务对象随便放的地方。我最近看资料时发现很多人把“表空间”理解成逻辑库的分组但实际上它更偏物理存储布局。数据库、模式、表、索引是逻辑对象表空间解决的是这些对象最终落在哪个目录、哪类介质上。对象类型我一般怎么理解它和表空间的关系现场建议数据库可以关联默认表空间但不是拿来替代对象级规划的库级默认只做兜底不做精细治理表表数据只能属于一个表空间大表、历史表、归档表适合单独规划索引索引是独立对象别默认认为会和表一起迁热点索引要单独盘点临时对象/临时文件和会话行为、排序/哈希压力强相关需要单独观察不要混着看系统共享对象走pg_global不建议碰业务规划这一点我特别想强调迁表不等于迁完了。很多现场真正占 I/O 的可能反而是索引和临时文件。哪些场景适合自定义表空间哪些场景我反而会克制一点GBase 8c 文档里对表空间的定位很清楚核心还是控制磁盘布局、隔离不同对象的存储位置。但我自己更倾向于把它用在下面几种场景场景我更推荐的做法原因热点交易表和历史归档表混在一个路径分开规划业务表空间容量和 I/O 行为差异太大热点索引需要更稳定的介质索引与表分开规划真实瓶颈常常先出现在索引读写原路径已经接近容量上限给后续新增对象切到新表空间比全量搬迁更稳临时排序和业务对象争抢磁盘评估单独的临时表空间策略能减少高峰期互相影响但也不是所有环境都值得自定义表空间。我最近整理资料时注意到在一些标准化云场景里文档本身就不建议用户随意使用自定义表空间。原因也不复杂底层存储往往已经标准化额外拆表空间不一定带来收益反而容易增加运维复杂度。所以我个人更倾向于这个判断顺序能用默认表空间解决的不急着拆。必须做物理隔离的再做自定义表空间。一旦做了就把对象范围、命名规范、迁移顺序一次想清楚。我更愿意采用的落地步骤1先准备目录而不是先写 SQL表空间对应的是目录目录条件不满足后面 SQL 再漂亮也没用。我自己一般会先在数据库节点把路径准备好再进入数据库层动作。#!/bin/bashforpin/data1/gbase/ts_hot\/data2/gbase/ts_hist\/data3/gbase/ts_tempdomkdir-p$pchown-Rgbase:gbase$pchmod700$pdone# 做变更前先确认目录为空forpin/data1/gbase/ts_hot /data2/gbase/ts_hist /data3/gbase/ts_tempdoecho$pls-la$pdone这里我一般会特别检查三件事检查项为什么要先看我自己的判断方式目录是否已存在且为空表空间创建依赖已有空目录先ls -la别直接上 SQL目录属主属组是否正确避免后面出现权限问题统一给数据库运行用户路径是否为稳定存储表空间丢失会直接影响实例工作不放移动介质、不放临时挂载点2创建表空间时先按用途命名我个人不太喜欢space1、space2这种命名。真到了半年后排查现场谁都记不住哪个是热表、哪个是历史、哪个是临时。CREATETABLESPACEts_hot LOCATION/data1/gbase/ts_hot;CREATETABLESPACEts_hist LOCATION/data2/gbase/ts_hist;CREATETABLESPACEts_temp LOCATION/data3/gbase/ts_temp;-- 按需授权给业务角色GRANTCREATEONTABLESPACEts_hotTOapp_rw;GRANTCREATEONTABLESPACEts_histTOapp_rw;命名我一般会直接带语义ts_hot高频交易对象ts_hist历史归档对象ts_temp临时对象或临时文件策略验证ts_idx_hot热点索引单独落盘时再建3新增对象尽量在创建阶段就落对地方我自己更倾向于把“对象落盘位置”前移到建表脚本而不是等上线后再改。尤其是大表和大索引后迁移的代价通常更高。CREATETABLEacct.bill_detail(bill_idbigintprimarykey,acct_novarchar(32)notnull,trade_datedatenotnull,trade_amountnumeric(18,2)notnull,statusvarchar(16)notnull,created_timetimestampnotnulldefaultcurrent_timestamp)TABLESPACEts_hot;CREATEINDEXidx_bill_detail_01ONacct.bill_detail(trade_date,acct_no)TABLESPACEts_hot;如果某一批对象在一个会话里统一创建我一般会显式设置默认表空间避免脚本里漏写SETdefault_tablespacets_hist;CREATETABLEacct.bill_detail_2024m12(likeacct.bill_detail including defaults);CREATEINDEXidx_bill_detail_2024m12_01ONacct.bill_detail_2024m12(trade_date,acct_no);而临时对象相关的策略我更愿意单独验证不和业务表迁移混在一个窗口里SETtemp_tablespacests_temp;CREATETEMPTABLEtmp_bill_checkASSELECT*FROMacct.bill_detailWHEREtrade_datedate2024-12-01;真正开始迁移前我一定会先做对象盘点很多人做对象迁移时最大的问题不是不会写ALTER而是不知道自己到底要迁什么。我一般先把目标模式里的表和索引盘出来至少先看清楚当前对象落在哪个表空间。SELECTn.nspnameASschema_name,c.relnameASobject_name,c.relkindASobject_type,COALESCE(t.spcname,pg_default)AStablespace_nameFROMpg_class cJOINpg_namespace nONn.oidc.relnamespaceLEFTJOINpg_tablespace tONt.oidc.reltablespaceWHEREn.nspnameacctANDc.relkindIN(r,i)ORDERBYn.nspname,c.relkind,c.relname;如果只是快速查看现有表空间我一般会直接用这两种方式SELECTspcnameFROMpg_tablespace;\db上面这个顺序我自己很少省。因为只要一跳过盘点后面就很容易出现两个问题表挪走了索引还在原路径。当前对象其实不大真正大的对象根本没被纳入本次变更。我更喜欢“先生成 SQL再分批执行”在现场里最怕的是手敲几十条ALTER TABLE ... SET TABLESPACE。我自己的习惯是先生成再复核再分批跑。迁移一批历史表SELECTformat(ALTER TABLE %I.%I SET TABLESPACE ts_hist;,schemaname,tablename)FROMpg_tablesWHEREschemanameacctANDtablenameLIKEbill_detail_2024%;迁移对应索引SELECTformat(ALTER INDEX %I.%I SET TABLESPACE ts_hist;,schemaname,indexname)FROMpg_indexesWHEREschemanameacctANDtablenameLIKEbill_detail_2024%;我个人更倾向于分三步走步骤我会怎么做这样做的原因第一步先生成迁移 SQL 清单防止漏对象、漏索引第二步先跑小批量对象验证窗口先看锁等待、I/O 波动、耗时第三步再分批处理大对象把风险拆小便于回退这里还有一个我实际排查时经常遇到的坑表迁完以后不代表业务路径就一定改善。如果热点访问主要落在索引或者高峰期压力来自临时排序那单纯挪表效果通常不会特别明显。这些坑我自己会提前写进变更单里坑一只看表不看索引这是最常见的。业务反馈“已经迁表了磁盘还是忙”最后一查大索引还在老路径上。坑二把表空间当容量回收工具表空间能重新布局对象但它不是空间回收工具。如果问题根源是历史垃圾、对象膨胀、无序增长只迁路径不治理对象后面还会再满。坑三高峰期直接迁大对象我自己一般不会在业务高峰做大对象迁移。即使 SQL 看起来简单底层也涉及真实数据文件移动这种动作最好还是留给明确的变更窗口。坑四路径规划没有命名规则没有命名规范的表空间时间一长就会变成“知道有、没人敢动”的状态。后面无论巡检、扩容还是迁移成本都会升高。坑五忘了删除前提是表空间必须为空这类问题通常出现在回滚或者试验环境清理时。表空间里还有对象DROP TABLESPACE就不会让你轻松过去。常见坑现场表现我更建议的做法只迁表不迁索引迁移后 I/O 改善不明显表和索引分开盘点、分开执行把表空间当扩容补丁过一段时间又满同时做对象分层和容量治理高峰期迁大对象业务抖动、窗口不可控小批量预演后再正式执行路径命名混乱后续无人敢维护建立统一命名和用途说明清理不彻底删除表空间失败先确认对象完全迁出我自己更认可的一套思路如果把这件事再压缩一下我现在会把 GBase 8c 表空间治理理解成三句话第一表空间解决的是物理落盘不是逻辑建模。第二新对象尽量创建时就放对位置别把所有问题留到后迁移。第三迁移动作一定是对象盘点、表索引分治、分批执行而不是一条命令糊过去。我最近整理下来觉得GBase 8c 的表空间能力并不难难的是把它用在真正合适的地方。该用的时候要把目录、对象、会话参数、执行窗口一起想清楚不该用的时候也别为了“看起来更专业”硬拆出一堆表空间。真正能让现场更稳的往往不是多建几个目录而是从一开始就把对象怎么落、后面怎么迁、出了问题怎么退提前想明白。参考资料[1] GBase 8c 文档介绍 https://www.gbase.cn/docs/gbase-8c/%E6%AC%A2%E8%BF%8E/ [2] 基本概念 | GBASE南大通用 https://www.gbase.cn/docs/gbase-8c/03%20%E5%BC%80%E5%8F%91%E8%80%85%E6%8C%87%E5%8D%97/%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5 [3] 数据库使用 | GBASE南大通用 https://www.gbase.cn/docs/gbase-8c/03%20%E5%BC%80%E5%8F%91%E8%80%85%E6%8C%87%E5%8D%97/%E6%95%B0%E6%8D%AE%E5%BA%93%E4%BD%BF%E7%94%A8 [4] gsql | GBASE南大通用 https://www.gbase.cn/docs/gbase-8c/04%20%E5%B7%A5%E5%85%B7%E5%8F%82%E8%80%83/01%20%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%B7%A5%E5%85%B7/gsql [5] GBase 8c 教程十五表空间 https://www.gbase.cn/community/post/1821
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2475629.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!