تلاشی برای ایجاد آنالوگ ASH برای PostgreSQL

بیانیه مشکل

برای بهینه سازی پرس و جوهای PostgreSQL، توانایی تجزیه و تحلیل تاریخچه فعالیت، به ویژه، انتظارها، قفل ها و آمار جدول بسیار مورد نیاز است.

فرصت های موجود

ابزار تحلیل بار کاری تاریخی یا "AWR for Postgres": راه حل بسیار جالبی است اما سابقه pg_stat_activity و pg_locks وجود ندارد.

پسوند pgsentinel :
«تمام اطلاعات انباشته شده فقط در RAM ذخیره می شود و میزان حافظه مصرفی با تعداد آخرین رکوردهای ذخیره شده تنظیم می شود.

فیلد queryid اضافه شده است - همان queryid از پسوند pg_stat_statements (پیش نصب لازم است).«

البته این خیلی کمک می‌کند، اما دردسرسازترین نکته اولین نکته است.»تمام اطلاعات انباشته شده فقط در RAM ذخیره می شود "، یعنی بر پایه هدف تأثیر می گذارد. علاوه بر این، تاریخچه قفل و آمار جدول وجود ندارد. آن ها راه حل به طور کلی ناقص است:هنوز پکیج آماده ای برای نصب وجود ندارد. پیشنهاد می شود خودتان منابع را دانلود و کتابخانه را جمع آوری کنید. ابتدا باید بسته “devel” را برای سرور خود نصب کنید و مسیر را روی pg_config در متغیر PATH تنظیم کنید.".

در کل هیاهو زیاد است و در مورد دیتابیس های تولیدی جدی شاید نتوان کاری با سرور انجام داد. ما باید دوباره چیزی از خودمان پیدا کنیم.

اخطار.

به دلیل حجم نسبتاً زیاد و به دلیل ناقص بودن دوره آزمایشی، مقاله عمدتاً جنبه اطلاعاتی دارد و به عنوان مجموعه ای از پایان نامه ها و نتایج میانی است.
مطالب دقیق تر بعداً در قسمت هایی تهیه خواهد شد

پیش نویس الزامات راه حل

لازم است ابزاری ایجاد کنید که به شما امکان می دهد ذخیره کنید:

تاریخچه مشاهده pg_stat_activity
تاریخچه قفل جلسه با استفاده از نمای pg_locks

نیاز راه حل-تاثیر را بر پایگاه داده هدف به حداقل برسانید.

ایده کلی- عامل جمع آوری داده ها نه در پایگاه داده هدف، بلکه در پایگاه داده نظارت به عنوان یک سرویس systemd راه اندازی می شود. بله، مقداری از دست دادن داده ها ممکن است، اما این برای گزارش گیری حیاتی نیست، اما هیچ تاثیری بر پایگاه داده هدف از نظر حافظه و فضای دیسک ندارد. و در مورد استفاده از یک استخر اتصال، تأثیر آن بر فرآیندهای کاربر حداقل است.

مراحل اجرا

1. جداول سرویس

یک طرح واره جداگانه برای ذخیره جداول استفاده می شود تا تجزیه و تحلیل جداول اصلی مورد استفاده را پیچیده نکند.

DROP SCHEMA IF EXISTS activity_hist ;
CREATE SCHEMA activity_hist AUTHORIZATION monitor ;

مهم: طرحواره در پایگاه داده هدف ایجاد نمی شود، بلکه در پایگاه داده نظارت ایجاد می شود.

تاریخچه مشاهده pg_stat_activity

یک جدول برای ذخیره عکس های فوری فعلی نمای pg_stat_activity استفاده می شود

activity_hist.history_pg_stat_activity:

--ACTIVITY_HIST.HISTORY_PG_STAT_ACTIVITY
DROP TABLE IF EXISTS activity_hist.history_pg_stat_activity;
CREATE TABLE activity_hist.history_pg_stat_activity
(
  timepoint timestamp without time zone ,
  datid             oid  , 
  datname           name ,
  pid               integer,
  usesysid          oid    ,
  usename           name   ,
  application_name  text   ,
  client_addr       inet   ,
  client_hostname   text   ,
  client_port       integer,
  backend_start     timestamp with time zone ,
  xact_start        timestamp with time zone ,
  query_start       timestamp with time zone ,
  state_change      timestamp with time zone ,
  wait_event_type   text ,                     
  wait_event        text ,                   
  state             text ,                  
  backend_xid       xid  ,                 
  backend_xmin      xid  ,                
  query             text ,               
  backend_type      text ,  
  queryid           bigint
);

برای سرعت بخشیدن به درج - بدون فهرست یا محدودیت.

برای ذخیره خود تاریخچه، از جدول پارتیشن بندی شده استفاده می شود:

activity_hist.archive_pg_stat_activity:

DROP TABLE IF EXISTS activity_hist.archive_pg_stat_activity;
CREATE TABLE activity_hist.archive_pg_stat_activity
(
  timepoint timestamp without time zone ,
  datid             oid  , 
  datname           name ,
  pid               integer,
  usesysid          oid    ,
  usename           name   ,
  application_name  text   ,
  client_addr       inet   ,
  client_hostname   text   ,
  client_port       integer,
  backend_start     timestamp with time zone ,
  xact_start        timestamp with time zone ,
  query_start       timestamp with time zone ,
  state_change      timestamp with time zone ,
  wait_event_type   text ,                     
  wait_event        text ,                   
  state             text ,                  
  backend_xid       xid  ,                 
  backend_xmin      xid  ,                
  query             text ,               
  backend_type      text ,
  queryid           bigint
)
PARTITION BY RANGE (timepoint);

از آنجایی که در این مورد هیچ الزامی برای سرعت درج وجود ندارد، برخی از شاخص ها برای سرعت بخشیدن به ایجاد گزارش ایجاد شده اند.

تاریخچه مسدود کردن جلسه

یک جدول برای ذخیره عکس های لحظه ای فعلی از قفل های جلسه استفاده می شود:

activity_hist.history_locking:

--ACTIVITY_HIST.HISTORY_LOCKING
DROP TABLE IF EXISTS activity_hist.history_locking;
CREATE TABLE activity_hist.history_locking
(
	timepoint timestamp without time zone ,
	locktype text ,
	relation oid ,
	mode text ,
	tid xid ,
	vtid text ,
	pid integer ,
	blocking_pids integer[] ,
	granted boolean
);

همچنین برای سرعت بخشیدن به درج، هیچ فهرست یا محدودیتی وجود ندارد.

برای ذخیره خود تاریخچه، از جدول پارتیشن بندی شده استفاده می شود:

activity_hist.archive_locking:

DROP TABLE IF EXISTS activity_hist.archive_locking;
CREATE TABLE activity_hist.archive_locking
(
	timepoint timestamp without time zone ,
	locktype text ,
	relation oid ,
	mode text ,
	tid xid ,
	vtid text ,
	pid integer ,
	blocking_pids integer[] ,
	granted boolean	
)
PARTITION BY RANGE (timepoint);

از آنجایی که در این مورد هیچ الزامی برای سرعت درج وجود ندارد، برخی از شاخص ها برای سرعت بخشیدن به ایجاد گزارش ایجاد شده اند.

2. پر کردن تاریخچه فعلی

برای جمع‌آوری مستقیم عکس‌های فوری، از یک اسکریپت bash استفاده می‌شود که تابع plpgsql را اجرا می‌کند.

get_current_activity.sh

#!/bin/bash
#########################################################
#get_current_activity.sh

ERROR_FILE='/home/demon/get_current_activity'$(date +%Y%m%d-)'T'$(date +%H)$(date +%M)$(date +%S)
host=$1
s_name=$2
s_pass=$3

psql  -A -t -q -v ON_ERROR_STOP=1 -c "SELECT activity_hist.get_current_activity( '$host' , '$s_name' , '$s_pass' )" >/dev/null 2>$ERROR_FILE

line_count=`cat $ERROR_FILE | wc -l`
if [[ $line_count != '0' ]];
then
    rm -f /home/demon/*.err >/dev/null 2>/dev/null
	cp $ERROR_FILE $ERROR_FILE'.err' >/dev/null 2>/dev/null  
fi
rm $ERROR_FILE >/dev/null 2>/dev/null
exit 0

plpgsql تابع dblink به نماها در پایگاه داده هدف دسترسی پیدا می کند و ردیف ها را در جداول سرویس در پایگاه داده مانیتورینگ قرار می دهد.

get_current_activity.sql

CREATE OR REPLACE FUNCTION activity_hist.get_current_activity( current_host text , current_s_name text , current_s_pass text ) RETURNS BOOLEAN AS $$
DECLARE 
  database_rec record;
  dblink_str text ;
BEGIN   

	EXECUTE 'SELECT dblink_connect(''LINK1'',''host='||current_host||' port=5432 dbname=postgres'||
	                                         ' user='||current_s_name||' password='||current_s_pass|| ' '')';



--------------------------------------------------------------------
--GET pg_stat_activity stats
	INSERT INTO activity_hist.history_pg_stat_activity
	(
		SELECT * FROM dblink('LINK1',
			'SELECT 
			now() , 
			datid             , 
			datname           ,
			pid               ,
			usesysid              ,
			usename              ,
			application_name     ,
			client_addr          ,
			client_hostname      ,
			client_port       ,
			backend_start         ,
			xact_start            ,
			query_start           ,
			state_change          ,
			wait_event_type    ,                     
			wait_event         ,                   
			state              ,                  
			backend_xid         ,                 
			backend_xmin        ,                
			query              ,               
			backend_type   			
		FROM pg_stat_activity
		') 
		AS t (
		    timepoint 		  timestamp without time zone ,			
			datid             oid  , 
			datname           name ,
			pid               integer,
			usesysid          oid    ,
			usename           name   ,
			application_name  text   ,
			client_addr       inet   ,
			client_hostname   text   ,
			client_port       integer,
			backend_start     timestamp with time zone ,
			xact_start        timestamp with time zone ,
			query_start       timestamp with time zone ,
			state_change      timestamp with time zone ,
			wait_event_type   text ,                     
			wait_event        text ,                   
			state             text ,                  
			backend_xid       xid  ,                 
			backend_xmin      xid  ,                
			query             text ,               
			backend_type      text 			
		)
	);

---------------------------------------	
--ACTIVITY_HIST.HISTORY_LOCKING	
	INSERT INTO activity_hist.history_locking
	(
		SELECT * FROM dblink('LINK1',
			'SELECT 
			now() , 
			lock.locktype,
			lock.relation,
			lock.mode,
			lock.transactionid as tid,
			lock.virtualtransaction as vtid,
			lock.pid,
			pg_blocking_pids(lock.pid), 
			lock.granted
			FROM 	pg_catalog.pg_locks lock LEFT JOIN pg_catalog.pg_database db ON db.oid = lock.database
			WHERE NOT lock.pid = pg_backend_pid()	
		') 
		AS t (
			timepoint timestamp without time zone ,
			locktype text ,
			relation oid , 
			mode text ,
			tid xid ,
			vtid text ,
			pid integer ,
			blocking_pids integer[] ,
			granted boolean
		)
	);
	PERFORM dblink_disconnect('LINK1');
	
	RETURN TRUE ;
END
$$ LANGUAGE plpgsql;

برای جمع‌آوری عکس‌های فوری، از سرویس systemd و دو اسکریپت استفاده می‌شود:

pg_current_activity.service

# /etc/systemd/system/pg_current_activity.service
[Unit]
Description=Collect history of pg_stat_activity , pg_locks 
Wants=pg_current_activity.timer

[Service]
Type=forking
StartLimitIntervalSec=0
ExecStart=/home/postgres/pgutils/demon/get_current_activity.sh 10.124.70.40 postgres postgres

[Install]
WantedBy=multi-user.target

pg_current_activity.timer

# /etc/systemd/system/pg_current_activity.timer
[Unit]
Description=Run pg_current_activity.sh every 1 second
Requires=pg_current_activity.service

[Timer]
Unit=pg_current_activity.service
OnCalendar=*:*:0/1
AccuracySec=1

[Install]
WantedBy=timers.target

اختصاص حقوق به اسکریپت ها:
# chmod 755 pg_current_activity.timer
# chmod 755 pg_current_activity.service

بیایید سرویس را شروع کنیم:
# systemctl daemon-reload
# systemctl pg_current_activity.service را شروع کنید

بدین ترتیب تاریخچه نماها در قالب عکس های فوری ثانیه به ثانیه جمع آوری می شود. البته اگر همه چیز به همین شکل باقی بماند، اندازه میزها خیلی سریع افزایش می یابد و کار کم و بیش سازنده غیرممکن می شود.

سازماندهی آرشیو داده ها ضروری است.

3. تاریخچه بایگانی

برای بایگانی از آرشیو جداول پارتیشن بندی شده* استفاده می شود.

پارتیشن‌های جدید هر ساعت ایجاد می‌شوند، در حالی که داده‌های قدیمی از جداول تاریخ* حذف می‌شوند، بنابراین اندازه جداول تاریخ* تغییر زیادی نمی‌کند و سرعت درج با گذشت زمان کاهش نمی‌یابد.

ایجاد بخش های جدید توسط تابع plpgsql activity_hist.archive_current_activity انجام می شود. الگوریتم کار بسیار ساده است (با استفاده از مثال قسمت جدول archive_pg_stat_activity).

یک بخش جدید ایجاد و پر کنید

EXECUTE format(
'CREATE TABLE ' || partition_name || 
' PARTITION OF activity_hist.archive_pg_stat_activity FOR VALUES FROM ( %L ) TO ( %L ) ' , 
to_char(date_trunc('year', partition_min_range ),'YYYY')||'-'||
to_char(date_trunc('month', partition_min_range ),'MM')||'-'||
to_char(date_trunc('day', partition_min_range ),'DD')||' '||
to_char(date_trunc('hour', partition_min_range ),'HH24')||':00', 
to_char(date_trunc('year', partition_max_range ),'YYYY')||'-'||
to_char(date_trunc('month', partition_max_range ),'MM')||'-'||
to_char(date_trunc('day', partition_max_range ),'DD')||' '||
to_char(date_trunc('hour', partition_max_range ),'HH24')||':00'
);

INSERT INTO activity_hist.archive_pg_stat_activity
(
	SELECT 	* 
	FROM 	activity_hist.history_pg_stat_activity
	WHERE 	timepoint BETWEEN partition_min_range AND partition_max_range 		
);

ایجاد نمایه ها

EXECUTE format	(
'CREATE INDEX '||index_name||
' ON '||partition_name||' ( wait_event_type , backend_type , timepoint )' 
);

EXECUTE format	('CREATE INDEX '||index_name||
' ON '||partition_name||' ( wait_event_type , backend_type , timepoint , queryid )' 
);

حذف داده های قدیمی از جدول history_pg_stat_activity

DELETE 
FROM 	activity_hist.history_pg_stat_activity
WHERE 	timepoint < partition_max_range;

البته هر از چند گاهی قسمت های قدیمی به عنوان غیر ضروری حذف می شوند.

گزارش های اساسی

در واقع چرا این همه انجام می شود؟ برای به دست آوردن گزارش هایی که بسیار مبهم یادآور AWR اوراکل است.

اضافه کردن این نکته ضروری است که برای دریافت گزارش ها باید بین نماهای pg_stat_activity و pg_stat_statements ارتباط برقرار کنید. جداول با افزودن یک ستون "queryid" به جداول "history_pg_stat_activity"، "archive_pg_stat_activity" مرتبط می شوند. روش افزودن مقدار ستون خارج از محدوده این مقاله است و در اینجا توضیح داده شده است pg_stat_statements + pg_stat_activity + loq_query = pg_ash؟ .

کل زمان CPU برای پرسش ها

درخواست :

WITH hist AS
(
SELECT 
	aa.query ,aa.queryid ,			
	count(*) * interval '1 second' AS duration 
FROM 	activity_hist.archive_pg_stat_activity aa
WHERE timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND  pg_stat_history_end+(current_hour_diff * interval '1 hour')  AND backend_type = 'client backend' AND datname != 'postgres' AND	( aa.wait_event_type IS NULL  ) ANDaa.state = 'active'
GROUP BY aa.wait_event_type , aa.wait_event , aa.query ,aa.queryid		
UNION 
SELECT 
	ha.query ,ha.queryid,
	count(*) * interval '1 second' AS duration 
FROM 	activity_hist.history_pg_stat_activity_for_reports ha
WHERE timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour')  AND 	backend_type = 'client backend' AND datname != 'postgres' AND ( ha.wait_event_type IS NULL  )AND ha.state = 'active'
GROUP BY ha.wait_event_type , ha.wait_event , ha.query ,ha.queryid		
)
SELECT 	query , queryid , SUM( duration ) as duration 
FROM hist
GROUP BY  query , queryid 
ORDER BY 3 DESC

به عنوان مثال:

-------------------------------------------------------------------
| TOTAL CPU TIME FOR QUERIES : 07:47:36
+----+----------------------------------------+--------------------
|   #|                                 queryid|            duration
+----+----------------------------------------+--------------------
|   1|                      389015618226997618|            04:28:58
|   2|                                        |            01:07:29
|   3|                     1237430309438971376|            00:59:38
|   4|                     4710212362688288619|            00:50:48
|   5|                       28942442626229688|            00:15:50
|   6|                     9150846928388977274|            00:04:46
|   7|                    -6572922443698419129|            00:00:06
|   8|                                        |            00:00:01
+----+----------------------------------------+--------------------

کل زمان انتظار برای پرسش ها

درخواست :

WITH hist AS
(
SELECT 
	aa.query ,aa.queryid ,			
	count(*) * interval '1 second' AS duration 
FROM 	activity_hist.archive_pg_stat_activity aa
WHERE timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour')  AND 
	backend_type = 'client backend' AND datname != 'postgres' AND
	( aa.wait_event_type IS NOT NULL  ) 
GROUP BY aa.wait_event_type , aa.wait_event , aa.query ,aa.queryid		
UNION 
SELECT 
	ha.query ,ha.queryid,
	count(*) * interval '1 second' AS duration 
FROM 	activity_hist.history_pg_stat_activity_for_reports ha
WHERE timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour')  AND 
	backend_type = 'client backend' AND datname != 'postgres' AND				
	( ha.wait_event_type IS NOT NULL  )
GROUP BY ha.wait_event_type , ha.wait_event , ha.query ,ha.queryid		
)
SELECT 	query , queryid , SUM( duration ) as duration 
FROM hist
GROUP BY  query , queryid 
ORDER BY 3 DESC 

به عنوان مثال:

-------------------------------------------------------------------
| TOTAL WAITINGS TIME FOR QUERIES : 21:55:04
+----+----------------------------------------+--------------------
|   #|                                 queryid|            duration
+----+----------------------------------------+--------------------
|   1|                      389015618226997618|            16:19:05
|   2|                                        |            03:47:04
|   3|                     8085340880788646241|            00:40:20
|   4|                     4710212362688288619|            00:13:35
|   5|                     9150846928388977274|            00:12:25
|   6|                       28942442626229688|            00:11:32
|   7|                     1237430309438971376|            00:09:45
|   8|                     2649515222348904837|            00:09:37
|   9|                                        |            00:03:45
|  10|                     3167065002719415275|            00:02:20
|  11|                     5731212217001535134|            00:02:13
|  12|                     8304755792398128062|            00:01:31
|  13|                     2649515222348904837|            00:00:59
|  14|                     2649515222348904837|            00:00:22
|  15|                                        |            00:00:12
|  16|                     3422818749220588372|            00:00:08
|  17|                    -5730801771815999400|            00:00:03
|  18|                    -1473395109729441239|            00:00:02
|  19|                     2404820632950544954|            00:00:02
|  20|                    -6572922443698419129|            00:00:02
|  21|                     2369289265278398647|            00:00:01
|  22|                      180077086776069052|            00:00:01
+----+----------------------------------------+--------------------

در انتظار پرس و جو

درخواست ها:

WITH hist AS
(
SELECT 
	aa.wait_event_type , aa.wait_event 
FROM 	activity_hist.archive_pg_stat_activity aa
WHERE timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') AND 
	backend_type = 'client backend' AND datname != 'postgres' AND
	aa.wait_event IS NOT NULL 
GROUP BY aa.wait_event_type , aa.wait_event
UNION 
SELECT 
	ha.wait_event_type , ha.wait_event 
FROM 	activity_hist.history_pg_stat_activity_for_reports ha
WHERE timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') AND 
	backend_type = 'client backend' AND datname != 'postgres' AND
	ha.wait_event IS NOT NULL 
GROUP BY ha.wait_event_type , ha.wait_event		
)
SELECT 	wait_event_type , wait_event 
FROM hist
GROUP BY wait_event_type , wait_event
ORDER BY 1 ASC,2 ASC

----------------------------------------------------------------------

WITH hist AS
(
SELECT 
	aa.wait_event_type , aa.wait_event , aa.query ,aa.queryid ,			
	count(*) * interval '1 second' AS duration 
FROM 	activity_hist.archive_pg_stat_activity aa
WHERE timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') AND 
	backend_type = 'client backend' AND datname != 'postgres' AND
	( aa.wait_event_type = waitings_stat_rec.wait_event_type AND aa.wait_event = waitings_stat_rec.wait_event )
GROUP BY aa.wait_event_type , aa.wait_event , aa.query ,aa.queryid		
UNION 
SELECT 
	ha.wait_event_type , ha.wait_event , ha.query ,ha.queryid,
	count(*) * interval '1 second' AS duration 
FROM 	activity_hist.history_pg_stat_activity_for_reports ha
WHERE timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') AND 
	backend_type = 'client backend' AND datname != 'postgres' AND				
	( ha.wait_event_type = waitings_stat_rec.wait_event_type AND ha.wait_event = waitings_stat_rec.wait_event )
GROUP BY ha.wait_event_type , ha.wait_event , ha.query ,ha.queryid		
)
SELECT 	query , queryid , SUM( duration ) as duration 
FROM hist
GROUP BY  query , queryid 
ORDER BY 3 DESC

به عنوان مثال:

------------------------------------------------
| WAITINGS FOR QUERIES
+-----------------------------------------------
|                      wait_event_type = Client|
|                       wait_event = ClientRead|
|                        Total time  = 00:46:56|
------------------------------------------------
|    #|             queryid|            duration
+-----+--------------------+--------------------
|    1| 8085340880788646241|            00:40:20
|    2|                    |            00:03:45
|    3| 5731212217001535134|            00:01:53
|    4|                    |            00:00:12
|    5| 9150846928388977274|            00:00:09
|    6| 3422818749220588372|            00:00:08
|    7| 1237430309438971376|            00:00:06
|    8|   28942442626229688|            00:00:05
|    9| 4710212362688288619|            00:00:05
|   10|-5730801771815999400|            00:00:03
|   11| 8304755792398128062|            00:00:02
|   12|-6572922443698419129|            00:00:02
|   13|-1473395109729441239|            00:00:02
|   14| 2404820632950544954|            00:00:02
|   15|  180077086776069052|            00:00:01
|   16| 2369289265278398647|            00:00:01

+-----------------------------------------------
|                          wait_event_type = IO|
|                      wait_event = BufFileRead|
|                        Total time  = 00:00:38|
------------------------------------------------
|    #|             queryid|            duration
+-----+--------------------+--------------------
|    1|   28942442626229688|            00:00:38

+-----------------------------------------------

تاریخچه فرآیندهای قفل شده

درخواست:

SELECT 
MIN(date_trunc('second',timepoint)) AS started , 
	count(*) * interval '1 second' as duration ,
	pid , blocking_pids , relation , mode , locktype 	 
FROM 
	activity_hist.archive_locking al 
WHERE 
	timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') AND
	NOT granted AND 
	locktype = 'relation' 
GROUP BY pid , blocking_pids , relation , mode , locktype			
UNION
SELECT 
	MIN(date_trunc('second',timepoint)) AS started , 
	count(*) * interval '1 second' as duration ,
	pid , blocking_pids , relation , mode , locktype
FROM 
	activity_hist.history_locking 
WHERE 
	timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') AND
	NOT granted AND 
	locktype = 'relation' 
GROUP BY pid , blocking_pids , relation , mode , locktype			
ORDER BY 1

به عنوان مثال:

------------------------------------------------ ------------------------------------------------ --------------------------------- | تاریخچه فرآیندهای قفل شده +------------------------------------------------ --------+-------------------------- --------------- +------------------- | #| pid| شروع شد| مدت| blocking_pids| رابطه| حالت| نوع قفل +----------+--------------------------------------- ------------------------------------------------- -------------- | 1| 26224| 2019-09-02 19:32:16| 00:01:45| {26211}| 16541| AccessShareLock| رابطه | 2| 26390| 2019-09-02 19:34:03| 00:00:53| {26211}| 16541| AccessShareLock| رابطه | 3| 26391| 2019-09-02 19:34:03| 00:00:53| {26211}| 16541| AccessShareLock| رابطه | 4| 26531| 2019-09-02 19:35:27| 00:00:12| {26211}| 16541| AccessShareLock| رابطه | 5| 27284| 2019-09-02 19:44:02| 00:00:19| {27276}| 16541| AccessShareLock| رابطه | 6| 27283| 2019-09-02 19:44:02| 00:00:19| {27276}| 16541| AccessShareLock| رابطه | 7| 27286| 2019-09-02 19:44:02| 00:00:19| {27276}| 16541| AccessShareLock| رابطه | 8| 27423| 2019-09-02 19:45:24| 00:00:12| {27394}| 16541| AccessShareLock| رابطه | 9| 27648| 2019-09-02 19:48:06| 00:00:20| {27647}| 16541| AccessShareLock| رابطه | 10| 27650| 2019-09-02 19:48:06| 00:00:20| {27647}| 16541| AccessShareLock| رابطه | 11| 27735| 2019-09-02 19:49:08| 00:00:06| {27650}| 16541| AccessExclusiveLock| رابطه | 12| 28380| 2019-09-02 19:56:03| 00:01:56| {28379}| 16541| AccessShareLock| رابطه | 13| 28379| 2019-09-02 19:56:03| 00:00:01| 28377| 16541| AccessExclusiveLock| رابطه | | | | | 28376| | 

مسدود کردن تاریخچه فرآیندها

درخواست ها:

SELECT 
blocking_pids 
FROM 
	activity_hist.archive_locking al 
WHERE 
	timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') AND
	NOT granted AND 
	locktype = 'relation' 
GROUP BY blocking_pids 		
UNION
SELECT 
	blocking_pids 
FROM 
	activity_hist.history_locking 
WHERE 
	timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') AND
	NOT granted AND 
	locktype = 'relation' 
GROUP BY blocking_pids 		
ORDER BY 1

---------------------------------------------------------------

SELECT 
	pid , usename , application_name , datname ,
	MIN(date_trunc('second',timepoint)) as started , 
	count(*) * interval '1 second' as duration ,		 
	state , 
	query
				FROM  	activity_hist.archive_pg_stat_activity
				WHERE 	pid= current_pid AND 
						timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') 						 
				GROUP BY pid , usename , application_name , 
						datname , 
						state_change, 
						state , 
						query 
				UNION
				SELECT 
					pid , usename , application_name , datname ,
					MIN(date_trunc('second',timepoint)) as started , 
					count(*) * interval '1 second' as duration ,		 
					state , 
					query
				FROM  	activity_hist.history_pg_stat_activity_for_reports
				WHERE 	pid= current_pid AND 
						timepoint BETWEEN pg_stat_history_begin+(current_hour_diff * interval '1 hour') AND pg_stat_history_end+(current_hour_diff * interval '1 hour') 						 
				GROUP BY pid , usename , application_name , 
						datname , 
						state_change, 
						state , 
						query 
				ORDER BY 5 , 1

به عنوان مثال:

------------------------------------------------ ------------------------------------------------ ------------------------------------------------ ----------------------- تاریخچه فرآیندهای مسدود کردن +----+------------------- ---+--------------------------------------------- ------------------------------------------------ -------+-------------------------------------- | #| pid| نام کاربری| نام_برنامه| نام داده| شروع شد| مدت| ایالت| پرس و جو +----------+----------+------------------------- -+------------------------------------------------- ------------------------------------------------ ----------------- | 1| 26211| تیزر| psql| tdb1| 2019-09-02 19:31:54| 00:00:04| بیکار| | 2| 26211| تیزر| psql| tdb1| 2019-09-02 19:31:58| 00:00:06| بیکار در معامله| شروع؛ | 3| 26211| تیزر| psql| tdb1| 2019-09-02 19:32:16| 00:01:45| بیکار در معامله| قفل میز ویفر_داده; | 4| 26211| تیزر| psql| tdb1| 2019-09-02 19:35:54| 00:01:23| بیکار| مرتکب شدن؛ | 5| 26211| تیزر| psql| tdb1| 2019-09-02 19:38:46| 00:00:02| بیکار در معامله| شروع؛ | 6| 26211| تیزر| psql| tdb1| 2019-09-02 19:38:54| 00:00:08| بیکار در معامله| قفل میز ویفر_داده; | 7| 26211| تیزر| psql| tdb1| 2019-09-02 19:39:08| 00:42:42| بیکار| مرتکب شدن؛ | 8| 26211| تیزر| psql| tdb1| 2019-09-03 07:12:07| 00:00:52| فعال| test_del();

توسعه.

پرسش‌های اساسی نشان‌داده‌شده و گزارش‌های به‌دست‌آمده در حال حاضر هنگام تجزیه و تحلیل رویدادهای عملکرد، زندگی را بسیار آسان‌تر می‌کنند.
بر اساس پرس و جوهای اولیه، می توانید گزارشی دریافت کنید که به طور مبهم شبیه AWR اوراکل است.
نمونه گزارش خلاصه

+----------------------------------------------- ----------------------------------- | گزارش تلفیقی برای فعالیت و انتظارات. 

ادامه دارد. در ردیف بعدی ایجاد یک تاریخچه قفل (pg_stat_locks) است که شرح مفصل تری از فرآیند پر کردن جداول است.

منبع: www.habr.com

اضافه کردن نظر