ბაზის სერვერზე 1-დან 8 GB მეხსიერებით თითქმის ყველაფერს ხუთი პარამეტრი წყვეტს: shared_buffers, work_mem, max_connections, maintenance_work_mem და checkpoint-ის წყვილი. postgresql.conf-ის დანარჩენი ან ნაგულისხმევად კარგადაა, ან დაკარგული index-ის გვერდით დამრგვალების ცდომილებაა. თუ ამის წაკითხვის შემდეგ სხვა არაფერს შეცვლი, დააყენე shared_buffers მეხსიერების დაახლოებით მეოთხედზე, work_mem პატარა დატოვე, max_connections დაბალი, და autovacuum-ს დააცალე იმაზე უფრო ძლიერად იმუშაოს, ვიდრე გაშვებისას მუშაობს.
პატარა სერვერზე მორგება დიდზე უფრო მნიშვნელოვანია იმიტომ, რომ შეცდომის ხასიათი განსხვავებულია. დიდი მანქანა, რომელიც ოდნავ არასწორადაა მორგებული, უბრალოდ იმაზე ნელია, ვიდრე შეიძლებოდა. პატარა მანქანა, რომელიც არასწორადაა მორგებული, მეხსიერებას ამოწურავს, ხოლო მეხსიერების ამოწურვა შენელება არ არის - kernel პროცესს აჩერებს. ქვემოთ ყველაფერი სინამდვილეში ფიქსირებული მეხსიერების ბიუჯეტის მიზანმიმართულად ხარჯვაა.
ერთი გაფრთხილება რიცხვებამდე: ცვლილების გამოყენება შენს ჰოსტზეა დამოკიდებული. სერვერი, რომელსაც თავად ადმინისტრირებ, postgresql.conf-სა და shell-ს გაძლევს. მართვადმა ბაზამ შეიძლება superuser ანგარიში და ALTER SYSTEM მოგცეს, ან პანელი, ან ფიქსირებული კონფიგურაცია, რომლის შეცვლაც საერთოდ არ შეგიძლია. გაარკვიე, რომელია შენი, სანამ ცვლილებაზე გეგმას დააფუძნებ, და გახსოვდეს session-დონის ვარიანტები, რადგან ისინი ყველგან მუშაობს.
რას ვარაუდობს ნაგულისხმევი კონფიგურაცია#
PostgreSQL კონფიგურაციით მოდის, რომელიც თითქმის ნებისმიერ მანქანაზე ჩაირთვება, 256 MB მეხსიერებიანზეც. ეს პროექტის განზრახი არჩევანია და ნიშნავს, რომ ნაგულისხმევი მნიშვნელობები რეკომენდაცია არ არის.
| პარამეტრი | ნაგულისხმევი | რა არის |
|---|---|---|
shared_buffers | 128MB | PostgreSQL-ის საკუთარი page ქეში |
work_mem | 4MB | მეხსიერება ერთ sort-ზე ან hash-ზე, თითო node-ზე, თითო query-ზე |
maintenance_work_mem | 64MB | მეხსიერება VACUUM-ისთვის, index-ების აგებისთვის, ALTER TABLE-ისთვის |
effective_cache_size | 4GB | მინიშნება ჯამური ქეშის შესახებ, არაფერს გამოყოფს |
max_connections | 100 | ერთდროული backend პროცესები |
random_page_cost | 4.0 | რამდენად ძვირად ითვლება შემთხვევითი წაკითხვა |
effective_io_concurrency | 1 | რამდენი ერთდროული წაკითხვა შეუძლია storage-ს |
max_wal_size | 1GB | WAL, რომელიც checkpoint-ებს შორის შეიძლება დაგროვდეს |
checkpoint_timeout | 5min | მაქსიმალური დრო checkpoint-ებს შორის |
random_page_cost = 4.0 ყველაზე ნათელი მაგალითია. ის ვარაუდობს, რომ შემთხვევითი წაკითხვა თანმიმდევრულზე ოთხჯერ ძვირია, რაც 2005 წლის მბრუნავი დისკებისთვის მართალი იყო და NVMe-ზე უკიდურესად არასწორია. თუ ხელს არ ახლებ, ის planner-ს sequential scan-ებისკენ უბიძგებს იქ, სადაც index უფრო სწრაფი იქნებოდა. რას ცვლის NVMe სინამდვილეში ამ ხარვეზის ტექნიკურ მხარეს ფარავს.
მეხსიერება: სამი პარამეტრი, რომელიც ყველაფერს წყვეტს#
წარმოიდგინე სერვერის მეხსიერება სამ ქოთნად: ის, რასაც PostgreSQL ერთხელ იჭერს start-ზე, ის, რაც თითოეულ query-ს შეუძლია აიღოს გაშვებისას, და ის, რასაც ოპერაციული სისტემა ფაილის ქეშად ინახავს. თუ პირველ ორზე ზედმეტს დახარჯავ, მესამე ქრება და შემდეგ kernel ყველაფერს კლავს.
`shared_buffers` ერთხელ გამოიყოფა და ყველა backend-ს ინაწილებს. მანქანის მეხსიერების მეოთხედი დიდი ხნის წესია და დაახლოებით 8 GB-მდე კარგად მუშაობს. უფრო მაღალი მნიშვნელობა პატარა სერვერზე იშვიათად ეხმარება, რადგან ოპერაციული სისტემა იმავე ფაილებს მაინც ქეშავს და გაორმაგება მეხსიერებას ორჯერ ხარჯავს.
`work_mem` ის არის, რომელიც კბენს. ის კავშირზე არ არის: ის თითო sort-ზე, hash join-ზე ან hash aggregate node-ზეა, და ერთ რთულ query-ს შეიძლება რამდენიმე ჰქონდეს, თითოეულს მთელი მოცულობის უფლებით. ათ კავშირს, რომელთაგან თითოეული სამ-sort-იან query-ს უშვებს work_mem = 64MB-ით, თითქმის 2 GB-ის მოთხოვნა შეუძლია. გლობალური მნიშვნელობა პატარა დატოვე და გაზარდე ერთი ანგარიშისთვის, რომელსაც ეს სჭირდება:
BEGIN;SET LOCAL work_mem = '64MB';SELECT ... ; -- the monthly aggregateCOMMIT;`maintenance_work_mem` გამოიყენება VACUUM-ის, CREATE INDEX-ისა და ALTER TABLE-ის მიერ და ერთდროულად მხოლოდ რამდენიმე პროცესის მიერ (autovacuum worker-ები თითოეული იღებს autovacuum_work_mem-მდე, რომლის ნაგულისხმევიც ეს მნიშვნელობაა). ის ასაწევად ყველაზე იაფი პარამეტრია და მისი აწევა ხდის, რომ index-ის აგება და vacuum საათების ნაცვლად წუთებში სრულდება.
`effective_cache_size` საერთოდ არაფერს გამოყოფს. ის planner-ს უყვება, დაახლოებით რამდენი შენი მონაცემია სადმე ქეშში მოსალოდნელი, და რეალისტური მნიშვნელობა index scan-ებს ისეთივე იაფად აჩვენებს, როგორიც ისინი სინამდვილეში არიან. სპეციალურად ბაზისთვის განკუთვნილ სერვერზე ჯამური მეხსიერების ნახევრიდან ორ მესამედამდე სამართლიანი ვარაუდია.
აი საწყისი წერტილი და არა ჭეშმარიტება. შეამოწმე საკუთარ დატვირთვაზე.
| სერვერის RAM | shared_buffers | work_mem | maintenance_work_mem | max_connections |
|---|---|---|---|---|
| 1 GB | 192MB | 2MB | 64MB | 20 |
| 2 GB | 384MB | 4MB | 128MB | 25 |
| 4 GB | 1GB | 8MB | 256MB | 40 |
| 8 GB | 2GB | 12MB | 512MB | 60 |
| 14 GB | 3500MB | 16MB | 1GB | 80 |
effective_cache_size მათ გვერდით დააყენე სერვერის მეხსიერების დაახლოებით 60%-ზე: ზემოთ მოცემული სტრიქონებისთვის 512MB, 1GB, 2500MB, 5GB და 9GB.
RE:NODE-ზე მეხსიერების ლიმიტის მიღწევა კონტეინერს ჩერდება და სუფთად თავიდან იტვირთება, ნაცვლად იმისა, რომ swap-ში ჩავარდეს, რაც დანარჩენ მანქანას უფრო კეთილად ექცევა და ზედმეტად ოპტიმისტური work_mem-ის მიმართ დაუნდობელია. პანელის console მეხსიერებას, CPU-სა და დისკს გეგმის ლიმიტების წინააღმდეგ გრაფიკზე აჩვენებს, ასე რომ რიცხვი, რომელზეც უნდა დააფუძნო, ხილულია რაიმეს შეცვლამდე.
კავშირები მეხსიერების პარამეტრია#
ყოველი PostgreSQL კავშირი საკუთარი მეხსიერების მქონე ოპერაციული სისტემის პროცესია. უმოქმედონი იაფია, მაგრამ არა უფასო, ხოლო დაკავებულებს work_mem-ის რამდენჯერმე უფლება აქვთ. ეს max_connections-ს მეხსიერების გადაწყვეტილებად აქცევს და არა ტევადობისად, და პასუხი პატარა სერვერზე გასაკვირად პატარა რიცხვია.
ბაზას ორი CPU ბირთვით ერთდროულად რამდენიმე query-ზე მეტის გაშვება სასარგებლოდ არ შეუძლია. ამ ზღვრის მიღმა კავშირები PostgreSQL-ის შიგნით რიგში დგანან, სადაც რიგში დგომა pool-ში დგომაზე უფრო ძვირია, რადგან ყოველ მოლოდინში მყოფ backend-ს მაინც უჭირავს მეხსიერება და scheduling სლოტი.
- ჯერ აპლიკაციის pool-ის ზომა განსაზღვრე: 10-დან 20-მდე თითო პროცესზე ვებ აპლიკაციების უმეტესობას ფარავს.
- გაამრავლე პროცესების რაოდენობაზე და დაამატე ფონური worker-ები. ეს ჯამი შენი რეალური მოთხოვნაა.
max_connectionsოდნავ ზემოთ დააყენე,superuser_reserved_connections-ით (ნაგულისხმევი 3), რომელიც შენთვის ადგილს ინახავს.- თუ ჯამი დიდი ხდება, ლიმიტის აწევის ნაცვლად წინ pooler დადე.
FATAL: sorry, too many clients already თითქმის ყოველთვის გაჟონვა ან შეუზღუდავი pool-ია და არა ნამდვილი დატვირთვა. Connection pool-ები და ლიმიტები მოკლე ვერსიაა იმისა, თუ რატომ ხდის მეტი კავშირი საქმეს უფრო ნელს, ხოლო თავად კავშირის პარამეტრები PostgreSQL-ის დისტანციურ კავშირებშია.
planner-ს ეუბნები, რა storage გაქვს#
ეს არაფერი ჯდება და ცვლის, რომელ გეგმას აირჩევს planner-ი. NVMe-ზე:
random_page_cost = 1.1effective_io_concurrency = 200default_statistics_target = 100random_page_cost = 1.1 ამბობს, რომ შემთხვევითი წაკითხვა თითქმის ისევე ძვირია, როგორც თანმიმდევრული, რაც flash-ზე სიმართლესთან ახლოსაა. ეს ყველაზე ეფექტური ერთხაზიანი ცვლილებაა სერვერზე, რომლის მონაცემებიც ძირითადად ქეშში ეტევა, რადგან planner-ს აღარ აძლევს full table scan-ის უპირატესობას index-თან შედარებით, რომელიც მას აქვს.
effective_io_concurrency planner-ს საშუალებას აძლევს, ივარაუდოს, რომ რამდენიმე წაკითხვა შეიძლება ერთდროულად მიმდინარეობდეს, რაც bitmap heap scan-ებს ეხმარება. default_statistics_target ზრდის, რამდენ დეტალს აგროვებს ANALYZE თითო სვეტზე; გლობალურად დატოვე 100-ზე და გაზარდე თითო სვეტზე ALTER TABLE ... ALTER COLUMN ... SET STATISTICS 500-ით იმ სვეტზე, რომელსაც დახრილი განაწილება აქვს და planner მას სულ არასწორად აფასებს.
კიდევ ორი, ორივე პატარა სერვერის რეალობებზეა. jit PostgreSQL 12-დან ნაგულისხმევად ჩართულია და ეხმარება გრძელ ანალიტიკურ query-ებს, ხოლო მოკლეებს კომპილაციის დროსა და მეხსიერებას ამატებს; პატარა OLTP ბაზაზე გაზომე და მისი გამორთვა გონივრული ნაგულისხმევია. თუ შენი გეგმა სრულ ბირთვზე ნაკლებ CPU-ს გაძლევს, დააყენე max_parallel_workers_per_gather = 0: პარალელური worker-ები მკაცრ CPU შეზღუდვაზე იმავე ნაჭერს უფრო მეტ ნაწილად ყოფენ და კოორდინაციას ამატებენ. როცა გეგმები არასწორად გამოიყურება, ინსტრუმენტი არის EXPLAIN ANALYZE და არა მეტი გამოცნობა.
Checkpoint-ები, WAL და ჩაწერები#
ყოველი ცვლილება ჯერ write-ahead log-ში იწერება და პერიოდულად checkpoint შეცვლილ გვერდებს მონაცემთა ფაილებში გადაიტანს. checkpoint-ები, რომლებიც ზედმეტად ხშირად მოდის, პატარა ჩაწერის დატვირთვას სრული გვერდის ჩაწერების ნაკადად აქცევს, რადგან გვერდის პირველი ცვლილება checkpoint-ის შემდეგ მთელ გვერდს WAL-ში წერს.
checkpoint_timeout = 15minmax_wal_size = 2GBmin_wal_size = 512MBcheckpoint_completion_target = 0.9wal_compression = oncheckpoint-ების ერთმანეთისგან დაშორება ამცირებს ჩაწერის გაძლიერებას crash-ის შემდეგ უფრო გრძელი აღდგენის ფასად. თხუთმეტი წუთი პატარა სერვერისთვის გონივრული შუალედია. max_wal_size არის ჭერი იმაზე, რამდენი WAL შეიძლება checkpoint-ებს შორის დაგროვდეს, და 2GB 20 GB დისკზე კომფორტულია; ის დისკის რეზერვი არ არის, უბრალოდ ზედა ზღვარია, სანამ checkpoint იძულებით გაეშვება.
checkpoint_completion_target-ის ნაგულისხმევი მნიშვნელობა PostgreSQL 14-დან 0.9-ია, რაც ისედაც ის მნიშვნელობაა, რაც გინდა: ის flush-ს ინტერვალის 90%-ზე ანაწილებს და ერთბაშად არ გადმოყრის. wal_compression = on ცოტა CPU-ს ცვლის შესამჩნევად ნაკლებ WAL-ზე, რაც მნიშვნელოვანია, როცა დისკი 2 TB-ის ნაცვლად 20 GB-ია.
პარამეტრი, რომელიც ხალხს ცდუნებს, synchronous_commit-ია. მისი გამორთვა commit-ებს WAL-ის flush-მდე აბრუნებინებს, რაც ჩაწერაზე მძიმე დატვირთვისთვის რეალური აჩქარებაა და ნიშნავს, რომ მძიმე crash-ს შეუძლია commit-ირებული ტრანზაქციების ბოლო წამის ნაწილი დაკარგოს. ის ბაზას არ აფუჭებს, და ეს განსხვავებაა მთელი არგუმენტი: ანალიტიკისა და მოვლენების მიღებისთვის მისაღებია, ფულთან დაკავშირებულ ყველაფერში - არა. fsync = off და full_page_writes = off სხვა სახეობისაა - მათ შეუძლიათ ბაზა აღუდგენელი დატოვონ და production სერვერზე არ არსებობს დატვირთვა, რომლისთვისაც ისინი ღირს.
Autovacuum პატარა სერვერზე#
autovacuum-ის ნაგულისხმევი ზღვრები ელოდება, სანამ ცხრილის 20% მკვდარი გახდება და მერე წმენდს. პატარა სერვერზე ეს არასწორი გაცვლაა: დიდი vacuum დატვირთულ ცხრილზე ბევრად უფრო დამაზიანებელია, ვიდრე ხშირი პატარები, და მკვდარი ხაზები იმ მეხსიერებასა და ქეშს იკავებენ, რომელიც არ გაქვს.
autovacuum_vacuum_scale_factor = 0.05autovacuum_analyze_scale_factor = 0.02autovacuum_vacuum_cost_limit = 1000autovacuum_naptime = 30slog_autovacuum_min_duration = 1sეს კომბინაცია 20%-ის ნაცვლად 5% მკვდარ ხაზზე წმენდს, ხელახლა ანალიზს უფრო მონდომებით აკეთებს, რომ planner-ის სტატისტიკა პატიოსანი დარჩეს, და cost ლიმიტს ზრდის, რომ worker-ი მცოცავ სიჩქარემდე არ შეიზღუდოს. ცხრილს, რომელიც ყველაზე მეტ ჩაწერას იღებს, ჩვეულებრივ საკუთარი პარამეტრები ეკუთვნის და არა გლობალური ცვლილება:
ALTER TABLE app.sessions SET ( autovacuum_vacuum_scale_factor = 0.01, autovacuum_vacuum_cost_delay = 0);autovacuum არასოდეს გამორთო. სრული ამბავი იმისა, რას აკეთებს, რატომ ჩამორჩება და რა უჯდება bloat, Postgres-ის vacuum-სა და bloat-შია.
Timeout-ები და ლიმიტები, რომლებიც ღირს დაყენება#
აქ ნაგულისხმევი ყველაფერი „შეუზღუდავია“, რაც ნიშნავს, რომ ერთ ცუდ query-ს შეუძლია lock-ის დაკავება, დისკის დროებითი ფაილებით შევსება, ან ტრანზაქციის იმდენ ხანს ღიად დატოვება, რომ autovacuum-მა არაფრის წმენდა ვეღარ შეძლოს. ეს ოთხი ხაზი პატარა სერვერზე უფრო მეტ ინციდენტს გაგარიდებს, ვიდრე მეხსიერების ნებისმიერი რაოდენობით მორგება:
statement_timeout = 30sidle_in_transaction_session_timeout = 60slock_timeout = 5stemp_file_limit = 2GBstatement_timeout უკეთესია role-ზე დაყენდეს და არა გლობალურად, რომ migration ან ღამის ანგარიში შუაში არ მოკვდეს: ALTER ROLE app SET statement_timeout = '30s'. idle_in_transaction_session_timeout კლავს session-ებს, რომლებმაც ტრანზაქცია გახსნეს და წავიდნენ, რაც ყველაზე გავრცელებული მიზეზია, რის გამოც vacuum ვერაფერს იბრუნებს. lock_timeout DDL ბრძანებას უშლის ხელს, გრძელი წაკითხვის უკან რიგში დადგეს და თავის მხრივ ყველა ჩამწერი დაბლოკოს. temp_file_limit ზღუდავს, რას დაღვრის ერთი session დისკზე, როცა work_mem არ ჰყოფნის, რაც 20 GB volume-ზე განსხვავებაა ნელ query-სა და სავსე დისკს შორის. PostgreSQL 17-მა transaction_timeout-იც დაამატა, თუ ისეთ ვერსიაზე ხარ, რომელსაც აქვს.
სად ცხოვრობს პარამეტრები და რომელს სჭირდება restart#
არსებობს ოთხი ადგილი, საიდანაც პარამეტრი შეიძლება მოვიდეს, პრიორიტეტის ზრდის მიხედვით: postgresql.conf (და ნებისმიერი ფაილი, რომელსაც ის მოიცავს), postgresql.auto.conf (იწერება ALTER SYSTEM-ით), თითო ბაზისა და თითო role-ის პარამეტრები და თავად session.
-- See the value, its unit, and whether changing it needs a restartSELECT name, setting, unit, context, source, pending_restartFROM pg_settingsWHERE name IN ('shared_buffers','work_mem','max_connections','random_page_cost');-- Change one durably, if your host gives you the superuser accountALTER SYSTEM SET random_page_cost = 1.1;SELECT pg_reload_conf();-- Narrower scopes, which need no superuserALTER DATABASE shop SET work_mem = '8MB';ALTER ROLE reporting SET work_mem = '64MB';SET LOCAL work_mem = '64MB'; -- this transaction onlycontext სვეტი ის არის, რომელიც უნდა წაიკითხო. postmaster ნიშნავს restart-ს: shared_buffers, max_connections, max_worker_processes და ყველაფერი shared_preload_libraries-ში. sighup ნიშნავს, რომ reload საკმარისია: work_mem, autovacuum-ის პარამეტრები, planner-ის ღირებულებები, timeout-ები. user ნიშნავს, რომ ნებისმიერ session-ს შეუძლია მისი საკუთარი თავისთვის შეცვლა.
მიიღებ თუ არა თავად postgresql.conf-ს, ALTER SYSTEM-ს თუ არცერთს, ჰოსტზეა დამოკიდებული, ამიტომ შეამოწმე, რისი შეცვლის უფლებას გაძლევს შენი, სანამ ფაილის რედაქტირებაზე გეგმას დაწერ. ორი ჩვევა ამას უსაფრთხოს ხდის, სადაც არ უნდა მოხვდე: შეცვალე ერთი პარამეტრი ერთდროულად და restart-მდე გააკეთე backup, რადგან სერვერი, რომელიც კონფიგურაციის ფაილში ბეჭდვის შეცდომის გამო არ იწყება, ცუდი დროა იმის აღმოსაჩენად, რომ backup არ გაქვს. RE:NODE-ზე აღდგენა ღილაკია და backup სლოტები ყველა დონეს მოჰყვება - აღდგენის გამოცდა, სანამ დაგჭირდება ამტკიცებს, რომ მისი ერთხელ განზრახ დაჭერა ღირს.
გაზომვა, ცვლილებამდე და მის შემდეგ#
გაზომვის გარეშე მორგება დეკორაციაა. სამი წყარო თითქმის ყველაფერს ფარავს.
-- The queries actually costing you time (needs the extension installed)CREATE EXTENSION IF NOT EXISTS pg_stat_statements;SELECT calls, round(mean_exec_time::numeric, 1) AS avg_ms, round(total_exec_time::numeric) AS total_ms, queryFROM pg_stat_statementsORDER BY total_exec_time DESCLIMIT 10;pg_stat_statements shared_preload_libraries-ში უნდა იყოს, რაც მის ჩასართავად restart-ს ნიშნავს. ეს restart ღირს: ეს ერთადერთი view-ა, რომელიც გეუბნება, სად მიდის დრო და არა იქ, სადაც შენ ფიქრობ, რომ მიდის.
log_min_duration_statement = 500mslog_checkpoints = onlog_temp_files = 0log_lock_waits = onlog_temp_files = 0 ყოველ დროებით ფაილს ლოგავს, რითაც აღმოაჩენ, რომ work_mem კონკრეტული query-სთვის ძალიან პატარაა და არა ყველაფრისთვის. log_checkpoints (PostgreSQL 15-დან ნაგულისხმევად ჩართული) გეუბნება, checkpoint-ებს timeout-ის ნაცვლად max_wal_size აიძულებს თუ არა, რაც სიგნალია მის ასაწევად. log_lock_waits ასახელებს ბრძანებას, რომელიც სხვებს ბლოკავს.
და ბოლოს, pg_stat_activity ინციდენტის დროს, pg_stat_database ქეშის თანაფარდობებისთვის დროში, და pg_stat_io, თუ PostgreSQL 16-ზე ან უფრო ახალზე ხარ. შეადარე ერთი და იგივე query ყოველ ცვლილებამდე და მის შემდეგ EXPLAIN (ANALYZE, BUFFERS)-ით და დატვირთვის გრაფიკის ფორმას ადევნე თვალი - სერვერის დატვირთვის გრაფიკის კითხვა განმარტავს, რატომ მალავს საშუალო იმას, რაც გატკინა. თუ რიცხვები ამბობს, რომ სამუშაო სიმრავლე უბრალოდ არ ეტევა, მორგებას ადგილი ამოეწურა და როდის გაიუმჯობესო შენი გეგმა პატიოსანი შემდეგი ნაბიჯია.
FAQ#
რამდენი უნდა იყოს shared_buffers 2 GB სერვერზე?
დაახლოებით 384 MB, რაც მეოთხედზე ცოტა ნაკლებია. უფრო დიდი მნიშვნელობები ოპერაციული სისტემის ქეშისა და query-ების მეხსიერებისთვის ნაკლებს ტოვებს, და პატარა სერვერზე გაორმაგებული ქეშირება უფრო მეტს ჯდება, ვიდრე დამატებული hit rate იგებს.
რატომ მოკლა ჩემი სერვერი მეხსიერების ამოწურვამ, როცა Postgres სწორად იყო კონფიგურირებული?
თითქმის ყოველთვის work_mem გამრავლებული პარალელურობაზე. პარამეტრი თითო sort ან hash node-ზეა და არა თითო კავშირზე, ამიტომ რამდენიმე რთულ query-ს თითოეულს შეუძლია მისი რამდენჯერმე მოთხოვნა. შეამცირე გლობალური მნიშვნელობა და გაზარდე თითო session-ზე, სადაც საჭიროა.
მჭირდება connection pooler პატარა ბაზაზე?
თუ შენი აპლიკაცია კავშირებს უკვე პროცესის შიგნით pool-ავს, ჩვეულებრივ არა. ის გჭირდება, როცა რამდენიმე აპლიკაციის პროცესს თითოეულს საკუთარი pool უჭირავს და ჯამი max_connections-ს ასობით რიცხვამდე აწევდა, ან როცა serverless სტილის worker-ები თითო მოთხოვნაზე კავშირს ხსნიან.
უსაფრთხოა synchronous_commit-ის გამორთვა?
უსაფრთხოა იმ გაგებით, რომ ბაზას ვერ დააზიანებს, და არაუსაფრთხო იმ გაგებით, რომ crash-ს შეუძლია ბოლო რამდენიმე commit-ირებული ტრანზაქციის დაკარგვა. გონივრულია მოვლენების მიღებისა და ანალიტიკისთვის, არა შეკვეთებისა და გადახდებისთვის. არასოდეს გამორთო fsync ან full_page_writes იმაზე, რაც გენაღვლება.
რომელ პარამეტრებს სჭირდება restart და არა reload?
shared_buffers, max_connections, max_worker_processes, wal_level, listen_addresses, port და shared_preload_libraries. შეამოწმე pg_settings-ის context სვეტი: postmaster ნიშნავს restart-ს, sighup - reload-ს.
რა უნდა მოვარგო პირველად, თუ ბაზა ნელია?
ამ პოსტიდან არაფერი. იპოვე ნელი query pg_stat_statements-ით, წაიკითხე მისი გეგმა და შეამოწმე, index ხომ არ აკლია. კონფიგურაცია პროცენტებს აბრუნებს; დიდ ცხრილზე დაკარგული index სიდიდის რიგებს ჯდება.




კომენტარები
სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.