در مطلب “چرا Huge Page” در مورد چرایی و مزیتهای استفاده از Huge Page مطالبی را ارائه کردیم. در این مطلب قصد داریم مطالبی را در مورد نحوه پیکربندی Huge Page برای دیتابیس پستگرس ارائه کنیم.
دیتابیس پستگرس هم همانند دیگر دیتابیسها از Huge Page پشتیبانی می کند و امکان استفاده از این قابلیت در محیط لینوکس از نسخه 9 و 10 وجود دارد و در نسخه 11، پستگرس، علاوه بر محیط لینوکس، Huge Page را در محیط ویندوز هم ساپورت می کند.
پستگرس در این زمینه پارامتری به نام huge_pages دارد که می تواند سه مقدار به خود بگیرد:
usefdb=# select enumvals from pg_settings where name=’huge_pages’;
enumvals
————–
{off,on,[try]}
huge_pages= try: مقدار پیش فرض پارامتر huge_pages برابر با try می باشد و در صورتی که Huge Pgae در سطح سیستم عامل پیکربندی شده باشد، دیتابیس پستگرس به صورت خودکار از این قابلیت استفاده می کند(با توجه به مقدار huge_pages= try).
نکته: huge_pages= try در پستگرس معادل use_large_pages=true در دیتابیس اوراکل می باشد و تنظیم پارامتر huge_pages به مقدار TRUE، امکان استفاده همزمان Huge Page و normal Page را خواهد داد.
huge_pages= on: با تنظم پارامتر huge_pages به مقدار on، در صورتی که پستگرس نتواند برای فضای shared buffer از Huge Page استفاده کند، دیتابیس در زمان استارت با خطا مواجه خواهد شد:
usefdb=# alter system set huge_pages=on;
ALTER SYSTEM
[root@myhost ~]# grep ^Huge /proc/meminfo
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
[postgres@myhost ~]$ pg_ctl -D /postgres/data1/ restart
2020-04-07 05:29:52.879 EDT [19172] FATAL: could not map anonymous shared memory: Cannot allocate memory
2020-04-07 05:29:52.879 EDT [19172] HINT: This error usually means that PostgreSQL’s request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 1124261888 bytes), reduce PostgreSQL’s shared memory usage, perhaps by reducing shared_buffers or max_connections.
2020-04-07 05:29:52.879 EDT [19172] LOG: database system is shut down
pg_ctl: could not start server
نکته: huge_pages=on در پستگرس معادل use_large_pages=only در اوراکل خواهد بود.
huge_pages= off: با این تنظیم، دیتابیس از Huge Page استفاده نمی کند. پستگرس برای حافظه کمتر از 2GB این گزینه را پیشنهاد می کند.
پیکربندی Huge Page برای پستگرس
مهمترین فاکتور اثرگذار برای تصمیم گیری در مورد مقدار پارامتر nr_hugepages، مقدار جاری پارامتر shared_buffers می باشد.
توجه: shared buffer در پستگرس مشابه SGA در اوراکل است.
با این حال داکیومنت پستگرس، برای تنظیم مقدار پارامتر nr_hugepages انجام مراحل زیر را پیشنهاد می کند.
مرحله 1: قبل از آنکه Huge Page را پیکربندی کرده باشیم، دیتابیس را استارت کرده و شماره server process اصلی پستگرس که در فایل PGDATA/postmaster.pid$ قرار دارد را مشخص می کنیم.
عدم پیکربندی Huge Page:
[root@myhost ~]# grep ^Huge /proc/meminfo
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
تعیین شماره پروسس Postmaster:
[postgres@myhost ~]$ export PGDATA=/postgres/data1
[postgres@myhost ~]$ head -1 $PGDATA/postmaster.pid
32676
با دستور زیر خواهیم دید که این پروسس(32676)، parent پروسسهای دیگر پستگرس می باشد:
[root@myhost ~]# ps -eaf|grep postgres
postgres 32676 1 0 09:34 pts/2 00:00:00 /postgres/11/bin/postgres -D /postgres/data1
postgres 3357 32676 0 09:34 ? 00:00:00 postgres: checkpointer
postgres 3358 32676 0 09:34 ? 00:00:00 postgres: background writer
postgres 3359 32676 0 09:34 ? 00:00:00 postgres: walwriter
postgres 3360 32676 0 09:34 ? 00:00:00 postgres: autovacuum launcher
postgres 3361 32676 0 09:34 ? 00:00:00 postgres: stats collector
postgres 3362 32676 0 09:34 ? 00:00:00 postgres: logical replication launcher
مرحله 2: در گام دوم، مقدار (Peak virtual memory size(VmPeak یا همان حداکثر حافظه ای که توسط پروسس 32676 استفاده شده را با کمک دستور زیر مشخص می کنیم.
[postgres@myhost ~]$ grep ^VmPeak /proc/32676/status
VmPeak: 1224964 kB
مرحله 3: دستور زیر سایز پیش فرض هر Huge Page را در سیستم عامل مشخص می کند(این عدد می تواند از 2MB تا 1GB باشد و نحوه تغییر آن قبلا توضیح داده شد).
[postgres@myhost ~]$ grep ^Hugepagesize /proc/meminfo
Hugepagesize: 2048 kB
مرحله 4: با کمک فرمول VmPeak/Hugepagesize مقدار پارامتر nr_hugepages را مشخص می کنیم:
usefdb=# select 1224964/2048;
?column?
———-
598
عدد بدست آمده را برای پارامتر vm.nr_hugepages در فایل sysctl.conf یا فایلهای موجود در زیر دایرکتوری /etc/sysctl.d/ تنظیم می کنیم:
[root@myhost ~]# vi /etc/sysctl.conf
vm.nr_hugepages=600
دو راه برای اعمال مقدار تنظیم شده برای پارامتر vm.nr_hugepages وجود دارد. یکی reboot و دیگری استفاده از دستور sysctl به همراه سوییچ p، که البته استفاده از reboot هر چند که نیاز به downtime بیشتری دارد ولی معمولا توصیه می شود:
[root@myhost ~]# sysctl -p
با اجرای دستور فوق، خواهیم دید که Huge Page کانفیگ شده است.
[root@myhost ~]# grep ^Huge /proc/meminfo
HugePages_Total: 600
HugePages_Free: 600
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
مرحله 5: مقدار محدودیت max locked memory یا همان memlock را برای کاربر سیستم عاملی postgres افزایش می دهیم. به عبارت دیگر، مجوز لازم برای قفل کردن قسمتی از حافظه را به این کاربر می دهیم.
مقدار memlock را می توان برابر حاصل ضرب HugePage و Hugepagesize قرار داد البته این عدد طبق نکاتی که در مرحله دوم گفته شد، برابر خواهد بود با مقدار VmPeak:
*مقدار memlock بر مبنای KB می باشد.
memlock=2048*598= 1224704
[root@myhost ~]# vi /etc/security/limits.conf
postgres soft memlock 1224704
postgres hard memlock 1224704
بعد از تنظیم مقدار memlock، مجددا به سرور login کرده و دستور زیر را اجرا می کنیم:
[root@myhost ~]# exit
Logout
[root@myhost ~]# su – postgres
[postgres@myhost ~]$ ulimit -l
1224704
توجه: در صورتی که قصد تعریف سرویس برای استارت دیتابیس پستگرس را در محیط systemd داریم، باید مقدار memlock را در فایل کانفیگ سرویس تعیین کنیم:
vi /etc/systemd/system/postgres.service
[Service]
…
LimitMEMLOCK=infinity
مرحله 6: پستگرس توصیه می کند Transparent Huge Page را در سیستم عامل غیرفعال کنیم. مراحل غیرفعال کردن THP و همچنین دلایل توصیه عدم استفاده از آن در مقاله “تفاوتهای Transparent Huge Page با standard Huge Page” توضیح داده شده است.
مرحله 7: بعد از انجام تنظیمات انجام شده، دیتابیس را restart می کنیم:
[postgres@myhost ~]$ pg_ctl -D /postgres/data1/ restart
با بررسی مجدد خواهیم دید که Huge Page توسط پستگرس در حال استفاده است:
[root@myhost ~]# grep ^Huge /proc/meminfo
HugePages_Total: 600
HugePages_Free: 574
HugePages_Rsvd: 511
HugePages_Surp: 0
Hugepagesize: 2048 kB