PostgreSQL sorgumun ne kadar uzun olduğunu nasıl öğrenebilirim?


35

SELECT ... INTO sorgumun gerçekte kaç satır işleyeceği hakkında oldukça iyi bir fikrim var (örneğin, kaç tanenin gerçekleşeceğini biliyorum).

Anlıyorum ki Postgres bana yüzde bütünlüğünü söylemeyecek, hedef tabloya kaç satır pompalandığını ya da SELECT sorgusu tarafından okunduğumu öğrenebilmemin bir yolu var (kütüklere, sistem tablolarına veya başka bir yere gömülü) ?

Yanıtlar:


33

Daniel Vérité'nin dediği gibi, genel bir çözüm gibi görünmüyor. Bir dosyadan bir tabloya veri yüklerken aşağıdaki teknik, yükün ilerlemesini elde etmek için kullanılabilir.

KOPYA komut konsolu ilerleme çubuğu

Boş bir tablo oluşturun.

CREATE TABLE mytest (n int);

Tabloya yüklemek için 10 milyon satırlık bir veri dosyası oluşturun.

$ seq 10000000 > /tmp/data.txt

Verileri dosyadan tabloya yükleyin ve bir ilerleme çubuğu görüntüleyin.

$ pv /tmp/data.txt | psql -c "COPY mytest FROM STDIN;"

gösteri

görüntü tanımını buraya girin

Bu nasıl çalışır

Kopyalama komutları STDIN seçeneğini kullanarak kopyalama işlemi için verileri başka bir işlemden besleyebiliriz. Pv komutu bir dosya çıkarır ve bir ilerleme çubuğu, ETA, geçen toplam süre ve veri aktarım hızını gösteren ilerlemesini izler.

COPY komutu grafiksel ilerleme çubuğu

Aynı genel tekniği kullanarak, grafiksel bir uygulamada veya web tabanlı bir uygulamada bir ilerleme çubuğu görüntüleyebiliriz. Örneğin python kullanmak, psycopg2 modülü, copy komutunu seçtiğiniz bir dosya nesnesiyle çağırmanızı sağlar. Daha sonra dosya nesnenizin ne kadarının okunduğunu izleyebilir ve bir ilerleme çubuğu görüntüleyebilirsiniz.


2
pvKomuta daha önce rastlamamıştım ve varsayılan olarak Debian sunucumda kurulmamıştı, ama depoda. Açıklamada "pv (Pipe Viewer), verilerin ne kadar hızlı bir şekilde geçtiğinin görsel bir gösterimini vermek için iki işlem arasında herhangi bir normal boru hattına yerleştirilebileceğini" söylüyor. Çok kullanışlı bir komut!
Richard Turner,

27

Genel, desteklenen bir yöntem gibi görünmüyor, ancak bireysel bir sorgunun ilerlemesini değerlendirmek için sınırlı bağlamlarda kullanılabilecek bazı püf noktaları var. Bunlardan bazıları.

Diziler

Bir SELECT veya UPDATE sorgusu herhangi birini içerdiğinde nextval(sequence_name)veya bir INSERT nextvalvarsayılan olarak bir hedef sütuna sahipse , geçerli sıra değeri art arda ile başka bir oturumda sorgulanabilir SELECT sequence_name.last_value. Çalışır çünkü sekanslar işlemlerle sınırlı değildir. Yürütme planı, sıralama sorgu sırasında doğrusal olarak artırılacak şekilde olduğunda, bir ilerleme göstergesi olarak kullanılabilir.

pgstattuple

Pgstattuple contrib modülü veri sayfalarına doğrudan gözetleme işlevleri sağlar. Tupler boş bir masaya yerleştirildiğinde ve henüz tamamlanmadığında, dead_tuple_countalandaki pgstattuplefonksiyondan sayıldıkları görülüyor .

9.1 ile Demo: boş bir tablo oluşturun

CREATE TABLE tt AS (n numeric);

İçine 10M satır ekleyelim:

INSERT INTO tt SELECT * FROM random() from generate_series(1,10000000);

Başka bir oturumda, ekleme sırasında her saniye pgstattuple'ı kontrol edin:

$ while true;
   do psql -Atc "select dead_tuple_count from pgstattuple('tt')";
   sleep 1;
  done

Sonuçlar:

0
69005
520035
1013430
1492210
1990415
2224625
2772040
3314460
3928660
4317345
4743770
5379430
6080950
6522915
7190395
7953705
8747725
9242045
0

Ekleme bittiğinde 0'a geri döner (tüm perdeler görünür ve canlanır).

Bu numara, tablo yeni yaratılmadığında da kullanılabilir, ancak başlangıçta dead_tuple_countsıfır olmayan bir değere sahip olması muhtemeldir ve aynı zamanda autovacuum gibi diğer yazma aktiviteleri devam ederse aynı zamanda değişebilir (muhtemelen? eşzamanlılık autovacuum ile beklemek

Ancak , oluşturma işlemi gerçekleştiği için tablo ifadenin kendisi tarafından oluşturulmuşsa ( CREATE TABLE ... AS SELECTveya SELECT * INTO newtable) kullanılamaz. Çözüm, çizelgeyi satır içermeyen (ekleme LIMIT 0) oluşturmak ve bir sonraki işlemde doldurmak olacaktır.

pgstattupleÜcretsiz gelmediğini unutmayın : Her aramada tüm masayı tarar. Ayrıca süper kullanıcılar ile sınırlıdır.

Özel sayaç

Pavel Stehule'un blogunda, C'de uygulanan ve belirtilen sayıda idamda BİLDİRİMİ yükselten bir sayaç işlevi sağlar . Yürütücünün çağırmasına izin vermek için işlevi bir şekilde sorguyla birleştirmeniz gerekir. Sorgu sırasında bildirimler gönderilir ve ayrı bir oturuma ihtiyaç duymazlar, yalnızca onları görüntüleyen bir SQL istemcisi ( psqlaçık aday olur).

İhbarları yükseltmek için yeniden yapılan INSERT INTO örneği:

/* transformation */
INSERT INTO destination_table
   SELECT (r).*
  FROM (SELECT counter(to_destination_table(_source), 1000, true) r
           FROM source _source) x

İşlevler için stackoverflow ile ilgili soru:
Uzun süren PostgreSQL işlevinden istemciye ilerleme nasıl bildirilir?

Gelecek seçenekler?

Mayıs 2017'den itibaren, geliştirici topluluğuna gelecek vaat eden bir yama var: [PATCH v2] Uzun süredir devam eden SQL sorgularının ilerlemesini izlemek için ilerleme komutu

PostgreSQL 11 veya sonraki sürümlerinde genel bir çözüm olarak ortaya çıkabilir. Devam eden çalışma özelliklerine katılmak isteyen kullanıcılar, düzeltme ekinin en son sürümünü uygulayabilir ve önerilen PROGRESSkomutu deneyebilir .


3

İlerleme raporunun işlevselliği genişletilinceye kadar, cevabında @AmirAliAkbari'nin dediği gibi, işletim sistemi düzeyinde bir geçici çözüm.

Bu sadece Linux'larda çalışır, ancak muhtemelen herhangi bir işletim sistemi için kolayca göze çarpan benzer çözümler vardır.

Onun artalanının tüm kullanarak basit tek iş parçacıklı işlemler olduğu büyük avantaj ve PostgreSQL de dezavantajı, lseek(), read()ve write()onlar paylaşılan mem ve kilitleri üzerinde etkileşime girerken, onların masa dosyalarını işlemek için.

Bu sonuç, tüm arka uç işlemlerinin her zaman kolayca bulunabilen ve kolayca bulunabilen tek bir sorguda çalışıyor olması straced.

Önce, bir arka uç PID görebilirsiniz SELECT * FROM pg_stat_activity;:

29805270 | dbname  | 20019 |    16384 | username  |                  |             |                 |          -1 | 2018-09-19 21:31:57.68234+02  | 2018-09-19 21:31:59.435376+02 | 2018-09-\
20 00:34:30.892382+02 | 2018-09-20 00:34:30.892386+02 | Client          | ClientRead | active              |       92778 |        92778 |  INSERT INTO ...something...

Üçüncü sütun ise pid. PostgreSQL'de, arka uçtaki Linux işlem pidiyle aynıdır.

Daha sonra, örneğin strace -p 20019 -s 8192:: ( -s 8192postgresql 8192 byte uzunluğunda bloklarla çalıştığı için kullanışlıdır) ile onu bozabilirsiniz.

sendto(10, "C\0\0\0\17INSERT 0 1\0Z\0\0\0\5T", 22, 0, NULL, 0) = 22
recvfrom(10, "Q\0\0\1\267 INSERT <removed by @peterh>", 8192, 0, NULL, NULL) = 440
sendto(10, "C\0\0\0\17INSERT 0 1\0Z\0\0\0\5T", 22, 0, NULL, 0) = 22
lseek(298, 343634345)...
read(298, "<block data which was read in>"....
write(298, "<block data which was written out>"...

Anlamları:

  • sendtoarka uç bir müşteriye bir şey yanıtlarsa olur. Örnekte, bir INSERTsorgunun sonucunu cevaplar .
  • recvfromarka uç bir müşteriden bir şey alırsa olur. Tipik olarak yeni bir sorgu, örnekte bir başkası INSERT.
  • lseek arka uç bir tablo dosyasındaki yerini değiştirirse olur.
  • read arka uç bir tablo dosyasından bir blok okursa olur.
  • write arka uç bir tablo dosyasına bir blok yazarsa olur.

Durumunda readve write, ayrıca tabloda bu bloğun içeriği görebilirsiniz. Ne olduğunu, nerede olduğunu ve nerede olduğunu anlamak için çok yardımcı olabilir.

Bu durumda recvfrom, asıl sorguyu arka uçta ne bulduğunu görebilirsiniz.


2

Diğer cevaplarda belirtildiği gibi, şu anda genel olarak ilerleme raporlaması için doğrudan bir yol bulunmamaktadır.

PostgreSQL, komut çalıştırma sırasında belirli komutların ilerleyişini raporlama yeteneğine sahiptir. Şu anda, ilerleme raporlamasını destekleyen tek komut VACUUM'dur. Bu gelecekte genişletilebilir.

Bununla birlikte, 9.6'dan başlayarak, ne zaman VACUUMçalışıyorsa, pg_stat_progress_vacuumgörünüm, şu anda vakumda olan her bir arka uç için (autovacuum çalışan işlemleri dahil) bir satır içerecektir. Daha ayrıntılı bilgi pg_stat_progress_vacuumdokümantasyonda bulunabilir: 27.4 İlerleme Raporlaması .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.