做者:瀚高PG實驗室 (Highgo PG Lab)- 徐雲鶴 postgresql將數據庫運行告警日誌導入表中的方法及時間時區問題解決。 ==若是是看錶中日誌記錄時間log_time和session_start_time和實際時間相差10小時或者8小時之類問題的解決方案,能夠直接往下拉。==sql
想將pg數據庫運行告警日誌支持導入表中,須要配置以下參數: logging_collector:日誌開關。設置爲on。修改此參數須要重啓。 log_directory:日誌存放路徑。此處舉例設置爲log,則放置到data目錄的log下。修改此參數須要reload。 log_destination:日誌記錄方法。設置爲csvlog。修改此參數須要reload。數據庫
提供一個模板供參考: 該模板可實現: 1.日誌記錄開啓。 2.存放於data數據目錄的log目錄下 3.天天一個,每週循環覆蓋,不限制日誌大小。session
alter system set logging_collector = on; alter system set log_directory = 'log'; alter system set log_filename = 'pg-%a.log'; alter system set log_rotation_age = '1d'; alter system set log_rotation_size = 0; alter system set log_truncate_on_rotation = on;
開啓日誌模式爲csvlog後,就能夠將其導入表中了。 不一樣版本數據庫日誌列的內容略有差異,例如pg13比pg12多了backend_type列。下邊附一下官方手冊提供的建表語句。 PG13:app
CREATE table postgres_log ( log_time timestamp(3) with time zone, user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time timestamp with time zone, virtual_transaction_id text, transaction_id bigint, error_severity text, sql_state_code text, message text, detail text, hint text, internal_query text, internal_query_pos integer, context text, query text, query_pos integer, location text, application_name text, backend_type text, PRIMARY KEY (session_id, session_line_num) )
PG9-12:post
CREATE TABLE postgres_log ( log_time timestamp(3) with time zone, user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time timestamp with time zone, virtual_transaction_id text, transaction_id bigint, error_severity text, sql_state_code text, message text, detail text, hint text, internal_query text, internal_query_pos integer, context text, query text, query_pos integer, location text, application_name text, PRIMARY KEY (session_id, session_line_num) );
下面導入日誌內容:日誌
COPY postgres_log FROM 'log/postgresql-2021-01-15_000000.csv' WITH csv;
若是提示ERROR: extra data after last expected column或者ERROR: missing data for column "backend_type"之類的,則說明日誌列數和表列數不一致。按照上邊的檢查一下便可。 導入成功會提示COPY XXX。 而後查詢便可。postgresql
select * from postgres_log;
若是log_time和session_start_time的時間和實際時間相差10小時或者8小時之類問題,繼續往下:code
若是日誌記錄時區參數是PRC或者Asia/Shanghai,那麼日誌csv的log_time和session_start_time是以CST結尾。 而CST爲以下4個不一樣的時區的縮寫: 美國中部時間:Central Standard Time (USA) UT-6:00 澳大利亞中部時間:Central Standard Time (Australia) UT+9:30 中國標準時間:China Standard Time UT+8:00 古巴標準時間:Cuba Standard Time UT-4:00 PG將其當成了美國中部時間。由於表中查詢的時間有誤。 查詢pg_timezone_names能夠發現大部分時區名簡稱均爲CST。orm
postgres=# select * from pg_timezone_names where utc_offset='+08:00:00'; name | abbrev | utc_offset | is_dst --------------------+--------+------------+-------- ROC | CST | 08:00:00 | f Asia/Hong_Kong | HKT | 08:00:00 | f Asia/Choibalsan | +08 | 08:00:00 | f Asia/Macao | CST | 08:00:00 | f Asia/Kuala_Lumpur | +08 | 08:00:00 | f Asia/Manila | PST | 08:00:00 | f Asia/Kuching | +08 | 08:00:00 | f Asia/Chongqing | CST | 08:00:00 | f Asia/Makassar | WITA | 08:00:00 | f Asia/Brunei | +08 | 08:00:00 | f Asia/Ulaanbaatar | +08 | 08:00:00 | f Asia/Taipei | CST | 08:00:00 | f Asia/Shanghai | CST | 08:00:00 | f Asia/Macau | CST | 08:00:00 | f Asia/Ulan_Bator | +08 | 08:00:00 | f Asia/Singapore | +08 | 08:00:00 | f Asia/Chungking | CST | 08:00:00 | f Asia/Harbin | CST | 08:00:00 | f Asia/Ujung_Pandang | WITA | 08:00:00 | f Asia/Irkutsk | +08 | 08:00:00 | f Australia/West | AWST | 08:00:00 | f Australia/Perth | AWST | 08:00:00 | f Hongkong | HKT | 08:00:00 | f Etc/GMT-8 | +08 | 08:00:00 | f Singapore | +08 | 08:00:00 | f PRC | CST | 08:00:00 | f (26 rows)
所以能夠採起以下解決方案: 1.設置數據庫參數log_timezone爲'Asia/Hong_Kong','Hongkong','Etc/GMT-8'之一併reload數據庫。這樣在導入日誌到表中查詢,時間就沒有問題了。 2.建表語句去掉帶時區的timestamp便可。 PG13:server
CREATE table postgres_log ( log_time timestamp(3), user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time timestamp, virtual_transaction_id text, transaction_id bigint, error_severity text, sql_state_code text, message text, detail text, hint text, internal_query text, internal_query_pos integer, context text, query text, query_pos integer, location text, application_name text, backend_type text, PRIMARY KEY (session_id, session_line_num) )
PG9-12:
CREATE TABLE postgres_log ( log_time timestamp(3), user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time timestamp, virtual_transaction_id text, transaction_id bigint, error_severity text, sql_state_code text, message text, detail text, hint text, internal_query text, internal_query_pos integer, context text, query text, query_pos integer, location text, application_name text, PRIMARY KEY (session_id, session_line_num) );
最後簡單提一個能夠查看實時日誌內容的方法的demo:
create extension file_fdw; create server pg_file_server foreign data wrapper file_fdw; CREATE foreign table pg_log ( log_time timestamp(3) with time zone, user_name text, database_name text, process_id integer, connection_from text, session_id text, session_line_num bigint, command_tag text, session_start_time timestamp with time zone, virtual_transaction_id text, transaction_id bigint, error_severity text, sql_state_code text, message text, detail text, hint text, internal_query text, internal_query_pos integer, context text, query text, query_pos integer, location text, application_name text, backend_type text ) SERVER pg_file_server options(filename 'log/postgresql.csv',format 'csv',header 'false'); select * from pg_log;