Bagaimana cara menunggu PostgreSQL menjadi dapat mulai / dipulihkan?

8

Saya sedang menguji peningkatan PostgreSQL 8.2.1 ke 9.2 pada mesin virtual yang menjalankan distro Linux khusus. Prosedur peningkatan adalah sebagai berikut:

  1. Mulai pglayanan
  2. Vakum semua DB (tidak yakin apakah ini diperlukan)
  3. Cadangkan dengan pg_dumpall
  4. Hentikan pglayanan
  5. Pindahkan direktori tempat data disimpan ( /var/pg; ini adalah pengaturan server tunggal yang sederhana)
  6. Instal PostgreSQL 9.2
  7. initdb
  8. Mulai server
  9. Kembalikan data yang dibuang
  10. reindexdb semua DB
  11. Buat kembali referential_constraintspemandangan
  12. Kosongkan semua DB (AFAIK diperlukan setelah peningkatan ini)

Prosedur ini berfungsi dengan baik pada satu host, mencadangkan dan memulihkan tanpa hambatan. Di komputer lain dengan titik basis data yang berbeda 1 hingga 7 berfungsi dengan baik, tetapi server tidak akan memulai kecuali saya menambahkan sleep 1setelah initdb, dan bahkan kemudian data yang dibuang tidak dapat dipulihkan karena "sistem basis data mulai". Apa cara standar untuk mengatasi ini, kecuali untuk peretasan yang mengerikan ini:

  1. sleepuntuk sejumlah waktu sebelum operasi,
  2. perulangan sampai berfungsi atau sampai batas waktu yang baik tercapai, atau
  3. pengulangan sampai menerima kueri sepele atau batas waktu tercapai.

Sunting: " Solusi " tidak berhasil sama sekali. Apa yang diperlukan untuk memastikan database siap menjalankan pemulihan?

l0b0
sumber
Hanya sebuah ide: dapatkah Anda menguji initdbstatus keluar? Saya kira ketika itu mengatur pekerjaan dilakukan.
dezso
@dezso Tidak, initdbdijalankan secara serempak, sehingga ketika server dimulai initdbsudah selesai dengan sukses.
l0b0
Maka saya tidak punya ide yang lebih baik daripada mengulang tes sederhana yang memeriksa semuanya sudah siap.
dezso
2) tidak diperlukan. 10) juga tidak diperlukan karena mengembalikan dump akan membuat kembali semua indeks.
a_horse_with_no_name

Jawaban:

5

initdb tidak kembali sampai selesai, jadi seharusnya tidak ada jeda yang diperlukan antara itu dan startup server. Ada bug di PostgreSQL di mana ia selesai tanpa membuang semua ke disk terlebih dahulu. Saya tidak tahu ada yang tersisa sekarang, tetapi sifat bug adalah bahwa Anda tidak selalu tahu tentang mereka.

Jika Anda menggunakan perintah pg_ctl untuk memulai database, gunakan parameter "-w" untuk menunggu sampai startup selesai sebelum kembali. Itu tidak melakukan sesuatu yang mewah - itu hanya "sudah siap?" lingkaran untuk Anda.

Perhatikan bahwa jika Anda mendapatkan server crash dengan banyak data yang perlu diputar ulang sebelum server dapat mulai, batas waktu yang ditetapkan oleh "-t" pada pg_ctl menunggu mungkin terlalu rendah.

Tidak ada alasan untuk VACUUM database sumber sebelum melakukan pg_dump dari mereka. Meskipun mungkin mempercepat pembuangan sedikit, ruang hampa itu sendiri akan membutuhkan waktu lebih lama dari perbaikan itu.

Greg Smith
sumber
Apakah 12. langkah ini diperlukan? Saya berharap tabel tersebut bersebelahan (atau hampir bersebelahan setelah pg_restore -j{morethan1}).
dezso
Kami berlari postmasteruntuk memulai daemon, dan sepertinya tidak memiliki opsi seperti itu.
l0b0
2

Itu kerjasolusi rusak adalah memodifikasi skrip init untuk memeriksa berulang kali apakah port yang relevan sedang digunakan. Jika tidak muncul setelah satu menit, startup dianggap gagal. Kode semu:

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

Sunting: Ternyata ini tidak cukup. Langkah pemulihan:

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"

Pesan eror:

psql: FATAL:  the database system is starting up
l0b0
sumber