Yoğun UPDATE iş yükleri tablolarda şişmeye neden olur; VACUUM çalıştırılsa bile ölü demetler birikir ve tablo boyutu artar. pg_repack uzantısı, ApsaraDB RDS for PostgreSQL'de bu alanı geri kazanır. İşlem süresince tabloda özel kilit tutmadığı için CLUSTER veya VACUUM FULL komutlarına göre daha az kesinti yaratır.
Önkoşullar
Başlamadan önce aşağıdaki koşulları sağladığınızdan emin olun:
Örnek, PostgreSQL 10 veya sonraki bir sürümü çalıştırıyor olmalıdır.
Küçük motor sürümü 20240229 veya üzeri olmalıdır (PostgreSQL 17 için sürüm 20241030 veya üzeri gereklidir).
Küçük motor sürümünü güncellemek için bkz. ApsaraDB RDS for PostgreSQL örneğinin küçük motor sürümünü güncelleme.
Küçük motor sürümü 20240229'dan eskiyse, herhangi bir pg_repack işlevini çalıştırdığınızda ERROR: must be superuser to use xxx function hatası alırsınız.
Sınırlamalar
Geçici tablolar veya GiST dizinleri yeniden paketlenemez.
Tam tablo yeniden paketleme sırasında, tablo üzerindeki DDL deyimleri engellenir. pg_repack bunu uygulamak için bir ACCESS SHARE kilidi tutar.
Tam tablo yeniden paketleme işlemi, yeniden paketlemek istediğiniz tablonun en az iki katı kadar kullanılabilir depolama alanı gerektirir.
Tam tablo yeniden paketleme G/Ç yoğun bir işlemdir. Performans düzeyi 1 (PL1) olan Geliştirilmiş SSD (ESSD) kullanan bir örnekte, 100 GB'lık bir tabloyu yeniden paketlemek maksimum G/Ç aktarım hızı olan 250 MB/s değerine ulaşabilir; bu nedenle işlemi yoğun saatler dışında çalıştırın.
Çalışma mantığı
Tam tablo yeniden paketleme
pg_repack, tabloyu yedi adımda yeniden oluşturur:
Yeniden paketleme sırasında orijinal tabloda yapılan değişiklikleri yakalamak için bir günlük tablosu oluşturur.
Her INSERT, UPDATE ve DELETE işlemini günlük tablosuna yazmak üzere orijinal tabloya tetikleyiciler ekler.
Tüm satırları yeni bir tabloya kopyalar.
Yeni tablo üzerinde dizinler oluşturur.
Biriken günlük tablosu değişikliklerini yeni tabloya uygular.
Sistem kataloğunda orijinal tablo ile yeni tabloyu değiştirir.
Orijinal tabloyu siler.
pg_repack, 1, 2, 6 ve 7. adımlarda bir ACCESS EXCLUSIVE kilidi tutar. Diğer tüm adımlarda yalnızca bir ACCESS SHARE kilidi tutar; bu sayede orijinal tablo üzerindeki INSERT, UPDATE ve DELETE işlemleri kesintisiz devam eder.
Yalnızca dizin yeniden paketleme
Yeni dizinleri eş zamanlı olarak oluşturur.
Sistem kataloğunda orijinal dizinler ile yeni dizinleri değiştirir.
Orijinal dizinleri siler.
pg_repack'i etkinleştirme veya devre dışı bırakma
Bu deyimleri ayrıcalıklı hesap kullanarak çalıştırın.
-- Enable
CREATE EXTENSION pg_repack;
-- Disable
DROP EXTENSION pg_repack;
pg_repack istemci yardımcı programını yükleme
pg_repack komut satırı istemcisi, Elastic Compute Service (ECS) örneğinizde çalışır ve RDS örneğine uzaktan bağlanır. Aşağıdaki adımlar, Alibaba Cloud Linux 3.2104 veya sonraki sürümleri çalıştıran ECS örnekleri için geçerlidir.
-
Derleme bağımlılıklarını yükleyin:
sudo yum install postgresql* redhat-rpm-config libpq* openssl-devel readline-devel -y -
PostgreSQL ikili dosyalarını yolunuza ekleyin:
NotYukarıdaki komuttaki yol ve PostgreSQL sürümü örnek amaçlıdır. Bunları kendi ortamınızın değerleriyle değiştirin.
export PATH=$PATH:/usr/lib64/pgsql/postgresql-12/bin -
İstemciyi indirin, derleyin ve yükleyin:
wget https://github.com/reorg/pg_repack/archive/refs/tags/ver_1.4.6.tar.gz tar zxvf ver_1.4.6.tar.gz cd pg_repack-ver_1.4.6 make && make install
Tabloyu yeniden paketleme
Kullanılabilir depolama alanını kontrol etme
Tam tablo yeniden paketleme işlemi, tablo boyutunun en az iki katı kadar kullanılabilir depolama alanı gerektirir. Yeniden paketlemeden önce yeterli boş alana sahip olduğunuzdan emin olun.
Tablo boyutunu kontrol etmek ve gerekli depolama alanını tahmin etmek için aşağıdaki sorguları çalıştırın:
-- Check total table size (including TOAST and indexes)
SELECT pg_size_pretty(pg_total_relation_size('schema1.table1')) AS total_size;
-- Check heap size only
SELECT pg_size_pretty(pg_relation_size('schema1.table1')) AS heap_size;
Tam tablo yeniden paketleme işlemine başlamadan önce, mevcut toplam tablo boyutunun en az 2 katı kadar boş depolama alanı ayırın.
Kuru çalıştırma (önerilir)
Herhangi bir değişiklik yapmadan işlemi doğrulamak için --dry-run seçeneğiyle çalıştırın:
pg_repack --dry-run --no-superuser-check --echo --no-order \
-h <endpoint> -p <port> -d <database> -U <user> \
--table schema1.table1
Tam tablo yeniden paketleme
pg_repack --no-superuser-check --echo --no-order \
-h <endpoint> -p <port> -d <database> -U <user> \
--table schema1.table1
Yer tutucuları gerçek değerlerle değiştirin:
| Yer Tutucu | Açıklama | Örnek |
|---|---|---|
<endpoint> |
RDS örneği uç noktası | rm-xxx.pg.rds.aliyuncs.com |
<port> |
Bağlantı noktası numarası | 5432 |
<database> |
Veritabanı adı | mydb |
<user> |
Veritabanı kullanıcı adı | myuser |
Sonucu doğrulama
Alanın geri kazanıldığını onaylamak için yeniden paketleme öncesi ve sonrası tablo boyutunu kontrol edin.
Yeniden paketlemeden önce:
SELECT pg_size_pretty(pg_relation_size('schema1.table1'));
Yeniden paketlemeden sonra aynı sorguyu çalıştırın. Başarılı bir yeniden paketleme işlemi daha küçük bir değer gösterir.
Sorun giderme
Hata: pg_repack failed with error: You must be a superuser to use pg_repack
Süper kullanıcı kontrolünü atlamak için -k (veya --no-superuser-check) ekleyin:
pg_repack -k --no-superuser-check ...
Tam bir tabloyu yeniden paketlerken izinleri almak için bu yöntemi kullanamazsınız.
Kaynakça
PostgreSQL veritabanlarında minimum kilitlemeyle tabloları yeniden düzenleme — pg_repack resmi belgeleri