MariaDB
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> MariaDB

Kiểm tra đối tượng lược đồ cơ sở dữ liệu tự động

Việc theo dõi các thay đổi lược đồ cơ sở dữ liệu của bạn trong MySQL / MariaDB cung cấp một trợ giúp rất lớn vì nó giúp tiết kiệm thời gian phân tích sự phát triển cơ sở dữ liệu của bạn, thay đổi định nghĩa bảng, kích thước dữ liệu, kích thước chỉ mục hoặc kích thước hàng. Đối với MySQL / MariaDB, việc chạy một truy vấn tham chiếu information_schema cùng với performance_schema cung cấp cho bạn kết quả chung để phân tích thêm. Lược đồ hệ thống cung cấp cho bạn các chế độ xem đóng vai trò là số liệu chung rất hữu ích để theo dõi các thay đổi hoặc hoạt động của cơ sở dữ liệu.

Nếu bạn có nhiều máy chủ cơ sở dữ liệu, sẽ thật tẻ nhạt khi chạy một truy vấn mọi lúc. Bạn cũng phải phân tích kết quả đó thành một kết quả dễ đọc hơn và dễ hiểu hơn.

Trong blog này, chúng tôi sẽ tạo ra một hệ thống tự động hóa hữu ích làm công cụ tiện ích của bạn để cơ sở dữ liệu hiện có của bạn được theo dõi và thu thập các số liệu liên quan đến các thay đổi cơ sở dữ liệu hoặc các hoạt động thay đổi lược đồ.

Tạo Tự động hóa để Kiểm tra Đối tượng Lược đồ Cơ sở dữ liệu

Trong bài tập này, chúng ta sẽ theo dõi các số liệu sau:

  • Không có bảng khóa chính nào

  • Các chỉ mục trùng lặp

  • Tạo biểu đồ cho tổng số hàng trong lược đồ cơ sở dữ liệu của chúng tôi

  • Tạo biểu đồ cho tổng kích thước của các lược đồ cơ sở dữ liệu của chúng tôi

Bài tập này sẽ cung cấp cho bạn thông tin cơ bản và có thể được sửa đổi để thu thập các số liệu nâng cao hơn từ cơ sở dữ liệu MySQL / MariaDB của bạn.

Sử dụng Con rối cho IaC và Tự động hóa của chúng tôi

Bài tập này sẽ sử dụng Puppet để cung cấp tính năng tự động hóa và tạo ra kết quả mong đợi dựa trên các chỉ số mà chúng tôi muốn theo dõi. Chúng tôi sẽ không đề cập đến việc cài đặt và thiết lập Puppet, bao gồm cả máy chủ và ứng dụng khách, vì vậy tôi hy vọng bạn biết cách sử dụng Puppet. Bạn có thể muốn truy cập blog cũ của chúng tôi Triển khai tự động MySQL Galera Cluster lên Amazon AWS với Puppet, bao gồm quá trình thiết lập và cài đặt Puppet.

Chúng tôi sẽ sử dụng phiên bản Puppet mới nhất trong bài tập này nhưng vì mã của chúng tôi bao gồm cú pháp cơ bản, nó sẽ chạy cho các phiên bản Puppet cũ hơn.

Máy chủ Cơ sở dữ liệu MySQL Ưu tiên

Trong bài tập này, chúng tôi sẽ sử dụng Máy chủ Percona 8.0.22-13 vì tôi thích Máy chủ Percona chủ yếu để thử nghiệm và một số triển khai nhỏ cho mục đích kinh doanh hoặc cá nhân.

Công cụ vẽ đồ thị

Có rất nhiều tùy chọn để sử dụng, đặc biệt là sử dụng môi trường Linux. Trong blog này, tôi sẽ sử dụng công cụ dễ nhất mà tôi tìm thấy và một công cụ mã nguồn mở https://quickchart.io/.

Hãy chơi với con rối

Giả định tôi đưa ra ở đây là bạn đã thiết lập máy chủ chính với máy khách đã đăng ký sẵn sàng giao tiếp với máy chủ chính để nhận các triển khai tự động.

Trước khi chúng tôi tiếp tục, đây là thông tin máy chủ của tôi:

Máy chủ chính:192.168.40.200

Máy khách / Máy chủ Tác nhân:192.168.40.160

Trong blog này, máy chủ khách / máy chủ của chúng tôi là nơi máy chủ cơ sở dữ liệu của chúng tôi đang chạy. Trong trường hợp thực tế, nó không cần phải đặc biệt để giám sát. Miễn là nó có thể giao tiếp với nút đích một cách an toàn, thì đó cũng là một thiết lập hoàn hảo.

Thiết lập Mô-đun và Mã

  1. Đi tới máy chủ chính và trong đường dẫn / etc / rốilabs / mã / môi trường / sản xuất / mô-đun, hãy tạo các thư mục cần thiết cho bài tập này:

mkdir schema_change_mon/{files,manifests}

  1. Tạo tệp chúng tôi cần

touch schema_change_mon/files/graphing_gen.sh
touch schema_change_mon/manifests/init.pp
  1. Điền vào tập lệnh init.pp với nội dung sau:

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. Điền vào tệp graphing_gen.sh. Tập lệnh này sẽ chạy trên nút đích và tạo đồ thị cho tổng số hàng trong cơ sở dữ liệu của chúng tôi và cũng như tổng kích thước cơ sở dữ liệu của chúng tôi. Đối với tập lệnh này, hãy làm cho nó đơn giản hơn và chỉ cho phép loại cơ sở dữ liệu MyISAM hoặc 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. Cuối cùng, đi tới thư mục đường dẫn mô-đun hoặc / etc / rốilabs / code / môi trường / production trong thiết lập của tôi. Hãy tạo tệp kê khai / schema_change_mon.pp.

touch manifests/schema_change_mon.pp
  1. Sau đó điền các nội dung sau vào tệp kê khai / schema_change_mon.pp,

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

Nếu hoàn tất, bạn sẽ có cấu trúc cây sau giống như cấu trúc của tôi,

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

Mô-đun của chúng ta làm gì?

Mô-đun của chúng tôi được gọi là schema_change_mon thu thập những điều sau đây,

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

...

Thực hiện lệnh mysql và chạy truy vấn để truy xuất các bảng không có khóa chính. Sau đó,

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

thu thập các chỉ mục trùng lặp tồn tại trong các bảng cơ sở dữ liệu.

Tiếp theo, các đường tạo biểu đồ dựa trên các chỉ số được thu thập. Đây là những dòng sau,

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

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

Khi truy vấn chạy thành công, nó sẽ tạo ra biểu đồ, biểu đồ này phụ thuộc vào API được cung cấp bởi https://quickchart.io/.

Đây là kết quả của biểu đồ sau:

Trong khi nhật ký tệp chỉ chứa các chuỗi với tên bảng, tên chỉ mục của nó. Xem kết quả bên dưới,

[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

Tại sao không sử dụng ClusterControl?

Vì bài tập của chúng tôi trình bày về tự động hóa và nhận thống kê lược đồ cơ sở dữ liệu chẳng hạn như các thay đổi hoặc hoạt động, ClusterControl cũng cung cấp điều này. Ngoài ra còn có các tính năng khác và bạn không cần phải phát minh lại bánh xe. ClusterControl có thể cung cấp nhật ký giao dịch, chẳng hạn như deadlocks như được hiển thị ở trên hoặc các truy vấn chạy dài như được hiển thị bên dưới:


ClusterControl cũng hiển thị mức tăng trưởng DB như được hiển thị bên dưới,

ClusterControl cũng cung cấp thông tin bổ sung như số hàng, kích thước đĩa, kích thước chỉ mục và tổng kích thước.

Trình phân tích giản đồ trong tab Hiệu suất -> Trình phân tích lược đồ rất hữu ích. Nó cung cấp các bảng không có khóa chính, bảng MyISAM và các chỉ mục trùng lặp,

Nó cũng cung cấp cảnh báo trong trường hợp phát hiện các chỉ mục hoặc bảng trùng lặp không có bảng chính các phím chẳng hạn như bên dưới,

Bạn có thể xem thêm thông tin về ClusterControl và các tính năng khác của nó trên trang Sản phẩm của chúng tôi.

Kết luận

Cung cấp tính năng tự động hóa để theo dõi các thay đổi cơ sở dữ liệu của bạn hoặc bất kỳ thống kê lược đồ nào như ghi, chỉ mục trùng lặp, cập nhật hoạt động như thay đổi DDL và nhiều hoạt động cơ sở dữ liệu rất có lợi cho DBA. Nó giúp nhanh chóng xác định các liên kết yếu và các truy vấn có vấn đề sẽ cung cấp cho bạn cái nhìn tổng quan về nguyên nhân có thể gây ra các truy vấn xấu sẽ khóa cơ sở dữ liệu của bạn hoặc làm hỏng cơ sở dữ liệu của bạn.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách hoạt động của LEFT () trong MariaDB

  2. Nhiều nô lệ sao chép bị trì hoãn để khôi phục thảm họa với RTO thấp

  3. Giám sát MySQL chủ động (Developer Studio / Góc cố vấn)

  4. MariaDB JSON_MERGE_PRESERVE () Giải thích

  5. Cách DATE_ADD () hoạt động trong MariaDB