第2章:MySQL安装与配置(续)
2.4 MySQL基本配置
MySQL的配置对于数据库的性能、安全性和可靠性至关重要。本节将详细介绍MySQL的配置文件、常用配置参数、字符集设置以及安全配置等内容。
2.4.1 配置文件概述
MySQL使用配置文件来存储服务器和客户端的设置。了解配置文件的位置和结构是管理MySQL的基础。
配置文件位置
MySQL会按照特定的顺序查找并加载配置文件。配置文件的位置取决于操作系统:
Windows系统:
C:\ProgramData\MySQL\MySQL Server 8.0\my.ini
C:\Program Files\MySQL\MySQL Server 8.0\my.ini
C:\my.ini
C:\Windows\my.ini
Linux/Unix系统:
/etc/my.cnf
/etc/mysql/my.cnf
/usr/local/mysql/etc/my.cnf
~/.my.cnf
(用户特定配置)
可以使用以下命令查看MySQL当前使用的配置文件:
bash
mysql --help | grep "Default options" -A 1
配置文件结构
MySQL配置文件使用INI格式,由多个部分组成,每个部分以方括号中的标签开始。常见的配置部分包括:
[mysqld]
:MySQL服务器配置[mysql]
:MySQL命令行客户端配置[client]
:所有MySQL客户端程序的通用配置[mysqldump]
:mysqldump工具的配置[mysqladmin]
:mysqladmin工具的配置
示例配置文件结构:
ini
[mysqld]
# 服务器配置
port=3306
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
[mysql]
# 命令行客户端配置
prompt=\u@\h [\d]>\_
[client]
# 所有客户端的通用配置
port=3306
socket=/var/lib/mysql/mysql.sock
配置优先级
MySQL按照以下优先级加载配置(从低到高):
- 全局配置文件(如
/etc/my.cnf
) - MySQL安装目录中的配置文件
- 用户特定的配置文件(
~/.my.cnf
) - 命令行参数
这意味着命令行参数会覆盖配置文件中的设置,而用户特定的配置会覆盖全局配置。
2.4.2 常用配置参数
MySQL有数百个配置参数,但只有少数参数需要经常调整。以下是一些最常用的配置参数及其说明:
基本设置
ini
[mysqld]
# 服务器标识,在复制环境中必须唯一
server-id=1
# 监听地址和端口
bind-address=0.0.0.0 # 监听所有网络接口
port=3306
# 数据目录
datadir=/var/lib/mysql
# 套接字文件位置
socket=/var/run/mysqld/mysqld.sock
# 临时目录
tmpdir=/tmp
# 最大连接数
max_connections=200
# 连接超时(秒)
wait_timeout=28800
interactive_timeout=28800
# 最大允许的数据包大小
max_allowed_packet=64M
内存相关设置
ini
[mysqld]
# InnoDB缓冲池大小(通常设置为系统内存的50-80%)
innodb_buffer_pool_size=1G
# InnoDB缓冲池实例数(通常设置为缓冲池大小/1GB)
innodb_buffer_pool_instances=1
# 查询缓存大小(MySQL 8.0已移除查询缓存)
# query_cache_size=32M
# query_cache_type=1
# 排序缓冲区大小
sort_buffer_size=2M
# 连接缓冲区大小
join_buffer_size=2M
# 表定义缓存
table_definition_cache=1400
# 表打开缓存
table_open_cache=2000
日志设置
ini
[mysqld]
# 错误日志
log_error=/var/log/mysql/error.log
# 一般查询日志(通常在生产环境中禁用)
general_log=0
general_log_file=/var/log/mysql/mysql.log
# 慢查询日志
slow_query_log=1
slow_query_log_file=/var/log/mysql/mysql-slow.log
long_query_time=2 # 记录执行时间超过2秒的查询
# 二进制日志(用于复制和时间点恢复)
log_bin=/var/log/mysql/mysql-bin.log
expire_logs_days=14 # 自动删除14天前的日志
max_binlog_size=100M
InnoDB存储引擎设置
ini
[mysqld]
# 默认存储引擎
default_storage_engine=InnoDB
# InnoDB日志文件大小
innodb_log_file_size=256M
# InnoDB日志缓冲区大小
innodb_log_buffer_size=16M
# InnoDB刷新方法
innodb_flush_method=O_DIRECT
# InnoDB刷新日志的频率
# 1=最安全但最慢,0=最快但最不安全,2=折中
innodb_flush_log_at_trx_commit=1
# InnoDB文件每表一个(MySQL 5.6+)
innodb_file_per_table=1
# InnoDB缓冲池转储和加载
innodb_buffer_pool_dump_at_shutdown=1
innodb_buffer_pool_load_at_startup=1
复制设置
ini
[mysqld]
# 启用二进制日志(用于复制)
log_bin=mysql-bin
# 服务器ID(在复制环境中必须唯一)
server_id=1
# 二进制日志格式(ROW, STATEMENT, MIXED)
binlog_format=ROW
# 从服务器设置
# read_only=1 # 使从服务器只读
# relay_log=relay-bin
# relay_log_index=relay-bin.index
2.4.3 字符集和排序规则设置
字符集和排序规则对于正确存储和比较多语言数据至关重要。MySQL 8.0默认使用utf8mb4字符集和utf8mb4_0900_ai_ci排序规则,这是一个很好的选择,因为它支持所有Unicode字符(包括表情符号)。
设置全局字符集和排序规则
在配置文件中设置全局字符集和排序规则:
ini
[mysqld]
# 服务器字符集和排序规则
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
[mysql]
# 客户端字符集
default-character-set=utf8mb4
[client]
# 连接字符集
default-character-set=utf8mb4
查看当前字符集设置
连接到MySQL后,可以使用以下命令查看当前的字符集和排序规则设置:
sql
-- 查看服务器字符集变量
SHOW VARIABLES LIKE 'character_set%';
-- 查看排序规则变量
SHOW VARIABLES LIKE 'collation%';
修改现有数据库和表的字符集
对于已经创建的数据库和表,可以使用以下命令修改其字符集和排序规则:
sql
-- 修改数据库字符集
ALTER DATABASE database_name CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修改表字符集
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
-- 修改列字符集
ALTER TABLE table_name MODIFY column_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
字符集最佳实践
-
使用utf8mb4:始终使用utf8mb4而不是utf8,因为utf8mb4支持所有Unicode字符,包括表情符号和一些罕见的中文字符。
-
保持一致性:在服务器、数据库、表和连接级别使用相同的字符集,以避免转换问题。
-
选择适当的排序规则:
utf8mb4_unicode_ci
:准确但较慢utf8mb4_general_ci
:速度较快但不太准确utf8mb4_0900_ai_ci
:MySQL 8.0的默认值,结合了准确性和性能
-
注意连接设置:确保应用程序连接字符串中指定了正确的字符集。
2.4.4 安全配置
MySQL的安全配置对于保护数据库和数据至关重要。以下是一些基本的安全配置建议:
网络安全
ini
[mysqld]
# 限制MySQL只监听特定IP地址(如本地连接)
bind-address=127.0.0.1
# 禁用远程root登录
# 注意:这需要在MySQL中使用SQL命令设置
# 使用安全连接
require_secure_transport=ON # 要求使用SSL/TLS连接(MySQL 5.7+)
认证和访问控制
ini
[mysqld]
# 使用强密码加密(MySQL 8.0默认)
default_authentication_plugin=caching_sha2_password
# 启用密码验证组件(MySQL 8.0+)
plugin-load-add=validate_password.so
validate_password.policy=MEDIUM
validate_password.length=8
文件系统安全
ini
[mysqld]
# 限制文件系统访问
secure-file-priv=/var/lib/mysql-files
# 设置适当的文件权限(这是系统级设置,不在配置文件中)
# sudo chown -R mysql:mysql /var/lib/mysql
# sudo chmod 750 /var/lib/mysql
用户账户安全
MySQL 8.0引入了角色,这使得权限管理更加灵活和安全。以下是一些用户账户安全的最佳实践(通过SQL命令实现):
sql
-- 创建具有最小权限的用户
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT SELECT, INSERT, UPDATE, DELETE ON app_database.* TO 'app_user'@'localhost';
-- 创建角色(MySQL 8.0+)
CREATE ROLE 'app_read_role', 'app_write_role';
GRANT SELECT ON app_database.* TO 'app_read_role';
GRANT INSERT, UPDATE, DELETE ON app_database.* TO 'app_write_role';
-- 将角色分配给用户
GRANT 'app_read_role' TO 'read_user'@'localhost';
GRANT 'app_write_role' TO 'write_user'@'localhost';
-- 激活角色
SET DEFAULT ROLE ALL TO 'read_user'@'localhost', 'write_user'@'localhost';
审计和日志
ini
[mysqld]
# 启用审计日志(企业版功能,社区版可以使用MariaDB审计插件)
# audit_log=FORCE_PLUS_PERMANENT
# audit_log_file=/var/log/mysql/audit.log
# 启用一般查询日志(仅用于调试,生产环境通常禁用)
general_log=0
general_log_file=/var/log/mysql/mysql.log
# 记录所有失败的登录尝试
log_error_verbosity=3
2.4.5 性能优化配置
MySQL的性能很大程度上取决于其配置。以下是一些基本的性能优化配置:
缓冲池和内存设置
ini
[mysqld]
# InnoDB缓冲池大小(根据可用内存调整)
# 对于专用服务器,可以设置为系统内存的50-80%
innodb_buffer_pool_size=4G
# InnoDB缓冲池实例数(每GB内存一个实例)
innodb_buffer_pool_instances=4
# InnoDB读写I/O线程数
innodb_read_io_threads=4
innodb_write_io_threads=4
# 表定义缓存
table_definition_cache=2000
# 表打开缓存
table_open_cache=4000
table_open_cache_instances=16
并发设置
ini
[mysqld]
# 最大连接数
max_connections=500
# 线程缓存大小
thread_cache_size=32
# 临时表大小
tmp_table_size=64M
max_heap_table_size=64M
# 后台线程并发
innodb_parallel_read_threads=4 # MySQL 8.0.14+
日志和事务设置
ini
[mysqld]
# InnoDB日志文件大小(通常设置为缓冲池大小的25%)
innodb_log_file_size=1G
# InnoDB日志缓冲区大小
innodb_log_buffer_size=32M
# InnoDB刷新设置
# 1=最安全但最慢,0=最快但最不安全,2=折中
innodb_flush_log_at_trx_commit=1
# 二进制日志同步
sync_binlog=1 # 最安全设置,每次事务都同步
查询优化
ini
[mysqld]
# 排序缓冲区大小
sort_buffer_size=4M
# 连接缓冲区大小
join_buffer_size=4M
# 读取缓冲区大小
read_buffer_size=2M
read_rnd_buffer_size=2M
# 优化器设置
optimizer_switch='mrr=on,mrr_cost_based=off,batched_key_access=on'
2.4.6 监控和调优配置
为了有效地监控和调优MySQL,可以启用一些特定的配置选项:
性能模式(Performance Schema)
Performance Schema是MySQL的一个功能,用于监控MySQL服务器的执行情况:
ini
[mysqld]
# 启用性能模式
performance_schema=ON
# 设置性能模式内存限制(根据可用内存调整)
performance_schema_max_table_instances=500
performance_schema_max_table_handles=500
performance_schema_max_mutex_instances=5000
performance_schema_max_rwlock_instances=2000
信息模式(Information Schema)
Information Schema提供了对数据库元数据的访问:
ini
[mysqld]
# 启用额外的统计信息
innodb_stats_on_metadata=ON
慢查询日志
慢查询日志对于识别性能问题非常有用:
ini
[mysqld]
# 启用慢查询日志
slow_query_log=1
slow_query_log_file=/var/log/mysql/mysql-slow.log
# 记录执行时间超过1秒的查询
long_query_time=1
# 记录未使用索引的查询
log_queries_not_using_indexes=1
# 限制每分钟记录的未使用索引的查询数
log_throttle_queries_not_using_indexes=10
# 记录管理语句(如ALTER TABLE)
log_slow_admin_statements=1
2.4.7 配置文件示例
以下是一个综合的MySQL配置文件示例,适用于中等规模的应用:
ini
[mysqld]
# 基本设置
user=mysql
pid-file=/var/run/mysqld/mysqld.pid
socket=/var/run/mysqld/mysqld.sock
port=3306
basedir=/usr
datadir=/var/lib/mysql
tmpdir=/tmp
bind-address=0.0.0.0
# 字符集设置
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
# InnoDB设置
default_storage_engine=InnoDB
innodb_buffer_pool_size=2G
innodb_buffer_pool_instances=2
innodb_log_file_size=512M
innodb_log_buffer_size=16M
innodb_flush_log_at_trx_commit=1
innodb_file_per_table=1
innodb_flush_method=O_DIRECT
innodb_read_io_threads=4
innodb_write_io_threads=4
# 连接设置
max_connections=300
thread_cache_size=32
wait_timeout=3600
interactive_timeout=3600
max_allowed_packet=64M
# 表缓存设置
table_open_cache=2000
table_definition_cache=1400
table_open_cache_instances=16
# 临时表设置
tmp_table_size=32M
max_heap_table_size=32M
# 查询缓冲设置
sort_buffer_size=2M
join_buffer_size=2M
read_buffer_size=1M
read_rnd_buffer_size=1M
# 日志设置
log_error=/var/log/mysql/error.log
slow_query_log=1
slow_query_log_file=/var/log/mysql/mysql-slow.log
long_query_time=2
log_queries_not_using_indexes=0
log_slow_admin_statements=1
# 二进制日志设置
log_bin=/var/log/mysql/mysql-bin.log
expire_logs_days=14
max_binlog_size=100M
binlog_format=ROW
sync_binlog=1
# 复制设置
server_id=1
# 如果是从服务器,取消下面的注释
# read_only=1
# relay_log=relay-bin
# relay_log_index=relay-bin.index
# 安全设置
secure-file-priv=/var/lib/mysql-files
default_authentication_plugin=caching_sha2_password
# 性能模式
performance_schema=ON
[mysql]
default-character-set=utf8mb4
[client]
default-character-set=utf8mb4
2.4.8 动态配置参数
MySQL的许多配置参数可以在运行时动态修改,无需重启服务器。这对于调试和优化非常有用。
查看可动态修改的参数
sql
-- 查看所有系统变量
SHOW VARIABLES;
-- 查看特定变量
SHOW VARIABLES LIKE 'max_connections';
-- 查看变量是否可动态修改
SELECT @@max_connections;
动态修改参数
sql
-- 修改全局变量(影响新连接)
SET GLOBAL max_connections = 500;
-- 修改会话变量(仅影响当前连接)
SET SESSION sort_buffer_size = 4*1024*1024;
持久化动态参数(MySQL 8.0+)
MySQL 8.0引入了SET PERSIST命令,可以动态修改参数并将其保存到配置文件中,使其在重启后仍然有效:
sql
-- 修改参数并持久化
SET PERSIST max_connections = 500;
-- 仅持久化参数,不立即修改
SET PERSIST_ONLY max_connections = 500;
-- 查看持久化的配置
SELECT * FROM performance_schema.persisted_variables;
-- 删除持久化的配置
RESET PERSIST max_connections;
RESET PERSIST IF EXISTS max_connections;
RESET PERSIST; -- 删除所有持久化配置
2.4.9 配置最佳实践
以下是一些MySQL配置的最佳实践:
-
基于实际需求配置:根据应用程序的实际需求和服务器的硬件资源调整配置。
-
监控和调整:定期监控MySQL的性能,并根据监控结果调整配置。
-
增量调整:一次只调整一个或少数几个参数,然后观察效果,避免大规模更改导致问题难以诊断。
-
记录更改:记录所有配置更改及其效果,以便将来参考。
-
使用默认值作为起点:MySQL的默认配置在大多数情况下是合理的,可以作为调整的起点。
-
考虑工作负载类型:不同类型的工作负载(如OLTP、OLAP)需要不同的配置优化。
-
定期审查安全设置:定期检查和更新安全配置,确保数据库的安全性。
-
备份配置文件:在修改配置文件之前,始终创建备份,以便在出现问题时可以恢复。
-
测试环境验证:在生产环境应用配置更改之前,先在测试环境中验证。
-
使用配置管理工具:对于多服务器环境,考虑使用配置管理工具(如Ansible、Puppet或Chef)来管理MySQL配置。
通过合理配置MySQL,可以显著提高数据库的性能、安全性和可靠性,为应用程序提供稳定高效的数据存储和检索服务。