Установка и оптимизация Postgres 9 на Linux под высокую нагрузку

440hz

php.ru
Это не мануал. Это то, с чем я столкнулся. Благодарю всех, чьими статьями я пользовался и всех тех, кто помогал мне в этом. Многие увидят куски других статей, чьим авторам отдельное большое спасибо.


Предварительная установка:

Встала задача поставить Постгрес на тачку:

CPU: Intel(R) Xeon(R) CPU E5420 @ 2.50GHz (8 ядер)
MEM: 24ГБ
DSK: 12 дисков FUJITSU MBB2147RC по 160Г каждый

Требовалось максимально выжать из железа производительность при размере БД 50ГБ с учетом роста до 200ГБ. Самая большая таблица с индексами была примерно 10Г. Текущий сервер упирался в производительность дисков. Загрузка винтов доходила до 90%. С учетом этого на новой тачке 10 винтов (4/6) из 12 были объединены в 2 массива RAID10. и 2 оставлены на hotswap.

Код:
/dev/sda1             261G  3,1G  245G   2% /
...
/dev/sdb1             409G   48G  341G  13% /postgres
такое разбиение позволяло разнести данные БД (/var/lib/postgresql/9.0/main/base) и файлы транзакций (/var/lib/postgresql/9.0/main/(pg_clog|pg_xlog)), что значительно уменьшало нагрузку на дисковое пространство. так же был вынесен файл статистики в отдельный виртуальный диск.

Код:
tmpfs                 400M  272K  400M   1% /var/lib/postgresql/9.0/main/pg_stat_tmp
таким способом мы получили 3 отдельных устройства распределяющие нагрузку между собой. что бы еще более разгрузить нагрузку на диски были смонтированы разделы с опциями noatime,nodiratime.

Код:
UUID=32adf683-9ed6-4cb8-9245-52323ba7c0b5 /               ext4    noatime,nodiratime,errors=remount-ro 0       1
...
/dev/sdb1 /postgres                                       ext4    noatime,nodiratime 0       1
tmpfs /var/lib/postgresql/9.0/main/pg_stat_tmp            tmpfs   noatime,nodiratime,size=500M,mode=700,uid=104,gid=113
Разобравшись с дисками началась сама установка...

Код:
#apt-get install python-software-properties
#add-apt-repository ppa:pitti/postgresql
#apt-get update
#apt-get install postgresql postgresql-contrib-9.0
#sudo -u postgres pg_dropcluster --stop 9.0 main
#sudo -u postgres pg_createcluster --start -locale=ru_RU.UTF8 9.0 main
#sudo -u postgres psql postgres
psql (9.0.2)
Type "help" for help.
postgres=# \password
Enter new password:
Enter it again:
postgres=# \q
#/etc/init.d/postgresql stop
 * Stopping PostgreSQL 9.0 database server
тут надо вынести файл статистики на виртуальный диск и разнести БД и транзакции на разные диски.
смотрим uid и gid пользователя postgres и мапим рамдиск

Код:
# id postgres
uid=104(postgres) gid=113(postgres) группы=113(postgres),112(ssl-cert)
добаляем в /etc/fstab/, перемонтируем. сейчас на боевой БД размер файла достигает 100М-150М. С запасом берем 500М.

Код:
#nano /etc/fstab
+ tmpfs /var/lib/postgresql/9.0/main/pg_stat_tmp tmpfs noatime,nodiratime,size=500M,mode=700,uid=104,gid=113
#mount -a
Изначально раздел был сделан 100М и получили косяк, когда ПГ не хватало места для файла статистики. Останавливать ПГ было нельзя. Боевой сервер. Поэтому добавляли размер на лету.

Код:
#mount -o remount,size=500M /var/lib/postgresql/8.4/main/pg_stat_tmp
разносим БД и все остальное. копируем на диск2 (/postgres) каталог base/ и делаем на него линк
Код:
/var/lib/postgresql/9.0/main#ln -s /postgres/base base
lrwxrwxrwx  1 root     root        14 2010-12-24 18:36 base -> /postgres/base
пускаем

Код:
#/etc/init.d/postgresql start
 * Starting PostgreSQL 9.0 database server
таким образом получили разнос основных дисковых операций ПГ на различные файловые системы. это даст нам прирост производительности за счет разброса дисковых операций по разным устройствам и шинам.


Опимизация (она же тюнинг):

Имея 24Г памяти можно немного расслабится...


postgres.conf
Код:
max_connections = 500 
shared_buffers = 16GB
temp_buffers = 64MB
work_mem = 512MB
maintenance_work_mem = 4GB
max_stack_depth = 4MB
...
vacuum_cost_delay = 10ms
...
wal_buffers = 32MB 
...
effective_cache_size = 4GB
...
autovacuum = on
autovacuum_max_workers = 16 
autovacuum_naptime = 1min
...
max_locks_per_transaction = 256
checkpoint_segments = 64
checkpoint_timeout = 15min
скажем ядру, что нам надо много памяти. пусть выдает.

/etc/sysctl.conf
Код:
kernel.shmall = 17670512640
kernel.shmmax = 17670512640
перезапускаем

Код:
# sysctl -p
kernel.shmall = 17670512640
kernel.shmmax = 17670512640
и делаем stop/start постгре.

Имеем:

Код:
# ipcs

------ Сегменты совм. исп. памяти --------
ключ   shmid      владелец права байты nattch     состояние
0x0052e2c1 9797632    postgres   600        17670512640 19
0x7a010596 9633793    zabbix     666        1245800    8

------ Массивы семафоров --------
ключ   semid      владелец права nsems
0x0052e2c1 94044160   postgres   600        17
0x0052e2c2 94076929   postgres   600        17
0x0052e2c3 94109698   postgres   600        17
0x0052e2c4 94142467   postgres   600        17
0x0052e2c5 94175236   postgres   600        17
0x0052e2c6 94208005   postgres   600        17
0x0052e2c7 94240774   postgres   600        17
0x7a010596 89686023   zabbix     666        5
0x0052e2c8 94273544   postgres   600        17
0x0052e2c9 94306313   postgres   600        17
0x0052e2ca 94339082   postgres   600        17
0x0052e2cb 94371851   postgres   600        17
0x0052e2cc 94404620   postgres   600        17
0x0052e2cd 94437389   postgres   600        17
0x0052e2ce 94470158   postgres   600        17
0x0052e2cf 94502927   postgres   600        17
0x0052e2d0 94535696   postgres   600        17
0x0052e2d1 94568465   postgres   600        17
0x0052e2d2 94601234   postgres   600        17
0x0052e2d3 94634003   postgres   600        17
0x0052e2d4 94666772   postgres   600        17
0x0052e2d5 94699541   postgres   600        17
0x0052e2d6 94732310   postgres   600        17
0x0052e2d7 94765079   postgres   600        17
0x0052e2d8 94797848   postgres   600        17
0x0052e2d9 94830617   postgres   600        17
0x0052e2da 94863386   postgres   600        17
0x0052e2db 94896155   postgres   600        17
0x0052e2dc 94928924   postgres   600        17
0x0052e2dd 94961693   postgres   600        17
0x0052e2de 94994462   postgres   600        17
0x0052e2df 95027231   postgres   600        17
0x0052e2e0 95060000   postgres   600        17
0x0052e2e1 95092769   postgres   600        17
0x002fa327 58851362   root       666        2

------ Очереди сообщений --------
ключ   msqid      владелец права исп. байты сообщения
Код:
# iostat 1 1
Linux 2.6.32-21-server (*****)      31.12.2010      _x86_64_        (8 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0,42    0,15    0,25    0,27    0,00   98,90

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda               4,74       523,57       994,31  318117850  604142240
sdb               7,13       692,47       881,73  420741862  535733686
Код:
PRC | sys   0.63s | user   0.85s | #proc    216 | #zombie    0 | #exit    161 |
CPU | sys      5% | user      6% | irq       0% | idle    790% | wait      0% |
cpu | sys      1% | user      1% | irq       0% | idle     98% | cpu000 w  0% |
cpu | sys      1% | user      1% | irq       0% | idle     99% | cpu007 w  0% |
cpu | sys      0% | user      1% | irq       0% | idle     99% | cpu002 w  0% |
cpu | sys      1% | user      1% | irq       0% | idle     97% | cpu006 w  0% |
cpu | sys      0% | user      0% | irq       0% | idle    100% | cpu003 w  0% |
cpu | sys      1% | user      1% | irq       0% | idle     98% | cpu004 w  0% |
cpu | sys      0% | user      0% | irq       0% | idle    100% | cpu005 w  0% |
cpu | sys      0% | user      0% | irq       0% | idle    100% | cpu001 w  0% |
CPL | avg1   0.66 | avg5    0.45 | avg15   0.38 | csw     7774 | intr    7914 |
MEM | tot   23.6G | free  997.4M | cache  21.6G | buff   88.4M | slab  258.9M |
SWP | tot    0.0M | free    0.0M |              | vmcom  16.8G | vmlim  11.8G |
DSK |         sda | busy      0% | read       0 | write     16 | avio    4 ms |
DSK |         sdb | busy      0% | read       0 | write      5 | avio    4 ms |
NET | transport   | tcpi     351 | tcpo     344 | udpi     195 | udpo     195 |
NET | network     | ipi      551 | ipo      540 | ipfrw      0 | deliv    550 |
NET | eth0     0% | pcki     382 | pcko     342 | si   16 Kbps | so   17 Kbps |
NET | lo     ---- | pcki     195 | pcko     195 | si   76 Kbps | so   76 Kbps |

Локализация:

Для работы с cp1251

Код:
#localedef -c -f /usr/share/i18n/charmaps/CP1251 -i /usr/share/i18n/locales/ru_RU /usr/lib/locale/ru_RU.CP1251
#cd /usr/lib/locale
#ln -s ru_RU.cp1251 ru_RU.CP1251
PGBounucer:

Код:
#apt-get install pgbouncer

п.с. после НГ допишу настройку.
 

~WR~

Новичок
Здорово) Какая же там нагрузка, чтобы продавить такую машину.

С настолько большими системами работать не приходилось, но вспоминая книгу PostgreSQL High Performance, писали о том, что слишком большой shared_buffers может оказывать негативное влияние на производительность.

Т.к. постгрес сначала ищет данные в этом буфере, и только потом читает их с диска.
Если чаще запрашивается одно и то же, то это плюс. Если же все время разное - минус.

Впрочем, разница небольшая.
 
Сверху