Redshift存储过程错误处理报错及日志记录方案咨询
Redshift存储过程异常处理问题解决与答疑
一、解决"ROLLBACK cannot be invoked from an atomic context"报错
Redshift存储过程默认以**原子上下文(ATOMIC TRUE)**运行,整个过程属于一个原子事务:一旦触发异常,系统会自动执行ROLLBACK回滚所有操作,包括EXCEPTION块内的DML(如插入错误日志表的操作),从而引发冲突报错。
解决方式是创建存储过程时指定ATOMIC FALSE关闭原子上下文模式,此时EXCEPTION块内的错误记录操作可独立执行,不会被自动回滚:
修改后的完整代码:
CREATE TABLE employee (firstname varchar, lastname varchar); INSERT INTO employee VALUES ('Tomas','Smith'); CREATE TABLE employee_error_log (message varchar, error_code varchar, error_time timestamp DEFAULT current_timestamp); CREATE OR REPLACE PROCEDURE update_employee_sp() AS $$ BEGIN UPDATE employee SET firstname = 'Adam' WHERE lastname = 'Smith'; EXECUTE 'select invalid'; -- 触发测试错误 EXCEPTION WHEN OTHERS THEN RAISE INFO 'An exception occurred.'; -- 写入错误信息与错误代码 INSERT INTO employee_error_log (message, error_code) VALUES ('Error message: ' || SQLERRM, SQLSTATE); END; $$ LANGUAGE plpgsql ATOMIC FALSE; -- 关键配置:关闭原子上下文
执行该存储过程后,错误日志会正常写入employee_error_log,原UPDATE操作不会被自动回滚(若需回滚特定操作,可在EXCEPTION块内手动处理)。
二、记录DML/DDL错误信息与错误代码
在存储过程的EXCEPTION块中,可通过以下内置变量获取错误详情:
SQLERRM:获取错误描述信息SQLSTATE:获取标准5位SQL错误代码- 如需更详细的错误栈信息,可使用
GET STACKED DIAGNOSTICS语句,示例:DECLARE err_msg TEXT; err_state TEXT; err_detail TEXT; BEGIN -- 业务逻辑语句 EXCEPTION WHEN OTHERS THEN GET STACKED DIAGNOSTICS err_msg = MESSAGE_TEXT, err_state = RETURNED_SQLSTATE, err_detail = PG_EXCEPTION_DETAIL; INSERT INTO employee_error_log (message, error_code, detail) VALUES (err_msg, err_state, err_detail); END;
三、Redshift中类似Teradata error_messages的系统视图
Redshift没有直接对应Teradata error_messages的系统表,但可通过以下系统视图查询历史错误记录:
STL_ERROR:记录数据库级错误,包含错误代码、消息、发生时间、执行语句等,日志保留时长取决于集群配置SVL_STATEMENT_ERROR:语句级错误详情视图,包含执行用户、会话ID、错误时间、代码及消息,适合排查具体语句错误SVL_QLOG:包含所有查询的执行日志(含失败查询),可关联其他视图获取完整错误信息
查询示例:
-- 查询最近10条错误记录 SELECT err_code, err_reason, starttime, querytxt FROM STL_ERROR ORDER BY starttime DESC LIMIT 10;
内容的提问来源于stack exchange,提问作者Developer
相关产品推荐
相关产品推荐

