Chúng tôi thực hiện khoảng 100 nghìn câu lệnh DDL trong một giao dịch trong PostgreSQL. Trong quá trình thực thi, kết nối Postgres tương ứng tăng dần về mức sử dụng bộ nhớ của nó và một khi nó không thể có thêm bộ nhớ (tăng từ 10MB lên 2.2GB trên ram 3GB), kẻ giết người OOM đánh nó với 9 kết quả là Postgres bị chuyển sang chế độ phục hồi .
BEGIN;
CREATE SCHEMA schema_1;
-- create table stmts - 714
-- alter table add pkey stmts - 714
-- alter table add constraint fkey stmts - 34
-- alter table add unique constraint stmts - 2
-- alter table alter column set default stmts - 9161
-- alter table alter column set not null stmts - 2405
-- alter table add check constraint stmts - 4
-- create unique index stmts - 224
-- create index stmts - 213
CREATE SCHEMA schema_2;
-- same ddl statements as schema_1 upto schema_7
-- ...
-- ...
-- ...
CREATE SCHEMA schema_7;
COMMIT
Bao gồm câu lệnh tạo lược đồ, khoảng 94304 câu lệnh DDL có nghĩa là được thực thi.
Theo DDL giao dịch trong PostgreSQL
Giống như một số đối thủ cạnh tranh thương mại khác, một trong những tính năng nâng cao hơn của PostgreSQL là khả năng thực hiện DDL giao dịch thông qua thiết kế Nhật ký Viết trước. Thiết kế này hỗ trợ sao lưu các thay đổi lớn đối với DDL, chẳng hạn như tạo bảng. Bạn không thể khôi phục từ một thêm / thả trên cơ sở dữ liệu hoặc không gian bảng, nhưng tất cả các hoạt động danh mục khác đều có thể đảo ngược.
Chúng tôi thậm chí đã nhập khoảng 35GB dữ liệu vào PostgreSQL trong một giao dịch mà không gặp vấn đề gì, nhưng tại sao kết nối Postgres lại cần bộ nhớ lớn khi thực hiện hàng ngàn câu lệnh DDL trong một giao dịch?
Chúng tôi có thể giải quyết tạm thời bằng cách tăng RAM hoặc phân bổ trao đổi, nhưng chúng tôi có thể nói rằng số lần tạo lược đồ trong một giao dịch có thể tăng lên tới 50 - 60 (khoảng 1 triệu câu lệnh DDL) sẽ cần hơn 100 Gigs RAM hoặc trao đổi mà không khả thi ngay bây giờ.
Phiên bản PostgreSQL: 9.6.10
Có bất kỳ lý do tại sao thực hiện nhiều câu lệnh DDL đòi hỏi nhiều bộ nhớ hơn trong khi câu lệnh dml không? Không phải cả hai đều xử lý các giao dịch bằng cách viết vào WAL bên dưới sao? Vậy tại sao, đối với DLL thì khác?
Lý do giao dịch đơn
Chúng tôi đồng bộ hóa toàn bộ cơ sở dữ liệu của khách hàng từ Tiền đề khách hàng (Máy chủ SQL) sang đám mây (PostgreQuery). Tất cả các khách hàng không có cơ sở dữ liệu khác nhau. Quá trình là, toàn bộ dữ liệu sẽ được tạo dưới dạng CSV từ SQL Server và nhập vào PostgreQuery bằng cách sử dụng Bảng tạm thời, SAO CHÉP và TRÊN CONFLICT DO CẬP NHẬT. Trong quá trình này, chúng tôi coi mỗi khách hàng là một cơ sở dữ liệu duy nhất trong PG và DB riêng lẻ trong SQL Server của khách hàng như các lược đồ trong PG DB của khách hàng.
Vì vậy, dựa trên dữ liệu CSV, chúng tôi sẽ tạo các lược đồ động và nhập dữ liệu vào đó. Theo thiết kế ứng dụng của chúng tôi, dữ liệu trong PG phải hoàn toàn nhất quán tại bất kỳ thời điểm nào và không nên có bất kỳ lược đồ / bảng / dữ liệu nào. Vì vậy, chúng tôi đã phải đạt được điều này trong một giao dịch duy nhất. Ngoài ra, chúng tôi tăng dần đồng bộ hóa từ khách hàng lên đám mây DB cứ sau 3 phút. Vì vậy, việc tạo lược đồ có thể xảy ra trong đồng bộ hóa đầu tiên hoặc đồng bộ hóa gia tăng. Nhưng xác suất tạo ra rất nhiều lược đồ trong lần đầu tiên đồng bộ hóa là rất cao.
Cập nhật 1
Nhận xét các ALTER TABLE ALTER COLUMN
câu lệnh làm giảm đáng kể việc sử dụng bộ nhớ vì giờ đây chỉ mất tối đa 300 MB. Phải hợp nhất những điều đó vào chính các CREATE TABLE
tuyên bố.
Sẽ hỏi vấn đề cốt lõi trong danh sách gửi thư của PG Hackers.
CREATE DATABASE
không thể được thực thi trong một khối giao dịch ) hoặc được thực hiện trong một quy trình riêng biệt? Câu hỏi liên quan (có thể là viết lại câu hỏi trước): làm thế nào để ứng dụng nhận biết về một khách hàng mới / cơ sở dữ liệu mới?