Utilitas pembuatan profil perf yang dikirimkan dengan kernel Linux sangat berguna untuk memeriksa perilaku sistem dan multi-proses – tetapi melakukan lebih banyak daripada profil CPU yang sering digunakan. Anda mungkin pernah melihat perf top -az atau perf top -u postgres output, tapi itu hanya sedikit dari apa yang dapat dilakukannya. (Jika Anda menginginkan versi TL/DR, lompat ke bawah ke “User space dynamic probes”).
Salah satu keuntungan besar perf adalah bahwa itu tidak mengganggu. Anda tidak perlu melampirkan debugger dan menginterupsi eksekusi. Anda tidak perlu menjalankan perintah langsung di bawah profiler di lingkungan khusus. Tidak perlu memulai ulang server untuk men-debug beban kerja yang bermasalah, dan seringkali tidak perlu mengkompilasi ulang dengan opsi debug. Ini sangat berguna saat Anda mencoba melacak masalah kinerja dalam sistem langsung, karena memungkinkan Anda menguji teori tentang apa yang mungkin terjadi dengan cepat dan dengan dampak minimal.
sempurna bukan hanya profiler, tetapi juga memiliki dukungan penelusuran. Pembuatan profil didasarkan pada pengambilan sampel status sistem saat dipicu oleh penghitung kinerja perangkat keras atau perangkat lunak; ini memberikan sampling statistik dari titik-titik di mana sistem menghabiskan sebagian besar waktu. Sebagai gantinya, penelusuran mengambil sampel setiap kali peristiwa pelacakan tertentu terjadi, jadi ini jauh lebih berguna untuk peristiwa yang jarang tetapi penting.
Saat bekerja dengan PostgreSQL salah satu fitur paling menarik dari perf adalah kemampuan untuk melacak proses ruang pengguna . Ingin tahu seberapa sering PostgreSQL Anda menukar segmen WAL, seberapa sering pencarian kunci asing, dll? Untuk satu backend PostgreSQL atau di seluruh cluster? sempurna dapat membantu dengan itu.
Tracepoint ruang pengguna dan ruang kernel dapat dicampur dan dapat digunakan pada saat yang sama sebagai profil penghitung kinerja untuk membantu Anda mendapatkan gambaran yang baik tentang sistem. sempurna dapat menangkap jejak tumpukan dari kernel dan ruang pengguna, dan juga dapat melakukan visualisasi statistik. Tracepoint ruang pengguna dibuat dengan probe dinamis; yang kernel-space dapat ditentukan sebelumnya atau dapat berupa probe dinamis.
Jadi, bagaimana Anda menggunakan beberapa fitur ini?
Instal alat
Pertama, pastikan Anda menggunakan perf saat ini . Artikel ini ditulis di Fedora 19 dengan perf 3.11.6 pada x86_64, dan beberapa fiturnya relatif baru.
Jika Anda menginginkan hasil tumpukan ruang pengguna, Anda ingin kode yang Anda lihat dibuat dengan -Og -ggdb -fno-omit-frame-pointer . Jika Anda menggunakan perf dibangun dengan libunwind Anda tidak membutuhkan frame-pointer; lihat posting Stack Overflow ini dan RH Bugzilla #1025603. Semua ini tidak diperlukan jika Anda hanya tertarik pada data sisi kernel. Jika Anda menggunakan paket distro, Anda mungkin perlu menginstal -debuginfo paket juga.
Semua pengujian berikut dijalankan dengan paket PGDG PostgreSQL 9.2 stok dari http://yum.postgresql.org/ menggunakan perf dibangun kembali dengan libunwind mendukung sesuai dengan petunjuk di atas.
Tracepoint dan probe kernel
sempurna dapat menangkap data dari titik jejak kernel yang telah ditentukan sebelumnya, beberapa di antaranya informatif saat melihat masalah dengan fragmentasi memori, I/O disk, dll. Anda bisa mendapatkan daftar titik jejak dengan sudo perf list . Daftar tracepoint dapat ditentukan dan wildcard didukung. Misalnya, jika kita ingin mendapatkan statistik write dan disk flush pada instance PostgreSQL yang sedang berjalan, kita dapat menjalankan:
sudo perf record -g dwarf -e block:block_rq_issue,syscalls:sys_enter_fsync -u postgres sleep 10
untuk menangkap datanya. Alih-alih tidur, Anda dapat menggunakan no command dan menekan control-C saat Anda selesai merekam, atau Anda dapat menggunakan beberapa perintah lain seperti psql -c untuk memicu beban kerja yang ingin Anda ukur.
-u postgres profil semua proses yang berjalan sebagai pengguna postgres . Anda dapat menggunakan -a untuk pembuatan profil seluruh sistem di semua CPU. Dimungkinkan juga untuk melacak hanya satu backend. Mulai psql , jalankan pilih pg_backend_pid() , jalankan perf dengan -p $the_pid , lalu mulai beban kerja di psql . yang sama sesi.
Saat Anda bekerja dengan PostgreSQL, proses target default, yaitu perintah yang dijalankan di bawah kendali perf , biasanya tidak terlalu berguna karena backend melakukan sebagian besar pekerjaan, bukan psql . Masih berguna untuk menggunakan subperintah untuk mengontrol beban kerja dan waktu pengujian.
Setelah Anda mengambil data, Anda dapat menggunakan laporan kinerja untuk memeriksanya. Ada terlalu banyak opsi untuk didiskusikan di sini – untuk mengontrol agregasi dan penyederhanaan hasil, tampilan pelacakan tumpukan, kutukan interaktif vs keluaran laporan teks, dan banyak lagi.
Ambil sesi ini sebagai contoh, di mana ada sesi shell (terminal “T2”) dan sesi postgres terhubung ke database “regress” (terminal “T1”):
T1| regress=> pilih pg_backend_pid();T1| pg_backend_pid T1| ----------------T1| 4495T1|(1 baris)
T2| $ sudo perf record -g dwarf -e block:block_rq_*,syscalls:sys_enter_write,syscalls:sys_enter_fsync -p 4495
T1| regress=> buat tabel x sebagai pilih FROM generate_series(1,1000000) a;T1| regress=>
T2| $ ^CT2| [ catatan kinerja:Bangun 332 kali untuk menulis data ]T2| [ catatan perf:Ditangkap dan ditulis 86.404 MB perf.data (~3775041 sampel) ]T2|T2| $ sudo laporan kinerja -g
Anda dapat menggunakan laporan kinerja gui kutukan untuk menggali jejak, atau Anda dapat menggunakan perf report --stdio opsi untuk membuatnya mengalirkan data ke stdout. Misalnya, jika Anda ingin pelacakan tumpukan, Anda dapat menjalankan:
$ sudo perf report -g --stdio... bla bla ...# Contoh:1 dari peristiwa 'syscalls:sys_enter_fsync'# Jumlah peristiwa (perkiraan):1## Perintah Overhead Simbol Objek Bersama# .. ...... ........ ............. .................# 100.00 % postgres libc-2.17.so [.] __GI___libc_fsync | --- __GI___libc_fsync mdimmedsync heap_sync intorel_shutdown standard_ExecutorRun ExecCreateTableAs PortalRunUtility PortalRunMulti PortalRun PostgresMain ServerLoop PostmasterMain main __libc_start_main _start (nil)... blah blah...
menunjukkan bahwa untuk acara syscalls:sys_enter_fsync ada satu peristiwa dengan tumpukan di atas, fsync dipanggil melalui ExecCreateTableAs .
(Karena suatu alasan saya belum dapat menentukan fsync() final final sepertinya tidak ditangkap oleh perf ketika psql dijalankan langsung di bawah kendali perf . Ini bukan masalah dengan statistik kinerja , hanya rekor kinerja . Itu sebabnya saya melompat melalui rintangan untuk memilih backend dengan pid di atas.)
Probe dinamis ruang pengguna
Terkadang Anda lebih tertarik pada sesuatu yang terjadi di dalam PostgreSQL itu sendiri daripada peristiwa di dalam kernel yang dipicu oleh PostgreSQL. Versi perf yang lebih baru dapat membantu dengan ini dengan menyisipkan tracepoint dinamis yang memicu panggilan di program ruang pengguna.
Katakanlah Anda tertarik untuk menonton aktivitas WAL, dan ingin melihat kapan XLogFlush , XLogFileInit atau XLogFileOpen disebut. Anda dapat menyisipkan titik jejak dinamis untuk panggilan ini dengan perf :
sudo perf probe -x `which postgres` XLogFileInitsudo perf probe -x `which postgres` XLogFileOpensudo perf probe -x `which postgres` XLogFlush
Anda hanya dapat menyelidiki simbol eksternal (non-statis, tidak disembunyikan oleh tanda -fvisibility) kecuali jika Anda membuat dengan -ggdb . sempurna akan mengeluh tidak ada simbol yang ditemukan jika Anda mencoba menggunakan simbol yang tidak ada. Pada saat penulisan perf tidak mendukung penggunaan debuginfo eksternal untuk mencari simbol untuk probe, meskipun dapat menggunakannya untuk analisis tumpukan. Secara umum, jika itu adalah eksternal di src/include Anda dapat menggunakannya dengan perf .
Setiap tracepoint akan mencetak nama tracepoint yang dibuat dan Anda dapat menggunakan perf probe -l untuk tetap mencantumkan semuanya:
$ sudo perf probe -l probe_postgres:XLogFileInit (pada 0x0000000000009a360) probe_postgres:XLogFileOpen (pada 0x0000000000009a860) probe_postgres:XLogFlush (pada 0x00000000000a0670)
Probe ini sekarang dapat digunakan sebagai acara perf. Mari kita lihat aktivitas xlog selama contoh beban kerja, pemantauan di seluruh cluster saat saya menjalankan pgbench:
sudo perf record -g dwarf -u postgres -e probe_postgres:XLogFileInit,probe_postgres:XLogFileOpen,probe_postgres:XLogFlush
Cobalah sendiri dengan perf report -g . Begini tampilan hasilnya. Anda dapat menggunakan opsi seperti -g fractal,0 untuk mengontrol detail. Anda akan dapat melihat persentase hit penghitung tertentu yang berasal dari satu cabang tumpukan atau lainnya, pid dan proses, dll. --sort opsi memberi Anda kontrol lebih besar atas agregasi dan pengelompokan.
Tapi tunggu, masih ada lagi
Anda juga harus memeriksa statistik kinerja dan perf top perintah. Mereka dapat mengambil daftar acara yang sama dengan perf record , meskipun untuk beberapa alasan aneh dukungan filter proses mereka berbeda.
Berikut adalah contoh yang menjalankan beban kerja dummy dan melihat tracepoint kernel I/O selama proses:
$ sudo perf stat -e block:block_rq_*,syscalls:sys_enter_write,syscalls:sys_enter_fsync -a -r 5 -- psql -q -U postgres craig -c "jatuhkan tabel jika ada x; buat tabel x sebagai pilih a DARI generate_series(1,1000000) a;"; Statistik penghitung kinerja untuk 'psql -U postgres craig -c drop table jika ada x; buat tabel x sebagai pilih FROM generate_series(1,1000000) a;' (5 berjalan):0 blok:block_rq_abort [100.00%] 0 blok:block_rq_requeue [100.00%] 97 blok:block_rq_complete ( +- 14,82% ) [100.00%] 96 blok:block_rq_insert ( +- 14,97% ) [100.00%] 98 block:block_rq_issue ( +- 14.67% ) [100.00%] 0 block:block_rq_remap [100.00%]10.607 syscalls:sys_enter_write ( +- 0.17% ) [100.00%] 1 syscalls:sys_enter_fsync 0.908835058 detik waktu berlalu ( +- 18.31% ) /pra>Anda dapat melihatnya melakukan rata-rata sekitar 100 permintaan I/O lapisan blok lebih dari 10rb write()s dan melakukan satu fsync(). Beberapa di antaranya adalah kebisingan latar belakang sistem karena kami melakukan semua profil sistem (-a ), tetapi karena sistemnya cukup menganggur, itu tidak banyak, dan rata-rata berjalan lebih dari lima kali.
Demikian pula, dengan menggunakan probe dinamis yang kami tambahkan sebelumnya, awasi aktivitas xlog selama menjalankan pgbench:
$ sudo perf stat -e probe_postgres:XLogFileInit,probe_postgres:XLogFileOpen,probe_postgres:XLogFlush -a -- /usr/pgsql-9.2/bin/pgbench -U postgres craig -c 2 -t 10000starting vacuum...end. jenis transaksi:TPC-B (semacam) faktor penskalaan:100 mode kueri:sederhanajumlah klien:2jumlah utas:1jumlah transaksi per klien:10000jumlah transaksi yang benar-benar diproses:20000/20000tps =715.854663 (termasuk pembuatan koneksi)tps =716.092133 ( tidak termasuk pembuatan koneksi) Statistik penghitung kinerja untuk '/usr/pgsql-9.2/bin/pgbench -U postgres craig -c 2 -t 10000':64 probe_postgres:XLogFileInit [100.00%] 0 probe_postgres:XLogFileOpen [100.00%] 55.440 probe_postgres:XLogFlush 27.987364469 detik waktu berlaluMasih banyak lagi yang dapat Anda lakukan, termasuk menangkap status variabel lokal dengan perf probe . Saya akan menulis beberapa contoh yang berguna nanti. Sementara itu, mainkan, jelajahi, dan bersenang-senanglah dengan alat diagnostik baru.
Pembaruan: Michael Paquier baru-baru ini menulis artikel terkait tentang melacak PostgreSQL dengan systemtap yang mungkin menarik bagi pembaca yang satu ini. Anda harus mengkompilasi ulang Pg untuk menggunakan pendekatan itu, tetapi sintaksnya lebih bagus dan menawarkan beberapa keuntungan lain.