Làm thế nào để chờ PostgreSQL khởi động / khôi phục?


8

Tôi đang thử nghiệm bản nâng cấp PostgreSQL 8.2.1 lên 9.2 trên máy ảo chạy bản phân phối Linux tùy chỉnh. Quy trình nâng cấp như sau:

  1. Bắt đầu pgdịch vụ
  2. Hút tất cả các DB (không chắc chắn nếu điều này là cần thiết)
  3. Sao lưu với pg_dumpall
  4. Dừng pgdịch vụ
  5. Di chuyển khỏi thư mục nơi dữ liệu được lưu trữ ( /var/pg; đó là một thiết lập máy chủ đơn giản)
  6. Cài đặt PostgreSQL 9.2
  7. initdb
  8. Khởi động máy chủ
  9. Khôi phục dữ liệu bị đổ
  10. reindexdb tất cả các DB
  11. Tái tạo referential_constraintsgóc nhìn
  12. Hút tất cả các DB (yêu cầu AFAIK sau khi nâng cấp này)

Quy trình này hoạt động tốt trên một máy chủ, sao lưu và khôi phục mà không gặp trở ngại. Trên một máy khác có cơ sở dữ liệu khác điểm 1 đến 7 hoạt động tốt, nhưng máy chủ sẽ không khởi động trừ khi tôi thêm sleep 1sau đó initdbvà thậm chí sau đó dữ liệu bị hủy không thể được khôi phục vì "hệ thống cơ sở dữ liệu đang khởi động". Các cách tiêu chuẩn để đối phó với điều này là gì, ngoại trừ những vụ hack khủng khiếp này:

  1. sleeping cho một số lượng lớn thời gian trước khi hoạt động,
  2. lặp cho đến khi nó hoạt động hoặc cho đến khi đạt được thời gian chờ hào phóng, hoặc
  3. lặp cho đến khi nó chấp nhận một truy vấn tầm thường hoặc hết thời gian chờ.

Chỉnh sửa: " Giải pháp " không hoạt động sau tất cả. Cần gì để đảm bảo cơ sở dữ liệu đã sẵn sàng để chạy khôi phục?


Chỉ là một ý tưởng: bạn có thể kiểm tra initdbtrạng thái thoát? Tôi cho rằng khi nó hoàn thành công việc.
dezso

@dezso Không, initdbđược chạy đồng bộ, vì vậy khi máy chủ được khởi động initdbđã kết thúc thành công.
l0b0

Sau đó, tôi không có ý tưởng nào tốt hơn là lặp lại một bài kiểm tra đơn giản để kiểm tra mọi thứ đã sẵn sàng.
dezso

2) là không cần thiết. 10) cũng không cần thiết vì khôi phục kết xuất sẽ tạo lại tất cả các chỉ mục.
a_horse_with_no_name

Câu trả lời:


5

initdb không quay trở lại cho đến khi hoàn thành, vì vậy không nên có bất kỳ tạm dừng nào cần thiết giữa nó và máy chủ khởi động. Đã có lỗi trong PostgreSQL khi nó hoàn thành mà không xóa mọi thứ vào đĩa trước. Tôi không biết về bất kỳ bên trái nào ngay bây giờ, nhưng bản chất của lỗi là bạn không luôn biết về chúng.

Nếu bạn sử dụng lệnh pg_ctl để khởi động cơ sở dữ liệu, hãy sử dụng tham số "-w" để chờ cho đến khi khởi động xong trước khi quay lại. Nó không làm bất cứ điều gì lạ mắt - nó chỉ làm "nó đã sẵn sàng chưa?" vòng lặp cho bạn.

Lưu ý rằng nếu bạn gặp sự cố máy chủ với nhiều dữ liệu cần được phát lại trước khi máy chủ có thể khởi động, thời gian chờ được đặt bởi "-t" trên pg_ctl chờ đợi có thể quá thấp.

Không có lý do gì để VACUUM cơ sở dữ liệu nguồn trước khi thực hiện pg_dump của chúng. Mặc dù nó có thể tăng tốc độ đổ lên một chút, nhưng chân không sẽ mất nhiều thời gian hơn cải tiến đó.


Là bước 12. bắt buộc? Tôi hy vọng các bảng sẽ liền kề nhau (hoặc gần kề nhau sau một pg_restore -j{morethan1}).
dezso

Chúng tôi đang chạy postmasterđể bắt đầu trình nền, và dường như không có tùy chọn như vậy.
l0b0

2

Các đang làm việcgiải pháp bị hỏng là sửa đổi tập lệnh init để kiểm tra lại xem cổng có liên quan được sử dụng hay không. Nếu nó không xuất hiện sau một phút, thì khởi động được coi là đã thất bại. Mã giả:

start() {
    pg start
    checks=0
    while checks < 30:
        return true if the port is in use
        sleep 2
        checks++
    return false
}

Chỉnh sửa: Hóa ra điều này là không đủ. Bước khôi phục:

PGOPTIONS='--client-min-messages=warning' psql \
    --no-psqlrc \
    --variable=ON_ERROR_STOP=1 \
    --quiet \
    --log-file="$restore_log" \
    --single-transaction \
    --username postgres \
    --file="$sql_backup"

Thông báo lỗi:

psql: FATAL:  the database system is starting up
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.