أفضل إعدادات لملف my.cnf في خادم لينكس

من المعروف لمدراء الخوادم أن ملف الإعدادات “my.cnf” هو المسؤول عن كثير من إعدادات محرك قواعد البيانات MySQL أو InnoDB أو غيرها. ووضع إعدادات خاطئة أو الاعتماد على الإعدادات الافتراضية يسبب في كثير من الأحيان مشاكل كبيرة لا حصر لها، من استخدام خاطئ لموارد الخادم إلى ضعف الأداء في التعامل مع كم كبير من استعلامات قواعد البيانات ما يسبب في النهاية إلى انهيار الخادم وتوقفه بسبب إعدادات غير صحيحة.

يجب أن أنوه على أن الإعدادات التالية لا تناسب كل خادم، ذلك لاختلاف العتاد من خادم لآخر. فهناك خوادم بذاكرة عشوائية أكبر من غيرها وهناك خوادم بمعالجات أنوية متعددة (ثنائية، رباعية وغيرها). هذين العاملين مهمين جداً عند تغيير قيم المتغيرات في ملف my.cnf

سأحاول هنا شرح إعداد خادم Linux بذاكرة عشوائية 16GB ذو أربعة أنوية.

أولاً أين يوجد ملف my.cnf ؟

لو ذهبنا لموقع MySQL وقرأنا التعليمات هناك في الصفحة التالية (http://dev.mysql.com/doc/refman/5.7/en/option-files.html) هناك قسم 5.2 يذكر أماكن تواجد الملف my.cnf والذي يمكننا التعديل عليه:

Table 5.2 Option Files Read on Unix and Unix-Like Systems

File Name Purpose
/etc/my.cnf Global options
/etc/mysql/my.cnf Global options
SYSCONFDIR/my.cnf Global options
$MYSQL_HOME/my.cnf Server-specific options (server only)
defaults-extra-file The file specified with --defaults-extra-file, if any
~/.my.cnf User-specific options
~/.mylogin.cnf User-specific login path options (clients only)


هناك بعض برامج باش bash التي تساعدك في وضع إعدادات محرك قواعد البيانات MySQL أو InnoDB تناسب استخدامك وتعتمد على آخر إحصائيات الخادم لقواعد البيانات لوضع قيم مناسبة. شخصياً استخدم اثنين لكن لا أعتمد كثيراً على القيم النهائية، لأنها فقط نصائح وليس بالضرورة تناسبك.

السكربتات هي:

  • Tuning-Primer.sh
  • mysqltuner.pl

الأول سكربت باش والثاني سكربت بيرل. كلاهما مفيد جداً إذا كنت لا تمتلك الخبرة الكافية لإعداد قواعد قيم MySQL.

قبل أن نبداً بتنصيب واستخدام البرنامجين لنقوم أولاً بإصلاح جميع قواعد البيانات في الخادم عن طريق الأمر التالي (سيقوم الأمر بإصلاح فقط قواعد MySQL وليس InnoDB لأنه لا يمكن استخدام هذا الأمر عليها:

 # mysqlcheck --check --auto-repair --all-databases 


لنقوم الآن بتثبيت mysqltuner على الخادم عن طريق الأوامر التالية:

# cd /usr/local/bin

# wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl 

# chmod +x mysqltuner.pl

والآن نقوم بتثبيت tuning-primer على الخادم عن طريق الأوامر التالية:

# cd /usr/local/bin

# wget https://launchpadlibrarian.net/78745738/tuning-primer.sh

# chmod u+x tuning-primer.sh

الآن وبعد أن قمنا بتحميل كلا البرنامجين، وقبل تشغيلهما تأكد أنك أن الخادم كان يعمل على الأقل لمدة يوم كامل أو يومين.

طريقة تشغيل mysqltuner هي:

# cd /usr/local/bin
# /usr/local/bin/mysqltuner.pl

طريقة تشغيل tuning-primer هي:

# cd /usr/local/bin
# tuning-primer.sh

بعد تشغيل tuning-primer سيكون الناتج شيء مشابه للتالي وهي نتائج لكل عملية فحص للإعدادات في ملف my.cnf والقيم التي يجب أن تكون عليها.

ولو لاحظنا في البداية أن الخادم يعمل بدون انقطاع لمدة 5 أيام، وهنا ملاحظة أنه كلما قمنا بتشغيل البرنامج بعد عمل الخادم لمدة أكثر كلما كانت القيم أكثر دقة ومناسبة.

التعديلات في الإعدادات ستكون باللون الأحمر وإذا كانت الاعدادات سليمة ستكون باللون الأخضر.

وإتبع ماذا يقترح عليك السكربت، حتى تصل إلى أفضل إعدادات.

-- MYSQL PERFORMANCE TUNING PRIMER --
- By: Matthew Montgomery -

MySQL Version 5.6.34-log x86_64

Uptime = 5 days 1 hrs 18 min 8 sec
Avg. qps = 47
Total Questions = 20634985
Threads Connected = 6

Server has been running for over 48hrs.
It should be safe to follow these recommendations

To find out more information on how each of these
runtime variables effects performance visit:
http://dev.mysql.com/doc/refman/5.6/en/server-system-variables.html
Visit http://www.mysql.com/products/enterprise/advisors.html
for info about MySQL's Enterprise Monitoring and Advisory Service

SLOW QUERIES
The slow query log is NOT enabled.
Current long_query_time = 10.000000 sec.
You have 499879 out of 20635006 that take longer than 10.000000 sec. to complete
Your long_query_time seems to be fine

BINARY UPDATE LOG
The binary update log is enabled
Binlog sync is not enabled, you could loose binlog records during a server crash

WORKER THREADS
Current thread_cache_size = 50
Current threads_cached = 45
Current threads_per_sec = 0
Historic threads_per_sec = 0
Your thread_cache_size is fine

MAX CONNECTIONS
Current max_connections = 400
Current threads_connected = 6
Historic max_used_connections = 129
The number of used connections is 32% of the configured maximum.
Your max_connections variable seems to be fine.

INNODB STATUS
Current InnoDB index space = 3 M
Current InnoDB data space = 3 M
Current InnoDB buffer pool free = 99 %
Current innodb_buffer_pool_size = 4.00 G
Depending on how much space your innodb indexes take up it may be safe
to increase this value to up to 2 / 3 of total system memory

MEMORY USAGE
Max Memory Ever Allocated : 5.20 G
Configured Max Per-thread Buffers : 1.58 G
Configured Max Global Buffers : 4.69 G
Configured Max Memory Limit : 6.27 G
Physical Memory : 11.56 G
Max memory limit seem to be within acceptable norms

KEY BUFFER
Current MyISAM index space = 262 M
Current key_buffer_size = 64 M
Key cache miss rate is 1 : 113
Key buffer free ratio = 50 %
Your key_buffer_size seems to be too high.
Perhaps you can use these resources elsewhere

QUERY CACHE
Query cache is enabled
Current query_cache_size = 512 M
Current query_cache_used = 297 M
Current query_cache_limit = 4 M
Current Query cache Memory fill ratio = 58.04 %
Current query_cache_min_res_unit = 4 K
MySQL won't cache query results that are larger than query_cache_limit in size

SORT OPERATIONS
Current sort_buffer_size = 512 K
Current read_rnd_buffer_size = 512 K
Sort buffer seems to be fine

JOINS
Current join_buffer_size = 2.00 M
You have had 2364 queries where a join could not use an index properly
You should enable "log-queries-not-using-indexes"
Then look for non indexed joins in the slow query log.
If you are unable to optimize your queries you may want to increase your
join_buffer_size to accommodate larger joins in one pass.

Note! This script will still suggest raising the join_buffer_size when
ANY joins not using indexes are found.

OPEN FILES LIMIT
Current open_files_limit = 65536 files
The open_files_limit should typically be set to at least 2x-3x
that of table_cache if you have heavy MyISAM usage.
Your open_files_limit value seems to be fine

TABLE CACHE
Current table_open_cache = 4000 tables
Current table_definition_cache = 4000 tables
You have a total of 2725 tables
You have 3984 open tables.
Current table_cache hit rate is 28%
, while 99% of your table cache is in use
You should probably increase your table_cache

TEMP TABLES
Current max_heap_table_size = 1.00 G
Current tmp_table_size = 1.00 G
Of 812930 temp tables, 42% were created on disk
Perhaps you should increase your tmp_table_size and/or max_heap_table_size
to reduce the number of disk-based temporary tables
Note! BLOB and TEXT columns are not allow in memory tables.
If you are using these columns raising these values might not impact your
ratio of on disk temp tables.

TABLE SCANS
Current read_buffer_size = 512 K
Current table scan ratio = 58 : 1
read_buffer_size seems to be fine

TABLE LOCKING
Current Lock Wait ratio = 1 : 1695
You may benefit from selective use of InnoDB.
If you have long running SELECT's against MyISAM tables and perform
frequent updates consider setting 'low_priority_updates=1'


بعد تشغيل mysqltuner.pl سيكون الناتج شيء مشابه للتالي وفي الأخير سترى Recommendations وهنا ستجد القيم التي يستحسن منك تعديلها، طبعا هناك نتائج ونصائح أعلى النتائج حاول أيضاً اتباعها:

>>MySQLTuner 1.6.20 - Major Hayden <major@mhtx.net>
>>Bug reports, feature requests, and downloads at http://mysqltuner.com/
>>Run with '--help' for additional options and output filtering

[--] Skipped version check for MySQLTuner script
[OK] Currently running supported MySQL version 5.6.34-log
[OK] Operating on 64-bit architecture

-------- Storage Engine Statistics -----------------------------------------------------------------
[--] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MEMORY +MRG_MYISAM +MyISAM +PERFORMANCE_SCHEMA
[--] Data in MyISAM tables: 1G (Tables: 2524)
[--] Data in InnoDB tables: 6M (Tables: 115)
[--] Data in MEMORY tables: 0B (Tables: 4)
[OK] Total fragmented tables: 0

-------- Security Recommendations ------------------------------------------------------------------
[OK] There are no anonymous accounts for any database users
[OK] All database users have passwords assigned
[!!] There is no basic password file list!

-------- CVE Security Recommendations --------------------------------------------------------------
[--] Skipped due to --cvefile option undefined

-------- Performance Metrics -----------------------------------------------------------------------
[--] Up for: 5d 1h 34m 8s (20M q [47.325 qps], 730K conn, TX: 104G, RX: 7G)
[--] Reads / Writes: 79% / 21%
[--] Binary logging is enabled (GTID MODE: OFF)
[--] Physical Memory: 11.6G
[--] Max MySQL memory: 7.3G
[--] Other process memory: 507.8M
[--] Total buffers: 5.7G global + 4.0M per thread (400 max threads)
[--] P_S Max memory usage: 0B
[--] Galera GCache Max memory usage: 0B
[OK] Maximum reached memory usage: 6.2G (53.56% of installed RAM)
[OK] Maximum possible memory usage: 7.3G (62.71% of installed RAM)
[OK] Overall possible memory usage with other process is compatible with memory available
[OK] Slow queries: 2% (501K/20M)
[OK] Highest usage of available connections: 32% (129/400)
[OK] Aborted connections: 0.02%(153/730535)
[!!] Query cache may be disabled by default due to mutex contention.
[OK] Sorts requiring temporary tables: 0% (300 temp sorts / 806K sorts)
[!!] Joins performed without indexes: 2367
[!!] Temporary tables created on disk: 74% (606K on disk / 816K total)
[OK] Thread cache hit rate: 99% (136 created / 730K connections)
[OK] Table cache hit rate: 28% (3K open / 14K opened)
[OK] Open file limit used: 9% (6K/65K)
[OK] Table locks acquired immediately: 99% (7M immediate / 7M locks)
[OK] Binlog cache memory access: 100.00% ( 556 Memory / 556 Total)

-------- Performance schema ------------------------------------------------------------------------
[--] Performance schema is disabled.

-------- ThreadPool Metrics ------------------------------------------------------------------------
[--] ThreadPool stat is disabled.

-------- MyISAM Metrics ----------------------------------------------------------------------------
[!!] Key buffer used: 52.1% (34M used / 67M cache)
[OK] Key buffer size / total MyISAM indexes: 64.0M/262.3M
[OK] Read Key buffer hit rate: 99.1% (589M cached / 5M reads)
[OK] Write Key buffer hit rate: 96.8% (112M cached / 3M writes)

-------- AriaDB Metrics ----------------------------------------------------------------------------
[--] AriaDB is disabled.

-------- InnoDB Metrics ----------------------------------------------------------------------------
[--] InnoDB is enabled.
[OK] InnoDB buffer pool / data size: 4.0G/6.7M
[OK] InnoDB buffer pool instances: 4
[--] InnoDB Buffer Pool Chunk Size not used or defined in your version
[OK] InnoDB Read buffer efficiency: 99.98% (4023136 hits/ 4023896 total)
[!!] InnoDB Write Log efficiency: 39.19% (1097 hits/ 2799 total)
[OK] InnoDB log waits: 0.00% (0 waits / 1702 writes)

-------- TokuDB Metrics ----------------------------------------------------------------------------
[--] TokuDB is disabled.

-------- Galera Metrics ----------------------------------------------------------------------------
[--] Galera is disabled.

-------- Replication Metrics -----------------------------------------------------------------------
[--] Galera Synchronous replication: NO
[--] No replication slave(s) for this server.
[--] This is a standalone server.

-------- Recommendations ---------------------------------------------------------------------------
General recommendations:
Restrict Host for user@% to user@SpecificDNSorIp
Adjust your join queries to always utilize indexes
Temporary table size is already large - reduce result set size
Reduce your SELECT DISTINCT queries without LIMIT clauses
Variables to adjust:
query_cache_type (=0)
join_buffer_size (> 2.0M, or always use indexes with joins)

وللتعديل على القيم نقوم باستخدام أي محرر، أفضل شخصياً pico كالتالي:

# pico /etc/my.cnf
ملف my.cnf الخاص بأحد خوادم مناري كالتالي:
#############################################
#DATE: 2016-10-29
#SITE: https://manary.net
#DESCRIPTION: MySQL config 5.6.x
#RAM: 16GB RAM dedicated server
#Connections: 400 connections
#By: MUSTAFA AL-YOUSEF
#############################################

[client]
socket = /var/lib/mysql/mysql.sock
default-character-set = utf8

[mysqld]
## Charset and Collation
default-storage-engine = MyISAM
default-tmp-storage-engine = MyISAM
character-set-server = utf8
collation-server = utf8_general_ci
performance-schema = on
local-infile=0

## Files
back_log = 300
open_files_limit=10000
#open_files = 1024
port = 3306
socket = /var/lib/mysql/mysql.sock
pid-file = /var/lib/mysql/mysql.pid
skip-external-locking
skip-name-resolve

## Logging
datadir = /var/lib/mysql
relay_log = mysql-relay-bin
relay_log_index = mysql-relay-index
#log = mysql-gen.log
log_error = mysql-error.err
log_warnings
log_bin = mysql-bin
slow_query_log=1
slow_query_log=1
slow_query_log_file=mysql-slow.log
log_queries_not_using_indexes
long_query_time = 10 #default: 10
max_binlog_size = 256M #max size for binlog before rolling
expire_logs_days = 4 #binlog files older than this will be purged

## Per-Thread Buffers * (max_connections) = total per-thread mem usage
thread_stack = 512K #default: 32bit: 192K, 64bit: 256K
sort_buffer_size = 512K #default: 2M, larger may cause perf issues
read_buffer_size = 512K #default: 128K, change in increments of 4K
read_rnd_buffer_size = 512K #default: 256K
join_buffer_size = 3M #default: 128K
binlog_cache_size = 64K #default: 32K, size of buffer to hold TX queries
## total per-thread buffer memory usage: 44160000K = 43.125GB

## Query Cache
query_cache_type = 1
query_cache_size = 512M #32MB for every 1GB of RAM
query_cache_limit = 4M #max query result size to put in cache

## Connections
max_connections = 400 #multiplier for memory usage via per-thread buffers
max_connect_errors = 10 #default: 10
concurrent_insert = 2 #default: 1, 2: enable insert for all instances
connect_timeout = 30 #default -5.1.22: 5, +5.1.22: 10
max_allowed_packet=268435456

## Table and TMP settings
max_heap_table_size = 1G #recommend same size as tmp_table_size
bulk_insert_buffer_size = 1G #recommend same size as tmp_table_size
tmp_table_size = 1G #recommend 1G min

## Table cache settings
table_definition_cache = 4000
table_open_cache = 4000 #5.1.x, 5.5.x <default: 64>
#tmpdir = /data/mysql-tmp0:/data/mysql-tmp1 #Recommend using RAMDISK for tmpdir

## Thread settings
thread_concurrency = 32 #recommend 2x CPU cores
thread_cache_size = 50 #recommend 5% of max_connections

## MyISAM Engine
key_buffer = 64M ## 128MB for every 1GB of RAM
myisam_sort_buffer_size = 64M #index buffer size for creating/altering indexes
myisam_max_sort_file_size = 64M #max file size for tmp table when creating/alering indexes
myisam_repair_threads = 4 #thread quantity when running repairs
myisam_recover = BACKUP #repair mode, recommend BACKUP

## InnoDB Plugin Independent Settings
innodb_data_home_dir = /var/lib/mysql
#innodb_data_file_path = ibdata1:128M;ibdata2:10M:autoextend
innodb_log_file_size = 256M #64G_RAM+ = 768, 24G_RAM+ = 512, 8G_RAM+ = 256, 2G_RAM+ = 128
innodb_log_files_in_group = 4 #combined size of all logs <4GB. <2G_RAM = 2, >2G_RAM = 4
innodb_buffer_pool_size = 4G #global buffer
innodb_additional_mem_pool_size = 4M #global buffer
innodb_status_file #extra reporting
innodb_file_per_table = 1 #enable always
innodb_flush_log_at_trx_commit = 2 #2/0 = perf, 1 = ACID
innodb_table_locks = 0 #preserve table locks
innodb_log_buffer_size = 128M #global buffer
innodb_lock_wait_timeout = 60
innodb_thread_concurrency = 16 #recommend 2x core quantity
innodb_commit_concurrency = 16 #recommend 4x num disks
#innodb_flush_method = O_DIRECT #O_DIRECT = local/DAS, O_DSYNC = SAN/iSCSI
innodb_support_xa = 0 #recommend 0, disable xa to negate extra disk flush
skip-innodb-doublewrite
#innodb_force_recovery = 1
innodb_buffer_pool_instances = 4

## Binlog sync settings
## XA transactions = 1, otherwise set to 0 for best performance
sync_binlog = 0

[mysqldump]
quick
quote-names
max_allowed_packet = 128M


أتمنى أنني وفقت بالشرح وإذا كانت لديكم ملاحظات أسئلة أو مشاكل، اكتبوا تعليق على الموضوع وسأقوم إن شاء الله تعالى بالرد عليها.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *