1 说明
1.1 问题说明
session_exec可以对登录postgresql的用户进行锁定,当用户登录失败的次数达到指定的次数,就可以将其锁定。
postgresql14使用session_exec的的时候报错如下
NOTICE: user: replicator! psql: error: connection to server at "127.0.0.1", port 18126 failed: FATAL: unhandled exception in login function "public.login" DETAIL: extra data after last expected column CONTEXT: session_exec: perform login function "public.login" COPY postgres_log, line 1: "2022-07-07 11:16:16.176 CST,,,19425,,62c64fff.4be1,1,,2022-07-07 11:16:15 CST,,0,LOG,00000,"ending l..." SQL statement "select count(*) from (select log_time,user_name,error_severity,message,detail from public.postgres_log where command_tag = 'authentication' and user_name = res.rolname and (detail is null or detail not like 'Role % does not exist.%') order by log_time desc limit failed_login_times) A WHERE A.error_severity='FATAL'" PL/pgSQL function login() line 12 at SQL statement
配置session_exec 之前是在pg 12.8上配置的 没什么问题 在新的14版本上配置 只要服务一重启,登录的时候就会报错
1.2 配置session_exec
这里只说说postgresql14配置session_exec的troubleshooting过程 不说配置session_exec的具体细节
pg配置session_exec的无坑步骤 可以去看 postgresql配置session_exec 达到锁定登录失败用户的目的
2 问题解决和思路
做过一些尝试,发现有临时解决办法
删除日志目录的所有.log
和.csv
此时没有日志数据了 login函数想select也没数据可以select 此时可以通过psql登录
但是只要一重启 就又报这个错 无法登录
报错是说: login里的select语句出现问题了
此时 想到 有没有可能是14和12的日志打印不一样了 各拿出一条pg的日志 比较了下
pg12
2022-07-07 10:15:35.953 CST,,,13496,,62c641c7.34b8,1,,2022-07-07 10:15:35 CST,,0,LOG,00000,"ending log output to stderr",,"Future log output will go to log destination ""csvlog"".",,,,,,,""
pg14
2022-07-07 11:18:59.961 CST,,,19677,,62c650a3.4cdd,1,,2022-07-07 11:18:59 CST,,0,LOG,00000,"ending log output to stderr",,"Future log output will go to log destination ""csvlog"".",,,,,,,"","postmaster",,0
太长了 不好看 将它复制到编辑器里 逐个比较 发现: pg14的csv日志 多打了三个列
这样就可以解释上边出现的问题了
想把数据从csv文件里读取 然后插入到表格里 创建表的时候23个字段 但是实际pg的日志26个字段 无法完成数据插入 所以在登陆时候执行login函数就会出现问题
修改为如下
create extension file_fdw;
CREATE SERVER pglog FOREIGN DATA WRAPPER file_fdw;
CREATE FOREIGN TABLE public.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,
process_name text,
extra_parama text,
extra_paramb bigint
) SERVER pglog
OPTIONS ( program 'find /data/logs/postgresql -type f -name "*.csv" -mtime -1 -exec cat {} \;', format 'csv' );
grant SELECT on postgres_log to PUBLIC;
新增加了三个字段 去承接 pg14多打的三列
操作完后 再次登录pg14 没有报错 再重启pg14 然后再次测试登录 也没问题 问题解决
由于对pg不是很在行 只是简单使用,所以遇到这个问题也阻塞了半天,第二天才发现具体的问题,及时调整,在博客里记录下。