Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / PostgreSQL Новый топик    Ответить
 Разогнать применение WAL на реплике (странное происходит)  [new]
flashgun
Member

Откуда:
Сообщений: 14
Коллеги, нужен ваш совет, что-то не понимаю, что происходит.

Дано: в Hetzner стоят две совершенно одинаковые машины AX41-NVMe. На обеих PostgreSQL 12/Ubuntu 20.04.

Первая -- мастер, настраивал исходя из паттерна OLTP-нагрузки, с подстроенным вакуумом. На ней вся логика, все обновления, вставки, всё вот это вот. Нагрузка +- равномерная по времени суток и дням недели. Примерно так выглядит в pgtop:

last pid: 3333915;  load av  4.70,  5.43,  5.78;       up 47+03:06:26   12:04:35
190 processes: 187 sleeping, 3 uninterruptable
CPU states: 5.7% user, 0.0% nice, 13.2% system, 69.2% idle, 11.9% iowait
Memory: 40G used, 23G free, 252M buffers, 18G cached
DB activity: 821 tps, 0 rollbs/s, 1042 buffer r/s, 98 hit%, 29099 row r/s, 1849 row w/s
DB I/O: 0 reads/s, 0 KB/s, 0 writes/s, 0 KB/s
DB disk: 859.5 GB total, 770.2 GB free (10% used)
Swap: 32G free

Вторая -- физическая реплика первой + на ней веб-морда с недо-аналитикой и некоторые простые, но длительные запросы выполняюся через dblink, настраивал как OLAP. Выглядит так:

last pid: 3281771;  load av  4.16,  3.65,  3.60;       up 1+10:37:51    12:06:46
8 processes: 4 other background task(s), 3 idle, 1 active
CPU states: 1.1% user, 0.0% nice, 6.7% system, 69.1% idle, 23.2% iowait
Memory: 22G used, 40G free, 0K shared, 220M buffers, 1807M cached
Swap: 0K used, 32G free, 0K cached, 0K in, 0K out

Из необычного: и там, и там используется zfs с включённым сжатием:

front:~$ zfs get compress
NAME PROPERTY VALUE SOURCE
tank compression lz4 local
front:~$ zfs get compressratio
NAME PROPERTY VALUE SOURCE
tank compressratio 4.02x -
front:~$

Кроме того, так как zfs -- это copy-on-write, отключены
wal_init_zero 
и
wal_recycle
.

Размер базы 372 Гб.

ПРОБЛЕМА:

Реплика при почти полном отсутствии нагрузки не успевает применять WAL-логи на базу. Сеть исключил, количество файлов в каталоге мастера -- 138, слейва -- 1568, и это число растёт, но медленно, примерно 350 файлов в сутки. При этом логи применяются, проверял. Сейчас отставание реплики от мастера 8 часов и 2 минуты, и это время растёт, примерно на 4..5 секунд в минуту.

Не понимаю даже, куда смотреть. Мастер нагружен, и там всё ок, слейв свободен, но не успевает.

Что ещё: на слейве включен
huge_pages
. dmesg на обеих машинах пустой (без ошибок).

Дайте, пожалуйста, наводку: куда посмотреть, где почесать. Началось примерно дней 5 назад, как мне кажется, на пустом месте. Примерно две недели назад тюнил на мастере autovacuum.
26 июл 20, 15:26    [22173818]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4230
flashgun,

Для начала top -S первые строк 20 на реплике покажите
причем подождите 10 секунд чтобы статистика накопилась побольше.

Тогда и можно будет гипотезы выдвигать.


И покажите отличия конфига базы на мастере и на реплике у вас.

Сообщение было отредактировано: 26 июл 20, 18:06
26 июл 20, 18:08    [22173846]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
flashgun
Member

Откуда:
Сообщений: 14
Maxim Boguk,

Вот top -S:
top - 11:20:39 up 2 days,  9:51,  1 user,  load average: 2.37, 3.22, 3.48
Tasks: 318 total, 2 running, 316 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.3 us, 4.8 sy, 0.0 ni, 83.2 id, 11.5 wa, 0.0 hi, 0.2 si, 0.0 st
MiB Mem : 64251.5 total, 41188.4 free, 20484.7 used, 2578.4 buff/cache
MiB Swap: 32768.0 total, 32768.0 free, 0.0 used. 43057.7 avail Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2840 postgres 20 0 16.5g 9132 6572 D 7.6 0.0 257:45.88 postgres
705 root 1 -19 0 0 0 S 3.0 0.0 68:16.87 z_wr_iss
706 root 1 -19 0 0 0 S 3.0 0.0 68:16.97 z_wr_iss
708 root 1 -19 0 0 0 S 3.0 0.0 68:16.65 z_wr_iss
711 root 1 -19 0 0 0 S 3.0 0.0 68:18.26 z_wr_iss
712 root 1 -19 0 0 0 S 3.0 0.0 68:16.89 z_wr_iss
713 root 1 -19 0 0 0 S 3.0 0.0 68:16.33 z_wr_iss
707 root 1 -19 0 0 0 S 2.7 0.0 68:16.89 z_wr_iss
709 root 1 -19 0 0 0 S 2.7 0.0 68:17.72 z_wr_iss
710 root 1 -19 0 0 0 S 2.7 0.0 68:16.41 z_wr_iss
698 root 0 -20 0 0 0 S 2.3 0.0 115:16.42 z_rd_int
699 root 0 -20 0 0 0 S 2.3 0.0 115:14.58 z_rd_int
700 root 0 -20 0 0 0 S 2.3 0.0 115:13.44 z_rd_int
701 root 0 -20 0 0 0 S 2.3 0.0 115:15.64 z_rd_int
702 root 0 -20 0 0 0 S 2.3 0.0 115:16.28 z_rd_int
703 root 0 -20 0 0 0 S 2.3 0.0 115:14.52 z_rd_int
704 root 0 -20 0 0 0 S 2.3 0.0 115:15.93 z_rd_int
697 root 0 -20 0 0 0 S 2.0 0.0 115:14.28 z_rd_int
2842 postgres 20 0 16.5g 5824 3704 D 1.3 0.0 45:41.35 postgres
1319280 eugene 20 0 93424 78628 13064 S 1.3 0.1 0:29.31 xbl-script.pl
535 root 0 -20 0 0 0 S 1.0 0.0 37:03.35 spl_kmem_cache
714 root 0 -20 0 0 0 S 1.0 0.0 30:27.17 z_wr_iss_h
664101 postgres 20 0 16.5g 13572 10988 D 1.0 0.0 27:22.73 postgres
2 root 20 0 0 0 0 S 0.3 0.0 13:55.04 kthreadd
530 root 0 -20 0 0 0 S 0.3 0.0 7:40.13 spl_dynamic_tas
715 root 0 -20 0 0 0 S 0.3 0.0 10:55.65 z_wr_int
716 root 0 -20 0 0 0 S 0.3 0.0 10:56.30 z_wr_int
717 root 0 -20 0 0 0 S 0.3 0.0 10:55.54 z_wr_int
718 root 0 -20 0 0 0 S 0.3 0.0 10:56.49 z_wr_int
719 root 0 -20 0 0 0 S 0.3 0.0 10:56.12 z_wr_int
720 root 0 -20 0 0 0 S 0.3 0.0 10:55.80 z_wr_int
721 root 0 -20 0 0 0 S 0.3 0.0 10:55.76 z_wr_int
722 root 0 -20 0 0 0 S 0.3 0.0 10:56.05 z_wr_int
750 root 39 19 0 0 0 S 0.3 0.0 1:44.21 dp_sync_taskq
753 root 39 19 0 0 0 S 0.3 0.0 1:43.58 dp_sync_taskq
2964529 root 20 0 0 0 0 I 0.3 0.0 0:00.21 kworker/6:2-events
1 root 20 0 167312 11460 8516 S 0.0 0.0 2:49.89 systemd
3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_par_gp
6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H-kblockd
9 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq
10 root 20 0 0 0 0 S 0.0 0.0 0:08.12 ksoftirqd/0
11 root 20 0 0 0 0 I 0.0 0.0 1:37.12 rcu_sched
12 root rt 0 0 0 0 S 0.0 0.0 0:00.80 migration/0
13 root -51 0 0 0 0 S 0.0 0.0 0:00.00 idle_inject/0
14 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuhp/0
15 root 20 0 0 0 0 S 0.0 0.0 0:00.00 cpuhp/1
16 root -51 0 0 0 0 S 0.0 0.0 0:00.00 idle_inject/1

А вот отличия реплики от мастера:

$ diff postgresql.conf /etc/postgresql/12/main/postgresql.conf
41c41
< data_directory = '/var/lib/postgresql/12/main' # use data in another directory
---
> data_directory = '/tank/postgresql/12/main' # use data in another directory
59c59
< #listen_addresses = 'localhost' # what IP address(es) to listen on;
---
> listen_addresses = '*' # what IP address(es) to listen on;
121c121
< shared_buffers = 16GB # min 128kB
---
> shared_buffers = 15GB # min 128kB
123c123
< huge_pages = on # on, off, or try
---
> #huge_pages = try # on, off, or try
130,131c130
< # work_mem = 4660kB # min 64kB
< work_mem = 64MB
---
> work_mem = 1310kB # min 64kB
165c164
< #vacuum_cost_limit = 200 # 1-10000 credits
---
> vacuum_cost_limit = 1000 # 1-10000 credits
178c177
< max_parallel_maintenance_workers = 4 # taken from max_parallel_workers
---
> #max_parallel_maintenance_workers = 2 # taken from max_parallel_workers
194c193
< #wal_level = replica # minimal, replica, or logical
---
> wal_level = replica # minimal, replica, or logical
208c207
< full_page_writes = on # recover from partial page writes
---
> full_page_writes = off # recover from partial page writes
318c317
< max_standby_archive_delay = -1 # max delay before canceling queries
---
> #max_standby_archive_delay = 30s # max delay before canceling queries
321c320
< max_standby_streaming_delay = -1 # max delay before canceling queries
---
> #max_standby_streaming_delay = 30s # max delay before canceling queries
362,363c361,362
< enable_partitionwise_join = on
< enable_partitionwise_aggregate = on
---
> #enable_partitionwise_join = off
> #enable_partitionwise_aggregate = off
388c387
< effective_cache_size = 48GB
---
> effective_cache_size = 45GB
402c401
< default_statistics_target = 500 # range 1-10000
---
> default_statistics_target = 100 # range 1-10000
579c578
< #log_autovacuum_min_duration = -1 # -1 disables, 0 logs all actions and
---
> log_autovacuum_min_duration = 1s # -1 disables, 0 logs all actions and
586c585
< #autovacuum_vacuum_threshold = 50 # min number of row updates before
---
> autovacuum_vacuum_threshold = 10000 # min number of row updates before
590c589
< #autovacuum_vacuum_scale_factor = 0.2 # fraction of table size before vacuum
---
> autovacuum_vacuum_scale_factor = 0 # fraction of table size before vacuum
650c649
< datestyle = 'iso, dmy'
---
> datestyle = 'iso, mdy'
666c665
< lc_messages = 'ru_RU.UTF-8' # locale for system error message
---
> lc_messages = 'en_US.UTF-8' # locale for system error message
668,670c667,669
< lc_monetary = 'ru_RU.UTF-8' # locale for monetary formatting
< lc_numeric = 'ru_RU.UTF-8' # locale for number formatting
< lc_time = 'ru_RU.UTF-8' # locale for time formatting
---
> lc_monetary = 'en_US.UTF-8' # locale for monetary formatting
> lc_numeric = 'en_US.UTF-8' # locale for number formatting
> lc_time = 'en_US.UTF-8' # locale for time formatting
673c672
< default_text_search_config = 'pg_catalog.russian'
---
> default_text_search_config = 'pg_catalog.english'
$

Там, где в начале строки ">" -- это мастер.
Где "<" -- реплика.

Сегодня уже 2236 wal-файлов на слейве, на мастере 156. Почитал про то, что реплика применяет логи в один поток, поэтому так медленно. Есть даже средство борьбы: https://github.com/joyent/pg_prefaulter -- но с моим скудным пониманием экосистемы go запустить не удалось: жалуется на невозможность подключения к агенту.

Плюс, списался с Константином Книжником по поводу его патча двухлетней давности: https://www.postgresql-archive.org/WAL-prefetch-td6024900.html по его словам, интерес к этой теме недавно возник снова: https://www.postgresql.org/message-id/flat/226b5950-7404-a51d-8dc7-53895b363a38@pgmasters.net#6ee015f86ddc1c235f7086af4f4fa103 но мне надо сперва понять, в этом ли проблема.

Спасибо, Максим, буду рад наводкам, куда ещё посмотреть!
27 июл 20, 14:30    [22174199]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4230
flashgun,

А что на реплике показывает iostat -xmd 1 (десяток-другой отсчетов)?
У меня сильное подозрение что все таки беда в zfs в которой я не сильно большой специалист.
Потому что обычно если упирается в проигрывание WAL то у вас или %IO под 80% будет и диски не справляются или recovery процесс postgresql в 100% cpu сидит (а у вас он только 5% занимает).
Если есть возможность я бы поднял реплику на таком же железе но на ext4 без сжатия и посмотрел бы.

Может у zfs где то есть настройки больше потоков или процессора ей выдать.
27 июл 20, 17:26    [22174304]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
flashgun
Member

Откуда:
Сообщений: 14
Maxim Boguk,

$ iostat -xmd 1
Linux 5.4.0-42-generic (front) 07/27/2020 _x86_64_ (12 CPU)

Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 1675.54 50.50 0.04 0.00 0.57 30.86 386.80 17.61 0.83 0.21 1.01 46.62 0.04 0.12 0.00 0.00 7.55 2985.58 0.74 80.36
nvme1n1 1012.74 30.73 0.00 0.00 1.00 31.07 263.84 11.19 0.00 0.00 1.63 43.45 0.00 0.00 0.00 0.00 0.00 0.00 1.03 76.56


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 2329.00 70.14 0.00 0.00 0.21 30.84 23.00 0.44 3.00 11.54 0.35 19.46 0.00 0.00 0.00 0.00 0.00 0.00 0.03 98.80
nvme1n1 1565.00 46.59 0.00 0.00 0.22 30.48 15.00 0.22 0.00 0.00 0.00 14.93 0.00 0.00 0.00 0.00 0.00 0.00 0.01 96.80


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 1829.00 55.51 0.00 0.00 0.45 31.08 69.00 1.27 0.00 0.00 0.01 18.79 0.00 0.00 0.00 0.00 0.00 0.00 0.24 93.20
nvme1n1 1127.00 34.70 0.00 0.00 0.60 31.53 77.00 1.33 0.00 0.00 0.04 17.69 0.00 0.00 0.00 0.00 0.00 0.00 0.22 92.80


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 1325.00 40.05 0.00 0.00 0.67 30.95 617.00 28.75 0.00 0.00 0.72 47.72 0.00 0.00 0.00 0.00 0.00 0.00 0.58 89.60
nvme1n1 776.00 23.77 0.00 0.00 0.75 31.37 328.00 12.46 0.00 0.00 0.65 38.90 0.00 0.00 0.00 0.00 0.00 0.00 0.42 79.20


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 606.00 18.47 0.00 0.00 1.55 31.21 626.00 30.42 0.00 0.00 0.95 49.75 0.00 0.00 0.00 0.00 0.00 0.00 1.00 48.40
nvme1n1 368.00 11.04 0.00 0.00 8.34 30.73 619.00 24.54 0.00 0.00 1.87 40.60 0.00 0.00 0.00 0.00 0.00 0.00 3.84 39.60


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 2053.00 61.89 0.00 0.00 0.35 30.87 72.00 1.25 0.00 0.00 0.03 17.82 0.00 0.00 0.00 0.00 0.00 0.00 0.12 96.00
nvme1n1 1231.00 37.82 0.00 0.00 0.46 31.46 73.00 1.39 0.00 0.00 0.04 19.52 0.00 0.00 0.00 0.00 0.00 0.00 0.13 95.60


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 2059.00 62.85 0.00 0.00 0.23 31.26 26.00 0.60 0.00 0.00 0.00 23.62 0.00 0.00 0.00 0.00 0.00 0.00 0.03 95.20
nvme1n1 1580.00 48.89 0.00 0.00 0.23 31.68 20.00 0.47 0.00 0.00 0.00 23.98 0.00 0.00 0.00 0.00 0.00 0.00 0.04 96.80


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 2232.00 65.37 0.00 0.00 0.22 29.99 21.00 0.45 0.00 0.00 0.05 21.76 0.00 0.00 0.00 0.00 0.00 0.00 0.04 98.80
nvme1n1 1502.00 45.29 0.00 0.00 0.24 30.88 24.00 0.53 0.00 0.00 0.04 22.54 0.00 0.00 0.00 0.00 0.00 0.00 0.03 98.00


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 1781.00 53.35 0.00 0.00 0.35 30.67 334.00 10.40 0.00 0.00 0.16 31.89 0.00 0.00 0.00 0.00 0.00 0.00 0.08 93.60
nvme1n1 1174.00 33.91 0.00 0.00 0.39 29.58 264.00 8.95 0.00 0.00 0.29 34.71 0.00 0.00 0.00 0.00 0.00 0.00 0.10 90.40


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 71.00 2.41 0.00 0.00 31.39 34.70 905.00 50.86 0.00 0.00 1.46 57.55 0.00 0.00 0.00 0.00 0.00 0.00 2.91 47.20
nvme1n1 32.00 1.04 0.00 0.00 47.72 33.27 618.00 33.75 0.00 0.00 2.62 55.92 0.00 0.00 0.00 0.00 0.00 0.00 2.57 46.80


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 1966.00 62.44 0.00 0.00 0.40 32.52 254.00 2.00 0.00 0.00 0.03 8.07 0.00 0.00 0.00 0.00 0.00 0.00 0.12 92.40
nvme1n1 1394.00 43.13 0.00 0.00 1.04 31.68 289.00 2.36 0.00 0.00 0.74 8.35 0.00 0.00 0.00 0.00 0.00 0.00 1.09 91.60


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 2105.00 66.53 0.00 0.00 0.27 32.37 39.00 0.70 4.00 9.30 0.21 18.33 0.00 0.00 0.00 0.00 0.00 0.00 0.06 97.60
nvme1n1 1425.00 45.46 0.00 0.00 0.32 32.67 43.00 0.90 0.00 0.00 0.02 21.51 0.00 0.00 0.00 0.00 0.00 0.00 0.08 96.00


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 1937.00 60.69 0.00 0.00 0.37 32.09 67.00 1.38 0.00 0.00 0.01 21.10 0.00 0.00 0.00 0.00 0.00 0.00 0.14 95.20
nvme1n1 1221.00 39.34 0.00 0.00 0.41 32.99 61.00 1.03 0.00 0.00 0.03 17.30 0.00 0.00 0.00 0.00 0.00 0.00 0.11 96.40


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 2243.00 70.22 0.00 0.00 0.30 32.06 56.00 1.05 0.00 0.00 0.04 19.20 0.00 0.00 0.00 0.00 0.00 0.00 0.06 96.80
nvme1n1 1180.00 36.50 0.00 0.00 0.44 31.68 61.00 1.17 0.00 0.00 0.05 19.69 0.00 0.00 0.00 0.00 0.00 0.00 0.11 97.20


Device r/s rMB/s rrqm/s %rrqm r_await rareq-sz w/s wMB/s wrqm/s %wrqm w_await wareq-sz d/s dMB/s drqm/s %drqm d_await dareq-sz aqu-sz %util
nvme0n1 46.00 1.39 0.00 0.00 24.33 30.88 1109.00 56.94 0.00 0.00 1.61 52.57 0.00 0.00 0.00 0.00 0.00 0.00 2.23 54.00
nvme1n1 36.00 1.20 0.00 0.00 40.67 34.06 485.00 26.78 0.00 0.00 2.17 56.54 0.00 0.00 0.00 0.00 0.00 0.00 2.22 29.20

^C
$

Два диска собраны в страйп (raid0). Скорость важна, RTO/RPO -- нет.

Ну, я пока склоняюсь к версии, изложенной здесь: https://github.com/joyent/pg_prefaulter

https://github.com/joyent/pg_prefaulter

PostgreSQL’s streaming-based replication system is based on "log-shipping:" the WAL is streamed to remote hosts. Database replicas apply the changes listed in the instructions within the WAL using the PostgreSQL crash recovery mechanism: they read the log from beginning to end, find the changes to the underlying datafiles (the "PostgreSQL Heap", or "Heap" for short) and make the relevant changes to the database files.

The replica’s WAL-apply operation is performed in a single process, using a single thread. Each time a WAL-entry is "consumed" as the replica reads in the corresponding page of the underlying datafile. The WAL-replay process on the replica waits for the serial execution of disk I/O to complete and load the underlying page(s) from the heap. Unlike the primary, the follower lacks the ability to spread its work across multiple processes. As a consequence, the replicas only perform single-process, single-threaded, blocking IO, and cannot apply the WAL as quickly as the primary who generates the WAL files and are using parallel IO. To add insult to injury, the follower is prone to having its filesystem cache fault, resulting in a physical disk IO, further slowing down the apply process.


Получается, что, в отличие от Мастера, который накатывает логи не из WAL-файлов на диске, а из кеша операционной системы, к тому же в несколько потоков, реплика вынуждена их (WAL) брать всё-таки с диска и в один поток с блокирующим в/в. Так я это понял, по крайней мере. Не очень понятно, что мешает receiver-у точно также при записи попадать в кеш ОС, а recovery из этого кеша и читать. Ну, разве что да, один поток. И ещё понятен выигрыш при HDD, но у меня то аж NVMe...

Посмотрю параметры zfs в части настройки под постгрес, тем более, что там есть, что настраивать:

https://github.com/timescale/timescaledb/issues/638
https://gist.github.com/saurabhnanda/5258207935bf23cd112be292d22f00d5

Спасибо!
27 июл 20, 19:47    [22174378]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4230
flashgun,

реплика тоже может с кеша брать если его хватает но да там блокирующий IO в один поток... и скорее всего zfs добавляет такую задержку что реплику не справляется (именно изза задержек на IO при сжатии-разжатии).

кстати у zfs свой кеш не тот что у обычных FS и у вас он явно не настроен... потому что у вас там 40G free а должно быть не так очевидно...

так что у вас два пути (можно оба пробовать)
1)настойку кеша zfs
2)попробовать на реплике 48GB (а то и 56gb) shared buffers поставить чтобы база кешировала все что можно у себя только обязательно с huge pages on

вариант 2 проверить 15 минут займет.. и понаблюдать час-два не стало ли быстрее

фактически что мастер что реплика у вас работают как сервера не с 64gb памяти а с 16-18gb сейчас
27 июл 20, 21:51    [22174419]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
flashgun
Member

Откуда:
Сообщений: 14
Maxim Boguk, спасибо за совет!

База, правда, запускалась 23 минуты, но при первом приближении количество WAL-сегментов начало уменьшаться. Сейчас их 3089 (было 3103 на момент останова базы). Продолжаю наблюдение.

Скажите, есть ли смысл на основном сервере включить huge pages и увеличить размер shared_buffers? Там похожая картина: вечно свободно 20+ гигабайт ОЗУ.
28 июл 20, 01:46    [22174488]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
Maxim Boguk
Member

Откуда: Melbourne, Австралия
Сообщений: 4230
flashgun,

При тех настройках zfs что у вас сейчас - скорее всего да имеет.
28 июл 20, 08:54    [22174521]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
flashgun
Member

Откуда:
Сообщений: 14
Maxim Boguk
2)попробовать на реплике 48GB (а то и 56gb) shared buffers поставить чтобы база кешировала все что можно у себя только обязательно с huge pages on

Супер, похоже, что это помогло! Количество WAL медленно, но верно уменьшается, уже 1100 (было 3100).
28 июл 20, 09:48    [22174539]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
Melkij
Member

Откуда: Санкт-Петербург
Сообщений: 1111
flashgun
что мешает receiver-у точно также при записи попадать в кеш ОС, а recovery из этого кеша и читать

Вы ещё упускаете момент, что писать-читать надо не только сами WAL. Если там целиком страница данных (первое изменение после чекпойнта, full page writes) то может и ладно. Но на каждый чих в wal писать целиком страницу - это очень много wal. А если из wal читаем не целиком страницу, а дельту изменения на ней - то сперва надо достать страницу данных которую меняем, её поменять и пометить dirty.
Если в shared_buffers нужной странички нет - просим у ОС прочитать. А ОС уже может достать из своего page cache, но с которым у вас похоже что-то очень не так. (я так же по zfs не специализируюсь)
Я если ещё и bgwriter и чекпойнтер не справляются со сбросом dirty страниц - то сам startup их будет ещё и писать на диск чтобы расчистить места в shared_buffers для изменяемой в данный момент страницы.
28 июл 20, 11:04    [22174567]     Ответить | Цитировать Сообщить модератору
 Re: Разогнать применение WAL на реплике (странное происходит)  [new]
flashgun
Member

Откуда:
Сообщений: 14
Melkij,

Спасибо за уточнения!

С кешем zfs всё действительно не так просто: почему-то у меня его объём 1,3..1,5 Гб, должно при нормальных условиях быть в разы больше. Но, в любом случае мне проще увеличить shared_buffers, чем разбираться с zfs: я погуглил, у большинства прямо противоположная проблема: arc забирает всю память, и люди вынуждены ограничивать объём кеша сверху.

Вот один из немногих примеров схожей с моей проблемы: https://www.reddit.com/r/zfs/comments/98klp2/zfs_arc_size_not_increasing/ - и советы окружающих "zfs/arc виднее".

Тем более, что shared_buffers быстро и понятно помогло: за сутки количество WAL уменьшилось до 625, а задержка с 53 тысяч секунд до 5900.

Спасибо, коллеги!
29 июл 20, 02:01    [22174917]     Ответить | Цитировать Сообщить модератору
Все форумы / PostgreSQL Ответить