MariaDB
 sql >> Teknologi Basis Data >  >> RDS >> MariaDB

Otomatisasi Pemeriksaan Objek Skema Basis Data

Memantau perubahan skema database Anda di MySQL/MariaDB memberikan bantuan besar karena menghemat waktu menganalisis pertumbuhan database Anda, perubahan definisi tabel, ukuran data, ukuran indeks, atau ukuran baris. Untuk MySQL/MariaDB, menjalankan kueri yang mereferensikan information_schema bersama dengan performance_schema memberi Anda hasil kolektif untuk analisis lebih lanjut. Skema sistem memberi Anda tampilan yang berfungsi sebagai metrik kolektif yang sangat berguna untuk melacak perubahan atau aktivitas basis data.

Jika Anda memiliki banyak server database, menjalankan kueri sepanjang waktu akan membosankan. Anda juga harus mencerna hasil tersebut menjadi lebih mudah dibaca dan dipahami.

Di blog ini, kami akan membuat otomatisasi yang akan berguna sebagai alat utilitas Anda agar database yang ada dapat dipantau dan mengumpulkan metrik terkait perubahan database atau operasi perubahan skema.

 Membuat Otomatisasi untuk Pemeriksaan Objek Skema Basis Data

Dalam latihan ini, kami akan memantau metrik berikut:

  • Tidak ada tabel kunci utama

  • Indeks duplikat

  • Buat grafik untuk jumlah total baris dalam skema database kami

  • Buat grafik untuk ukuran total skema database kami

Latihan ini akan memberi Anda petunjuk dan dapat dimodifikasi untuk mengumpulkan metrik yang lebih canggih dari database MySQL/MariaDB Anda.

Menggunakan Wayang untuk IaC dan Otomatisasi

Latihan ini akan menggunakan Wayang untuk menyediakan otomatisasi dan menghasilkan hasil yang diharapkan berdasarkan metrik yang ingin kita pantau. Kami tidak akan membahas instalasi dan pengaturan Wayang, termasuk server dan klien, jadi saya harap Anda mengetahui cara menggunakan Wayang. Anda mungkin ingin mengunjungi blog lama kami, Automated Deployment of MySQL Galera Cluster to Amazon AWS with Puppet, yang mencakup penyiapan dan pemasangan Wayang.

Kami akan menggunakan versi terbaru dari Wayang dalam latihan ini, tetapi karena kode kami terdiri dari sintaks dasar, itu akan berjalan untuk versi Wayang yang lebih lama.

Server Database MySQL Pilihan

Dalam latihan ini, kita akan menggunakan Server Percona 8.0.22-13 karena saya lebih suka Server Percona sebagian besar untuk pengujian dan beberapa penerapan kecil baik untuk penggunaan bisnis atau pribadi.

Alat Grafik 

Ada banyak pilihan untuk digunakan terutama menggunakan lingkungan Linux. Di blog ini, saya akan menggunakan yang paling mudah yang saya temukan dan alat opensource https://quickchart.io/.

Ayo Main Wayang

Asumsi yang saya buat di sini adalah Anda telah menyiapkan server master dengan klien terdaftar yang siap berkomunikasi dengan server master untuk menerima penerapan otomatis.

Sebelum melanjutkan, berikut informasi server saya:

Server utama:192.168.40.200

Server Klien/Agen:192.168.40.160

Di blog ini, server klien/agen kami adalah tempat server basis data kami berjalan. Dalam skenario dunia nyata, tidak harus khusus untuk pemantauan. Selama itu dapat berkomunikasi ke node target dengan aman, maka itu adalah pengaturan yang sempurna juga.

Siapkan Modul dan Kode

  1. Buka server master dan di jalur /etc/puppetlabs/code/environments/production/module, mari buat direktori yang diperlukan untuk latihan ini:

mkdir schema_change_mon/{files,manifests}

  1. Buat file yang kita butuhkan

touch schema_change_mon/files/graphing_gen.sh
touch schema_change_mon/manifests/init.pp
  1. Isi skrip init.pp dengan konten berikut:

class schema_change_mon (
  $db_provider = "mysql",
  $db_user = "root",
  $db_pwd = "[email protected]",
  $db_schema = []
) {

$dbs = ['pauldb', 'sbtest']
service { $db_provider :
ensure       => running,
enable       => true,
hasrestart   => true,
hasstatus    => true
}
exec { "mysql-without-primary-key" :
require     => Service['mysql'],
command => "/usr/bin/sudo MYSQL_PWD=\"${db_pwd}\" /usr/bin/mysql -u${db_user} -Nse \"select concat(tables.table_schema,'.',tables.table_name,', ', tables.engine) from information_schema.tables left join ( select table_schema , table_name from information_schema.statistics group by table_schema , table_name , index_name having  sum( case  when non_unique = 0  and nullable != 'YES' then 1  else 0  end ) = count(*) ) puks on tables.table_schema = puks.table_schema and tables.table_name = puks.table_name where puks.table_name is null and tables.table_type = 'BASE TABLE' and tables.table_schema not in ('performance_schema',  'information_schema', 'mysql');\" >> /opt/schema_change_mon/assets/no-pk.log"
}
$dbs.each |String $db| {
exec { "mysql-duplicate-index-$db" :
require     => Service['mysql'],
command => "/usr/bin/sudo MYSQL_PWD=\"${db_pwd}\" /usr/bin/mysql -u${db_user} -Nse \"SELECT concat(t.table_schema,'.', t.table_name, '.', t.index_name, '(', t.idx_cols,')') FROM ( SELECT table_schema, table_name, index_name, Group_concat(column_name) idx_cols FROM ( SELECT table_schema, table_name, index_name, column_name FROM statistics WHERE table_schema='${db}' ORDER BY index_name, seq_in_index) t GROUP BY table_name, index_name) t JOIN ( SELECT table_schema, table_name, index_name, Group_concat(column_name) idx_cols FROM ( SELECT table_schema, table_name, index_name, column_name FROM statistics WHERE table_schema='pauldb' ORDER BY index_name, seq_in_index) t GROUP BY table_name, index_name) u where t.table_schema = u.table_schema AND t.table_name = u.table_name AND t.index_name<>u.index_name AND locate(t.idx_cols,u.idx_cols);\" information_schema >> /opt/schema_change_mon/assets/dupe-indexes.log"
}
}

$genscript = "/tmp/graphing_gen.sh"
file { "${genscript}" :
ensure => present,
owner  => root,
group  => root,
mode   => '0655',
source => 'puppet:///modules/schema_change_mon/graphing_gen.sh'
}
exec { "generate-graph-total-rows" :
require     => [Service['mysql'],File["${genscript}"]],
path =>  [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ],
provider => "shell",
logoutput => true,
command => "/tmp/graphing_gen.sh total_rows"
}
exec { "generate-graph-total-len" :
require  => [Service['mysql'],File["${genscript}"]],
path =>  [ '/bin/', '/sbin/' , '/usr/bin/', '/usr/sbin/' ],
provider => "shell",
logoutput => true,
command => "/tmp/graphing_gen.sh total_len"
}
}

  1. Isi file graphing_gen.sh. Script ini akan berjalan pada node target dan menghasilkan grafik untuk jumlah baris dalam database kami dan juga ukuran total database kami. Untuk skrip ini, buat lebih sederhana , dan izinkan hanya tipe database MyISAM atau InnoDB.

#!/bin/bash
graph_ident="${1:-total_rows}"
unset json myisam innodb nmyisam ninnodb; json='' myisam='' innodb='' nmyisam='' ninnodb='' url=''; json=$(MYSQL_PWD="[email protected]" mysql -uroot -Nse "select json_object('dbschema', concat(table_schema,' - ', engine), 'total_rows', sum(table_rows), 'total_len', sum(data_length+data_length), 'fragment', sum(data_free)) from information_schema.tables where table_schema not in ('performance_schema', 'sys', 'mysql', 'information_schema') and engine in ('myisam','innodb') group by table_schema, engine;" | jq . |  sed ':a;N;$!ba;s/\n//g' | sed 's|}{|},{|g' | sed 's/^/[/g'| sed 's/$/]/g' | jq '.' ); innodb=""; myisam=""; for r in $(echo $json | jq 'keys | .[]'); do if [[ $(echo $json| jq .[$r].'dbschema') == *"MyISAM"* ]]; then nmyisam=$(echo $nmyisam || echo '')$(echo $json| jq .[$r]."${graph_ident}")','; myisam=$(echo $myisam || echo '')$(echo $json| jq .[$r].'dbschema')','; else ninnodb=$(echo $ninnodb || echo '')$(echo $json| jq .[$r]."${graph_ident}")','; innodb=$(echo $innodb || echo '')$(echo $json| jq .[$r].'dbschema')','; fi; done; myisam=$(echo $myisam|sed 's/,$//g'); nmyisam=$(echo $nmyisam|sed 's/,$//g'); innodb=$(echo $innodb|sed 's/,$//g');ninnodb=$(echo $ninnodb|sed 's/,$//g'); echo $myisam "|" $nmyisam; echo $innodb "|" $ninnodb; url=$(echo "{type:'bar',data:{labels:['MyISAM','InnoDB'],datasets:[{label:[$myisam],data:[$nmyisam]},{label:[$innodb],data:[$ninnodb]}]},options:{title:{display:true,text:'Database Schema Total Rows Graph',fontSize:20,}}}"); curl -L -o /vagrant/schema_change_mon/assets/db-${graph_ident}.png -g https://quickchart.io/chart?c=$(python -c "import urllib,os,sys; print urllib.quote(os.environ['url'])")

  1. Terakhir, buka direktori jalur modul atau /etc/puppetlabs/code/environments /produksi di pengaturan saya. Mari kita buat filenya manifests/schema_change_mon.pp.

touch manifests/schema_change_mon.pp
  1. Kemudian isi file manifests/schema_change_mon.pp dengan isi sebagai berikut,

node 'pupnode16.puppet.local' { # Applies only to mentioned node. If nothing mentioned, applies to all.
        class { 'schema_change_mon':
        }
}

Jika sudah selesai, Anda akan memiliki struktur pohon berikut seperti milik saya,

[email protected]:/etc/puppetlabs/code/environments/production/modules# tree schema_change_mon
schema_change_mon
├── files
│   └── graphing_gen.sh
└── manifests
    └── init.pp

Apa yang dilakukan modul kita?

Modul kami yang disebut schema_change_mon mengumpulkan yang berikut,

 exec { "mysql-without-primary-key" :

Yang menjalankan perintah mysql dan menjalankan kueri untuk mengambil tabel tanpa kunci utama. Kemudian,

$dbs.each |String $db| {
exec { "mysql-duplicate-index-$db" :

yang mengumpulkan indeks duplikat yang ada di tabel database.

Selanjutnya, garis menghasilkan grafik berdasarkan metrik yang dikumpulkan. Ini adalah baris berikut,

exec { "generate-graph-total-rows" :
...

exec { "generate-graph-total-len" :
…

Setelah kueri berhasil dijalankan, kueri akan menghasilkan grafik, yang bergantung pada API yang disediakan oleh https://quickchart.io/.

Berikut adalah hasil grafiknya:

Sedangkan file log hanya berisi string dengan nama tabel, nama indeks. Lihat hasilnya di bawah ini,

[email protected]:~# tail -n+1 /opt/schema_change_mon/assets/*.log
==> /opt/schema_change_mon/assets/dupe-indexes.log <==
pauldb.c.my_index(n,i)
pauldb.c.my_index2(n,i)
pauldb.d.a_b(a,b)
pauldb.d.a_b2(a,b)
pauldb.d.a_b3(a)
pauldb.d.a_b3(a)
pauldb.t3.b(b)
pauldb.c.my_index(n,i)
pauldb.c.my_index2(n,i)
pauldb.d.a_b(a,b)
pauldb.d.a_b2(a,b)
pauldb.d.a_b3(a)
pauldb.d.a_b3(a)
pauldb.t3.b(b)

==> /opt/schema_change_mon/assets/no-pk.log <==
pauldb.b, MyISAM
pauldb.c, InnoDB
pauldb.t2, InnoDB
pauldb.d, InnoDB
pauldb.b, MyISAM
pauldb.c, InnoDB
pauldb.t2, InnoDB
pauldb.d, InnoDB

Mengapa Tidak Menggunakan ClusterControl?

Saat latihan kami menampilkan otomatisasi dan mendapatkan statistik skema database seperti perubahan atau operasi, ClusterControl juga menyediakan ini. Ada juga fitur lain selain ini dan Anda tidak perlu menemukan kembali kemudi. ClusterControl dapat menyediakan log transaksi seperti kebuntuan seperti yang ditunjukkan di atas, atau kueri yang berjalan lama seperti yang ditunjukkan di bawah ini:


 

ClusterControl juga menunjukkan pertumbuhan DB seperti yang ditunjukkan di bawah ini,

ClusterControl juga memberikan informasi tambahan seperti jumlah baris, ukuran disk, ukuran indeks, dan ukuran total.

Penganalisis skema di bawah tab Kinerja -> Penganalisis Skema sangat membantu. Ini menyediakan tabel tanpa kunci utama, tabel MyISAM, dan indeks duplikat,

Ini juga menyediakan alarm jika ada indeks atau tabel duplikat yang terdeteksi tanpa primer kunci seperti di bawah ini,

Anda dapat melihat informasi lebih lanjut tentang ClusterControl dan fitur lainnya di halaman Produk kami.

Kesimpulan

Menyediakan otomatisasi untuk memantau perubahan basis data Anda atau statistik skema apa pun seperti penulisan, indeks duplikat, pembaruan operasi seperti perubahan DDL, dan banyak aktivitas basis data sangat bermanfaat bagi DBA. Ini membantu dengan cepat mengidentifikasi tautan lemah dan kueri bermasalah yang akan memberi Anda gambaran umum tentang kemungkinan penyebab kueri buruk yang akan mengunci basis data Anda atau membuat basis data Anda basi.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Kiat untuk Menyimpan Cadangan MariaDB Anda di Cloud

  2. MariaDB FOUND_ROWS() Dijelaskan

  3. 2018 Dalam Ulasan:7 Tonggak MariaDB yang Mungkin Anda Lewatkan

  4. Bagaimana RIGHT() Bekerja di MariaDB

  5. Bagaimana TIMESTAMP() Bekerja di MariaDB