PostgreSQL系统参数设置
配置文件是数据库目录下的postgresql.conf文件,8.0以后的版本可支持K,M,G这样的参数,只要修改相应参数后重新启动PG服务就OK了。
shared_buffers:这是最重要的参数,postgresql通过shared_buffers和内核和磁盘打交道,因此应该尽量大,让更多的数据缓存在shared_buffers中。通常设置为实际RAM的10%是合理的,比如50000(400M)。将所有的内存都给shared_buffers 将导致没有内存来运行程序。 unix 管理内存使用 swap,当没有内存可用的时候,内核会将长时间不用的内存挪到 swap 去,这个叫:swappageout,当你再次使用它的时候内核又会将其挪回来,这个叫:swappagein,这个操作有很大的不好,因为它会导致你的程序挂起直到操作完成。
正确的 Shared Buffer Cache大小:
(1) 它应该足够大来应付通常的表访问操作。
(2) 它应该足够小来避免 swap pagein的发生。
work_mem: 在pgsql8.0之前叫做sort_mem。postgresql在执行排序操作时,会根据work_mem的大小决定是否将一个大的结果集拆分为几个小的和work_mem查不多大小的临时文件。显然拆分的结果是降低了排序的速度。因此增加work_mem有助于提高排序的速度。通常设置为实际RAM的2%-4%,根据需要排序结果集的大小而定,比如81920(80M)。
cache size 和 sort size都影响内存的使用。记住, cache size 是在postmaster 启动的时候就申请好的,sort size的改变是依赖于执行多少个排序。通常,cache size 比 sort size 更有效果。一开始调整,如果你只有一些大的session而有更多的小session: 10% of RAM for cache size 2-4% ofRAM for sort size 还有一个很有价值的参数:effective_cache_size。优化器用这个参数来预估内核的硬盘 buffer cache. 当内核有 unifiedbuffer cache (统一缓冲),这个值将是没被使用的内存的平均值,因为这种内核会使用所有没有使用的内存来作最近硬盘访问的缓存的;当内核用 fixed-sizeddisk buffer cache 时,这个参数应该设成一样的,通常是内存的 10%.
effective_cache_size:是postgresql能够使用的最大缓存,这个数字对于独立的pgsql服务器而言应该足够大,比如4G的内存,可以设置为3.5G(437500)
maintence_work_mem:这里定义的内存只是在CREATEINDEX,VACUUM等时用到,因此用到的频率不高,但是往往这些指令消耗比较多的资源,因此应该尽快让这些指令快速执行完毕:给maintence_work_mem大的内存,比如512M(524288)
max_connections:通常,max_connections的目的是防止max_connections *work_mem超出了实际内存大小。比如,如果将work_mem设置为实际内存的2%大小,则在极端情况下,如果有50个查询都有排序要求,而且都使用2%的内存,则会导致swap的产生,系统性能就会大大降低。当然,如果有4G的内存,同时出现50个如此大的查询的几率应该是很小的。不过,要清楚max_connections和work_mem的关系。
maintenance_work_mem(integer):声明在维护性操作中使用的最大的内存数,比如 VACUUM, CREATE INDEX,和ALTER TABLE ADD FOREIGN KEY 等。 数值是用千字节计的,缺省是 16384 千字节(16MB)。因为在一个数据库会话里,任意时刻只有一个这样的操作可以执行,并且一个数据库安装通常不会有太多这样的工作并发执行,把这个数值设置得比work_mem 更大是安全的。 更大的设置可以改进清理和恢复数据库转储的速度。
max_stack_depth(integer):声明服务器的执行堆栈的最大安全深度。为此设置一个参数的原因是内核强制的实际堆栈尺寸(就是ulimit -s或者局部等效物的设置),小于一个安全的一兆字节左右的范围。需要这么一个安全的界限是因为在服务器里,并非所有过程都检查了堆栈深度,儿只是在可能递规的过程,比如表达式计算这样的过程里面进行检查。把这个参数设置得大于实际的内核限制讲意味着一个正在跑的递归函数可能会导致一个独立服务器进程的崩溃。缺省设置是2048 KB (两兆),这个值相对比较小,不容易导致崩溃。 但是,这个值可能太小了,以至于无法执行复杂的函数。
自由空间映射max_fsm_pages(integer):设置在共享的自由空间映射表里自由空间会跟踪的最大数目的磁盘页面数。每个页面槽位需要消耗六个字节的共享内存。这个设置必须大于16 * max_fsm_relations。 缺省是 20000。这个选项只能在服务器启动的时候设置。
max_fsm_relations(integer):设置自由空间将在共享地自由空间映射里跟踪的最大数目的关系(表和索引)。每个槽位大概要使用五十字节左右。缺省是1000。这个选项只能在服务器启动的时候设置。
内核资源使用max_files_per_process(integer):设置每个服务器进程允许同时打开的最大的文件数目。缺省是1000。如果内核强制一个合理的每进程限制,那么你不用操心这个设置。但是在一些平台上(特别指出的是,大多数 BSD 系统),sysconf 返回一个系统真正可以支持的数目大的多的数值。如果你发现有 "Too many open files"这样的失败现象,那么就尝试缩小这个设置。这个选项只能在服务器启动时设置。
preload_libraries(string):这个变量声明一个或者多个在服务器启动的时候预先装载的共享库。可以选择在装载每个库的时候调用一个无参数的初始化函数。要声明这个函数,可以在库名字后面加一个冒号,然后增加一个初始化函数名字。比如'$libdir/mylib:mylib_init' 会预先装载 mylib 并且执行mylib_init。如果装载了多过一个库,用逗号分隔它们。如果没有找到声明的库或者没有找到初始化函数,那么服务器将启动失败。可以用这个方法预先装载PostgreSQL 的过程语言库, 通常是使用 '$libdir/plXXX:plXXX_init' 语法,这里的 XXX 是pgsql,perl,tcl,或者 python。
通过预先装载一个共享库(以及在需要的时候初始化它),我们就可以避免第一次使用这个库的那些启动时间。不过,启动每个服务器进程的时间可能会增加,即使进程从来没有使用过这些库也这样。因此我们只是建议对那些将被大多数会话使用的库才使用这个选项。
基于开销的清理延迟:在 VACUUM 和 ANALYZE命令执行过程中, 系统维护一个内部的指针,这个指针跟踪所执行的各种 I/O 操作的近似开销。 如果积累的开销达到了一个限制(通过vacuum_cost_limit 声明),那么执行这个操作的进程将睡眠一会儿(用 vacuum_cost_delay 声明)。然后它会重置指针然后继续执行。
这个特性的目的时允许管理员减少这些命令在并发活动的数据库上的 I/O影响。 有些情况下,像 VACUUM 和 ANALYZE这样的维护命令并不需要迅速完成;但是,通常都不希望这些命令会严重干扰系统执行其它数据库操作的响应能力。基于开销的清理延迟为管理员提供了一个实现这个目的的手段。
缺省的时候,这个特性是关闭的。要想打开它,把vacuum_cost_delay 变量设置为一个非零值。
vacuum_cost_delay(integer):以毫秒计的时间长度,如果超过了开销限制,那么进程将睡眠一会儿。缺省值是0,它关闭基于开销的清理延迟特性。正数值打开基于开销的清理。 不过,要注意在许多系统上,sleep 延迟的有效分辨率是 10 毫秒;把vacuum_cost_delay 设置为一个不是 10 的整数倍的数值与将它设置为下一个 10的整数倍作用相同。
vacuum_cost_page_hit(integer):清理一个在共享缓存里找到的缓冲区的开销。它代表锁住缓冲池,查找共享的散列表以及扫描页面的内容的开销。缺省值是1。
vacuum_cost_page_miss(integer):清理一个要从磁盘上读取的缓冲区的估计开销。这个行为代表锁住缓冲池,查找共享散列表,从磁盘读取需要的数据块以及扫描它的内容的开销。缺省值是10。
vacuum_cost_page_dirty(integer):如果清理修改一个原先是干净的块的预计开销。它需要一个把脏的磁盘块再次冲刷到磁盘上的额外开销。缺省值是20。
vacuum_cost_limit(integer):导致清理进程休眠的积累开销。缺省是 200。
注意:有些操作会持有关键的锁,并且应该尽快结束。在这样的操作过程中,基于开销的清理延迟不会发生作用。为了避免在这种情况下的长延时,实际的延迟是这样计算的:vacuum_cost_delay * accumulated_balance / vacuum_cost_limit 与vacuum_cost_delay * 4 之间的最大值。
后端写进程
从 PostgreSQL 8.0开始,就有一个独立的服务器进程,叫做后端写进程,它唯一的功能就是发出写"脏"共享缓冲区的命令。这么做的目的是让持有用户查询的服务器进程应该很少或者几乎不等待写动作的发生,因为后端写进程会做这件事情。这样的安排同样也减少了检查点造成的性能下降。后端写进程将持续的把脏页面刷新到磁盘上,所以再检查点到来的时候,只有几个页面需要刷新到磁盘上。但是这样还是增加了I/O的总净负荷,因为以前的检查点间隔里,一个重复弄脏的页面可能只会冲刷一次,而同一个间隔里,后端写进程可能会写好几次。在大多数情况下,连续的低负荷要比周期性的尖峰负荷好,但是在本节讨论的参数可以用于为本地需要调节其行为。
bgwriter_delay(integer):声明后端写进程活跃回合之间的延迟。在每个回合里,写进程都会为一些脏的缓冲区发出写操作(可以用下面的参数控制)。选取的缓冲区总是那些在当前的脏缓冲区里当前最少使用的。然后它就休眠bgwriter_delay 毫秒,然后重复动作。缺省值是 200。 请注意在许多系统上,休眠延时的有效分辨率是 10毫秒;因此,设置 bgwriter_delay 为一个不是 10 的倍数的数值与把它设置为下一个 10的倍数是一样的效果。这个选项只能在服务器启动的时候或者 postgresql.conf 文件里设置。
bgwriter_percent(integer):在每个回合里,当前的脏缓冲区中不超过这个百分比的量将被写到磁盘上(把小数圆整为下一个整数缓冲区的数值)。这个选项只能在服务器启动的时候或者postgresql.conf 文件里设置。
bgwriter_maxpages(integer):在每个回合里,不超过这个数值的脏缓冲区写入。缺省值是 100。这个选项只能在服务器启动的时候或者postgresql.conf 文件里设置。
小的 bgwriter_percent 和bgwriter_maxpages 减少后端写进程导致的额外 I/O负荷,但是会导致在检查点的时候的更多工作。要降低检查点时的峰值负荷,增加这些值。要想完全关闭后台写进程,可以把bgwriter_percent 和/或 bgwriter_maxpages 设置为零。
有三个主要方面可以提升PostgreSQL的潜能。
查询方式的变化
这主要涉及修改查询方式以获取更好的性能:
创建索引,包括表达式和部分索引;
使用COPY语句代替多个Insert语句;
将多个SQL语句组成一个事务以减少提交事务的开销;
从一个索引中提取多条记录时使用CLUSTER;
从一个查询结果中取出部分记录时使用LIMIT;
postgresql优化与维护
1. 硬件
数据库最重要的就是 I/O了。所以一切从I/O开始。
RAID: 这个基本不用说,数据库放RAID10上面,只读的备份数据库可以放RAID0,反正挂了没关系。谨记:数据库是RandomRead
RAID卡的选择:
RAID卡一定要带电池的才可以(BBU)有电源的才能做到东西写进 CACHE,RAID就返回硬盘写成功(不用等)
1. Areca
2. LSI (真正的LSI,re-brand不要)
3. HP P400 以上系列
硬盘选择:
首选是SAS: 15K RPM 每个SAS大约能提供25MB/s的RandomWrite。也就是说在RAID10的设定下,如果需要50MB/s的Random Write就需要4个硬盘
节俭选择是: SATA可以多用几个硬盘(SAS一倍数量)达到在RAID10中接近SAS的速度。就算SATA买SAS一倍的数量,价格仍然比SAS便宜。
也可以买 产品: 例如 Compaq的 MSA 70 (P800 Battery backed RAID control)
CPU:64位
Cache:越大越好 (现在个人电脑都3M的cache了)
CORE:越多 越好 (postgresql毕竟是跑cpu的)建议最少4个core
RAM: 最少4G。通常根据具体需求,用16-64G的RAM
2. OS (系统)
可用系统:
1. Debian Stable
2. CentOS
3. Ubuntu LTS
4. Red Hat
5. SUSE Enterprise
如果准备付费(服务),那么就是 Canonical, Novell 跟 Redhat这三家选择而已
如果准备不买任何服务,可以用Debian, CentOS, Ubuntu LTS
这里还是觉得系统用Red Hat (不付费就CentOS)毕竟人家是企业级的老大哥,错不了。
* 现在CentOS也可以买到服务了。
不可用系统: 例如 fedora (redhat QA) ubuntu (non-LTS)
Scheduler:
Grub 增加: elevator=deadline
redhat 的图标可以看出,deadline是数据库的最佳选择
文件系统 (Filesystem)
这里的选择是:ext2,ext3 跟ext4。为什么只考虑这几个呢?因为数据库还是稳定第一,内核开发人员所做的文件系统,理论上说出问题的情况会少点。
WAL: 放ext2 因为WAL本身自己有Journal了,不需要用ext3 (ext2快很多)
data: ext3
Block Size: postgres自己是8k的block size。所以文件系统也用8k的 blocksize。这样才能最佳的提高系统的效能。
ext4:出来时间还 不够长,不考虑。
分区 (Partitioning)
Postgres 跟系统 OS 应该在不同分区
系统(OS):系统应该放独立的RAID1
数据库 (Postgres Data):数据库应该放独立的RAID10上。 如果RAID是带电池的,mount 的时候给data=writeback的选项
独立的数据库分区,就不许要记录文件时间了(都是放数据的)所以mount的时候要给noatime的选项,这样可以节约更新时间(timestamp)的I/O了。
WAL日志(xlogs): 独立的RAID1上 (EXT2 系统)日志是 Sequentialwrite,所以普通的硬盘(SATA)速度就足够了,没有必要浪费SAS在log上
Postgresql 日志(logs):直接丢给syslog就可以。最好在syslog.conf中设定单独的文件名.这里例如用local2来做postgresql
local2.* -/var/log/postgres/postgres.log
记得log要给Async,这样才不会等卡在log的I/O上, 同时记得设定logrotate以及创建路径(path)
ext2 VS ext3 性能测试:
HP DL585
4 Dual Core 8222 processors
64GB RAM
(2) MSA70 direct attached storage arrays.
25 spindles in each array (RAID 10)
HP P800 Controller
6 Disk in RAID 10 on embedded controller
xlog with ext3: avg = 87418.44 KB/sec
xlog with ext2: avg = 115375.34 KB/sec
3. Postgres 内存 (Memory Usage)
Shared Buffer Cache
Working Memory
Maintenance Memory
Shared Buffers
Postgres 启动时要到的固定内存。每个allocation是8k。Postgres不直接做硬盘读写,而是把硬盘中的东西放入Shared Buffers,然后更改SharedBuffers,在flush 到硬盘去。
通常 Shared Buffers设定为内存(available memory)的25%-40%左右。
在系统(OS)中,记得设置 kernel.shmmax的值(/etc/sysctl.conf)
kernel.shmmax决定了进程可调用的最大共享内存数量。简单的计 算方法是
kernel.shmmax=postgres shared_buffers + 32 MB
要保留足够的空间(不然会out of memory)postgresql除了sharedbuffer还会用到一些其他的内存,例如max_connections,max_locks_pre_transaction
Working Memory
这个是postgres运行作业中 (task)需要的内存,例如内存内的hashed (aggregates, hashjoins)sort (order by, distinct等等)合理的设定,可以保证postgres在做这些东西的时候可以完全在内存内完成,而不需要把数据吐回到硬盘上去作swap。但是设定太大的话,会造成postgres使用的内存大于实际机器的内存,这个时候就会去硬盘swap了。(效能下降)
working memory是per connection and persort的设定。所以设定一定要非常小心。举例来说,如果设定working memory为32MB,那么以下例子:
select * from lines, lineitems
where lines.lineid = lineitems.lineid
and lineid=6
order by baz;
这里就可 能用到64MB的内存。
hashjoin between lines and lineitems (32MB)
order by baz (32MB)
要注意自己有多少query是用到了order by或者join
如果同时有100个链接,那么就是 100 connection X 64MB = 6400MB (6G) 内存
通常来说,working mem不要给太大,2-4MB足够
在postgres 8.3之后的版本,working mem可以在query中设定
Query:
begin;
set work_mem to ‘128MB’;
select * from foo order by bar;
insert into foo values (‘bar’);
reset work_mem;
commit;
Function:
create function return_foo() returns setof text as
$ select * from foo order by bar; $
SET work_mem to ‘128MB’
LANGUAGE ’sql’
postgres官方不建议(但是支持)在 postgresql.conf文件中更改work_mem然后HUP(数据库应该没有任何中断)
利用 explain analyze可以检查是否有足够的work_mem
sort (cost=0.02..0.03 rows=1 width=0) (actualtime=2270.744..22588.341 rows=1000000 loops=1)
Sort Key: (generate_series(1, 1000000))
Sort Method: external merge Disk:13696kb
-> Result (cost=0.00..0.01 rows=1 width=0) (actualtime=0.006..144.720 rows=1000000 loops=1)
Total runtime: 3009.218 ms
(5 rows)
以上的 query分析显示,这里需要从硬盘走13MB的东西。所以这个query应给setwork_mem到16MB才能确保性能。
Maintenance Memory (维护内存)
maintenance_work_mem 决定系统作维护时可以调用的内存大小。
这个也是同样可以在query中随时设定。
这个内存只有在VACUUM, CREATE INDEX 以及 REINDEX等等系统维护指令的时候才会用到。系统维护是,调用硬盘swap会大大降低系统效能。通常maintenance_work_mem超过1G的时候并没有什么实际的效能增加(如果内存够,设定在1G足以)
Background Writer (bgwriter)
功能:
负责定时写 shared buffer cache 中的 dirty shared buffers
好处:
a. 减少系统flush shared buffers到硬盘(已经被bgwriter做了)
b. 在checkpoint中,不会看到I/O的突然性暴增,因为dirty buffers在背景中已经被flush进硬盘
坏处:
因为一直定时在背后flush disk,会看到平均硬盘I/O怎加(好过checkpoint时I/O暴增)
设定:
bgwriter_delay:
sleep between rounds。 default 200(根据机器,数据而调整)
bgwriter_lru_maxpages:
决 定每次bgwriter写多少数据。如果实际数据大于这里的设定,那么剩余数据将会被postgres的进程(serverprocess)来完成。serverporcess自己写的数据会造成一定的性能下降。如果想确定所有的数据都由bgwriter来写,可以设定这里的值为-1
bgwriter_lru_multiplier:
采 用计算的方式来决定多少数据应该被bgwriter来写。这里保持内置的2.0就可以。
计算bgwriter的I/O:
1000 / bgwriter_delay * bgwriter_lru_maxpages * 8192 = 实际I/O
(8192是 postgres的8k block)
例如:
1000/200 * 100 * 8192 = 4096000 = 4000 kb
bgwrater 可以用 pg_stat_bgwriter 来监测。如果想要观察bgwrater的运行状况,记得首先清理旧的stat信息。
bgwriter如果设定的太大(做太多事情)那么就会影响到前台的效能 (server)但是如果由系统(server)来做bufferflush同样会影响效能。所以这里的最好设定就是通过观察 pg_stat_bgwriter 来找到一个最佳的平衡点。
WAL (write ahead log)
postgres中的所有写动作都是首先写入WAL,然后才执行的。这样可以确保数据的准确跟完整。当中途数据库崩溃的时候,postgres可以通过WAL恢复到崩溃前的状况而不会出现数据错误等等问题。
WAL 会在两种情况下被回写硬盘。
1.commit。当commit数据的时候,WAL会被强制写回硬盘(flush)并且所有这个commit之前的东西如果在WAL中,也会一同被flush。
2. WAL writer进程自己会定时回写。
FSYNC vs ASYNC
postgres 的 default 是做fsync,也就是说postgres会等待数据被写入硬盘,才会给query返回成功的信号。如果设定sync=no关闭fsync的话,postgres不会等待WAL会写硬盘,就直接返回query成功。通常这个会带来15-25%的性能提升。
但是缺点就是,如果系统崩溃 (断电,postgres挂掉)的时候,你将有可能丢失最后那个transcation.不过这个并不会造成你系统的数据结构问题。(no datacorrupt)如果说在系统出问题的时候丢失1-2笔数据是可以接受的,那么25%的性能提升是很可观的。
WAL设定:
fsync 可以选择on或者off
wal_sync_method:
linux中是使用fdatasync。其他的。。。不知道,应该是看系统的文 件参数了
full_page_writes:
开启的时候,在checkpoint之后的第一次对page的更改,postgres会将每 个diskpage写入WAL。这样可以防止系统当机(断电)的时候,page刚好只有被写一半。打开这个选项可以保证pageimage的完整性。
关 闭的时候会有一定的性能增加。尤其使用带电池的 RAID卡的时候,危险更低。这个选项属于底风险换取性能的选项,可以关闭
wal_buffers:
WAL 的储存大小。default 是 64 kb。 实验证明, 设定这个值在 256 kb 到 1 MB之间会提升效能。
wal_writer_delay
WAL 检查WAL数据(回写)的间隔时间。值是毫秒(milliseconds)
Checkpoints
确保数据回写硬盘。dirty data page会被 flushed回硬盘。
checkpoint由以下3中条件激发(bgwriter如果设定,会帮忙在后台写入,所以就不会有checkpoint时候的短期高I/O出现)
1. 到达设定的WAL segments
2. 到达设定的timeout
3. 用户下达checkpoint指令
如果checkpoint运行频率高于checkpint_warning值。postgres会在日志(log)中记录出来,通过观察log,可以来决定checkpoint_segments的设定。
增加cehckpoint_segments或者checkpoint_timeout可以有一定的效能提升。而唯一的坏处就是如果系统挂了,在重启的时需要多一点时间来回复(系统启动回复期间数据库是不能用的)鉴于postgres很少挂掉,这个其实可以设定的很长(1天都可以)
设定:
checkpoint_segments 最多的wal log数量,到达后会激发checkpoint,通常设定在30就好
checkpoint_timeout 一般设置15-20分钟,常的可以设定1天也没关系
checkpoint_completion_target这个保持不动就好。内建是0.5,意思就是每个checkpoint预计在下个checkpoint完成前的一半时间内完成(听起来有点绕嘴,呵呵)
checkpoint_warning 如果checkpint速度快于这个时间,在log中记录。内建是30秒
理论中的完美设定,就是你的backend从来不用回写硬盘。 东西都是由background来写入的。这个就要靠调整bgwriter,checkpoints跟wal到一个最佳平衡状态。当然这个是理想中的完美,想真的做到。。。继续想吧。呵呵
4. 维护 – 保持postgres的笑容
维护数据库是必 须的。基本维护
vacuum
delete数据的时候,数据库只是记录这笔数据是‘不要的‘并不是真的删除数据。所以这个时候就要vacuum了,vacuum会把标记为‘不要‘的数据清除掉。这里要注意的是,vacuum不会清理index。当数据更改超过75%的时候,需要重新建立index。postgres8.4 index可以用cluster重建速度快很多。在postgres9.x中,vacuum=cluster,没有任何区别了(保留cluster只是为了兼容旧版指令)
Full Vacuum
这个会做exclusive lock。vacuum跟fullvacuum的区别是vacuum会把标志为‘不要‘的空间标志成可以再次使用(回收)而 fullvacuum则会把这个空间删除(返还给系统OS)所以vacuum之后你的postgres在硬盘上看到的占用空间不会减少,但是fullvacuum会减小硬盘占用空间。不建议使用full vacuum,第一没必要,第二exclusive lock不好玩。
ANALYZE
Analyze 会更新统计信息(statistics)所有的query的最佳方案,以及sql preparedstatement都是靠这统计信息而决定的。所以当数据库中的一定量数据变动后(例如超过10%),要作analyze,严格的说,这个是应该常做的东西,属于数据库正常维护的一部分。另外一个很重要的就是,如果是upload数据(restore那种)做完之后要记得作analyze(restore自动不给你作的)
当建立新的table的时候,或者给table增加index,或者对table作reindex,或者restore数据进数据库,需要手动跑analyze才可以。analyze直接影响default_statistics_target数据。
Autovacuum
根据postgres的官方资料,autovacuum在8.3之后才变得比较真的实用(8.1推出的)因为在8.3之前,autovacuum一次只能同时做一个数据库中的一个table。8.3之后的版本,可以作多数据库多table。
设定
log_autovacuum_min_duration:
-1为关闭。0是log全部。>0就是说超过这个时间的就log下来。例如设定为30,那么所有超过30ms的都会被日志记录。
autovacuum_max_workers:
同 时启用的autovacuum进程。通常不要设定太高,3个就可以。
autovacuum_naptime:
检查数据库的时 间,default是1分钟,不用改动
autovacuum_vacuum_threshold:
最低n行记录才会引发 autovacuum。也就是数据改变说低于这个值,autovacuum不会运行。default是50
autovacuum_analyze_threshold:
运 行analyze的最低值,跟上面的一样
autovacuum_vacuum_scale_factor:
table中的百分比的计算方 式(超过一定百分比作vacuum)内建是20% (0.2)
autovacuum_analyze_scale_factor:
同上, 不过是analyze的设定
autovacuum_freeze_max_age:
最大XID出发autovacuum
autovacuum_vacuum_cost_delay:
延 迟。。如果系统负荷其他东西,可以让vacuum慢点,保证其他东西的运行.这里是通过延迟来限制
autovacuum_vacuum_cost_limit:
同 上,也是作限制的,这里是通过cost限制limit
Cluster
Cluster 类似于vacuum full。建议使用cluster而不是vacuum full。cluster跟vacuumfull一样会重写table,移除所有的dead row。同样也是要做exclusive lock。
Truncate
Turncat 会删除一个table中的所有数据, 并且不会造成任何的dead row(delete则会造成deadrow)同样的,turncate也可以用来重建table
begin;
lock foo in access exclusive mode;
create table bar as select * from foo;
turncate foo;
insert into foo (select * from bar);
commit;
这样就重新清理了 foo这个table了。
REINDEX
重 新建立index
5. 其他
planner:
statistics直接决定planner的结果。使用planner,那么要记得确保statistics的准确(analyze)
default_statistics_target:
设定analyze分析的值。这个可以在 query中随时设定更改
set default_statistics_target to 100;
analyze verbose mytable;
INFO: analyzing “aweber_shoggoth.mytable”
INFO: “mytable”: scanned 30000 of 1448084 pages, containing 1355449live rows and 0 dead rows; 30000 rows in sample, 65426800 estimatedtotal rows
ANALYZE
set default_statistics_target to 300;
analyze verbose mytable;
INFO: analyzing “aweber_shoggoth.mytable”
INFO: “mytable”: scanned 90000 of 1448084 pages, containing 4066431live rows and 137 dead rows; 90000 rows in sample, 65428152estimated total rows
ANALYZE
Set statistics per column 给不同的column设定不同的 statistics
alter table foo alter column bar set statistics 120
查找何时需要增加statistics
跑 个query作expain analyze
这个就会看到例如:
-> Seq Scan on bar (cost=0.00-52.00 rows=52 width=2(actual time=0.007..1.894 rows=3600 loops=1)
这里的rows应该跟真正的rows数量差不多才 是正确的。
seq_page_cost
planner 作sequential scan时候的cost。default是1,如果内存,cache,sharedbuffer设定正确。那么这个default的值太低了,可以增加
random_page_cost
planner 作random page fetch的值。default是4.0 如果内存,cache,sharedbuffer设定正确,那么这个值太高了,可以降低
seq_page_cost跟random_page_cost的值可以设定成一样的。然后测试效能,可以适当降低random_page_cost的值
cpu_operator_cost
default 是0.0025,测试为,通常设定在0.5比较好
set cpu_operator_cost to 0.5;
explain analyze select ….
cpu_tuple_cost
default 是0.01 测试为,通常设定在0.5比较好
set cpu_tuple_cost to 0.5;
explain analyze select …
effective_cache
应 该跟尽可能的给到系统free能接受的大小(越大越好)
total used free shared buffer cached
mem: xxxx yyyyy zzz aaaa bbbb cccc
设定的计算方法为:
effective_cache=cached X 50% + shared
这里的50%可以根据服务器的繁忙程度 在40%-70%之间调整。
监测方法:
explain analyze ;
set effective_cache_size=新的值;
explain analyze ;
reset effective_cache_size;
尝试出一个最适合的值,就可以改postgresql.conf文件设定成固定了。
Natural vs Primary Key
Primary Key 基本因为要做join,跟Natural相比多消耗20%左右的效能。所以尽力primary做在Naturalkey上。
Btree vs hash
btree 比 hash 快,不管什么情况,所以不要用hash
gin vs gist
full text的时候,用gin不要用 gist