Nhiều quản trị viên hệ thống thường bỏ qua tầm quan trọng của việc điều chỉnh cấu hình cơ sở dữ liệu liên tục. Các tùy chọn cấu hình thường được định cấu hình hoặc điều chỉnh một lần, trong giai đoạn cài đặt và bị bỏ qua cho đến khi một số sự kiện không mong muốn xảy ra với dịch vụ cơ sở dữ liệu. Chỉ khi đó, người ta mới chú ý đến việc truy cập lại các tùy chọn cấu hình và điều chỉnh các giới hạn, ngưỡng, bộ đệm, bộ nhớ đệm, v.v. với mong muốn khôi phục lại dịch vụ cơ sở dữ liệu.
Trọng tâm của chúng tôi trong bài đăng trên blog này là tự động hóa quá trình xác thực và kiểm tra cấu hình cơ sở dữ liệu. Đây là một quá trình quan trọng vì các tùy chọn cấu hình luôn thay đổi trên các phiên bản chính. Tệp cấu hình không thay đổi có thể có các tùy chọn không dùng nữa không còn được hỗ trợ bởi phiên bản máy chủ mới hơn, điều này thường gây ra một số sự cố lớn đối với máy chủ được nâng cấp.
Công cụ Quản lý Cấu hình
Puppet, Ansible, Chef và SaltStack được DevOps sử dụng phổ biến nhất để quản lý cấu hình và tự động hóa. Quản lý cấu hình cho phép người dùng lập tài liệu về môi trường, cải thiện hiệu quả, khả năng quản lý và khả năng tái tạo, đồng thời là một phần không thể thiếu của tích hợp và triển khai liên tục. Hầu hết các công cụ quản lý cấu hình đều cung cấp danh mục các mô-đun và kho lưu trữ để những người khác đóng góp, đơn giản hóa lộ trình học tập cho người dùng cộng đồng để thích ứng với công nghệ.
Mặc dù các công cụ quản lý cấu hình chủ yếu được sử dụng để tự động hóa việc triển khai và cài đặt, chúng tôi cũng có thể thực hiện kiểm tra và thực thi cấu hình theo phương pháp đẩy ra tập trung. Mỗi công cụ này có một cách riêng để tạo tệp cấu hình. Đối với Puppet, tệp mẫu thường có đuôi là ".erb" và bên trong nó, chúng ta có thể xác định các tùy chọn cấu hình cùng với các giá trị được tạo sẵn.
Ví dụ sau hiển thị tệp mẫu cho cấu hình MySQL:
[mysqld]
thread_concurrency = <%= processorcount.to_i * 2 %>
# Replication
log-bin = /var/lib/mysql/mysql-bin.log
log-bin-index = /var/lib/mysql/mysql-bin.index
binlog_format = mixed
server-id = <%= @mysql_server_id or 1 %>
# InnoDB
innodb_buffer_pool_size = <%= (memorysizeinbytes.to_i / 2 / 1024 / 1024).to_i -%>M
innodb_log_file_size = <%= ((memorysizeinbytes.to_i / 2 / 1024 / 1024) * 0.25).to_i -%>M
Như hình trên, giá trị cấu hình có thể là một giá trị cố định hoặc được tính toán động. Do đó, kết quả cuối cùng có thể khác tùy theo đặc điểm kỹ thuật phần cứng của máy chủ đích với các biến được xác định trước khác. Trong tệp định nghĩa Con rối, chúng ta có thể đẩy mẫu cấu hình của mình như sau:
# Apply our custom template
file { '/etc/mysql/conf.d/my-custom-config.cnf':
ensure => file,
content => template('mysql/my-custom-config.cnf.erb')
}
Ngoài tạo khuôn mẫu, chúng ta cũng có thể đẩy các giá trị cấu hình trực tiếp từ tệp định nghĩa. Sau đây là ví dụ về định nghĩa con rối cho cấu hình MariaDB 10.5 sử dụng mô-đun Puppet MySQL:
# MariaDB configuration
class {'::mysql::server':
package_name => 'mariadb-server',
service_name => 'mariadb',
root_password => 't5[sb^D[+rt8bBYu',
manage_config_file => true,
override_options => {
mysqld => {
'bind_address' => '127.0.0.1',
'max_connections' => '500',
'log_error' => '/var/log/mysql/mariadb.log',
'pid_file' => '/var/run/mysqld/mysqld.pid',
},
mysqld_safe => {
'log_error' => '/var/log/mysql/mariadb.log',
},
}
}
Ví dụ trên cho thấy rằng chúng tôi đã sử dụng management_config_file => true với override_options để cấu trúc các dòng cấu hình của chúng tôi mà sau này sẽ bị Puppet đẩy ra. Bất kỳ sửa đổi nào đối với tệp kê khai sẽ chỉ phản ánh nội dung của tệp cấu hình MySQL đích. Mô-đun này sẽ không tải cấu hình vào thời gian chạy hoặc khởi động lại dịch vụ MySQL sau khi đẩy các thay đổi vào tệp cấu hình. SysAdmin có trách nhiệm khởi động lại dịch vụ để kích hoạt các thay đổi.
Đối với Con rối và Đầu bếp, hãy kiểm tra đầu ra của nhật ký tác nhân để xem liệu các tùy chọn cấu hình có được sửa hay không. Đối với Ansible, chỉ cần nhìn vào đầu ra gỡ lỗi để xem liệu lời chúc mừng có được cập nhật thành công hay không. Sử dụng các công cụ quản lý cấu hình có thể giúp bạn tự động kiểm tra cấu hình và thực thi phương pháp cấu hình tập trung.
MySQL Shell
Kiểm tra độ tỉnh táo là quan trọng trước khi thực hiện bất kỳ nâng cấp nào. MySQL Shell có một tính năng rất thú vị nhằm chạy một loạt các bài kiểm tra để xác minh xem cài đặt hiện có của bạn có an toàn hay không để nâng cấp lên MySQL 8.0, được gọi là Tiện ích Trình kiểm tra Nâng cấp. Bạn có thể tiết kiệm một lượng lớn thời gian khi chuẩn bị nâng cấp. Một bản nâng cấp lớn, đặc biệt là MySQL 8.0, giới thiệu và không chấp nhận nhiều tùy chọn cấu hình và do đó có nguy cơ lớn về sự không tương thích sau khi nâng cấp.
Công cụ này được thiết kế đặc biệt cho MySQL (bao gồm Máy chủ Percona), đặc biệt khi bạn muốn thực hiện nâng cấp lớn từ MySQL 5.7 lên MySQL 8.0. Để gọi tiện ích này, hãy kết nối với MySQL Shell và với tư cách là người dùng root, hãy chỉ định thông tin đăng nhập, phiên bản đích và tệp cấu hình:
$ mysqlsh
mysql> util.checkForServerUpgrade('[email protected]:3306', {"password":"p4ssw0rd", "targetVersion":"8.0.11", "configPath":"/etc/my.cnf"})
Ở cuối báo cáo, bạn sẽ nhận được bản tóm tắt chính:
Errors: 7
Warnings: 36
Notices: 0
7 errors were found. Please correct these issues before upgrading to avoid compatibility issues.
Trước tiên, hãy tập trung vào việc sửa tất cả các lỗi, vì điều này sẽ gây ra các vấn đề lớn sau khi nâng cấp nếu không có hành động nào được thực hiện. Hãy xem lại báo cáo đã tạo và tìm tất cả các vấn đề với từ ngữ nội dòng "Lỗi:", ví dụ:
15) Removed system variables
Error: Following system variables that were detected as being used will be
removed. Please update your system to not rely on them before the upgrade.
More information: https://dev.mysql.com/doc/refman/8.0/en/added-deprecated-removed.html#optvars-removed
log_builtin_as_identified_by_password - is set and will be removed
show_compatibility_56 - is set and will be removed
Sau khi tất cả các lỗi đã được khắc phục, hãy cố gắng giảm cảnh báo tùy theo mức có thể. Hầu hết các cảnh báo sẽ không ảnh hưởng đến độ tin cậy của máy chủ MySQL, nhưng có thể làm giảm hiệu suất hoặc hành vi thay đổi so với những gì chúng đã từng làm. Ví dụ:hãy xem các cảnh báo sau:
13) System variables with new default values
Warning: Following system variables that are not defined in your
configuration file will have new default values. Please review if you rely on
their current values and if so define them before performing upgrade.
More information:
https://mysqlserverteam.com/new-defaults-in-mysql-8-0/
back_log - default value will change
character_set_server - default value will change from latin1 to utf8mb4
collation_server - default value will change from latin1_swedish_ci to
utf8mb4_0900_ai_ci
event_scheduler - default value will change from OFF to ON
explicit_defaults_for_timestamp - default value will change from OFF to ON
innodb_autoinc_lock_mode - default value will change from 1 (consecutive) to
2 (interleaved)
innodb_flush_method - default value will change from NULL to fsync (Unix),
unbuffered (Windows)
innodb_flush_neighbors - default value will change from 1 (enable) to 0
(disable)
innodb_max_dirty_pages_pct - default value will change from 75 (%) 90 (%)
innodb_max_dirty_pages_pct_lwm - default value will change from_0 (%) to 10
(%)
innodb_undo_log_truncate - default value will change from OFF to ON
innodb_undo_tablespaces - default value will change from 0 to 2
log_error_verbosity - default value will change from 3 (Notes) to 2 (Warning)
max_allowed_packet - default value will change from 4194304 (4MB) to 67108864
(64MB)
max_error_count - default value will change from 64 to 1024
optimizer_trace_max_mem_size - default value will change from 16KB to 1MB
performance_schema_consumer_events_transactions_current - default value will
change from OFF to ON
performance_schema_consumer_events_transactions_history - default value will
change from OFF to ON
slave_rows_search_algorithms - default value will change from 'INDEX_SCAN,
TABLE_SCAN' to 'INDEX_SCAN, HASH_SCAN'
table_open_cache - default value will change from 2000 to 4000
transaction_write_set_extraction - default value will change from OFF to
XXHASH64
Upgrade Checker Utility cung cấp một cái nhìn tổng quan quan trọng về những gì sẽ xảy ra và ngăn chúng ta khỏi sự ngạc nhiên lớn sau khi nâng cấp.
Cố vấn ClusterControl
ClusterControl có một số chương trình nhỏ bên trong được gọi là Advisors, nơi bạn viết một chương trình nhỏ sống và chạy trong cấu trúc của các đối tượng ClusterControl. Bạn có thể coi nó như một hàm đã lên lịch thực thi một tập lệnh được tạo trong Developer Studio và tạo ra một kết quả có chứa trạng thái, lời khuyên và lời biện minh. Điều này cho phép người dùng dễ dàng mở rộng chức năng của ClusterControl bằng cách tạo các cố vấn tùy chỉnh có thể chạy theo yêu cầu hoặc theo lịch trình.
Ảnh chụp màn hình sau đây cho thấy một ví dụ về InnoDB Advisors được gọi là kiểm tra innodb_log_file_size, sau khi được kích hoạt và lên lịch bên trong ClusterControl:
Bạn có thể tìm thấy kết quả trên trong ClusterControl -> Performance -> Advisors. Đối với mọi Cố vấn, nó hiển thị trạng thái của cố vấn, cá thể cơ sở dữ liệu, lời biện minh và lời khuyên. Ngoài ra còn có thông tin về lịch trình và thời gian thực hiện cuối cùng. Cố vấn cũng có thể được thực thi theo yêu cầu bằng cách nhấp vào nút "Biên dịch và Chạy" trong Developer Studio.
Các cố vấn ở trên có chứa đoạn mã sau, được viết bằng ClusterControl Domain-Specific Language (DSL), khá giống với JavaScript:
#include "common/mysql_helper.js"
#include "cmon/graph.h"
var DESCRIPTION="This advisor calculates the InnoDB log growth per hour and"
" compares it with the innodb_log_file_size configured on the host and"
" notifies you if the InnoDB log growth is higher than what is configured, which is important to avoid IO spikes during flushing.";
var TITLE="Innodb_log_file_size check";
var MINUTES = 20;
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();
print(" ");
print(host);
print("==========================");
if (!connected)
{
print("Not connected");
continue;
}
if (checkPrecond(host))
{
var configured_logfile_sz = host.sqlSystemVariable("innodb_log_file_size");
var configured_logfile_grps = host.sqlSystemVariable("innodb_log_files_in_group");
if (configured_logfile_sz.isError() || configured_logfile_grps.isError())
{
justification = "";
msg = "Not enough data to calculate";
advice.setTitle(TITLE);
advice.setJustification("");
advice.setAdvice(msg);
advice.setHost(host);
advice.setSeverity(Ok);
advisorMap[idx]= advice;
continue;
}
var endTime = CmonDateTime::currentDateTime();
var startTime = endTime - MINUTES * 60 /*seconds*/;
var stats = host.sqlStats(startTime, endTime);
var array = stats.toArray("created,interval,INNODB_LSN_CURRENT");
if(array[2,0] === #N/A || array[2,0] == "")
{
/* Not all vendors have INNODB_LSN_CURRENT*/
advice.setTitle(TITLE);
advice.setJustification("INNODB_LSN_CURRENT does not exists in"
" this MySQL release.");
advice.setAdvice("Nothing to do.");
advice.setHost(host);
advice.setSeverity(Ok);
advisorMap[idx]= advice;
continue;
}
var firstLSN = array[2,0].toULongLong();
var latestLSN = array[2,array.columns()-1].toULongLong();
var intervalSecs = endTime.toULongLong() - startTime.toULongLong();
var logGrowthPerHourMB = ceiling((latestLSN - firstLSN) * 3600 / 1024/1024 / intervalSecs / configured_logfile_grps);
var logConfiguredMB = configured_logfile_sz/1024/1024;
if (logGrowthPerHourMB > logConfiguredMB)
{
justification = "Innodb is producing " + logGrowthPerHourMB + "MB/hour, and it greater than"
" the configured innodb log file size " + logConfiguredMB + "MB."
" You should set innodb_log_file_size to a value greater than " +
logGrowthPerHourMB + "MB. To change"
" it you must stop the MySQL Server and remove the existing ib_logfileX,"
" and start the server again. Check the MySQL reference manual for max/min values. "
"https://dev.mysql.com/doc/refman/5.6/en/innodb-parameters.html#sysvar_innodb_log_file_size";
msg = "You are recommended to increase the innodb_log_file_size to avoid i/o spikes"
" during flushing.";
advice.setSeverity(Warning);
}
else
{
justification = "Innodb_log_file_size is set to " + logConfiguredMB +
"MB and is greater than the log produced per hour: " +
logGrowthPerHourMB + "MB.";
msg = "Innodb_log_file_size is sized sufficiently.";
advice.setSeverity(Ok);
}
}
else
{
justification = "Server uptime and load is too low.";
msg = "Not enough data to calculate";
advice.setSeverity(0);
}
advice.setHost(host);
advice.setTitle(TITLE);
advice.setJustification(justification);
advice.setAdvice(msg);
advisorMap[idx]= advice;
print(advice.toString("%E"));
}
return advisorMap;
}
ClusterControl cung cấp một môi trường phát triển tích hợp sẵn có (IDE) được gọi là Developer Studio (có thể truy cập trong Manage -> Developer Studio) để viết, biên dịch, lưu, gỡ lỗi và lên lịch cho Cố vấn:
Với Developer Studio và Advisors, người dùng không có giới hạn trong việc mở rộng các chức năng quản lý và giám sát của ClusterControl. Nó thực sự là công cụ hoàn hảo để tự động kiểm tra cấu hình cho tất cả phần mềm cơ sở dữ liệu nguồn mở của bạn như MySQL, MariaDB, PostgreSQL và MongoDB, cũng như các trình cân bằng tải như HAProxy, ProxySQL, MaxScale và PgBouncer. Bạn thậm chí có thể viết một Cố vấn để sử dụng Tiện ích Trình kiểm tra Nâng cấp MySQL Shell, như được trình bày trong chương trước.
Lời kết
Kiểm tra và điều chỉnh cấu hình là những phần quan trọng của quy trình DBA và SysAdmin để đảm bảo các hệ thống quan trọng như cơ sở dữ liệu và proxy ngược luôn phù hợp và tối ưu khi khối lượng công việc của bạn tăng lên.