PostgreSQL veri tabanlarınızda majör versiyon yükseltmesi yapmanız için 3 farklı yöntem mevcut. Bunlar :
- pg_dumpall ile tüm verinin hedef versiyonda yaratılmış bir veritabanı cluster’ına taşınması
- pg_upgrade ile system tablolarının yenilenmesi ve kullanıcı verilerinin olduğu gibi kullanılması
- Logical replication ile tüm verinin standby ortamda yeni versiyona taşınması ve switch-over ile rol değişimi yapılması.
Bu yöntemlerin avantaj/dezavantajları anlamında hızlıca üzerlerinden geçelim. pg_dumpall ile upgrade yapmak tüm veriyi kopyalamak anlamına geldiği için veri tabanı boyutu büyüdükçe uygulanabilirliği azalır. Boyut büyüdükçe kesinti süresi ve veri aktarımında hata ihtimali artacaktır. Ayrıca upgrade işlemi için ihtiyacımız olacak disk alanı da bir sorun haline gelebilir. Avantaj olarak ise eski versiyondaki cluster verilerinin üzerine yazılmamasından dolayı işlemin tehlikesiz olmasından, ayrıca veri tabanlarındaki tüm objelerin yeniden yaratılması ile fragmantasyon ve “index bloat” gibi sorunların giderilmesinden bahsedebiliriz. Ayrıca data export ve import işlemlerini aşağıdaki örnekteki gibi tek bir komutla yaparak upgrade işlemimizi hızlandırma opsiyonumuz da bulunmaktadır.
$ pg_dumpall -p 5432 | psql -d postgres -p 5433
Bu yöntem ile upgrade adımlarını PostgreSQL dökümantasyonundan inceleyebilirsiniz:
pg_upgrade ise büyük boyutlarda işimizi kolaylaştıracak bir yöntemdir. pg_upgrade’in sunduğu “–link” seçeneği ile verinin taşınmasına gerek kalmadan mevcut data file’lar, üzerinde “hard link” oluşturarak kullanılabilir. (Bu arada, varsayılan ayarlarda çalıştırılırsa pg_upgrade veri tabanı dosyalarını eski versiyondaki data dizininden yeni versiyondaki data dizinine kopyalar) Link yönteminde eski versiyon cluster, upgrade işleminden sonra yeniden sağlıklı bir şekilde açılamayacaktır, bunun için upgrade öncesinde veri tabanlarının yedeğinin alınması önemlidir. Bir diğer önemli nokta link modunda upgrade yapabilmemiz için eski ve yeni cluster’ın data dizinlerinin aynı filesystem üzerinde olması gerektiğidir. pg_upgrade’in “–check” opsiyonu ile upgrade işlemini yapmadan önce kontrolleri gerçekleştirmek de mümkündür. Yine PostgreSQL resmi dökümantasyonunda daha detaylı bilgi bulabilirsiniz.
Üçüncü yöntem ise “logical replication” konfigüresyonunun farklı versiyonlarda (primary/standby) çalışabilme avantajını kullanarak, yine büyük boyuttaki veri tabanlarının upgrade süresini minimalde tutmak için tercih edebileceğimiz bir seçenektir. Standby veri tabanımızı ister primary ile aynı sunucuda ister farklı bir sunucuda ve hedef PostgreSQL versiyonunda kurup replikasyon konfigürasyonunu tamamladıktan sonra, veri tabanları senkron iken switch-over işlemini yaparak kısa sürede upgrade işlemini tamamlamış olabiliriz. Detaylar için
PostgreSQL major upgrade kapsamında bu üç yöntemi inceledikten sonra, Ubuntu/Debian ortamlarda işimizi kolaylaştıran “pg_upgradecluster” dan da bahsedeceğiz. “postgresql-common” paketi ile birlikte gelen bu program PostrgeSQL cluster’ın yeni versiyona upgrade işlemini tek komut ile yaparken, eski versiyonun konfigürasyon dosyaları da yeni versiyon cluster’a uygun şekilde ayarlanarak kopyalanır. “pg_upgradecluster” kullanırken, upgrade yöntemi için pg_dump’ı ya da pg_upgrade’i seçebiliyoruz.
-m, –method=dump|upgrade|link|clone
“dump” seçeneği pg_dump ve pg_restore kullanırken, “upgrade” seçeneği pg_upgrade kullanır, varsayılan değer “dump”tır.
“link” seçeneği “upgrade –link” için kısayoldur ve pg_upgrade ‘i link opsiyonu ile birlikte kullanır.
“clone” ise yine “upgrade –clone” için kısayoldur ve pg_upgrade ‘i clone opsiyonu ile birlikte kullanır.
Daha önce bahsetmediğimiz “pg_upgrade –clone” seçeneği sadece belirli filesystem’lerin desteklediği bir opsiyondur ve upgade sırasında eski cluster’daki dosyaların bir klonunu yeni cluster’da hard link yöntemindeki gibi hızlı bir şekilde oluştururken, hard link’ten farklı olarak eski dosyaların orjinal bloklarını saklayarak eski cluster’ı açılabilir kılar. “reflink” olarak da bilinen bu yöntem aslında iki farklı dosyanın ortak veri bloklarını kullanmasını sağlayan bir filesystem özelliğidir.
pg_upgradecluster ‘ın man sayfasında daha fazla bilgi bulabilir ve komut opsiyonlarını inceleyebilirsiniz.
Şimdi PostgreSQL 16 versiyonundaki cluster’ımızı 17 versiyonuna pg_upgradecluster ile upgrade etme adımlarının üzerinden geçelim. Örneğimizde iki tane 16 versiyonunda cluster çalışmakta ve bunlardan birini 17 versiyonuna upgrade edeceğiz.
# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
16 main 5432 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
16 test 5433 online postgres /var/lib/postgresql/16/test /var/log/postgresql/postgresql-16-test.log
Öncelikle sunucumuza yeni versiyon PostgreSQL kurulumunu yapıyoruz.
# sudo apt-get upgrade
# wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
# sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'
# sudo apt-get install postgresql-17 postgresql-client-17
Yeni versiyonun kurulumu ile birlikte “main” isminde yeni bir cluster da otomatik olarak başlatıldı. Bu cluster’ı kullanmayacağımız için siliyoruz.
# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
16 main 5432 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
16 test 5433 online postgres /var/lib/postgresql/16/test /var/log/postgresql/postgresql-16-test.log
17 main 5434 online postgres /var/lib/postgresql/17/main /var/log/postgresql/postgresql-17-main.log
# pg_dropcluster --stop 17 main
# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
16 main 5432 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
16 test 5433 online postgres /var/lib/postgresql/16/test /var/log/postgresql/postgresql-16-test.log
Şimdi pg_upgradecluster komutunu varsayılan ayarları ile kullanarak “test” ismindeki cluster’ı 17 versiyonuna güncelliyoruz. Bu işlem 17 versiyonunda “test” isimli bir cluster yaratacak ve pg_dump kullanarak verileri yeni cluster’a taşıyacak. Aynı zamanda konfigürasyon dosyalarını taşıyacak ve 16 versiyonundaki eski cluster’ın port numarasını da değiştirecektir.
# pg_upgradecluster 16 test
Stopping old cluster...
Restarting old cluster with restricted connections...
Notice: extra pg_ctl/postgres options given, bypassing systemctl for start operation
Creating new PostgreSQL cluster 17/test ...
/usr/lib/postgresql/17/bin/initdb -D /var/lib/postgresql/17/test --auth-local peer --auth-host scram-sha-256 --no-instructions --encoding UTF8 --lc-collate en_US.UTF-8 --lc-ctype en_US.UTF-8 --locale-provider libc
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.UTF-8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/17/test ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... Etc/UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
Copying old configuration files...
Copying old start.conf...
Copying old pg_ctl.conf...
Starting new cluster...
Notice: extra pg_ctl/postgres options given, bypassing systemctl for start operation
Running init phase upgrade hook scripts ...
Roles, databases, schemas, ACLs...
set_config
------------
(1 row)
set_config
------------
(1 row)
Fixing hardcoded library paths for stored procedures...
Upgrading database postgres...
Fixing hardcoded library paths for stored procedures...
Upgrading database template1...
Stopping target cluster...
Stopping old cluster...
Disabling automatic startup of old cluster...
Starting upgraded cluster on port 5433...
Running finish phase upgrade hook scripts ...
vacuumdb: processing database "postgres": Generating minimal optimizer statistics (1 target)
vacuumdb: processing database "template1": Generating minimal optimizer statistics (1 target)
vacuumdb: processing database "postgres": Generating medium optimizer statistics (10 targets)
vacuumdb: processing database "template1": Generating medium optimizer statistics (10 targets)
vacuumdb: processing database "postgres": Generating default (full) optimizer statistics
vacuumdb: processing database "template1": Generating default (full) optimizer statistics
Success. Please check that the upgraded cluster works. If it does,
you can remove the old cluster with
pg_dropcluster 16 test
Ver Cluster Port Status Owner Data directory Log file
16 test 5434 down postgres /var/lib/postgresql/16/test /var/log/postgresql/postgresql-16-test.log
Ver Cluster Port Status Owner Data directory Log file
17 test 5433 online postgres /var/lib/postgresql/17/test /var/log/postgresql/postgresql-17-test.log
# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
16 main 5432 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
16 test 5434 down postgres /var/lib/postgresql/16/test /var/log/postgresql/postgresql-16-test.log
17 test 5433 online postgres /var/lib/postgresql/17/test /var/log/postgresql/postgresql-17-test.log
Şimdi ise pg_upgradecluster çalıştırırken “pg_upgrade –link” yöntemini kullanalım. Güncellediğimiz cluster’ı silerek, eski test cluster’ımızı yeniden açalım ve sonrasında pg_upgradecluster komutunu “link” yöntemi ile ve “parallel”, “rename” opsiyonlarını da deneyerek çalıştıralım.
# pg_dropcluster 17 test --stop
# pg_ctlcluster start 16 test
# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
16 main 5432 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
16 test 5434 online postgres /var/lib/postgresql/16/test /var/log/postgresql/postgresql-16-test.log
# pg_upgradecluster 16 test --method link --jobs 2 --rename test17
Stopping old cluster...
Creating new PostgreSQL cluster 17/test17 ...
/usr/lib/postgresql/17/bin/initdb -D /var/lib/postgresql/17/test17 --auth-local peer --auth-host scram-sha-256 --no-instructions --encoding UTF8 --lc-collate en_US.UTF-8 --lc-ctype en_US.UTF-8 --locale-provider libc
The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.
The database cluster will be initialized with locale "en_US.UTF-8".
The default text search configuration will be set to "english".
Data page checksums are disabled.
fixing permissions on existing directory /var/lib/postgresql/17/test17 ... ok
creating subdirectories ... ok
selecting dynamic shared memory implementation ... posix
selecting default "max_connections" ... 100
selecting default "shared_buffers" ... 128MB
selecting default time zone ... Etc/UTC
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
Copying old configuration files...
Copying old start.conf...
Copying old pg_ctl.conf...
Running init phase upgrade hook scripts ...
/usr/lib/postgresql/17/bin/pg_upgrade -b /usr/lib/postgresql/16/bin -B /usr/lib/postgresql/17/bin -p 5434 -P 5433 -d /etc/postgresql/16/test -D /etc/postgresql/17/test17 --link -j 2
Finding the real data directory for the source cluster ok
Finding the real data directory for the target cluster ok
Performing Consistency Checks
-----------------------------
Checking cluster versions ok
Checking database user is the install user ok
Checking database connection settings ok
Checking for prepared transactions ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking data type usage ok
Creating dump of global objects ok
Creating dump of database schemas
ok
Checking for presence of required libraries ok
Checking database user is the install user ok
Checking for prepared transactions ok
Checking for new cluster tablespace directories ok
If pg_upgrade fails after this point, you must re-initdb the
new cluster before continuing.
Performing Upgrade
------------------
Setting locale and encoding for new cluster ok
Analyzing all rows in the new cluster ok
Freezing all rows in the new cluster ok
Deleting files from new pg_xact ok
Copying old pg_xact to new server ok
Setting oldest XID for new cluster ok
Setting next transaction ID and epoch for new cluster ok
Deleting files from new pg_multixact/offsets ok
Copying old pg_multixact/offsets to new server ok
Deleting files from new pg_multixact/members ok
Copying old pg_multixact/members to new server ok
Setting next multixact ID and offset for new cluster ok
Resetting WAL archives ok
Setting frozenxid and minmxid counters in new cluster ok
Restoring global objects in the new cluster ok
Restoring database schemas in the new cluster
ok
Adding ".old" suffix to old global/pg_control ok
If you want to start the old cluster, you will need to remove
the ".old" suffix from /var/lib/postgresql/16/test/global/pg_control.old.
Because "link" mode was used, the old cluster cannot be safely
started once the new cluster has been started.
Linking user relation files
ok
Setting next OID for new cluster ok
Sync data directory to disk ok
Creating script to delete old cluster ok
Checking for extension updates ok
Upgrade Complete
----------------
Optimizer statistics are not transferred by pg_upgrade.
Once you start the new server, consider running:
/usr/lib/postgresql/17/bin/vacuumdb --all --analyze-in-stages
Running this script will delete the old cluster's data files:
./delete_old_cluster.sh
pg_upgradecluster: pg_upgrade output scripts are in /var/log/postgresql/pg_upgradecluster-16-17-test17.WyLf
Disabling automatic startup of old cluster...
Starting upgraded cluster on port 5434...
Running finish phase upgrade hook scripts ...
vacuumdb: processing database "postgres": Generating minimal optimizer statistics (1 target)
vacuumdb: processing database "template1": Generating minimal optimizer statistics (1 target)
vacuumdb: processing database "postgres": Generating medium optimizer statistics (10 targets)
vacuumdb: processing database "template1": Generating medium optimizer statistics (10 targets)
vacuumdb: processing database "postgres": Generating default (full) optimizer statistics
vacuumdb: processing database "template1": Generating default (full) optimizer statistics
Success. Please check that the upgraded cluster works. If it does,
you can remove the old cluster with
pg_dropcluster 16 test
Ver Cluster Port Status Owner Data directory Log file
16 test 5433 down postgres /var/lib/postgresql/16/test /var/log/postgresql/postgresql-16-test.log
Ver Cluster Port Status Owner Data directory Log file
17 test17 5434 online postgres /var/lib/postgresql/17/test17 /var/log/postgresql/postgresql-17-test17.log
# pg_lsclusters
Ver Cluster Port Status Owner Data directory Log file
16 main 5432 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log
16 test 5433 down postgres /var/lib/postgresql/16/test /var/log/postgresql/postgresql-16-test.log
17 test17 5434 online postgres /var/lib/postgresql/17/test17 /var/log/postgresql/postgresql-17-test17.log
Upgrade işlemi ile birlikte pg_upgradecluster’ın gerçekleştirdiği pre ve post işlemleri de komut çıktısında görebilirsiniz. Çıktıdaki şu uyarı link modu kullanıldığını ve yeni versiyon cluster açıldıktan sonra eski cluster’ın sağlıklı bir şekilde açılamayacağını belirtiyor: Because “link” mode was used, the old cluster cannot be safely started once the new cluster has been started.
Yöntemden bağımsız olarak upgrade işlemlerindeki en önemli iki nokta, doğru hazırlık ve geri dönüş planı oluşturmadır. Doğru hazırlık aşamasında veri tabanında çalışan tüm uygulamaların veri tabanının hedef versiyonunda test edilmeleri, ayrıca upgrade adımlarının da test ve dökümante edilmesi çok önemlidir. Geri dönüş planı ise upgade işlemi sırasında ya da sonrasında yaşanabilecek ciddi sorunlara karşı bir hazırlıktır. Veri tabanının yeni versiyona sağlıklı geçememesi ya da yeni versiyonda uygulama fonksiyonlarının doğru çalışmaması ile birlikte kısa süre içinde düzeltme şansının da olmaması durumlarında, eski versiyona veri kaybı olmadan geçebilmek gereklidir. Bunun için geri dönüş planımızı upgrade öncesinde oluşturmalı ve test etmeliyiz.
Bir yanıt yazın