ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MySQL配置文件/etc/my.cnf深度解析:段落机制与加载优先级

MySQL配置文件/etc/my.cnf深度解析:段落机制与加载优先级 1. 项目概述为什么一个配置文件值得被“庖丁解牛”/etc/my.cnf这个路径对任何接触过 Linux 下 MySQL 的人来说几乎刻在肌肉记忆里。它不是某个临时生成的缓存也不是用户家目录下的个人偏好设置而是整个 MySQL 实例启动、运行、甚至崩溃时最后依赖的“宪法性文件”。我第一次在生产环境里排查一个诡异的连接超时问题花了整整两天——日志里全是ERROR 2002 (HY000): Cant connect to local MySQL server through socket /tmp/mysql.sock但ls /tmp/确实没有这个 sock 文件。最后发现是/etc/my.cnf里socket /var/lib/mysql/mysql.sock这一行被注释掉了而 mysqld 启动时又没带-S参数它就默默按编译时的默认路径去找结果当然扑空。那一刻我才真正意识到这不是一个“可有可无”的配置文件它是 mysqld 进程从诞生到消亡全程的“呼吸节律器”。所谓“生命周期”绝非指文件被创建、修改、删除的时间线而是指它如何深度参与 mysqld 进程的每一个关键阶段启动前的参数解析、启动时的初始化决策、运行中的行为约束、故障时的诊断依据、乃至服务重启时的上下文继承。它不像logback.xml或application.yml那样只在应用启动初期读取一次就扔进内存/etc/my.cnf的影响是持续的、动态的、有时甚至是隐式的。比如你改了max_connections不重启服务新值不会生效但你改了slow_query_log_file只要执行SET GLOBAL slow_query_log ON;它立刻就会写入新路径——这种“半热加载”特性恰恰说明它的角色远比表面复杂。这个标题里的“庖丁解牛”不是故弄玄虚。它意味着我们要像庖丁看牛一样不把它当一个黑盒的.cnf文件而是拆开它的筋络哪些部分是 mysqld 自己硬编码识别的比如[mysqld]段哪些是客户端工具如mysql命令行专用的比如[client]段哪些是连mysqld_safe这种包装脚本都会去读的比如[mysqld_safe]段。更要搞清当系统里同时存在/etc/my.cnf、/usr/etc/my.cnf、~/.my.cnf、甚至命令行参数--port3307时它们之间不是简单覆盖而是一套有严格优先级的“宪法解释权”体系。网络上那些“MySQL安装教程”里一句带过的“编辑/etc/my.cnf”背后藏着的是整个 MySQL 生态的启动哲学。这篇文章就是带你亲手把这头“牛”的每一块骨头、每一根韧带都摸清楚。2. 内容整体设计与思路拆解从“文件位置”到“配置主权”2.1 为什么是/etc/my.cnf而不是其他路径这个问题的答案直接决定了你对整个配置体系的理解深度。很多新手会困惑“我明明在/home/user/.my.cnf里写了userroot为什么mysql -u test还是提示密码错误”——根源就在于MySQL 的配置文件读取根本不是“找一个文件读完就完事”而是一个多层叠加、按序扫描、优先级覆盖的精密流程。MySQL 官方文档明确列出了其默认的配置文件搜索顺序按优先级从高到低命令行参数--port3307,--socket/var/run/mysqld/mysqld.sock最高优先级直接覆盖所有文件配置。当前目录下的my.cnf./my.cnf极少用主要用于调试或容器内临时覆盖。/etc/my.cnf这是系统级全局配置对本机所有 MySQL 实例如果装了多个都有效也是绝大多数 Linux 发行版包管理器如yum install mysql-server默认安装和修改的位置。/etc/mysql/my.cnfDebian/Ubuntu 系发行版的惯用路径逻辑同/etc/my.cnf但存在即覆盖/etc/my.cnf。SYSCONFDIR/my.cnf通常是/usr/etc/my.cnf由 MySQL 编译时--sysconfdir参数指定属于“编译时约定”普通用户基本不会碰。$MYSQL_HOME/my.cnf如果设置了MYSQL_HOME环境变量用于为特定 MySQL 安装目录定制配置。defaults-extra-file指定的文件通过--defaults-extra-file/path/to/file.cnf一种显式、强制的额外配置文件加载方式优先级极高。~/.my.cnf用户家目录用户级配置只对当前用户启动的客户端如mysql,mysqldump生效对mysqld服务进程完全无效。这就是为什么你在~/.my.cnf里写userrootmysql命令能免密登录但systemctl start mysqld却完全无视它的原因。提示你可以用mysql --help | grep Default options来实时查看你本地 MySQL 版本实际使用的搜索路径列表。不同版本、不同编译方式路径可能微调但/etc/my.cnf和~/.my.cnf这两个核心路径是铁律。所以选择/etc/my.cnf作为“主战场”并非因为它天生高贵而是因为它处在整个搜索链的黄金分割点它足够靠前能覆盖大部分默认行为它又足够靠后不会被用户家目录的随意修改所干扰更重要的是它是systemd服务单元如mysqld.service在启动mysqld时默认信任并加载的唯一系统级配置源。当你执行systemctl restart mysqldsystemd脚本内部调用的mysqld --daemonize --pid-file/var/run/mysqld/mysqld.pid其背后隐含的配置加载逻辑就是从/etc/my.cnf开始的。2.2 “段落”Section才是真正的配置单元而非整份文件很多人误以为/etc/my.cnf是一个扁平的键值对集合比如port3306、bind-address127.0.0.1。这是巨大的认知偏差。MySQL 的配置文件本质是一个分段式SectionedINI 文件其灵魂在于方括号[]包裹的段落名。每个段落定义了一个“作用域”只有该作用域内的程序才会读取其中的配置。最常见的段落及其“管辖范围”如下段落名主要读取者典型用途关键注意事项[mysqld]mysqld服务进程本身服务器核心参数端口、socket、数据目录、缓冲区大小、日志开关等。这是你修改后必须重启mysqld才能生效的部分。mysqld启动时会将此段所有配置加载为内部变量。修改后不重启新值永远是“纸上谈兵”。[client]所有 MySQL 客户端命令行工具mysql,mysqldump,mysqladmin客户端通用参数默认 host、port、user、password、socket。避免每次敲命令都带-h localhost -P 3306。此段配置对mysqld服务进程完全无效。它只影响你敲mysql -u root这类命令的行为。[mysql]mysql命令行客户端特指交互式 shellmysql客户端专属参数pager,prompt,auto-rehash等提升交互体验的选项。它是[client]的子集只对mysql命令生效。如果[mysql]和[client]里有同名参数[mysql]优先。[mysqld_safe]mysqld_safe启动脚本mysqld的守护进程包装器启动保障参数pid-file,log-error,nice,malloc-lib。mysqld_safe会先读此段再用它来启动真正的mysqld。在现代systemd环境下mysqld_safe已逐渐被弃用但很多老教程和 RPM 包仍依赖它。log-error在此段设置比在[mysqld]里设置更可靠。[mysqldump]mysqldump备份工具备份专用参数max_allowed_packet,quick,skip-comments。专为备份场景优化不影响服务运行。理解这一点至关重要。如果你在[client]段里写了max_connections 1000那纯粹是浪费表情因为mysqld根本不认这个段。同样如果你在[mysqld]段里写了user root这行配置会被mysqld忽略因为mysqld启动时是以mysql用户身份运行的出于安全考虑它不会去读取一个要求它以root身份运行的指令。user这个参数只在[mysqld_safe]段里才有意义它告诉mysqld_safe“你帮我启动mysqld时请用mysql这个系统用户去跑它”。2.3 生命周期的起点mysqld启动时的“宪法宣誓”/etc/my.cnf的第一个高光时刻发生在mysqld进程诞生的零毫秒。此时它不是一个被动的“被读取对象”而是一个主动的“决策参与者”。整个过程可以分解为三个严谨的阶段第一阶段预解析与冲突检测Pre-parsing Conflict Resolutionmysqld启动时并非一股脑把/etc/my.cnf从头读到尾。它首先会进行一次“快速扫描”只提取出所有段落名和关键的、会影响后续解析逻辑的参数。例如它会寻找[mysqld]段因为这是它的“主政纲领”。它会寻找--defaults-file或--defaults-extra-file这类命令行参数一旦发现就会立即切换配置文件搜索路径/etc/my.cnf可能就此被跳过。它会检查是否存在语法错误比如一个未闭合的引号datadir /var/lib/mysql此时mysqld会直接报错退出并打印Fatal error in defaults handling. Program aborted!连日志文件都来不及写。第二阶段分段加载与变量绑定Section Loading Variable Binding确认文件无误后mysqld开始正式加载。它会按段落名将配置项一一映射到其内部的 C 结构体变量上。这个过程不是简单的字符串赋值而是带有类型转换和合法性校验的max_connections 1000会被转换为int类型并检查是否在1到100000的合法范围内。innodb_buffer_pool_size 2G会被解析为字节数2 * 1024 * 1024 * 1024并检查是否超过系统物理内存的 75%超出会警告。sql_mode STRICT_TRANS_TABLES,NO_ZERO_DATE会被解析为一个位掩码bitmask每个模式对应一个 bit。第三阶段初始化与“宪法效力”确立Initialization Effectiveness所有变量加载完毕后mysqld进入初始化函数init_server_components()。此时/etc/my.cnf的“宪法效力”才真正生效如果datadir指向的目录不存在mysqld会尝试创建它需要mysql用户有父目录写权限。如果socket指定的路径/var/run/mysqld/mysqld.sock所在的目录/var/run/mysqld/不存在mysqld会静默失败因为mysqld进程本身没有权限创建/var/run/下的子目录这是mysqld_safe或systemd的职责。如果log-error指向的文件无法写入mysqld会退回到标准错误输出stderr这在systemd环境下意味着错误日志会出现在journalctl -u mysqld的输出里而不是你期望的/var/log/mysqld.log。这个“三阶段”模型解释了为什么一个看似简单的配置修改会导致如此迥异的结果语法错误是第一阶段失败数值越界是第二阶段失败权限不足是第三阶段失败。它们的日志表现、错误代码、甚至修复方法都截然不同。3. 核心细节解析与实操要点深入my.cnf的每一行代码3.1 最常被误解的“万能”参数!includedir在/etc/my.cnf的顶部你几乎总能看到这样一行!includedir /etc/my.cnf.d它的作用是让mysqld去/etc/my.cnf.d/目录下按字母顺序加载所有以.cnf结尾的文件。这是一个极其强大的功能也是现代 MySQL 配置管理的基石。为什么需要它想象一下你在一个企业环境中需要为不同的业务线部署 MySQL。A 业务线要求开启审计日志B 业务线要求禁用查询缓存C 业务线要求使用特定的字符集。如果所有配置都堆在/etc/my.cnf里每次修改都得小心翼翼地 diff生怕删掉别人加的行。而有了!includedir你可以这样做/etc/my.cnf.d/audit.cnf专门放审计相关的配置。/etc/my.cnf.d/query_cache.cnf专门放查询缓存相关的配置。/etc/my.cnf.d/charset.cnf专门放字符集相关的配置。实操要点与陷阱加载顺序即覆盖顺序mysqld按文件名排序加载00-base.cnf会先于99-custom.cnf加载。因此通用的基础配置应放在名字靠前的文件里而具体的、覆盖性的定制配置应放在名字靠后的文件里。如果你在00-base.cnf里写了max_connections 200又在99-custom.cnf里写了max_connections 500那么最终生效的是500。!include与!includedir的区别!include /path/to/file.cnf是加载单个文件而!includedir是加载整个目录。!include更精确!includedir更灵活。两者可以共存。致命陷阱循环引用绝对禁止在a.cnf里写!include b.cnf又在b.cnf里写!include a.cnf。mysqld会陷入无限递归最终耗尽栈空间崩溃报错Segmentation fault (core dumped)。我在一个客户现场就遇到过他们为了“模块化”在common.cnf里!include了security.cnf而security.cnf为了复用又!include了common.cnf结果整个集群的 MySQL 都启不起来。注意!includedir指令本身必须独占一行且前面不能有任何空格。如果写成# !includedir /etc/my.cnf.d前面有空格mysqld会将其视为一条注释从而忽略该指令导致所有.cnf.d/下的配置失效。这是一个极其隐蔽、排查难度极高的错误。3.2 字符集与排序规则从latin1到utf8mb4的血泪史/etc/my.cnf中关于字符集的配置是引发线上事故的“重灾区”。一个典型的、充满迷惑性的配置是[mysqld] character-set-server utf8mb4 collation-server utf8mb4_unicode_ci [client] default-character-set utf8mb4看起来完美无缺对吧但现实是这行配置在 MySQL 5.7 之前会直接导致mysqld启动失败报错Unknown variable default-character-set。因为default-character-set这个参数在旧版本中只存在于[client]段而mysqld进程在解析[client]段时会忽略所有不认识的参数但某些版本的解析器会把它当作错误。正确的、向后兼容的写法是[mysqld] # 服务器默认字符集 character-set-server utf8mb4 # 服务器默认排序规则 collation-server utf8mb4_unicode_ci # 强制客户端连接时使用 utf8mb4 init_connect SET NAMES utf8mb4 # 禁止创建非 utf8mb4 的数据库可选强约束 skip-character-set-client-handshake 1 [client] # 客户端工具默认字符集 default-character-set utf8mb4 [mysql] # mysql 命令行客户端默认字符集 default-character-set utf8mb4关键原理character-set-server和collation-server是mysqld的“全局默认值”它决定了CREATE DATABASE时不指定CHARACTER SET时数据库用什么字符集。init_connect是一个 SQL 语句在每个新连接建立后自动执行。SET NAMES utf8mb4等价于同时执行SET character_set_client utf8mb4; SET character_set_results utf8mb4; SET character_set_connection utf8mb4;确保了连接层面的字符集统一。skip-character-set-client-handshake 1是一个“铁腕政策”它强制mysqld忽略客户端在连接握手时声明的字符集比如 Java 应用的useUnicodetruecharacterEncodingUTF-8一律使用服务器的character-set-server。这能彻底杜绝因客户端乱设字符集导致的乱码但代价是牺牲了灵活性。实测心得我曾在一个电商项目中将init_connect设置为SET NAMES utf8mb4结果发现后台管理系统的某些老报表 SQL 报错。排查发现那些 SQL 里用了CONVERT(... USING latin1)这种硬编码而init_connect的 SQL 在连接建立后立即执行导致latin1的上下文被覆盖。最终解决方案是将init_connect改为一个更精细的存储过程调用根据连接来源如user或host动态决定是否执行SET NAMES。这说明my.cnf里的每一行都不是孤立的它和你的应用代码是深度耦合的。3.3 性能调优的核心战场缓冲池与日志/etc/my.cnf是 MySQL 性能调优的主战场而其中最核心的两个参数就是innodb_buffer_pool_size和innodb_log_file_size。innodb_buffer_pool_size内存的“命脉”这个参数定义了 InnoDB 存储引擎用来缓存数据页和索引页的内存大小。它的设置直接决定了 MySQL 是“飞一般的感觉”还是“硬盘在哭泣”。计算公式经验法则innodb_buffer_pool_size (总物理内存 - 系统预留内存 - 其他服务内存) * 0.75例如一台 32GB 内存的服务器系统和nginx、php-fpm等共需 4GB则32 - 4 28GB28 * 0.75 ≈ 21GB。所以应设置为21G。为什么是 75%因为操作系统本身需要内存做文件系统缓存page cacheInnoDB 的 buffer pool 和 OS 的 page cache 是互补关系而非竞争关系。留出 25% 给 OS能让mysqld进程外的 I/O如日志写入、临时表也保持高效。致命错误设置为100G而物理内存只有 64GB。这会导致系统疯狂使用 swapmysqld进程响应时间从毫秒级飙升到秒级top里看到mysqld的%MEM是 95%但RES常驻内存却只有 40GB剩下的都是 swap性能灾难。innodb_log_file_size事务的“安全气囊”InnoDB 的 redo log重做日志是保证事务 ACID 特性的核心。innodb_log_file_size决定了每个 redo log 文件的大小。计算公式基于写入压力innodb_log_file_size (平均每秒产生的 redo log 字节数) * 60你可以通过SHOW ENGINE INNODB STATUS\G查看Log sequence number和Log flushed up to的差值再除以时间间隔估算出每秒的 redo 量。一个健康的、写入压力适中的系统这个值通常在1MB/s到10MB/s之间所以innodb_log_file_size设为64M到256M是比较常见的。为什么不能太大redo log 太大会导致mysqld在崩溃恢复时需要重放的 log 量巨大恢复时间变长。为什么不能太小redo log 太小会导致mysqld频繁地进行 checkpoint检查点将 buffer pool 中的脏页刷回磁盘这会产生大量随机 I/O严重拖慢写入性能。你会在slow query log里看到大量INSERT语句执行时间异常长但EXPLAIN显示它们根本没有走索引问题就出在这里。实操步骤修改innodb_log_file_size停止mysqldsystemctl stop mysqld备份并删除旧的 redo log 文件mv /var/lib/mysql/ib_logfile* /tmp/修改/etc/my.cnf设置新的innodb_log_file_size 256M启动mysqldsystemctl start mysqldmysqld会自动创建新的、指定大小的ib_logfile0和ib_logfile1。提示innodb_buffer_pool_size的修改是“热加载”的MySQL 5.7可以通过SET GLOBAL innodb_buffer_pool_size 21474836480;动态调整无需重启。但innodb_log_file_size的修改必须重启且必须删除旧文件否则mysqld会拒绝启动并报错InnoDB: Error: log file ib_logfile0 is of different size.4. 实操过程与核心环节实现一次完整的“配置手术”4.1 场景设定为一个高并发 Web 应用定制my.cnf假设我们接手了一个日活百万的新闻聚合 App其 MySQL 数据库正面临以下瓶颈SHOW PROCESSLIST里经常出现大量Sleep状态的连接数量稳定在 300但max_connections设置为 500资源浪费严重。Slow_queries计数器每分钟增长 20long_query_time设为 1 秒但很多SELECT语句执行时间在 0.8 秒左右游走在临界点。Innodb_buffer_pool_wait_free状态变量非零表明 buffer pool 频繁发生等待。我们的目标是通过精细化修改/etc/my.cnf在不增加硬件的前提下将平均响应时间降低 30%并将慢查询率压到每分钟 5 个以下。4.2 分析与诊断从SHOW VARIABLES和SHOW STATUS开始在动手修改前我们必须先“望闻问切”。登录 MySQL执行以下命令-- 查看所有运行时变量重点关注与连接、缓存、日志相关的 SHOW VARIABLES LIKE max_connections; SHOW VARIABLES LIKE wait_timeout; SHOW VARIABLES LIKE interactive_timeout; SHOW VARIABLES LIKE innodb_buffer_pool_size; SHOW VARIABLES LIKE query_cache%; -- 查看当前状态看瓶颈在哪里 SHOW STATUS LIKE Threads_connected; SHOW STATUS LIKE Threads_running; SHOW STATUS LIKE Innodb_buffer_pool_wait_free; SHOW STATUS LIKE Slow_queries; SHOW STATUS LIKE Created_tmp_disk_tables;关键发现max_connections 500但Threads_connected常年在 320 左右说明连接池配置过大连接空闲时间过长。wait_timeout 288008小时interactive_timeout 28800这是默认值但对于一个 Web 应用用户请求结束后连接应该在几秒内就释放而不是挂在那里 8 小时。innodb_buffer_pool_size 2G而服务器有 32G 内存显然太小。query_cache_type ON但Qcache_hits几乎为 0说明查询缓存完全没起作用反而增加了 CPU 开销。4.3 配置修改一份为生产环境量身定制的my.cnf基于以上诊断我们编写/etc/my.cnf的核心修改部分仅展示[mysqld]段[mysqld] # 连接管理 # Web 应用连接生命周期短大幅缩短超时时间快速回收连接 wait_timeout 60 interactive_timeout 60 # 连接池最大连接数根据监控的 Threads_connected 峰值320设置留 20% 余量 max_connections 400 # 启用连接复用减少 TCP 握手开销需应用端支持 skip-name-resolve 1 # 缓存与性能 # 将 buffer pool 提升至 24G占 32G 内存的 75% innodb_buffer_pool_size 24G # 启用 buffer pool 预热避免重启后性能骤降 innodb_buffer_pool_load_at_startup 1 innodb_buffer_pool_dump_at_shutdown 1 # 禁用已过时且低效的查询缓存 query_cache_type 0 query_cache_size 0 # 日志与慢查询 # 将慢查询阈值从 1 秒降到 0.5 秒更早发现问题 long_query_time 0.5 # 启用慢查询日志并记录未使用索引的查询 slow_query_log 1 slow_query_log_file /var/log/mysql/slow.log log_queries_not_using_indexes 1 # 启用 general log 用于短期深度分析生产环境慎用 # general_log 1 # general_log_file /var/log/mysql/general.log # InnoDB 优化 # 使用独立表空间便于单表迁移和恢复 innodb_file_per_table 1 # 提高刷新脏页的频率避免 checkpoint 爆发 innodb_io_capacity 200 innodb_io_capacity_max 400 # 启用自适应哈希索引加速等值查询 innodb_adaptive_hash_index 1 # 禁用双写缓冲如果文件系统是 XFS 或 ext4且开启了 barrier可安全禁用 # innodb_doublewrite 0参数详解与理由wait_timeout 60Web 应用的 HTTP 请求处理完后应用服务器如 Tomcat会将连接归还给连接池。连接池通常会在 30-60 秒内检测并关闭空闲连接。我们将wait_timeout设为 60确保 MySQL 不会比应用服务器更早地杀死连接避免MySQLNonTransientConnectionException: No operations allowed after connection closed这类错误。innodb_buffer_pool_load_at_startup 1这个参数是 MySQL 5.6 引入的。它会让mysqld在启动时自动从上次关机时保存的ib_buffer_pool文件中将热点数据页加载回内存。实测效果惊人一个 24G 的 buffer pool冷启动后 5 分钟内就能达到 90% 的缓存命中率而不用等用户请求慢慢“暖机”。log_queries_not_using_indexes 1这个参数非常有用但它有一个隐藏的坑如果一个SELECT * FROM table WHERE id ?查询id是主键它当然会用索引但log_queries_not_using_indexes会记录所有WHERE条件里没有索引的查询。对于一个有 100 个字段的大表SELECT *本身就会产生巨大的 I/O即使走了索引。所以我们启用它是为了抓出那些SELECT * FROM huge_table WHERE status pending这种典型的、status字段没有索引的慢查询。4.4 验证与上线灰度发布与效果监控配置修改完成后绝不能直接systemctl restart mysqld就完事。必须有一套严谨的验证流程第一步语法与逻辑验证# 检查 my.cnf 语法是否正确 mysqld --defaults-file/etc/my.cnf --verbose --help /dev/null 21 echo OK || echo ERROR # 检查配置是否会被正确加载模拟启动 mysqld --print-defaults # 输出应包含你刚修改的所有参数如 --max_connections400 --innodb_buffer_pool_size25769803776第二步小流量灰度在一个非核心的、流量较低的从库Slave上先应用新配置并重启。使用pt-query-digest工具持续分析该从库的慢查询日志 24 小时。对比灰度前后Slow_queries的数量、Created_tmp_disk_tables的数量、以及Innodb_buffer_pool_wait_free是否归零。第三步全量上线与 A/B 测试在业务低峰期如凌晨 2 点对主库执行滚动重启如果有主从架构先切从库再切主库。上线后立即在 Grafana 上观察核心指标MySQL ConnectionsThreads_connected是否稳定在 300-350不再飙升。MySQL Query LatencyP95 响应时间曲线是否出现明显下探。MySQL Slow Queries每分钟慢查询数量是否从 20 降至 5 以下。实操心得我们曾在一个金融项目中因为忽略了skip-name-resolve 1这个参数导致上线后所有来自内网 DNS 的连接都出现了 1 秒的延迟。原因是mysqld默认会对每个连接的 IP 做反向 DNS 解析PTR记录查询而我们的 DNS 服务器响应很慢。加上wait_timeout 60这 1 秒的延迟被放大了 60 倍造成了严重的连接堆积。这个教训告诉我们my.cnf里的每一行哪怕是一个小小的1都可能成为压垮骆驼的最后一根稻草。5. 常见问题与排查技巧实录那些让你深夜加班的“幽灵错误”5.1 错误ERROR 2002 (HY000): Cant connect to local MySQL server through socket ...这是 MySQL 领域的“头号通缉犯”网络上搜索量常年霸榜。它的真实含义是“客户端找不到 mysqld 进程监听的 Unix Socket 文件”。但它的成因却五花八门。排查树状图ERROR 2002 ├── mysqld 进程根本没在运行 │ ├── systemctl status mysqld → active (exited) 或 failed │ └── journalctl -u mysqld -n 50 → 查看最后 50 行启动日志找 fatal error ├── mysqld 进程在运行但 socket 文件路径不匹配 │ ├── 客户端读取的是 [client] 段的 socket服务端监听的是 [mysqld] 段的 socket │ │ ├── mysql --socket/var/lib/mysql/mysql.sock -u root → 强制指定 │ │ └── cat /etc/my.cnf | grep -A 5 \[client\] → 看 client 段的 socket │ └──
返回列表