当应用程序出现错误SQL,无法立即修改时,可以通过SQL映射功能,将错误的SQL映射为正确的SQL。SQL映射功能设置成功后,应用程序即使发送了错误的SQL,也会自动映射为正确的SQL。
注意事项
SQL映射功能会将字符串匹配的SQL全部映射为指定的SQL,请谨慎使用。
前提条件
确保所在数据库已创建polar_sql_mapping插件, 新创建的数据库默认已创建该插件,旧的数据库仍需手动创建。
执行以下命令,手动创建插件。
set default_with_rowids to off;
create extension polar_sql_mapping;
使用指南
设置
polar_sql_mapping.use_sql_mapping
参数,开启SQL映射功能,默认为off。alter database [dbname] set polar_sql_mapping.use_sql_mapping=on;
设置
polar_sql_mapping.record_error_sql
参数,开启自动收集错误的SQL功能, 默认为off。alter database [dbname] set polar_sql_mapping.record_error_sql=on;
说明使用完SQL映射功能之后建议关闭错误记录功能,减少对性能的影响。
alter database [dbname] set polar_sql_mapping.record_error_sql=off;
查询错误的SQL。
select * from emp;
返回结果如下:
ERROR: relation "emp" does not exist
错误的SQL被记录到了polar_sql_mapping.error_sql_info中,执行以下命令,查询polar_sql_mapping.error_sql_info详细信息。
select * from polar_sql_mapping.error_sql_info ;
返回结果如下:
id | query | emessage | calls ----+--------------------+-------------------------------+------- 1 | select * from emp; | relation "emp" does not exist | 1
建立映射关系,将error_sql_info中ID为1的SQL映射成指定的SQL。
select polar_sql_mapping.insert_mapping_id(1, ' select 1');
再次查询错误的SQL。
select * from emp;
返回结果如下:
?column? ---------- 1 (1 row)
说明对于大部分的应用程序都是使用PreparedStmt,在写新的SQL的时,需要注意占位符应该是$n而不是'?',示例如下:
select * from polar_sql_mapping.polar_sql_mapping_table ;
返回结果如下:
id | source_sql | target_sql ----+----------------------------------+--------------------------------- 4 | select 1 from dual where a = $1; | select 1 from dual where 1 = $1 (1 row)
参数说明
参数 | 说明 |
polar_sql_mapping.max_num | 用于控制最多被收集的不同的错误SQL的数量,超过设置数量的SQL会直接被忽略,如果需要修改则需要重启,默认值为10。 |
polar_sql_mapping.error_sql_info_clear() | 用于清空已记录的错误SQL。 |
替换运行正常的SQL
如果遇到运行没有错误的SQL,仍然想替换,可按照以下步骤进行操作:
设置
polar_sql_mapping.use_sql_mapping
参数,开启SQL映射功能,默认为off。alter database [dbname] set polar_sql_mapping.use_sql_mapping=on;
设置
polar_sql_mapping.record_error_sql
参数,开启自动收集错误的SQL功能, 默认为off。alter database [dbname] set polar_sql_mapping.record_error_sql=on;
说明使用完SQL映射功能之后建议关闭错误记录功能,减少对性能的影响。
alter database [dbname] set polar_sql_mapping.record_error_sql=off;
设置匹配模式,所有模式匹配的SQL都会被保存到polar_sql_mapping.error_sql_info中。
在如下示例中,即含有test_table的SQL都会被抓取(匹配逻辑和SQL中的LIKE操作符一致)。
设置匹配模式。
set polar_sql_mapping.error_pattern to '%test_table%';
开启匹配模式。
set polar_sql_mapping.record_error_sql to true;
创建被抓取的SQL语句。
select * from test_table; select a from test_table; select max(a) from test_table;
查看polar_sql_mapping.error_sql_info中的抓取结果。
select * from polar_sql_mapping.error_sql_info;
返回结果如下:
id | query | emessage | calls ----+--------------------------------+----------------------------+------- 1 | select * from test_table; | Error Pattern Force Record | 1 2 | select a from test_table; | Error Pattern Force Record | 1 3 | select max(a) from test_table; | Error Pattern Force Record | 1 (3 rows)
所有含有test_table的SQL都被抓取到了polar_sql_mapping.error_sql_info中。
将错误的SQL替换为正确的SQL。
select polar_sql_mapping.insert_mapping_id(x, 'text');
说明其中,x表示SQL的ID,text表示SQL的文本,请根据实际情况进行替换。
使用完后需要进行还原操作,以免影响性能。
reset polar_sql_mapping.error_pattern;