nwa*_*lke 7 postgresql postgresql-9.3
昨天我们在我们的生产数据库上运行了一个我们认为是安全的模式迁移,但遇到了一个问题。似乎添加新列会导致锁定,我们的应用程序无法再访问该表。以下是迁移前对表的说明:
Table "public.facilities"
Column | Type | Modifiers | Storage | Stats target | Description
-----------------------------------+-----------------------------+---------------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('facilities_id_seq'::regclass) | plain | |
name | character varying(255) | | extended | |
phone | character varying(255) | | extended | |
time_zone | character varying(255) | | extended | |
company_id | integer | | plain | |
created_at | timestamp without time zone | | plain | |
updated_at | timestamp without time zone | | plain | |
phnkey_id_token | character varying(255) | | extended | |
phnkey_api_key | character varying(255) | | extended | |
phnkey_auth_token | character varying(255) | | extended | |
payment_provider_name | character varying(255) | | extended | |
payment_provider_data | hstore | | extended | |
tenant_portal_key | character varying(255) | | extended | |
uuid | uuid | default uuid_generate_v4() | plain | |
deleted | boolean | default false | plain | |
deleted_on | timestamp without time zone | | plain | |
deleted_by_id | integer | | plain | |
accounting_method | character varying(255) | | extended | |
last_exported_on | timestamp without time zone | | plain | |
public_url | character varying(255) | | extended | |
access_hours_same_as_office_hours | boolean | default false | plain | |
logo | character varying(255) | | extended | |
next_lease_number | integer | default 1 | plain | |
email | character varying | | extended | |
fax | character varying | | extended | |
store_number | character varying | | extended | |
custom_portal_url | character varying | | extended | |
brand_name | character varying | | extended | |
Indexes:
"facilities_pkey" PRIMARY KEY, btree (id)
"index_facilities_on_tenant_portal_key" UNIQUE, btree (tenant_portal_key)
"index_facilities_on_uuid" UNIQUE, btree (uuid)
"index_facilities_on_company_id" btree (company_id)
Run Code Online (Sandbox Code Playgroud)
这是我们添加“地标”列后的表格:
Table "public.facilities"
Column | Type | Modifiers | Storage | Stats target | Description
-----------------------------------+-----------------------------+---------------------------------------------------------+----------+--------------+-------------
id | integer | not null default nextval('facilities_id_seq'::regclass) | plain | |
name | character varying(255) | | extended | |
phone | character varying(255) | | extended | |
time_zone | character varying(255) | | extended | |
company_id | integer | | plain | |
created_at | timestamp without time zone | | plain | |
updated_at | timestamp without time zone | | plain | |
phnkey_id_token | character varying(255) | | extended | |
phnkey_api_key | character varying(255) | | extended | |
phnkey_auth_token | character varying(255) | | extended | |
payment_provider_name | character varying(255) | | extended | |
payment_provider_data | hstore | | extended | |
tenant_portal_key | character varying(255) | | extended | |
uuid | uuid | default uuid_generate_v4() | plain | |
deleted | boolean | default false | plain | |
deleted_on | timestamp without time zone | | plain | |
deleted_by_id | integer | | plain | |
accounting_method | character varying(255) | | extended | |
last_exported_on | timestamp without time zone | | plain | |
public_url | character varying(255) | | extended | |
access_hours_same_as_office_hours | boolean | default false | plain | |
logo | character varying(255) | | extended | |
next_lease_number | integer | default 1 | plain | |
email | character varying | | extended | |
fax | character varying | | extended | |
store_number | character varying | | extended | |
custom_portal_url | character varying | | extended | |
brand_name | character varying | | extended | |
landmarks | character varying | | extended | |
Indexes:
"facilities_pkey" PRIMARY KEY, btree (id)
"index_facilities_on_tenant_portal_key" UNIQUE, btree (tenant_portal_key)
"index_facilities_on_uuid" UNIQUE, btree (uuid)
"index_facilities_on_company_id" btree (company_id)
Run Code Online (Sandbox Code Playgroud)
您在这里看到的是否会导致表锁定添加列“地标”?我们只是想避免将来出现停机时间。
更多信息:该表有 304 行,并且处于我们的应用程序 8 分钟无法使用它的状态。
该应用程序是一个 rails 应用程序,我们使用了一个 rake 任务来执行迁移。这是我们使用的代码:
class AddLandmarkToFacility < ActiveRecord::Migration
def change
add_column :facilities, :landmarks, :string
end
end
Run Code Online (Sandbox Code Playgroud)
我相信这会导致以下ALTER
声明:
ALTER TABLE "facilities" ADD "landmarks" character varying;
Run Code Online (Sandbox Code Playgroud)
ALTER TABLE
需要ACCESS EXCLUSIVE
锁。从文档:
ALTER TABLE 更改现有表的定义。下面描述了几个子表单。请注意,每个子表单所需的锁定级别可能不同。除非明确指出,否则将持有 ACCESS EXCLUSIVE 锁。当列出多个子命令时,持有的锁将是任何子命令所需的最严格的锁
如果没有默认值或表很小,通常不需要几分钟即可添加一列,而在您的情况下,您对两者都很好。
但是为了获得该锁,其他事务不应在同一个表上持有锁。有几件事情需要考虑:
SELECT
的表需要一个锁来阻止其他人执行ALTER TABLE
.ALTER TABLE ...ADD COLUMN
等待锁定,其他想要访问SELECT
该表的事务也将被阻塞。后果是:
如果有读取该表的长时间运行的事务,它们将阻塞ALTER TABLE
迁移直到它们完成。
如果迁移本身是更大事务的一部分,这将阻止其他想要访问该表的进程,直到它提交。
归档时间: |
|
查看次数: |
4504 次 |
最近记录: |