PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Memutakhirkan Basis Data Anda ke PostgreSQL Versi 10 - Yang Harus Anda Ketahui

Karena semakin banyak posting di PostgreSQL 11 muncul di web, Anda mungkin merasa semakin ketinggalan jaman saat menggunakan Postgres 9. Meskipun rilis versi PostgreSQL 10 baru terjadi beberapa bulan yang lalu, orang-orang sudah membicarakan versi berikutnya. Segalanya bergerak, jadi Anda tidak ingin ketinggalan. Di blog ini kita akan membahas apa yang perlu Anda ketahui untuk mengupgrade ke versi terbaru, Postgres 10.

Opsi Peningkatan

Hal pertama yang harus Anda perhatikan sebelum memulai adalah bahwa ada beberapa cara untuk melakukan peningkatan:

  1. pg_dumpall(pg_dump) / pg_restore(psql) tradisional
  2. Pg_upgrade tradisional
  3. Replikasi berbasis pemicu (Slony, ditulis sendiri)
  4. Menggunakan replikasi pglogical

Mengapa ada variasi seperti itu? Karena masing-masing memiliki sejarah yang berbeda, membutuhkan upaya yang berbeda untuk menyiapkan dan menawarkan layanan yang berbeda. Mari kita lihat lebih dekat satu per satu.

Pembuangan/Pemulihan Tradisional

pg_dump t > /tmp/f
psql -p 5433 -f /tmp/f

Pembuangan/pemulihan tradisional membutuhkan waktu paling lama untuk diselesaikan, namun sering kali menjadi pilihan populer bagi mereka yang mampu membayar waktu henti. Pertama, semudah mengambil cadangan logis dan memulihkannya ke versi database baru yang lebih tinggi. Anda bisa mengatakan itu bukan peningkatan, sungguh, karena Anda "mengimpor" data Anda ke "struktur baru". Akibatnya, Anda akan mendapatkan dua pengaturan - satu lama (versi lebih rendah) dan yang baru ditingkatkan. Jika proses pemulihan selesai tanpa kesalahan, Anda cukup sampai di sana. Jika tidak, Anda harus memodifikasi cluster lama yang ada untuk menghilangkan kesalahan dan memulai proses dari awal lagi.

Jika Anda menggunakan psql untuk impor, Anda mungkin juga perlu membuat beberapa skrip pramuat sendiri untuk dijalankan pada penyiapan baru sebelum migrasi. Misalnya, Anda ingin pg_dumpall -g untuk mendapatkan daftar peran yang diperlukan untuk disiapkan dalam penyiapan baru, atau sebaliknya jalankan pg_dump -x untuk melewati izin dari yang lama. Proses ini cukup sederhana pada database kecil, kompleksitas bertambah dengan ukuran dan kompleksitas struktur db Anda dan tergantung pada fitur apa yang telah Anda siapkan. Pada dasarnya agar metode ini berhasil, Anda harus terus mencoba dan memperbaikinya hingga upgrade berhasil.

Keuntungan menggunakan metode ini termasuk...

  • Meskipun Anda mungkin menghabiskan waktu lama dengan satu cadangan yang Anda buat - beban di server lama hanya sesedikit mengambil satu cadangan.
  • Metode ini sebagian besar hanya urutan pencadangan-pemulihan (berpotensi dengan beberapa mantra, lagu, dan permainan drum)
  • Menggunakan metode ini adalah cara tertua untuk meningkatkan dan telah diverifikasi oleh BANYAK orang

Ketika Anda akhirnya menyelesaikan pemutakhiran, Anda harus mematikan server lama atau menerima beberapa kehilangan data (atau memutar ulang DML yang terjadi ke server lama sambil memulihkan cadangan ke server baru). Dan waktu yang dihabiskan untuk melakukannya relatif terhadap ukuran database Anda.

Anda dapat, tentu saja, mulai "menggunakan" database baru sebelum pemulihan selesai (terutama sebelum semua indeks dibuat - seringkali waktu yang paling dibutuhkan adalah untuk indeks). Namun demikian, waktu henti seperti itu sering kali tidak dapat diterima.

Pg_upgrade tradisional

MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/initdb -D tl0 >/tmp/suppressing_to_save_screen_space_read_it

WARNING: enabling "trust" authentication for local connections
You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
MacBook-Air:~ vao$ /usr/local/Cellar/postgresql/10.2/bin/pg_upgrade -b /usr/local/Cellar/postgresql/9.5.3/bin -B /usr/local/Cellar/postgresql/10.2/bin -d t -D tl0 | tail
Creating script to delete old cluster                        ok

Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade so,
once you start the new server, consider running:
    ./analyze_new_cluster.sh

Running this script will delete the old cluster’s data files:
    ./delete_old_cluster.sh

pg_upgrade tradisional dibuat untuk mempersingkat waktu yang diperlukan untuk meningkatkan ke versi utama. Bergantung pada jumlah relasi yang Anda miliki, itu bisa secepat menit (detik dalam kasus konyol, seperti satu database tabel dan jam dalam "kasus yang berlawanan") terutama dengan --link argumen.

Urutan persiapan sedikit berbeda dari metode peningkatan pertama. Untuk meniru pemutakhiran dan dengan demikian untuk memeriksa apakah itu mungkin, Anda harus membuat replikasi streaming atau memulihkan server siaga dari WAL. Mengapa ini begitu rumit? Anda ingin memastikan untuk menguji pemutakhiran pada basis data as-close-in-state seperti yang Anda lakukan semula. Replikasi "biner" atau PITR akan membantu kami di sini. Setelah Anda menyelesaikan pemulihan dan recovery_target_action =promote (PITR) atau mempromosikan slave yang baru dibuat (pg_ctl promote atau menempatkan file pemicu) (replikasi streaming), Anda kemudian dapat mencoba menjalankan pg_upgrade. Memeriksa pg_upgrade_internal.log akan memberi Anda gambaran apakah prosesnya berhasil atau tidak. Selanjutnya, Anda memiliki pendekatan coba-dan-perbaiki yang sama dengan metode sebelumnya. Anda menyimpan tindakan yang diambil terhadap database pengujian dalam skrip, hingga Anda berhasil pg_upgrade. Selain itu, Anda dapat menghancurkan pengujian yang tidak diperlukan lagi database yang ditingkatkan, jalankan skrip yang disimpan untuk menyiapkan database asli untuk melakukan peningkatan.

Keuntungan menggunakan metode ini termasuk…

  • Waktu henti yang lebih singkat daripada pencadangan/pemulihan logis
  • Proses yang rapi - pg_upgrade mengupgrade database asli dengan data dan struktur yang ada
  • Telah banyak digunakan di masa lalu dan masih akan menjadi preferensi untuk sebagian besar DBA yang menjalankan versi di bawah 9.4 (yang memungkinkan penggunaan pglogical)

Kerugian menggunakan metode ini termasuk…

  • Membutuhkan waktu henti

Replikasi Berbasis Pemicu

Dengan asumsi versi 10 ada di port 5433 dan memiliki tabel yang sama yang disiapkan:

db=# create server upgrade_to_10 foreign data wrapper postgres_fdw options (port '5433', dbname 'dbl0');
CREATE SERVER
Time: 9.135 ms
db=# create user mapping for vao SERVER upgrade_to_10 options (user 'vao');
CREATE USER MAPPING
Time: 8.741 ms
db=# create foreign table rl0 (pk int, t text) server upgrade_to_10 options (table_name 'r');
CREATE FOREIGN TABLE
Time: 9.358 ms

Ini adalah fn() dan pemicu yang sangat sederhana untuk replikasi logis yang sangat mendasar. Pendekatan seperti itu sangat primitif sehingga tidak akan berfungsi dengan kunci asing, tetapi kodenya pendek:

db=# create or replace function tf() returns trigger as $$
begin
 if TG_0P = 'INSERT' then
   insert into r10 select NEW.*;
 elseif TG_0P = 'UPDATE' then
   delete from rl0 where pk = NEW.pk;
   insert into rl0 select NEW.*;
 elseif TG_0P = 'DELETE' then
   delete from rl0 where pk = OLD.pk;
 end if;
return case when TG_0P in ('INSERT','UPDATE') then NEW else OLD end;
end;
SS language plpgsql;
CREATE FUNCTION
Time: 8.531 ms
db=# create trigger t before insert or update or delete on r for each row execute procedure tf(); CREATE TRIGGER
Time: 8.813 ms

Contoh:

db=# insert into r(t) select chr(g) from generate_series(70,75) g;
INSERT 0 6
Time: 12.621 ms
db=# update r set t = 'updated' where pk=2;
UPDATE 1
Time: 10.398 ms
db=# delete from r where pk=1;
DELETE 1
Time: 9.634 ms
db=# select * from r;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 9.026 ms
db=# select * from rl0;
 pk |    t
----+---------
  3 | H
  4 | I
  5 | J
  6 | K
  2 | updated
(5 rows)

Time: 1.201 ms

Terakhir, periksa apakah kita mereplikasi ke database yang berbeda:

db=# select *,current_setting('port') from dblink('upgrade.to.lO','select setting from pg_settings where name=$$port$$') as t(setting_10 text);
 setting_10 | currerrt.setting
------------+------------------
 5433       | 5432
(l row)

Time: 23.633 ms

Saya akan menyebut metode ini yang paling eksotis. Baik karena fakta bahwa dengan replikasi streaming dan kemudian dengan pglogical, penggunaan replikasi berbasis pemicu menjadi kurang populer. Ini memiliki beban yang lebih tinggi pada master, peningkatan kompleksitas selama pengaturan dan kurangnya dokumentasi yang terstruktur dengan baik. Tidak ada persiapan (seperti) proses di sini, karena Anda hanya ingin menyiapkan Slony pada versi utama yang berbeda.

Keuntungan menggunakan metode ini antara lain…

  • Tidak perlu membuat cadangan dan tidak memerlukan waktu henti (terutama Anda berada di belakang pgbouncer atau haproxy).

Kerugian menggunakan metode ini termasuk…

  • Kerumitan penyiapan yang tinggi
  • Kurangnya dokumentasi terstruktur
  • Tidak terlalu populer - lebih sedikit kasus pengguna untuk dipelajari (dan dibagikan)

Sejalan dengan itu, replikasi pemicu yang ditulis sendiri adalah cara lain yang mungkin untuk meningkatkan. Meskipun idenya sama (Anda memutar database versi baru yang lebih tinggi dan mengatur pemicu pada versi yang lebih rendah untuk mengirim data yang dimodifikasi ke dalamnya), pengaturan yang ditulis sendiri akan jelas bagi Anda. Anda tidak akan membutuhkan dukungan, dan dengan demikian berpotensi menggunakan lebih sedikit sumber daya saat menjalankannya. Tentu saja, untuk alasan yang sama Anda mungkin akan berakhir dengan beberapa fitur yang hilang atau tidak berfungsi seperti yang diharapkan. Jika Anda memiliki beberapa tabel untuk dipindahkan ke versi baru, opsi seperti itu mungkin akan memakan waktu lebih sedikit dan, jika dilakukan dengan baik, mungkin lebih sedikit memakan sumber daya. Sebagai bonus, Anda dapat menggabungkan beberapa transformasi ETL dengan peningkatan, beralih ke versi baru tanpa waktu henti.

Unduh Whitepaper Hari Ini Pengelolaan &Otomatisasi PostgreSQL dengan ClusterControlPelajari tentang apa yang perlu Anda ketahui untuk menerapkan, memantau, mengelola, dan menskalakan PostgreSQLUnduh Whitepaper

Replikasi Logis Dengan pglogical

Ini adalah cara baru yang sangat menjanjikan untuk memutakhirkan Postgres. Idenya adalah untuk mengatur replikasi logis antara versi utama yang berbeda dan secara harfiah memiliki database versi paralel, lebih tinggi (atau lebih rendah) yang menjalankan data yang sama. Jika sudah siap, Anda tinggal mengganti koneksi dengan aplikasi Anda dari yang lama ke yang baru.

Keuntungan menggunakan metode ini antara lain…

  • Pada dasarnya tidak ada waktu henti
  • Fitur yang sangat menjanjikan, jauh lebih sedikit upaya daripada replikasi berbasis pemicu

Kerugian menggunakan metode ini termasuk…

  • Masih sangat rumit untuk disiapkan (terutama untuk versi lama)
  • Kurangnya dokumentasi terstruktur
  • Tidak terlalu populer - lebih sedikit kasus pengguna untuk dipelajari (dan dibagikan)

Baik migrasi versi utama berbasis pemicu dan replikasi pglogical dapat digunakan untuk menurunkan versi (tentu saja hingga beberapa nilai yang wajar, misalnya, pglogical tersedia dari 9.4 saja dan replikasi pemicu menjadi semakin sulit untuk diatur sebagai versi yang Anda inginkan untuk menurunkan versi menjadi lebih tua).

Tindakan yang Harus Dilakukan Sebelum Peningkatan Versi

  • Ambil cadangan
  • Pastikan ada cukup ruang disk
  • Periksa ekstensi Anda (penting bahwa semua modul eksternal juga kompatibel dengan biner, meskipun ini tidak dapat diperiksa oleh pg_upgrade)
  • Pastikan untuk menggunakan datcollate dan datctype yang sama dan seterusnya (periksa pg_database) pada database baru
  • Periksa (DDL + Drop) tampilan, fungsi, ekstensi, jenis yang dapat merusak peningkatan
  • Gunakan --check sebelum benar-benar pg_upgrade

Tindakan yang Harus Dilakukan Setelah Peningkatan Versi

  • Konsultasikan pg_upgrade_server.log (jika Anda menggunakan pg_upgrade)
  • Jalankan analisis pada database yang ditingkatkan (opsional, seperti yang akan dilakukan oleh autovacuum, tetapi Anda dapat memilih hubungan apa yang harus dianalisis terlebih dahulu jika Anda melakukannya sendiri)
  • Menghangatkan halaman populer (opsional, tetapi dapat meningkatkan performa di awal)

Kesimpulan

Berikut adalah beberapa catatan umum yang baik untuk diketahui sebelum Anda memutuskan untuk pergi ke PostgreSQL versi 10…

  • pg_sequences diperkenalkan, mengubah perilaku SELECT * FROM sequence_name yang sebelumnya populer - sekarang hanya last_value | log_cnt | is_call dikembalikan, menyembunyikan "properti awal" dari Anda (sesuaikan kode apa pun yang bergantung pada perilaku yang diubah)
  • pg_basebackup mengalirkan WAL secara default. Setelah peningkatan, Anda mungkin perlu memodifikasi skrip Anda (opsi -x dihapus)
  • Semua tindakan pg_ctl menunggu penyelesaian. Sebelumnya Anda harus menambahkan -w untuk menghindari mencoba terhubung ke database langsung setelah pg_ctl start. Jadi jika Anda masih ingin menggunakan start atau stop "async", Anda harus menandainya secara eksplisit dengan -W. Anda mungkin perlu menyesuaikan skrip agar berfungsi sebagaimana mestinya.
  • Semua skrip untuk pengarsipan WAL atau pemantauan/pengendalian replikasi streaming atau PITR perlu ditinjau, untuk menyesuaikannya dengan nama xlog yang diubah. Misalnya. select * from pg_is_xlog_replay_paused() tidak akan lagi menampilkan status replay WAL slave - Anda harus menggunakan select * from pg_is_wal_replay_paused() sebagai gantinya. Juga cp /blah/pg_xlog/* perlu diubah menjadi /blah/pg_wal/* dan seterusnya pada dasarnya untuk semua kemunculan pg_xlog. Alasan di balik perubahan besar-besaran yang tidak kompatibel ke belakang adalah untuk mengatasi kasus ketika seorang pemula menghapus write-ahead-logs untuk "membersihkan beberapa ruang" dengan menghapus log, dan kehilangan database.
  • Sesuaikan skrip menggunakan pg_stat_replication untuk nama baru (lokasi diubah menjadi lsn)
  • Sesuaikan kueri dengan mengatur fungsi pengembalian jika diperlukan
  • Jika Anda menggunakan pglogical sebagai ekstensi sebelum versi 10, Anda mungkin perlu menyesuaikan nilai perubahan pg_hba.conf antara "kolom"
  • Sesuaikan skrip untuk nama baru pg_log yang merupakan log, jadi seperti find /pg_data/pg_log/postgresql-*  -mmin +$((60*48)) -type f -exec bash /blah/moveto.s3 .SH {} \; akan bekerja. Tentu saja Anda dapat membuat tautan simbolik sebagai gantinya, tetapi tindakan perlu diambil untuk menemukan log di lokasi default. Perubahan kecil lainnya pada default adalah log_line_prefix - jika ekspresi reguler Anda bergantung pada format tertentu, Anda perlu menyesuaikannya.
  • Jika Anda masih menggunakan kata sandi yang tidak terenkripsi di database Postgres Anda, rilis ini akan menghapusnya. Jadi inilah saatnya untuk menyelesaikan masalah bagi mereka yang mengandalkan --unencrypted...
  • Perubahan lain yang tidak kompatibel dengan rilis sebelumnya terlalu baru untuk direferensikan dalam banyak kode (min_parallel_relation_size) atau terlalu kuno (tsearch2) atau terlalu eksotis (penghapusan dukungan cap waktu titik-mengambang dalam pembuatan), jadi kita akan melewatkan mereka. Tentu saja mereka terdaftar di halaman rilis.
  • Seperti halnya dengan 9,5 hingga 9,6, Anda mungkin perlu menyesuaikan skrip untuk kueri pg_stat_activity (satu kolom baru dan kemungkinan nilai baru)
  • Jika Anda menyimpan/menganalisis keluaran verbose vakum, Anda mungkin perlu menyesuaikan kode Anda
  • Anda juga mungkin ingin melihat implementasi partisi baru - Anda mungkin ingin memfaktorkan ulang "set" yang ada agar sesuai dengan "standar" baru
  • periksa timeline (akan direset untuk database baru jika Anda pg_upgrade)

Terlepas dari langkah-langkah yang harus Anda ketahui untuk meningkatkan ke 10, ada banyak hal yang membuat rilis ini sangat dinanti. Silakan baca bagian perubahan di catatan rilis atau blog depesz.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Memilih data ke dalam array Postgres

  2. Bagaimana mencegah PDO menafsirkan tanda tanya sebagai pengganti?

  3. Apakah mungkin untuk menyediakan parameter untuk nama tabel atau kolom di Pernyataan yang Disiapkan atau QueryRunner.update()?

  4. Temukan rentang tanggal yang tumpang tindih di PostgreSQL

  5. Opsi Multitenancy untuk PostgreSQL