一、Arch Linux部署数据库前的系统参数优化基础准备

在Arch Linux上部署数据库服务,尤其是像PostgreSQL这类需要大量资源的场景,很多人会发现默认参数跑起来性能总差点意思——要么交换分区占比太高,要么磁盘IO跟瓶颈似的拖慢整个服务。这时候就得从系统层面调几个关键参数,不用换硬件,就能明显提性能。这个优化特别适合中小团队用PostgreSQL做电商订单库、用户库这类核心业务数据库的场景,这些库要处理大量读写,内存占比高,调对参数后瓶颈会少很多。它的优点是成本低、见效快,不需要额外买服务器;但缺点是如果调得太狠,容易出问题,比如系统杀进程、数据库连不上,所以得一步步来,不能一次性全改。

二、内存相关参数优化

2.1 交换分区阈值调整

交换分区是系统把硬盘当临时内存用的地方,速度比物理内存慢几十倍,数据库能不用就不用,所以得降低交换的触发阈值。Arch默认的交换阈值是60,也就是当内存用了60%才会用交换,我们改成10,让系统尽量先用物理内存。这里给完整的操作示例,分临时生效(测试用)和永久生效(生产用):

# 临时调整,当前会话生效,不用重启
sysctl -w vm.swappiness=10
# 永久生效,修改Arch的sysctl配置文件,路径是/etc/sysctl.d/99-db.conf(如果文件不存在就新建)
echo "vm.swappiness = 10" >> /etc/sysctl.d/99-db.conf
# 永久生效的话,还要让系统加载配置,不用重启,执行:
sysctl -p /etc/sysctl.d/99-db.conf

这里注意,不能把swappiness设成0,万一物理内存不够,系统会直接OOM杀进程,设10是安全又能减少交换的数值。

2.2 大页内存配置

大页内存的作用是减少CPU找内存地址时的绕路,提升内存访问速度,对数据库这类高频访问内存的服务特别有用。这里的示例是给16G总内存的服务器配4G大页内存,刚好给PostgreSQL用:

# 先检查当前系统的大页数量,看到底还有多少空闲
grep HugePages_Total /proc/meminfo
# 设置要分配的大页数量,每大页默认是2M,4G就是2048个(4*1024/2=2048)
echo "vm.nr_hugepages = 2048" >> /etc/sysctl.d/99-db.conf
# 还要让PostgreSQL启用大页,修改它的配置文件,路径是/var/lib/postgres/data/postgresql.conf(注意Arch的PostgreSQL数据路径是这个,别搞错)
echo "huge_pages = on" >> /var/lib/postgres/data/postgresql.conf
# 改完重启PostgreSQL生效,或者用systemctl restart postgresql

这个优化的优点是内存访问速度提升10%以上,缺点是如果设太多大页,剩下的内存会不够其他进程用,所以要根据实际内存算,比如8G内存就设1024个大页,留4G给系统用。

三、IO调度参数优化

3.1 NVMe SSD的IO调度器调整

Arch默认的IO调度器是mq-deadline,但用NVMe SSD的话,用none调度器更好,因为NVMe是直接跟CPU通信的,不需要复杂的调度,减少额外开销。这里的示例是针对/dev/nvme0n1这个NVMe盘的调整:

# 先查看当前盘用的调度器,确认是哪个盘(用lsblk看自己的盘)
cat /sys/block/nvme0n1/queue/scheduler
# 临时设为none,测试用
echo none > /sys/block/nvme0n1/queue/scheduler
# 永久生效,用udev规则,这样重启也不会变,创建文件/etc/udev/rules.d/60-ioscheduler.rules,写入规则:
echo 'ACTION=="add|change", KERNEL=="nvme0n1", ATTR{queue/scheduler}="none"' >> /etc/udev/rules.d/60-ioscheduler.rules
# 重载udev规则生效
udevadm control --reload-rules && udevadm trigger

这个调整适合数据库用NVMe的场景,因为数据库的读写都是小IO密集型,none调度器能减少延迟;如果是机械盘,就用mq-deadline,别瞎改。

3.2 IO队列深度调整

IO队列深度是盘处理请求的能力,NVMe盘默认的队列深度比较小,改成2048刚好,能处理更多并发请求。示例:

# 查看当前队列深度
cat /sys/block/nvme0n1/queue/nr_requests
# 临时调整到2048
echo 2048 > /sys/block/nvme0n1/queue/nr_requests
# 永久生效,刚才的udev规则里加一行,修改后的规则:
echo 'ACTION=="add|change", KERNEL=="nvme0n1", ATTR{queue/scheduler}="none", ATTR{queue/nr_requests}="2048"' >> /etc/udev/rules.d/60-ioscheduler.rules
# 重载规则生效
udevadm control --reload-rules && udevadm trigger

注意,这个值不能设太大,否则会占太多内核内存,2048对于NVMe来说是最优值。

四、文件系统参数优化

Arch常用的文件系统是ext4或xfs,推荐用xfs给数据库,因为xfs的性能更好,适合大文件。主要改挂载选项,去掉不必要的日志更新,减少IO:

# 先看数据库数据盘的挂载情况,比如数据盘是/data/db,用mount命令找对应的UUID:
blkid | grep /data/db
# 修改/etc/fstab文件,原来的行大概是UUID=xxxx /data/db xfs defaults 0 0,改成:
UUID=xxxx /data/db xfs noatime,nodiratime,barrier=0 0 0
# 改完生效,不用重启,执行:
mount -o remount /data/db

这里的noatime是关闭文件访问时间的更新,nodiratime是关闭目录访问时间的更新,barrier=0是关闭xfs的日志 barrier,减少写操作的开销;注意barrier=0如果断电可能丢数据,所以如果数据库有冗余备份的话用,没有的话用barrier=1。

五、进程文件数限制优化

数据库连接多的时候,每个连接会打开多个文件,默认的文件数限制太小,会报“too many open files”的错误,所以要放开限制。Arch用systemd管理进程,要改两个地方:

# 第一个地方,修改limits.conf,路径是/etc/security/limits.d/99-db.conf,给postgres用户加限制:
postgres soft nofile 65536
postgres hard nofile 65536
postgres soft nproc 65536
postgres hard nproc 65536
# 第二个地方,systemd的PostgreSQL服务配置,Arch的服务文件路径是/etc/systemd/system/postgresql.service.d/override.conf(如果没有就新建),加:
[Service]
LimitNOFILE=65536
# 改完要重载systemd配置,生效:
systemctl daemon-reload
# 重启PostgreSQL生效:
systemctl restart postgresql

这个优化适合有大量并发连接的数据库,比如同时有几百个用户连数据库的场景,不会再报文件数不够的错。

六、调优后的验证与避坑指南

调完参数后要验证有没有效果,比如用vmstat看swap列,si和so都要是0,说明没用到交换;用iostat看%util,磁盘使用率不能一直100%;还要看PostgreSQL的后台写进程pg_stat_bgwriter,检查写操作是不是正常,有没有太多的临时写。避坑的话,不要一次性改所有参数,先改swap和大页,测一周没问题再改其他;如果改完后数据库连不上,先回滚最近改的参数,比如把swappiness改回60,再排查问题。这个调优的优点是能稳定提升性能15-30%,缺点是需要定期监控,因为服务器的内存、磁盘会变,参数也要跟着调。

七、总结

Arch Linux上部署数据库的系统参数优化,核心就是围绕减少交换、优化内存访问、降低IO开销、放开进程限制这几个点,不用复杂操作,只要按步骤调,就能明显提升数据库的性能,适合中小团队的业务场景。不管是PostgreSQL还是其他数据库,这套优化思路都通用,只是参数调整的数值可能根据硬件和业务略有不同,关键是要根据实际情况调整,不能照搬别人的数值。