vib*_*blo 6 postgresql ddl postgresql-9.3
我有一个经常使用的 PostgreSQL 数据库。有时我需要添加/删除列,最好不要中断任何服务。
我遵循https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql 中的安全操作列表,但是当更新更繁忙的表时,许多操作无论如何都会引起麻烦。
通常,我们为所有操作提供用户定义的函数,这些函数以以下方式运行:
表和函数定义:
create table a(
id serial primary key,
x integer
);
create or replace function select_a() returns setof a AS
$$
begin
return query
select a.* from a;
end;
$$ language plpgsql;
Run Code Online (Sandbox Code Playgroud)
然后实际查询由我们的应用程序运行
SELECT id FROM select_a();
Run Code Online (Sandbox Code Playgroud)
但是,如果我ALTER TABLE users ADD COLUMN y text;
在系统负载不足的情况下添加一列,我有时(系统承受的负载越频繁和持续越多)会出现这样的错误
错误 #42804 查询结构与函数结果类型不匹配:返回的列数 (2) 与预期的列数 (3) 不匹配。
是否可以以某种方式避免这种情况,或者我是否需要在此类更改期间使系统脱机?
要重新创建它,请按照下列步骤操作:
创建一个文件 loop_alter.sql
#!/usr/bin/env bash
for i in {0..1000}; do
echo "alter table a add column y text; alter table a drop column y;"
done;
Run Code Online (Sandbox Code Playgroud)创建一个文件 loop_select.sql
#!/usr/bin/env bash
for i in {0..100000} do
echo "select * from select_a() limit 1;"
done;
Run Code Online (Sandbox Code Playgroud)用 psql 同时运行这两个文件
在一个终端中:./loop_alter.sql | 查询语句
在另一个: ./loop_select.sql | 查询语句
如果您的函数确实使用SELECT *
,那么我建议改用显式字段列表,然后将表和函数的修改分开。
添加列: 首先更改表,然后在表完成后更改功能。
删除列: 先更改函数,然后更改表。如果桌子很大并且负载很重,我仍然会遇到问题。
归档时间: |
|
查看次数: |
523 次 |
最近记录: |