Pernahkah Anda bertanya-tanya apa yang memicu saran di ClusterControl bahwa disk Anda sedang terisi? Atau saran untuk membuat kunci utama pada tabel InnoDB jika tidak ada? Penasihat ini adalah skrip mini yang ditulis dalam ClusterControl Domain Specific Language (DSL) yang merupakan bahasa mirip Javascript. Skrip ini dapat ditulis, dikompilasi, disimpan, dieksekusi, dan dijadwalkan di ClusterControl. Itulah yang akan dibahas dalam seri blog ClusterControl Developer Studio.
Hari ini kami akan membahas dasar-dasar Developer Studio dan menunjukkan cara membuat penasihat pertama Anda di mana kami akan memilih dua variabel status dan memberikan saran tentang hasilnya.
Para Penasihat
Penasihat adalah skrip mini yang dijalankan oleh ClusterControl, baik sesuai permintaan atau setelah jadwal. Mereka dapat berupa apa saja mulai dari saran konfigurasi sederhana, peringatan tentang ambang batas atau aturan yang lebih kompleks untuk prediksi atau tugas otomatisasi seluruh klaster berdasarkan status server atau database Anda. Secara umum, penasihat melakukan analisis yang lebih mendetail, dan menghasilkan rekomendasi yang lebih komprehensif daripada peringatan.
Penasihat disimpan di dalam database ClusterControl dan Anda dapat menambahkan penasehat baru atau mengubah/memodifikasi penasehat yang ada. Kami juga memiliki repositori Github penasihat tempat Anda dapat membagikan penasihat Anda dengan kami dan pengguna ClusterControl lainnya.
Bahasa yang digunakan untuk penasihat adalah yang disebut ClusterControl DSL dan merupakan bahasa yang mudah dipahami. Semantik bahasa dapat dibandingkan dengan Javascript dengan beberapa perbedaan, di mana perbedaan yang paling penting adalah:
- Titik koma adalah wajib
- Berbagai tipe data numerik seperti integer dan unsigned long long integers.
- Array adalah dua dimensi dan array satu dimensi adalah daftar.
Anda dapat menemukan daftar lengkap perbedaannya di referensi DSL ClusterControl.
Antarmuka Studio Pengembang
Antarmuka Developer Studio dapat ditemukan di bawah Cluster> Manage> Developer Studio. Ini akan membuka antarmuka seperti ini:
Penasihat
Tombol penasehat akan menghasilkan ikhtisar semua penasehat dengan output mereka sejak terakhir kali dijalankan:
Anda juga dapat melihat jadwal penasihat dalam format crontab dan tanggal/waktu sejak pembaruan terakhir. Beberapa penasihat dijadwalkan untuk berjalan hanya sekali sehari sehingga saran mereka mungkin tidak lagi mencerminkan kenyataan, misalnya jika Anda telah menyelesaikan masalah yang telah diperingatkan. Anda dapat menjalankan kembali penasihat secara manual dengan memilih penasihat dan menjalankannya. Buka bagian “kompilasi dan jalankan” untuk membaca cara melakukannya.
Impor penasihat
Tombol Impor akan memungkinkan Anda untuk mengimpor tarball dengan penasehat baru di dalamnya. Tarball harus dibuat relatif terhadap jalur utama penasehat, jadi jika Anda ingin mengunggah versi baru dari skrip ukuran cache kueri MySQL (s9s/mysql/query_cache/qc_size.js), Anda harus membuat tarball dimulai dari direktori s9s.
Mengekspor penasihat
Anda dapat mengekspor penasehat atau bagian dari mereka dengan memilih simpul di pohon dan menekan tombol Ekspor. Ini akan membuat tarball dengan file-file di path lengkap dari struktur yang disajikan. Misalkan kita ingin membuat cadangan penasehat s9s/mysql sebelum melakukan perubahan, kita cukup memilih node s9s/mysql di pohon dan tekan Ekspor:
Catatan:pastikan direktori s9s ada di /home/myuser/.
Ini akan membuat tarball bernama /home/myuser/s9s/mysql.tar.gz dengan struktur direktori internal s9s/mysql/*
Membuat penasihat baru
Karena kami telah membahas ekspor dan impor, sekarang kami dapat mulai bereksperimen. Jadi mari kita buat penasihat baru! Klik tombol Baru untuk mendapatkan dialog berikut:
Dalam dialog ini, Anda dapat membuat penasihat baru Anda dengan file kosong atau mengisinya terlebih dahulu dengan template khusus Galera atau MySQL. Kedua template akan menambahkan penyertaan yang diperlukan (umum/mysql_helper.js) dan dasar-dasar untuk mengambil simpul Galera atau MySQL dan mengulangnya.
Membuat penasihat baru dengan template Galera terlihat seperti ini:
#include "common/mysql_helper.js"
Di sini Anda dapat melihat bahwa mysql_helper.js disertakan untuk menyediakan dasar untuk menghubungkan dan menanyakan node MySQL.
File ini berisi fungsi yang dapat Anda panggil jika diperlukan seperti misalnya readVariable(
var WARNING_THRESHOLD=0;
…
if(threshold > WARNING_THRESHOLD)
Ambang peringatan saat ini disetel ke 0, artinya jika ambang yang diukur lebih besar dari ambang peringatan, penasihat harus memperingatkan pengguna. Perhatikan bahwa ambang batas variabel belum disetel/digunakan dalam template karena ini adalah langkah awal untuk penasihat Anda sendiri.
var hosts = cluster::Hosts();
var hosts = cluster::mySqlNodes();
var hosts = cluster::galeraNodes();
Pernyataan di atas akan mengambil host di cluster dan Anda dapat menggunakan ini untuk mengulangnya. Perbedaan di antara mereka adalah bahwa pernyataan pertama mencakup semua host non-MySQL (juga host CMON), yang kedua semua host MySQL dan yang terakhir saja tuan rumah Galera. Jadi, jika kluster Galera Anda memiliki budak baca asinkron MySQL yang terpasang, host tersebut tidak akan disertakan.
Selain itu, semua objek ini akan berperilaku sama dan menampilkan kemampuan untuk membaca variabel, status, dan kuerinya.
Tombol penasihat
Sekarang kami telah membuat penasihat baru, ada enam tombol baru yang tersedia untuk penasihat ini:
Simpan akan menyimpan modifikasi terbaru Anda ke penasehat (disimpan dalam database CMON), Pindahkan akan memindahkan penasihat ke jalur baru dan Hapus jelas akan menghapus penasihat.
Yang lebih menarik adalah tombol baris kedua. Penyusunan penasehat akan menyusun kode penasehat. Jika kode dikompilasi dengan baik, Anda akan melihat pesan ini di Pesan dialog di bawah kode penasehat:
Sementara jika kompilasi gagal, kompiler akan memberi Anda petunjuk di mana gagalnya:
Dalam hal ini kompilator menunjukkan kesalahan sintaks ditemukan pada baris 24.
kompilasi dan jalankan tombol tidak hanya akan mengkompilasi skrip tetapi juga menjalankannya dan outputnya akan ditampilkan dalam dialog Pesan, Grafik, atau Mentah. Jika kita mengkompilasi dan menjalankan skrip cache tabel dari auto_tuners, kita akan mendapatkan output seperti ini:
Tombol terakhir adalah jadwal tombol. Ini memungkinkan Anda untuk menjadwalkan (atau membatalkan jadwal) penasihat Anda dan menambahkan tag ke dalamnya. Kami akan membahas ini di akhir posting ini ketika kami telah membuat penasihat kami sendiri dan ingin menjadwalkannya.
Penasihat pertama saya
Sekarang kita telah membahas dasar-dasar ClusterControl Developer Studio, sekarang kita akhirnya dapat mulai membuat penasihat baru. Sebagai contoh kita akan membuat penasehat untuk melihat rasio tabel sementara. Buat penasihat baru sebagai berikut:
Teori di balik penasihat yang akan kita buat sederhana:kita akan membandingkan jumlah tabel sementara yang dibuat pada disk dengan jumlah total tabel sementara yang dibuat:
tmp_disk_table_ratio = Created_tmp_disk_tables / (Created_tmp_tables + Created_tmp_disk_tables) * 100;
Pertama kita perlu mengatur beberapa dasar di kepala skrip, seperti ambang batas dan peringatan dan pesan ok. Semua perubahan dan penambahan diterapkan di bawah ini:
var WARNING_THRESHOLD=20;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive." ;
Kami menetapkan ambang batas di sini hingga 20 persen yang dianggap sudah sangat buruk. Tetapi lebih banyak tentang topik itu setelah kami menyelesaikan penasihat kami.
Selanjutnya kita perlu mendapatkan variabel status ini dari MySQL. Sebelum kita melompat ke kesimpulan dan mengeksekusi beberapa query “SHOW GLOBAL STATUS LIKE 'Created_tmp_%'”, sudah ada fungsi untuk mengambil variabel status dari instance MySQL, seperti yang kami jelaskan di atas di mana fungsi ini berada di common/mysql_helper. js:
statusVar = readStatusVariable(<host>, <statusvariablename>);
Kami dapat menggunakan fungsi ini di penasihat kami untuk mengambil Created_tmp_disk_tables dan Created_tmp_tables.
for (idx = 0; idx < hosts.size(); ++idx)
{
host = hosts[idx];
map = host.toMap();
connected = map["connected"];
var advice = new CmonAdvice();
var tmp_tables = readStatusVariable(host, ‘Created_tmp_tables’);
var tmp_disk_tables = readStatusVariable(host, ‘Created_tmp_disk_tables’);
Dan sekarang kita dapat menghitung rasio tabel disk sementara:
var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;
Dan waspada jika rasio ini lebih besar dari ambang batas yang kita tetapkan di awal:
if(checkPrecond(host))
{
if(tmp_disk_table_ratio > WARNING_THRESHOLD) {
advice.setJustification("Temporary tables written to disk is excessive");
msg = ADVICE_WARNING;
}
else {
advice.setJustification("Temporary tables written to disk not excessive");
msg = ADVICE_OK;
}
}
Penting untuk menetapkan Saran ke variabel msg di sini karena ini akan ditambahkan nanti ke objek saran dengan fungsi setAdvice(). Skrip lengkap untuk kelengkapan:
#include "common/mysql_helper.js"
/**
* Checks the percentage of max ever used connections
*
*/
var WARNING_THRESHOLD=20;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive.";
function main()
{
var hosts = cluster::mySqlNodes();
var advisorMap = {};
for (idx = 0; idx < hosts.size(); ++idx)
{
host = hosts[idx];
map = host.toMap();
connected = map["connected"];
var advice = new CmonAdvice();
var tmp_tables = readStatusVariable(host, 'Created_tmp_tables');
var tmp_disk_tables = readStatusVariable(host, 'Created_tmp_disk_tables');
var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;
if(!connected)
continue;
if(checkPrecond(host))
{
if(tmp_disk_table_ratio > WARNING_THRESHOLD) {
advice.setJustification("Temporary tables written to disk is excessive");
msg = ADVICE_WARNING;
advice.setSeverity(0);
}
else {
advice.setJustification("Temporary tables written to disk not excessive");
msg = ADVICE_OK;
}
}
else
{
msg = "Not enough data to calculate";
advice.setJustification("there is not enough load on the server or the uptime is too little.");
advice.setSeverity(0);
}
advice.setHost(host);
advice.setTitle(TITLE);
advice.setAdvice(msg);
advisorMap[idx]= advice;
}
return advisorMap;
}
Sekarang Anda dapat bermain-main dengan ambang batas 20, coba turunkan ke 1 atau 2 misalnya dan kemudian Anda mungkin dapat melihat bagaimana penasihat ini benar-benar akan memberi Anda nasihat tentang masalah tersebut.
Seperti yang Anda lihat, dengan skrip sederhana Anda dapat memeriksa dua variabel satu sama lain dan melaporkan/menyarankan berdasarkan hasilnya. Tapi apakah itu semua? Masih ada beberapa hal yang dapat kami tingkatkan!
Peningkatan pada penasihat pertama saya
Hal pertama yang dapat kami tingkatkan adalah bahwa penasihat ini tidak masuk akal. Apa yang sebenarnya dicerminkan oleh metrik adalah jumlah total tabel sementara pada disk sejak FLUSH STATUS terakhir atau startup MySQL. Apa yang tidak dikatakan adalah berapa rate itu benar-benar membuat tabel sementara pada disk. Jadi kita bisa mengonversi Created_tmp_disk_tables ke rate menggunakan uptime host:
var tmp_disk_table_rate = tmp_disk_tables / uptime;
Ini akan memberi kita jumlah tabel sementara per detik dan dikombinasikan dengan rasio tmp_disk_table_, ini akan memberi kita pandangan yang lebih akurat tentang berbagai hal. Sekali lagi, setelah kami mencapai ambang batas dua tabel sementara per detik, kami tidak ingin segera mengirimkan peringatan/saran.
Hal lain yang dapat kami tingkatkan adalah tidak menggunakan fungsi readStatusVariable(
Dalam hal ini kita dapat mengoptimalkannya dengan mengambil variabel status di peta menggunakan fungsi host.sqlInfo() dan mengambil semuanya sekaligus sebagai peta. Fungsi ini berisi informasi yang paling penting dari host, tetapi tidak berisi semua. Misalnya, waktu aktif variabel yang kita perlukan untuk tarif tidak tersedia di peta host.sqlInfo() dan harus diambil dengan fungsi readStatusVariable(
Beginilah tampilan penasihat kami sekarang, dengan perubahan/penambahan yang ditandai dengan huruf tebal:
#include "common/mysql_helper.js"
/**
* Checks the percentage of max ever used connections
*
*/
var RATIO_WARNING_THRESHOLD=20;
var RATE_WARNING_THRESHOLD=2;
var TITLE="Temporary tables on disk ratio";
var ADVICE_WARNING="More than 20% of temporary tables are written to disk and current rate is more than 2 temporary tables per second. It is advised to review your queries, for example, via the Query Monitor.";
var ADVICE_OK="Temporary tables on disk are not excessive.";
function main()
{
var hosts = cluster::mySqlNodes();
var advisorMap = {};
for (idx = 0; idx < hosts.size(); ++idx)
{
host = hosts[idx];
map = host.toMap();
connected = map["connected"];
var advice = new CmonAdvice();
var hostStatus = host.sqlInfo();
var tmp_tables = hostStatus['CREATED_TMP_TABLES'];
var tmp_disk_tables = hostStatus['CREATED_TMP_DISK_TABLES'];
var uptime = readStatusVariable(host, 'uptime');
var tmp_disk_table_ratio = tmp_disk_tables / (tmp_tables + tmp_disk_tables) * 100;
var tmp_disk_table_rate = tmp_disk_tables / uptime;
if(!connected)
continue;
if(checkPrecond(host))
{
if(tmp_disk_table_rate > RATE_WARNING_THRESHOLD && tmp_disk_table_ratio > RATIO_WARNING_THRESHOLD) {
advice.setJustification("Temporary tables written to disk is excessive: " + tmp_disk_table_rate + " tables per second and overall ratio of " + tmp_disk_table_ratio);
msg = ADVICE_WARNING;
advice.setSeverity(0);
}
else {
advice.setJustification("Temporary tables written to disk not excessive");
msg = ADVICE_OK;
}
}
else
{
msg = "Not enough data to calculate";
advice.setJustification("there is not enough load on the server or the uptime is too little.");
advice.setSeverity(0);
}
advice.setHost(host);
advice.setTitle(TITLE);
advice.setAdvice(msg);
advisorMap[idx]= advice;
}
return advisorMap;
}
Menjadwalkan penasihat pertama saya
Setelah kami menyimpan penasihat baru ini, mengompilasinya, dan menjalankannya, sekarang kami dapat menjadwalkan penasihat ini. Karena kami tidak memiliki beban kerja yang berlebihan, kami mungkin akan menjalankan penasihat ini sekali sehari.
Mode penjadwalan dasar mirip dengan Cron yang memiliki preset setiap menit, 5 menit, jam, hari, bulan dan inilah yang kami butuhkan dan sangat mudah untuk mengelola penjadwalan. Mengubah ini menjadi lanjutan akan membuka kunci bidang masukan berwarna abu-abu lainnya. Bidang masukan ini bekerja sama persis dengan crontab, sehingga Anda bahkan dapat menjadwalkan untuk hari tertentu, hari dalam sebulan, atau bahkan mengaturnya pada hari kerja.
Mengikuti blog ini, kami akan membuat pemeriksa untuk SELinux atau pemeriksaan keamanan untuk Spectre dan Meltdown jika node terpengaruh. Tetap disini!