sga را به عنوان shared global area می شناسیم! و قرار است پروسسها از این فضا به صورت مشترک استفاده کنند به همین جهت، قسمتی از حافظه که برای sga مورد استفاده قرار می گیرد، shared memory نامیده می شود.
دو پارامتر کلیدی shared memory در لینوکس، shmmax و shmall می باشند که shmmax حداکثر اندازه یک shared memory segment(بر اساس بایت) را مشخص می کند و shmall هم، اندازه کلی shared memory(بر اساس page) یا همان جمع اندازه shared memory segmentها را مشخص خواهد کرد.
نکته: پارامتر SHMMNI، حداکثر تعداد shared memory segment را مشخص خواهد کرد.
معمولا مقدار این دو پارامتر، متناسب با اندازه ram ماشین(یا سرور) و همچنین با نظر dba/sa تعیین می شود با این حال، در بسیاری از مستندات، فرمول زیر برای تعیین مقادیر این دو پارامتر، پیشنهاد می شود(البته تعیین مقادیر برای این پارامترها، به مقدار sga بستگی دارد که در ادامه مورد بحث قرار خواهد گرفت):
KERNEL.SHMMAX=1/2 of physical RAM
KERNEL.SHMALL= SHMMAX/PAGE_SIZE
* مقدار PAGE_SIZE با دستور getconf PAGE_SIZE مشخص می شود.
زمانی که مقدار پارامتر sga_target از مقدار تعیین شده برای shmmax کمتر باشد(shmmax>sga_target) تنها از یک shared memory segment استفاده خواهد شد و در غیر این صورت، بر تعداد shared memory segment افزوده خواهد شد. همچنین، حداکثر مقداری که برای sga قابل تنظیم است، برابر با مقدار پارامتر shmall خواهد بود.
نکته: معمولا توصیه می شود که اندازه پارامتر shmmax از مقدار sga بیشتر باشد.
در ادامه متن، قصد داریم به اثرگذاری پارامتر shmall بر روی مقدار sga بپردازیم.
در صورتی که مقدار پارامتر shmall، به عدد بسیار پایینی تنظیم شود، instance استارت نخواهد شد. مثال زیر را ببینید.
مثال: فضای ram در یک ماشین مجازی، 16GB می باشد.
[root@myhost ~]# free -g
total used free shared buffers cached
Mem: 15 0 15 0 0 0
-/+ buffers/cache: 0 15
Swap: 15 0 15
همچنین در این محیط، مقدار پارامتر kernel.shmall به عدد یک تنظیم شده است:
[root@myhost ~]# sysctl -a|grep shmall
kernel.shmall = 1
2GB مقداری است که برای sga در نظر گرفته شده است:
[root@myhost ~]# grep “sga” /home/oracle/a.ora
*.sga_max_size=2g
*.sga_target=2g
سوال! در چنین شرایطی، instance استارت خواهد شد؟ پاسخ منفی است:
SQL> startup pfile=’/home/oracle/a.ora’;
ORA-27104: system-defined limits for shared memory was misconfigured
همانطور که مشاهده می شود، استارت شدن instance، به دلیل مقدار بسیار پایین shmall، با خطا مواجه شده است.
حال قصد داریم به سوال دیگری پاسخ دهیم.
در صورتی که پارامتر kernel.shmall به یک مقدار بسیار بزرگ(فرضا بزرگتر از اندازه ram)، تنظیم شود، باز هم استارت شدن instance به خطا می انجامد؟ برای مشاهده پاسخ؛ مثال بعدی را ببینید.
مثال: در یک ماشین که سایز ram ان برابر با 16GB می باشد، پارامتر kernel.shmall به عدد بسیار بزرگی تنظیم شده است:
[root@myhost ~]# sysctl –a|grep shmall
kernel.shmall = 4194304001100110011
نکته: به کمک دستور ipcs هم می توانیم مشخصات shared memory را ببینیم:
[root@myhost ~]# ipcs -lm
—— Shared Memory Limits ——–
max number of segments = 4096
max seg size (kbytes) = 16777216
max total shared memory (kbytes) = 16777216004400440044
min seg size (bytes) = 1
همچنین در این محیط، مقدار پارامتر sga، برابر با 500GB می باشد:
[root@myhost ~]# grep “sga” /home/oracle/a.ora
*.sga_max_size=500g
*.sga_target=500g
سوال! در این شرایط، instance استارت خواهد شد؟ با اجرای دستور زیر، به این سوال پاسخ خواهیم داد:
SQL> startup pfile=’/home/oracle/a.ora’
ORACLE instance started.
Total System Global Area 5.3687E+11 bytes
Fixed Size 12240672 bytes
Variable Size 6.1203E+10 bytes
Database Buffers 4.7513E+11 bytes
Redo Buffers 524627968 bytes
Database mounted.
Database opened.
همانطور که می بینید، instance استارت شده و بانک در حالت open قرار گرفته است! در چنین شرایطی، وضعیت منابع مصرفی ماشین را بررسی می کنیم:
[root@ss ~]# free -g
total used free shared buffers cached
Mem: 15 15 0 14 0 14
-/+ buffers/cache: 0 14
Swap: 15 15 0
خروجی دستور free نشان می دهد که علاوه بر مصرف فضای ram، فضای swap هم به صورت کامل استفاده شده است! در این شرایط، اگر اوراکل بخواهد از مابقی فضای تعیین شده برای sga هم استفاده کند، به خطا برخواهد خورد و اصطلاحا down می شود:
2019-01-15T15:30:49.506743+03:30
PMON (ospid: 13381): terminating the instance due to ORA error 12752
Cause – ‘Instance is being terminated due to fatal process death (pid: 8, ospid: 13395, SA00)’
2019-01-15T15:30:49.726348+03:30
System state dump requested by (instance=1, osid=13381 (PMON)), summary=[abnormal instance termination].
System State dumped to trace file /18c/base/diag/rdbms/noncdb/noncdb/trace/noncdb_diag_13400_20190115153049.trc
2019-01-15T15:30:51.799980+03:30
Dumping diagnostic data in directory=[cdmp_20190115153049], requested by (instance=1, osid=13381 (PMON)), summary=[abnormal instance termination].
2019-01-15T15:30:53.305670+03:30
Instance terminated by PMON, pid = 13381
مطلع هستید که استفاده از پارامتر lock_sga، مانع از swap کردن اوراکل خواهد شد. سوال! در صورت تنظیم پارامتر lock_sga به مقدار true، مجددا instance استارت می شود؟ پاسخ منفی است:
*.LOCK_SGA=true
SQL> startup pfile=’/home/oracle/a.ora’;
ORA-27126: unable to lock shared memory segment in core
Linux-x86_64 Error: 12: Cannot allocate memory
Additional information: 4407
Additional information: 294921
Additional information: 17179869184
همانطور که می بینید، عملیات استارت instance، با خطا مواجه شده است برای جلوگیری از رخ دادن این خطا(در صورتی که پارامتر lock_sga به مقدار true تنظیم شده باشد)، نباید مقدار sga را عددی بزرگتر از اندازه ram در نظر گرفت.
برای مثال، با تغییر شرایط به شکل زیر، instance استارت خواهد شد:
RAM size =15G
*.sga_max_size=15g
*.sga_target=15g
*.LOCK_SGA=true
SQL> startup nomount pfile=’/home/oracle/a.ora’;
ORACLE instance started.
Total System Global Area 1.6106E+10 bytes
Fixed Size 12215648 bytes
Variable Size 2348810240 bytes
Database Buffers 1.3724E+10 bytes
Redo Buffers 21336064 bytes
SQL>