mysql实例是mysqld进程及其管理的所有资源总和,可托管多个database,每个database下含多张table;连接的是实例而非库,需use切换;实例含main、connection、redo log flush、page cleaner、purge等线程;关键内存为buffer pool和log buffer,query cache在8.0已移除;配置分静态(需重启)和动态(可set global),如innodb_buffer_pool_size增大可在线调,减小须重启。

MySQL实例到底是什么,和数据库、表是啥关系
MySQL实例不是“一个数据库”,而是 mysqld 进程 + 它管理的所有资源(内存、线程、磁盘数据)的总和。你启动一次 mysqld,就创建了一个实例;它能同时托管多个 database(逻辑库),每个 database 下再建多张 table。
常见误解是把“连接上 localhost:3306”当成连上了某个库——其实你连的是整个实例,后续用 USE db_name 才切换到具体 database。一个实例可以有多个用户、多种字符集配置、各自独立的权限体系,但共享同一套全局内存结构和后台线程。
mysqld 进程里跑着哪些关键线程
mysqld 启动后不是一个单线程程序,它会派生出若干后台线程协同工作:
-
main thread:负责初始化、监听端口、接收连接请求 -
connection thread:每个客户端连接进来,就会分配一个独立线程(或由线程池复用),处理该连接的 SQL 解析、执行、结果返回 -
redo log flush thread:定期将 redo log buffer 刷到磁盘 -
page cleaner thread:在 InnoDB 中负责刷脏页(dirty page)到磁盘 -
purge thread:清理 undo log 中已过期的版本记录
这些线程共用实例的全局内存区域(比如 innodb_buffer_pool),但各自维护私有栈空间。如果看到 SHOW PROCESSLIST 里大量 Sleep 状态连接,说明 connection thread 没释放,可能因应用没调用 close() 或连接池配置不当。
关键内存结构:buffer pool、log buffer 和 query cache 已被移除
InnoDB 的 innodb_buffer_pool_size 是最值得调的内存参数,它缓存表数据和索引页,直接影响读性能。默认值往往太小(比如 128MB),生产环境建议设为物理内存的 50%–75%,但别超过 innodb_buffer_pool_instances × 1GB(避免内部锁争用)。
innodb_log_buffer_size 控制 redo log 内存缓冲区大小,一般 4MB–16MB 足够,写密集场景可适当调大,避免频繁刷盘。
注意:query_cache_type 和 query_cache_size 在 MySQL 8.0 中已被彻底移除。如果你从 5.7 升级上来,配置文件里还留着这两项,mysqld 启动时会报 warning,且不生效。
my.cnf 里哪些配置项改了必须重启,哪些可以动态改
MySQL 配置分两类:静态变量(require restart)和动态变量(can SET GLOBAL)。判断依据很简单——查 SHOW VARIABLES 结果里的 Variable_name 对应的 Type 列是否为 Dynamic。
- 必须重启才生效:
innodb_buffer_pool_size、max_connections、datadir、port - 可在线修改:
innodb_lock_wait_timeout、sort_buffer_size(对新连接生效)、wait_timeout
容易踩坑的是 innodb_buffer_pool_size:它虽支持在线调整(MySQL 5.7+),但仅限“增大”,且要求新值是旧值的整数倍(如从 1G → 2G 可行,1G → 1.5G 会报错)。减小则必须重启。
配置文件路径优先级:/etc/my.cnf → /etc/mysql/my.cnf → /usr/etc/my.cnf → ~/.my.cnf。用 mysqld --help --verbose | grep "Default options" 可确认实际加载顺序。










