Câu hỏi Việc thêm một cột rỗng vào bảng postgres có gây ra khóa không?


Tôi nghĩ tôi đã đọc ở đâu đó chạy ALTER TABLE foo ADD COLUMN baz text trên cơ sở dữ liệu postgres sẽ không gây ra khóa đọc hoặc ghi. Đặt giá trị mặc định là nguyên nhân khóa, nhưng cho phép mặc định rỗng ngăn chặn khóa.

Tôi không thể tìm thấy điều này trong tài liệu, mặc dù. Bất cứ ai có thể trỏ đến một nơi mà nói, dứt khoát, nếu điều này là đúng hay không?


16
2017-10-22 17:59


gốc




Các câu trả lời:


Các loại khóa khác nhau và khi chúng được sử dụng được đề cập trong tài liệu Khóa cấp bảng. Trong khoảng ALTER TABLE, nó chỉ nói rằng nó có thể có được một SHARE UPDATE EXCLUSIVE hoặc là ACCESS EXCLUSIVE Khóa.

Nhưng trên thực tế, các phiên bản hiện tại của postgres có Access Exclusive Locks cho tất cả các biến thể của lệnh này, do đó, nó không đúng là đồng thời đọc có thể xảy ra cùng một lúc trong một số trường hợp.

Thật dễ dàng để kiểm tra mã nguồn bởi vì có một chức năng dành riêng cho việc thiết lập mức khóa cần thiết cho lệnh này trong các trường hợp khác nhau. Xem nhận xét trong src / backend / commands / tablecmds.c:

/*
 * AlterTableGetLockLevel
 *
 * Sets the overall lock level required for the supplied list of subcommands.
 * Policy for doing this set according to needs of AlterTable(), see
 * comments there for overall explanation.
 *
 * Function is called before and after parsing, so it must give same
 * answer each time it is called. Some subcommands are transformed
 * into other subcommand types, so the transform must never be made to a
 * lower lock level than previously assigned. All transforms are noted below.
 *
 * Since this is called before we lock the table we cannot use table metadata
 * to influence the type of lock we acquire.
 *
 * There should be no lockmodes hardcoded into the subcommand functions. All
 * lockmode decisions for ALTER TABLE are made here only. The one exception is
 * ALTER TABLE RENAME which is treated as a different statement type T_RenameStmt
 * and does not travel through this section of code and cannot be combined with
 * any of the subcommands given here.
 */

LOCKMODE
AlterTableGetLockLevel(List *cmds)
{
    /*
     * Late in 9.1 dev cycle a number of issues were uncovered with access to
     * catalog relations, leading to the decision to re-enforce all DDL at
     * AccessExclusiveLock level by default.

Chức năng có một số logic để có ổ khóa yếu hơn nhưng nó bị vô hiệu hóa trong hình thức hiện tại của nó để trở về AccessExclusiveLock trong tất cả trường hợp.


13
2017-10-22 20:02



Điều đó thật tuyệt vời - tôi chưa bao giờ nghĩ đến nguồn gốc, và nếu có, tôi sẽ không biết phải tìm đâu. Đáng ngạc nhiên là có thể đọc được. Tôi đang xem xét nó để xem nếu tôi có thể tìm thấy bằng chứng rằng nó chỉ là một khóa ngắn để thêm cột nullable, nhưng tôi không biết đủ để nói cho chắc chắn. Có lẽ một cái gì đó trong ATExecAddColumn? github.com/postgres/postgres/blob/master/src/backend/commands/… - jpadvo
@jpadvo: thêm cột nullable hoặc không nullable có cùng một loại khóa. Nếu một giá trị mặc định được cung cấp, nó vẫn là khóa tương tự nhưng nó được giữ lâu hơn bởi vì nó phải thực sự ghi giá trị vào mỗi hàng của bảng. - Daniel Vérité


Thêm cột null mới sẽ khóa bảng trong một thời gian rất ngắn vì không cần viết lại tất cả dữ liệu trên đĩa. Trong khi thêm cột với giá trị mặc định yêu cầu PostgreSQL tạo các phiên bản mới của tất cả các hàng và lưu trữ chúng trên đĩa. Và trong thời gian đó bảng sẽ bị khóa.

Vì vậy, khi bạn cần thêm cột với giá trị mặc định vào bảng lớn, bạn nên thêm giá trị null trước và sau đó cập nhật tất cả các hàng trong các phần nhỏ. Bằng cách này, bạn sẽ tránh tải cao trên đĩa và cho phép autovacuum làm công việc của nó, do đó bạn sẽ không phải tăng gấp đôi kích thước bảng.


16
2017-10-22 20:45





http://www.postgresql.org/docs/current/static/sql-altertable.html#AEN57290

"Việc thêm cột có giá trị mặc định không null hoặc thay đổi loại cột hiện tại sẽ yêu cầu toàn bộ bảng và chỉ mục được viết lại."

Vì vậy, tài liệu chỉ xác định khi nào bảng không được viết lại. Sẽ luôn luôn có một khóa, nhưng nó sẽ rất ngắn trong trường hợp bảng không được viết lại.


9
2017-10-23 15:02



WARN: cao hơn 9,4: Thêm một cột có mệnh đề DEFAULT hoặc thay đổi kiểu của một cột hiện có sẽ yêu cầu toàn bộ bảng và các chỉ mục của nó được viết lại. - Michail Nikolaev