ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

KeyarchOS集成pgtune:PostgreSQL自动调优实践指南

KeyarchOS集成pgtune:PostgreSQL自动调优实践指南 浪潮KeyarchOSKOS把pgtune-0.9.3-12塞进系统仓库这件事表面看只是多了一个软件包但对整天跟PostgreSQL打交道的人来说等于把“手工调参”这件又脏又累的活直接砍掉了一大半。pgtune是一个专门为PostgreSQL生成优化配置的小工具它根据你的CPU核数、内存大小、磁盘类型和负载场景批量算出一整套合理的postgresql.conf参数你不用再逐个参数去查文档、试错。而KeyarchOS以rpm包形式完成适配后最直接的受益者就是运维和DBA一条命令装完再跑一次pgtune就能把一台默认配置的PostgreSQL拉到“基本够用且不容易出事”的状态。这篇文章我就从为什么需要这种自动化调优讲起把pgtune的原理、KeyarchOS上的完整实操流程、以及我踩过的那些坑全部梳理一遍适合刚接触PostgreSQL调优的新手也适合想把手动流程固化成标准操作的老手。1. 为什么说pgtune适配是一件值得关注的事1.1 手工调参的现状与痛点先说说手工调参有多痛苦。我之前给一台64GB内存的服务器调PostgreSQL默认配置下shared_buffers只有128MBeffective_cache_size只有512MB。拿这种参数去跑业务等于开着一台2.0T的车却一直挂在一挡。问题是你明知道参数不合理但真要动手改的时候面对的是一份几百行的postgresql.conf里面几十个参数都有讲究哪些改了要重启、哪些reload就生效、work_mem设大了并发一高直接OOM、shared_buffers设大了内核shmmax不够连启动都起不来。更麻烦的是参数之间的联动关系。max_connections设成100work_mem设成64MB理论上每个连接最多能吃掉64MB排序内存100个连接就是6.4GB这还没算shared_buffers和maintenance_work_mem。如果你不把这些数值放在一起通盘考虑只是单点去调很容易调出一个“看起来合理、跑起来崩溃”的配置。这也是为什么很多刚接触PG的人照着网上的教程抄了一堆参数结果服务器反而变慢或者进程直接被OOM Killer干掉。1.2 系统适配带来的实际价值KeyarchOS这次把pgtune-0.9.3-12做成rpm包放进仓库价值不在于“多了一个软件”而在于它把获取工具的门槛降到了最低。以前你要用pgtune要么跑pip install pgtune要么去GitHub拉源码自己编译。pip装倒还好但如果你所在的服务器环境是离线内网或者Python版本比较老装个工具能折腾半小时。rpm包的方式就简单多了dnf install pgtune依赖一并处理好版本号可追溯卸载也干净这对生产环境来说太重要了。另外适配本身也是一种信号说明这个操作系统的软件生态在认真对待数据库场景。KOS本身是兼容CentOS生态的企业级Linux很多CentOS上能跑的包它都能跑但像pgtune这种相对小众的工具能被官方仓库收进去至少说明他们在做数据库调优场景的验证而不是只把系统做出来就完事。对于在KOS上跑PostgreSQL的团队来说这意味着“开箱即用”又往前推进了一步。2. pgtune是怎么“算”出一组优化参数的2.1 pgtune的核心逻辑基于硬件估算的配方生成器pgtune本质上不是一个“智能诊断工具”它是一个“基于硬件估算的配方生成器”。它做的事情很简单先获取你的CPU核数和内存大小也可以手动指定再根据你选择的负载类型——web/oltp、dw/olap、desktop、mixed——套用一套经验公式把postgresql.conf里的关键参数批量算出来最后输出一份新的建议配置。举例来说假设一台服务器有8核CPU、32GB内存、跑的是OLTP业务。pgtune会先把总内存按一定比例划给PostgreSQL使用比如OLTP类型大约拿出25%也就是8GB作为数据库专用内存然后在这个基数上分配shared_buffers取这8GB的25%也就是2GBeffective_cache_size取这8GB的75%也就是6GBwork_mem再根据max_connections倒推确保最坏情况下并发连接全开也不会把内存吃光。整个过程大概几秒钟出来的是一份完整的建议配置。这套公式不是拍脑袋想出来的它是PG社区多年实践下来形成的经验值。比如shared_buffers设为总内存的25%左右是PostgreSQL官方文档都认可的建议区间effective_cache_size设置得比实际内存略保守一些是为了让查询规划器在估算索引扫描成本时不至于过于乐观。pgtune把这些经验固化成代码你不需要懂背后的推导过程也能得到一个“大概率合理”的起点。2.2 关键参数的生成逻辑与数据库原理在pgtune生成的配置里最重要的几个参数我挨个说一下搞清楚它们的作用后面排查问题才有方向。第一个是shared_buffers它决定PostgreSQL共享缓冲区的大小也就是所有连接共享的那块内存缓存。太小的后果是热数据频繁走磁盘IO性能断崖式下跌太大的后果是启动时可能超过内核共享内存限制而且PG自身管理大缓冲区的效率会下降。默认配置里它只有128MB这在现代服务器上根本不现实pgtune按25%的比例给你拉上去是性价比最高的第一刀。第二个是effective_cache_size这个参数很有意思它不实际分配内存只是告诉查询规划器“操作系统文件缓存大概还有多少空间可用”。规划器根据这个值来判断走索引扫描划算还是走顺序扫描划算。设小了规划器会低估缓存命中率频繁选择顺序扫描设大了又会高估可能出现索引扫描反而更慢的情况。pgtune一般把它设在数据库专用内存的50%到75%之间留一点余量。第三个是work_mem它是每个排序、哈希操作能使用的内存上限。这个参数最阴险因为它不是按连接数一次性预分配而是按需分配的但一旦并发排序多了实际内存占用会成倍放大。pgtune的计算逻辑是拿数据库专用内存减去shared_buffers再除以max_connections乘以某个系数保证极端情况下所有连接同时排序也不至于把内存打爆。实际使用中我还会再手动调低一点因为服务器上往往还跑着监控、备份等杂七杂八的进程。第四个是maintenance_work_mem它负责VACUUM、CREATE INDEX、外键约束这些维护操作的内存上限比work_mem宽松很多一般给到1GB到2GB就够了。调大它能明显加快大表的索引创建但注意它也是在维护操作时按需分配的多个维护任务并发时同样会叠加内存占用。2.3 pgtune的适用边界pgtune绝不是万能的它有很明显的适用边界。第一它不知道你的业务长什么样。同样的硬件配置一个是纯OLTP交易系统一个是跑复杂报表的OLAP系统参数侧重点完全不同pgtune只能按照你选的负载类型给出一个通用模板。第二它不感知磁盘的真实型号和IO能力虽然在较新版本里可以手动指定SSD或HDD但它无法判断你的RAID卡策略、磁盘队列深度这些更底层的因素。第三它给的是“起点”而不是“终点”一键生成之后你仍然需要结合业务压测和监控数据进行二次微调。理解了这个边界你就能想明白一件事pgtune的价值在于把“从默认配置到合理配置”这一段路自动走完消除掉那些低级错误但它不会替你做性能调优的高级部分那是pgbench压测、慢查询日志分析、执行计划解读这些工作才能解决的问题。3. 环境准备在KeyarchOS上把PostgreSQL跑起来3.1 查看硬件与系统信息在动手之前先把服务器的底细摸清楚。这步虽然简单但很多人跳过之后后边生成的参数就完全不对了。打开终端依次执行下面几条命令查看关键信息# 查看系统版本确认KOS版本号和架构 cat /etc/os-release # 查看CPU核数注意看逻辑核而不是物理核 nproc # 查看内存总量单位是MB free -m # 查看磁盘类型确认是SSD还是HDD lsblk -d -o name,rota这里有个容易犯的错nproc输出的是逻辑CPU核数如果你的机器开了超线程物理核可能要除以2但pgtune这里用逻辑核数问题不大因为PostgreSQL的并行度配置通常也基于逻辑核。lsblk那一步很关键rota字段如果为1表示机械盘为0表示SSDpgtune生成配置时如果你指定了硬盘类型它会额外优化与随机IO相关的参数。另外如果这台服务器上还跑着其他应用内存不能按总容量算你得预留一部分给别的进程我个人习惯是把free -m里available的值再打八折宁可保守一点也不要让数据库把整台机器吃满。3.2 安装并初始化PostgreSQL在KeyarchOS上装PostgreSQL路径有两条。一条是直接用系统自带的软件源装的是跟KOS版本配套的PostgreSQL版本另一条是配置PGDG官方源装最新版本比如现在很多新项目直接用PG16甚至PG17。如果你是生产环境我的建议是优先用系统源里经过测试的版本稳定性优先如果你需要用到新版本才有的特性再走PGDG源。系统源的方式很简单# 安装服务端和客户端 dnf install -y postgresql-server postgresql # 初始化数据库 postgresql-setup --initdb # 启动并设置开机自启 systemctl enable --now postgresql初始化这一步很多人漏掉结果systemctl start postgresql直接失败日志里报“data directory /var/lib/pgsql/data does not exist”。用PGDG源的话安装完多一步dnf install postgresql-server会自带初始化脚本但还是建议手动跑一遍postgresql-setup确认无误。装好之后先别急着调优确认服务能正常启动、能用psql连上后面pgtune生成配置才有意义。3.3 安装pgtune并确认版本重点来了这就是KeyarchOS适配之后体验最顺滑的地方。在KOS上你不需要去pip或者GitHub折腾直接# 从KOS仓库安装pgtune dnf install -y pgtune # 确认安装版本 pgtune --version # 查看帮助确认支持的选项 pgtune --help如果dnf提示找不到包大概率是软件源没有刷新或者某些repo处于禁用状态先执行dnf makecache再检查/etc/yum.repos.d/下KOS相关的源是否enable1。装完之后pgtune --version如果输出0.9.3就跟标题里的版本对上了。注意有些平台会显示带release的版本号比如0.9.3-12这个-12是rpm打包的release次数不是pgtune本身的不同版本功能上没有区别。4. 一键优化实操生成、应用与验证4.1 生成优化配置安装完成之后真正的一键优化分为两步先让pgtune根据你的硬件生成建议配置再把建议配置落到PostgreSQL里。先说生成。最简单的方式是让pgtune自动探测硬件并读取现有的postgresql.conf# 基于当前系统配置生成优化后的配置文件 pgtune -i /var/lib/pgsql/data/postgresql.conf -o /tmp/pgtune.conf如果你对系统探测的硬件信息不放心或者想为特定场景做模拟可以手动指定参数。比如我要给一台16核64GB内存、跑OLTP业务的服务器生成配置pgtune --typeoltp --cpus16 --memory49152 -o /tmp/pgtune.conf注意这里memory我写的是49152MB也就是48GB而不是64GB这就是前面说的“预留内存给系统和其他进程”。pgtune支持的负载类型有web、oltp、dw、desktop、mixed几种oltp适合高并发短事务场景dw适合数据仓库类分析型负载。选错类型会直接影响shared_buffers等参数的比例所以这一步别偷懒先想清楚你的业务到底是读多还是写多、事务长还是短。生成完之后强烈建议先看一下pgtune.conf里都改了什么别直接一把梭覆盖上去。我常用的命令是diff /var/lib/pgsql/data/postgresql.conf /tmp/pgtune.conf你会看到它帮你调了大约二十个参数除了前面提到的shared_buffers、effective_cache_size、work_mem、maintenance_work_mem还有wal_buffers、max_wal_size、min_wal_size、checkpoint_completion_target、default_statistics_target等等。这些参数联动在一起才是完整的调优方案这也是为什么我从来不建议只改三五个“热门参数”。4.2 应用配置的三种方式配置文件生成好了接下来是怎么应用。这里有三条路各有适用场景我一条一条说清楚。方式一直接替换配置文件最彻底但最危险。先备份原文件再把pgtune.conf复制成postgresql.conf最后重启PostgreSQL。具体命令cp /var/lib/pgsql/data/postgresql.conf /var/lib/pgsql/data/postgresql.conf.bak cp /tmp/pgtune.conf /var/lib/pgsql/data/postgresql.conf systemctl restart postgresql这种方式适合你明确知道pgtune生成的就是最终想要的配置比如刚从默认配置调到目标配置中间没有自定义过其他参数。方式二使用ALTER SYSTEM精准可控我推荐这种方式。PostgreSQL从9.5开始支持ALTER SYSTEM SET它会把设置写入postgresql.auto.conf这个文件的优先级高于postgresql.conf而且不会覆盖你原有的配置。比如sudo -u postgres psql -c ALTER SYSTEM SET shared_buffers 2GB; sudo -u postgres psql -c ALTER SYSTEM SET effective_cache_size 6GB;注意有些参数需要重启才能生效比如shared_buffers、max_connections有些参数只要reload就行比如work_mem、effective_cache_size。判断方式是查pg_settings视图的context字段我后边会讲到。方式三直接在线改并reload适合那些可以热更新的参数。比如ALTER SYSTEM SET work_mem 64MB; SELECT pg_reload_conf();实际工作中我最常用的组合是把所有需要改的参数写进一个SQL脚本然后以postgres用户执行最后统一pg_reload_conf或重启。这样操作有记录、可回滚比手动改配置文件强得多。4.3 调优前后的对比验证配置生效之后别急着说“优化完成”先验证再收工。验证分三个层面参数是否生效、性能是否提升、系统是否稳定。参数是否生效直接查视图SELECT name, setting, unit, context FROM pg_settings WHERE name IN (shared_buffers, effective_cache_size, work_mem, maintenance_work_mem, max_connections);注意看context这一列如果显示postmaster说明必须重启才生效显示user则表示会话级可调、reload就生效。执行完这句如果发现某些参数还是旧值不用怀疑你就是没重启或者没reload。性能验证我用pgbench压测这是PG自带的工具不用额外装# 先初始化100万行左右的测试数据 sudo -u postgres pgbench -i -s 10 postgres # 用16个客户端、4个线程跑60秒输出详细报告 sudo -u postgres pgbench -c 16 -j 4 -T 60 -r postgres调优前后各跑一轮对比tps和平均延迟。我见过最典型的案例是默认配置下tps只有三千多shared_buffers从128MB调到2GB之后直接翻倍。但也有反过来的情况某些读多写少的场景effective_cache_size没调大的时候反而总走顺序扫描调大之后查询计划变了性能提升特别明显。系统稳定性方面注意观察两点一是free -m看可用内存有没有被吃空二是dmesg或journalctl看有没有OOM Killer的记录。如果出现OOM优先怀疑work_mem是不是设大了并发连接一多排序内存叠加起来就是灾难。5. 常见问题与排查技巧5.1 安装与环境问题我把实际操作中遇到的高频问题整理成一张速查表按出现频率排序问题现象排查思路与解决dnf找不到pgtune包提示No package pgtune available先dnf makecache刷新源再检查/etc/yum.repos.d/下KOS相关repo的enabled状态镜像源失效是最常见原因pgtune命令不存在dnf install显示已安装但执行pgtune报command not foundrpm -ql pgtune查看实际安装路径部分发行版会把可执行文件放在/usr/libexec下需要加路径调用pip安装方式报编译错误提示缺少python3-devel或gcc内网环境下先dnf install -y python3-devel gcc gcc-c再重试能走rpm就走rpm不建议在KOS上用pip方式PostgreSQL启动失败日志提示data directory不存在典型是漏了postgresql-setup --initdb初始化完成后再systemctl start这里特别提醒一句如果你是在内网离线环境部署KOSdnf没法在线拉包那就得提前把pgtune的rpm包下载好连同依赖一起拷进去。rpm包方式的优势这时候就体现出来了——它的依赖只有python3和一些基础库比编译安装省心太多。5.2 调优后启动失败与性能反降这个坑几乎每个人都会踩一次。调优完成、重启PostgreSQL结果服务起不来journalctl -u postgresql一看报错信息是“could not resize shared memory segment”或者“invalid value for parameter”。前者百分之百是shared_buffers设超过了内核shmmax限制。解决办法有两个方向。一是调内核参数打开/etc/sysctl.conf设置kernel.shmmax 68719476736 kernel.shmall 16777216然后sysctl -p生效。这里kernel.shmmax的单位是字节68719476736对应64GBshmall对应的是内存页数量16MB个页乘以默认4KB页大小也是64GB。另一个方向是调低shared_buffers别贪心不是内存多就一定要给25%如果你的机器同时跑着其他应用给到总内存的15%到20%更稳妥。还有一种情况是启动成功了但性能反而比之前更差。这时候先别慌回头检查一下work_mem是不是给的太高。work_mem太高会导致PostgreSQL倾向于生成内存排序的查询计划一旦并发上来了大量进程同时做内存排序内存很快耗尽系统开始疯狂使用swap那性能肯定断崖式下跌。遇到这种情况把work_mem从64MB调回32MB甚至16MB重新压测对比。5.3 参数生效的细节最后一个特别重要的细节就是搞清楚哪些参数要重启、哪些reload就生效。我见过太多人改了配置不重启然后跑过来问我“为什么优化没效果”。判断标准很简单查pg_settings视图的context列context为postmaster的参数比如shared_buffers、max_connections、max_prepared_transactions必须重启数据库进程才能生效context为sighup的参数比如work_mem、effective_cache_size、maintenance_work_mem执行pg_reload_conf()或者systemctl reload postgresql就能生效context为superuser或user的参数比如单个会话内的排序内存可以直接用SET命令在线调整。这里我个人的习惯是所有参数统一在维护窗口里一次性应用。即使某个参数支持热加载我也不会单独reload而是把一批参数改完、保存好重启一次数据库让全部参数进入预期状态。重启成本不高但参数状态是确定的排查问题的时候不用猜“到底哪个生效了哪个没生效”。另外再补一个小技巧改完参数之后用下面这条SQL把当前生效值导出来留档COPY (SELECT name, setting, unit FROM pg_settings WHERE source configuration file) TO /tmp/pg_settings_after_tuning.csv WITH (FORMAT csv, HEADER true);以后性能出问题对比这份文件和调优前的记录马上能看出是哪个参数被改动影响了。结尾我实际用pgtune走了这么几轮之后最大的体会是它最大的价值不是帮你省了敲命令的时间而是帮你规避了一大批“低水平的坑”。默认配置直接上生产、瞎改work_mem导致OOM、调大了shared_buffers忘记检查内核参数这些我都踩过。有了pgtune等于用社区沉淀的经验值帮你兜住了底线。但我还是要强调那句老话它给的是起点不是终点。每次跑完pgtune我都会再拿pgbench压一轮结合业务侧的慢查询日志在它给的基数上微调work_mem、max_connections这些和并发强相关的参数。如果你也在KOS上跑PostgreSQL建议先把这条链路跑通默认配置那套真的可以扔掉了。
返回列表