ARTICLE DETAIL

资讯详情

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

MySQL运维实战:部署、排障、优化与同步全解析

MySQL运维实战:部署、排障、优化与同步全解析 做后端开发那些年被 MySQL 的安装、启动、连不上、性能崩塌轮流折腾过的次数说实话比工作年限还多。如今再回头看管理 MySQL 的本质早就不是敲几条命令那么简单——你要能把一个新库从 Windows 本地跑起来也能在 Linux 裸机或 Docker 容器里部署整套实例还要能在连接失败、锁等待、主从延迟这种糟心时刻快速定位问题。这篇内容来自我实际跑过的线上线下环境覆盖了 Windows 本机、Linux 裸机、Docker 容器也涉及日常开发高频用到的索引、事务、锁、存储过程再到 Xtrabackup 主从、Flink 同步 ClickHouse、表结构转 TDengine 这类实战场景。无论你是刚入行的小白还是被线上故障折磨过几次的老开发都可以从里面找到能直接拿去用的操作套路和排障思路。1. 新环境部署Windows、Linux、Docker 三个入口都验证过的 MySQL 安装过程1.1 Windows 下 MySQL 8.0 压缩包的安装与初始化Windows 上我基本不用图形安装程序而是直接用 ZIP 解压版。原因很简单安装程序装完会注册服务、写一堆注册表卸载起来很麻烦解压版可以随时换目录、换版本出问题删掉目录就行。下载时去 MySQL 官网的 Community Server 页面选 Windows (x86, 64-bit), ZIP Archive。解压到像D:\mysql-8.0.40-winx64这种尽量不带空格的路径然后新建一个my.ini内容大概是[mysqld] basedirD:/mysql-8.0.40-winx64 datadirD:/mysql-8.0.40-winx64/data port3306 character-set-serverutf8mb4 collation-serverutf8mb4_unicode_ci default-time-zone08:00 [client] default-character-setutf8mb4注意路径里用正斜杠避免转义符问题。配好后用管理员身份打开 CMD进入 bin 目录执行初始化命令mysqld --initialize-insecure --console--initialize-insecure会创建一个空密码的 root 账号data目录也会自动生成。如果你用mysqld --initialize --console则会在控制台或错误日志里生成一个临时随机密码找类似[Note] A temporary password is generated for rootlocalhost:这一行。初始化完成后再安装 Windows 服务mysqld --install MySQL8 net start MySQL8启动成功后执行mysql -uroot -p空密码直接回车然后立刻改密码ALTER USER rootlocalhost IDENTIFIED BY YourPass123;这里最容易踩的坑有三个data目录不要提前手动创建否则初始化可能不成功端口 3306 可能被其他 MySQL 实例或程序占用先netstat -ano | findstr :3306看一眼如果服务启动失败不要反复重启直接去data目录下的.err文件里找真实原因。1.2 Linux 下 RPM 安装 MySQL 5.7 与 8.0 的差异Linux 服务器上我基本都用 RPM 包安装。以 CentOS 7 为例可以配置官方 yum 源也可以直接下载 rpm-bundle 离线装。官方源方式最省事wget https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm rpm -ivh mysql80-community-release-el7-7.noarch.rpm yum install mysql-community-server systemctl start mysqld5.7 和 8.0 安装后都有一个临时密码去日志里找grep temporary password /var/log/mysqld.log拿到临时密码登录后必须改密码而且 5.7 默认有 validate_password 策略密码太简单会直接拒绝。8.0 默认 root 只允许本机登录远程访问要单独创建用户并授权例如CREATE USER app% IDENTIFIED BY AppPass123; GRANT ALL PRIVILEGES ON appdb.* TO app%; FLUSH PRIVILEGES;很多人纠结“mysql 5.7.44 官方为什么之后 5.7.43”这种版本号页面排序的问题其实没什么好纠结的。5.7 系列早就进入维护尾声新环境我不建议再选 5.78.0 是目前绝对的主流8.4 LTS 则适合新平台、新项目。版本选择只看两点现有业务是否强制依赖 5.7 行为以及客户端组件是否能兼容 8.0 的认证插件。1.3 Docker 方式部署与 ARM 架构镜像Docker 部署 MySQL 最大的价值是快。开发环境我会直接用一行命令跑起来docker run -d --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDroot123 \ -v /opt/mysql/data:/var/lib/mysql \ -v /opt/mysql/conf:/etc/mysql/conf.d \ mysql:8.0数据目录和配置目录都挂出来容器重启或删掉重建也不会丢数据。MYSQL_ROOT_PASSWORD只是首次初始化时有效如果已经有数据目录这个变量就不会再生效。ARM 架构是另一个高频坑老版本镜像很多只有 amd64在树莓派或者国产化 ARM 服务器上跑会直接报exec format error。建议选 8.0.31 之后的 multi-arch 镜像或者用docker pull --platform linux/arm64 mysql:8.0指定平台。绿联 NAS、群晖这类设备装 MySQL我也更推荐 Docker 而不是套件中心里的老版本因为套件版本升级太慢端口和数据目录都不好自定义。1.4 安装后的基础验证与目录权限实例起来以后别急着塞业务数据先花两分钟确认几件事mysql -uroot -p能正常登录SHOW VARIABLES LIKE version;确认版本是预期值SHOW DATABASES;确认系统库不缺失Linux 下检查datadir目录属主是否为mysql:mysql权限不对会导致写入 redo log 失败Windows 下确认my.ini位置和 MySQL 启动时读取的路径一致。这些检查很基础但能省掉后面可能出现的“玄学”故障。2. 启动失败与远程连接报错从服务日志到客户端工具的排查链路2.1 net start mysql 服务无法启动的定位过程热词里的“net start mysql 服务无法启动”是我被问过最多次的问题。Windows 服务管理器给你的提示几乎没有任何信息量真正的原因永远在错误日志里。我的排查顺序固定如下打开data目录下主机名.err文件看最后几十行重点找[ERROR]。如果日志显示Failed to open and lock privilege tables说明初始化没成功或data目录权限不对。检查端口netstat -ano | findstr :3306如果端口被其他进程占用服务起不来。检查my.ini中basedir和datadir是否有空格、是否写反斜杠导致解析异常。如果多条 ERROR 反复出现并且含[ERROR] [MY-014060] [Server] invalid mysql server upgrade:多半是有人手动执行了旧版mysql_upgrade或my.cnf里有残留的skip-grant-tables。关于 MY-014060 这个错误我要专门提一句MySQL 8.0 的升级逻辑已经内置到 mysqld 启动流程里不需要你再手动执行mysql_upgrade。遇到这个错误先停止服务、备份data目录把配置里可疑参数去掉再正常启动让 mysqld 自己完成数据字典升级。如果仍然失败就要确认版本是真的 8.0 起步而不是从 5.7 直接把 data 目录整盘拷过来。2.2 SSL 连接错误与 caching_sha2_password 的适配远程客户端报SSL connection error是另一个高频问题。MySQL 8.0 默认开启 SSL但很多内部网络环境并没有配证书客户端一启用 SSL 校验就崩。遇到这类问题我第一步永远是先用一条命令隔离 SSL 因素mysql -h 192.168.1.10 -P 3306 -u root -p --ssl-modeDISABLED能连上说明问题在 SSL 配置连不上则要检查账号 host 是否匹配、密码是否正确。如果业务确实需要 SSL在my.cnf里配置ssl-ca、ssl-cert、ssl-key并保证客户端信任对应 CA。同时要注意 MySQL 8.0 默认认证插件是caching_sha2_password。旧版 Navicat for MySQL、某些老版本 JDBC 驱动会报 1251 错误处理方式有两种升级客户端或者把账号改成mysql_native_passwordALTER USER root% IDENTIFIED WITH mysql_native_password BY Password123;但如果目标版本是 8.4 LTSmysql_native_password可能已经被禁用硬改配置反而起不来。我的建议是新客户端一律支持caching_sha2_password不要为了迁就旧工具而降级认证插件。2.3 Sqoop、ODBC 连接不上的高频原因热词里有“sqoop连接不上mysql”这类问题十有八九是驱动类名和 JDBC URL 参数不对。Sqoop 1.x 时代常用com.mysql.jdbc.Driver但 MySQL 6.0 之后的驱动把包名改成了com.mysql.cj.jdbc.Driver。完整的 JDBC URL 至少要有这三个参数jdbc:mysql://host:3306/db?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrueuseSSLfalse是为了避免证书校验serverTimezone必须明确指定时区allowPublicKeyRetrievaltrue是为了让客户端从服务端获取 RSA 公钥解决caching_sha2_password认证时的公钥获取问题。至于“mysql odbc driver支持mysql8.0和microsoft visual c2015 14.0版本下载”这个热词我单独说明一下MySQL 官方 ODBC 驱动 8.x 是编译依赖 VC 2015-2022 运行库的缺库时最常见的报错是找不到MSVCP140.dll。做客户端部署时先装 Microsoft Visual C Redistributable再装 ODBC 驱动顺序反了会浪费很多时间。2.4 mysql -u -p 执行 SQL 超时的问题怎么查“mysql -u -p 执行sql 超时”这个热词指向的实际是多种超时。我把排查拆成三类连接阶段超时看connect_timeout如果服务器本身负载高或者中间有防火墙会卡在握手阶段。执行阶段超时看innodb_lock_wait_timeoutSQL 在等锁同时执行SHOW PROCESSLIST如果状态是Waiting for table metadata lock或Lock wait timeout exceeded说明有人在改表或未提交事务。返回结果超时看net_read_timeout和net_write_timeout大批量查询结果传输时容易触发。一个很隐蔽的原因是服务器开启了 DNS 反向解析客户端来源是域名而非 IP解析超时会导致整个连接变慢。如果在可信内网建议在my.cnf里加skip-name-resolveON但注意授权表里就不能再使用域名形式的 host。3. 表结构、索引、锁与存储过程日常开发最常触碰的 MySQL 对象管理3.1 修改表结构与误更新后的还原思路开发环境改表结构很随意生产环境就不能拍脑袋。MySQL 8.0 对ADD COLUMN支持了 INSTANT 算法可以只修改元数据而不锁表、不重建表。例如ALTER TABLE t ADD COLUMN status TINYINT NOT NULL DEFAULT 0, ALGORITHMINSTANT;但像修改列类型、修改主键这类操作仍然需要 INPLACE 或 COPY大表执行时会把主库和从库一起拖垮。所以我在线上大表改结构时通常用pt-online-schema-change或gh-ost原理都是通过触发器或临时表把变更分批复制把锁等待降到最低。热词里的“mysql update 还原”我理解成误 UPDATE 后想恢复数据。如果没有备份和 binlog基本只能靠程序日志手工修。正确预防方案是生产环境必须开启 ROW 格式 binlog误操作后用mysqlbinlog把对应时间段的逻辑日志导出再过滤出受影响的行进行回滚。比如mysqlbinlog --start-datetime2024-05-01 08:00:00 --stop-datetime2024-05-01 08:10:00 binlog.000042 replay.sql然后用文本编辑器或脚本把 UPDATE 语句逐条反推成原来的值核对后再导入。这个过程很痛苦所以最理想的还是先备份再上 binlog 做最后的兜底。“设置默认值为0”也是常见操作命令是ALTER TABLE t ALTER COLUMN status SET DEFAULT 0;注意这个操作只影响之后新插入的行历史数据不会自动改写。3.2 索引创建策略与排序优化MySQL 排序慢是所有业务系统的老问题。最常见的场景是ORDER BY导致Using filesort用EXPLAIN一看就现形。EXPLAIN SELECT id, name FROM user WHERE age 20 ORDER BY name LIMIT 10;如果索引只建立在age上age 20能走索引但后面的ORDER BY name还需要额外的排序操作。建立一个联合索引(age, name)就能让排序和过滤同时用索引MySQL 8.0 还支持降序索引CREATE INDEX idx_age_name ON user(age, name DESC);专门消除ORDER BY age ASC, name DESC的 filesort。索引失效的经典场景也要背下来索引列上套函数、隐式类型转换、LIKE 前置百分号、OR 连接非索引列、联合索引不满足最左前缀。排查优化时统一用EXPLAIN重点看type、key、rows、filtered、extra五个字段。3.3 存储过程与错误信息的处理存储过程现在用的场景少了但定时任务、批量脚本、报表计算里还是有价值。我建议不要把复杂业务逻辑塞进存储过程只把它当成一个可控的批处理执行器。处理错误信息的核心是异常 Handler。一个标准的带事务和回滚的存储过程可以这样写DELIMITER $$ CREATE PROCEDURE sp_batch_update() BEGIN DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN ROLLBACK; RESIGNAL; END; START TRANSACTION; UPDATE account SET balance balance - 100 WHERE id 1; UPDATE account SET balance balance 100 WHERE id 2; COMMIT; END$$ DELIMITER ;DECLARE EXIT HANDLER FOR SQLEXCEPTION的意思是一旦事务中任何 SQL 报异常立即回滚并重新抛出错误。没有这个 HandlerMySQL 默认会在部分语句失败后继续执行剩余语句数据错得没边。调试存储过程时最直接的方法是在关键位置加一个SELECT 变量;打印中间值也可以在调用端CALL sp_name;后观察返回的SQLSTATE和错误文本。3.4 事务隔离级别、锁的分类与锁表排查MySQL 默认隔离级别是 REPEATABLE READ这个和其他数据库习惯于 READ COMMITTED 很不一样。事务里普通SELECT走快照读不会加行锁但SELECT ... FOR UPDATE、UPDATE、DELETE走当前读会加 Record Lock、Gap Lock 或 Next-Key Lock具体加哪个取决于索引和扫描范围。锁等待的典型症状是业务超时报Lock wait timeout exceeded。排查命令固定三件套SHOW ENGINE INNODB STATUS; SELECT * FROM sys.innodb_lock_waits; SELECT * FROM performance_schema.metadata_locks WHERE OBJECT_SCHEMAdb;找到阻塞源头后KILL id;可以应急但根因通常是某个事务忘了 COMMIT或者长事务占住大量行锁。我的经验是控制事务时长比什么都重要单事务更新行数不要太多事务内不要调用外部接口大批量更新一定分批提交。死锁不同死锁是互相持有对方要的资源数据库会自动回滚其中一个事务业务端要做的更多是捕获死锁异常并重试。4. 性能调优与连接池不盲目改参数先定位瓶颈在哪里4.1 从慢查询日志和监控指标开始别急着改 buffer性能调优最容易犯的错是上来就抄模板把innodb_buffer_pool_size调到 16G结果机器内存不足直接崩。我的顺序比较固定开启慢查询日志SET global slow_query_logON; SET global long_query_time1;生产环境建议写进my.cnf。收集一段时间慢 SQL用mysqldumpslow或pt-query-digest汇总找出执行次数多、扫描行数大的语句。查看SHOW GLOBAL STATUS里的Threads_connected、Threads_running、Innodb_row_lock_waits判断是并发高还是锁等待多。配合系统层top、iostat区分瓶颈是 CPU、内存还是磁盘 IO。一个简单判断如果Threads_running长期高于 CPU 核心数的两倍以上SQL 堆积严重优先优化慢 SQL如果 IO util 长期 90% 以上再看 IO 层面是否该换 SSD而不是盲目加内存。4.2 常用参数调整参考这些数值不是越大越好下面这张表是我在常规业务服务器上的常用起点具体要看内存、磁盘和访问模型调整参数常见起点说明innodb_buffer_pool_size物理内存的60%~70%InnoDB 数据页缓存要留足 OS 和其他进程内存innodb_log_file_size128M~256Mredo log 太小会导致频繁 checkpointmax_connections峰值连接数 × 1.5不是越大越好过大反而增加线程切换开销wait_timeout依据业务几百到几千秒太小会频繁断开太大浪费连接max_allowed_packet128M~256M避免大数据包写入失败sort_buffer_size1M~2M单会话内存设置过大会累加内存占用skip-name-resolveON内网环境关掉 DNS 反向解析注意 MySQL 8.0 已经把 Query Cache 移除了网上教程让你开 query cache 的可以直接忽略。4.3 连接池配置要点连接数不是越多越好应用侧的连接池和数据库连接数必须一起看。很多“偶发连接失败”的根因不是数据库挂了而是连接池里的连接被 MySQL 的wait_timeout回收了业务拿到的还是旧连接。Druid 的配置是一个很好的参考spring: datasource: druid: url: jdbc:mysql://localhost:3306/app?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: app_user password: xxxxx initial-size: 5 min-idle: 5 max-active: 20 test-on-borrow: true validation-query: SELECT 1这里核心是validation-query每次从连接池拿出连接时先执行SELECT 1校验连接是否可用。如果配了test-on-borrowtrueMySQL 端断开的连接会被及时淘汰。HikariCP 默认会做类似检测但也要在 URL 里加connectionTestQuery的等价设置。max-active建议设置为 MySQLmax_connections的 50%~60%留出 DBA 手工连接、备份连接、其他后台任务的余量。连接数开满不一定是好事每个连接背后都有一个线程线程多了上下文切换更严重。4.4 常见的 SQL 性能病根我把平时排查到的典型 SQL 问题列一下每个都能用 EXPLAIN 验证隐式类型转换字段是 VARCHAR条件传数字导致索引失效。深分页LIMIT 100000, 20需要先扫描 100020 行再丢弃前 100000 行用延迟关联JOIN (SELECT id ... LIMIT 100000, 20) t优化。SELECT *返回大量不需要的列增加网络传输和临时表空间。OR跨两个非索引字段优化器可能放弃索引改用UNION ALL或IN。JOIN 两边字段字符集或排序规则不一致索引无法参与关联。排查 SQL 性能时我会先看rows和filtered是否合理如果type是 ALL 且扫描行数接近表数据量就要重新设计索引或改 SQL。5. 数据备份与同步实战从 Xtrabackup 主从到 Flink/ClickHouse、TDengine5.1 日常备份组合mysqldump 与 Xtrabackup 的选用备份这件事我不建议只依赖一种方式。数据量小、结构简单时用mysqldump做逻辑备份最直观mysqldump --single-transaction --quick --routines --triggers --events --set-gtid-purgedOFF db /backup/db.sql--single-transaction在 InnoDB 下会基于 RR 隔离级别做一致性快照备份期间不锁业务写入。但这个方案到了几百 GB 的大库上就不现实了逻辑导出慢、恢复也慢后面的 SQL 插入一条一条执行时间不可控。大库我强烈推荐 Percona XtraBackup 做物理备份xtrabackup --backup --target-dir/backup/full_20250101 --host127.0.0.1 --userbackup --passwordxxx --parallel4 xtrabackup --prepare --target-dir/backup/full_20250101--backup相当于把数据文件完整复制出来--prepare负责应用 redo log 让备份达到一致状态。恢复时把目录拷到目标实例的 datadirchown 给 mysql 用户然后启动实例即可。5.2 基于 GTID 的 Xtrabackup 备份部署从库热词里“linux 下 xtrabackup 备份mysql主库,部署从库,gtid同步方式”正好是我经常做的操作。传统做法是记录 binlog file 和 position新样式是开 GTID让位点自动对齐。主库需要这样配置server-id 1 log-bin mysql-bin binlog_format ROW gtid_mode ON enforce-gtid-consistency ON log_slave_updates ON然后用 Xtrabackup 做主库全备把备份拷贝到从库并 prepare启动从库实例后执行CHANGE MASTER TO MASTER_HOST主库IP, MASTER_USERrepl, MASTER_PASSWORDrepl_password, MASTER_PORT3306, MASTER_AUTO_POSITION1; START SLAVE; SHOW SLAVE STATUS\G重点看三个字段Slave_IO_Running: Yes、Slave_SQL_Running: Yes、Retrieved_Gtid_Set是否不断增长。用MASTER_AUTO_POSITION1时从库会通过 GTID 自动找到主库的同步位点不用再手工记 binlog 文件位置大幅降低搭建主从时的配置错误概率。5.3 Flink CDC 同步 MySQL 到 ClickHouse 的实践思路“使用flink 实现mysql同步到clickhouse”已经成了实时数仓的标配场景。思路并不复杂Flink CDC 连接器订阅 MySQL binlog把变更事件解析成流再写入 ClickHouse。前提是 MySQL 侧要开启 ROW 格式 binlog并给 Flink 用户授权GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO flinkuser%;Flink SQL 里建源表CREATE TABLE mysql_users ( id INT PRIMARY KEY, name STRING, updated_at TIMESTAMP(3) ) WITH ( connector mysql-cdc, hostname localhost, port 3306, username flinkuser, password xxx, database-name app, table-name users );再建 ClickHouse sink执行INSERT INTO ch_users SELECT ... FROM mysql_users;就能持续同步。如果不想引入 Flink替代方案是 canal 订阅 binlog Kafka 分发 自定义消费者写入。无论用哪种方案生产上都要注意主库 binlog 文件不能过早清理同步任务长时间中断后要能追位点ClickHouse 侧写入要设置合理的flush interval和缓冲大小避免小批次高频写入把 merge 拖慢。5.4 MySQL 表结构自动转 TDengine 超级表加子表TDengine 是时序数据库表模型和 MySQL 差别很大。MySQL 里一张普通业务表到 TDengine 通常要变成一个超级表加多个子表超级表定义表结构子表通过标签区分不同设备或实体。我的做法是从information_schema读取字段元数据写脚本生成 DDL。类型映射大致如下MySQL 类型TDengine 类型INT / INTEGERINTBIGINTBIGINTFLOAT / DOUBLE / DECIMALFLOAT / DOUBLEDATE / DATETIME / TIMESTAMPTIMESTAMPVARCHAR / CHAR / TEXTNCHAR 或 NCHAR(列长)转换时最关键的是确定“时间戳主列”。如果原表没有时间字段就要先补一个ts TIMESTAMP否则 TDengine 建不了超级表。标签列单独挑出来比如device_id、region用来做子表标识和数据过滤。生成的 DDL 形如CREATE DATABASE metrics KEEP 365D DURATION 10D BUFFER 16 WAL_LEVEL 1; CREATE STABLE meters (ts TIMESTAMP, current FLOAT, voltage INT) TAGS (device_id NCHAR(32), region NCHAR(64));插入时用USING meters TAGS (...)INSERT INTO m_device_001 USING meters TAGS (device_001, 华东) VALUES (2024-06-01 10:00:00, 1.2, 220);自动化脚本跑完后MySQL 里一张表就变成了 TDengine 的一个超级表加若干子表查询时按时间范围和标签维度做聚合非常快。这个方案我在设备监控项目里用过手工建超级表太容易漏字段写脚本从information_schema生成 DDL 是最稳的。6. 版本选择与面试高频点不踩版本坑回答才有底气6.1 MySQL 5.7、8.0、8.4 LTS 怎么选热词里有一堆关于 “mysql 5.7.26下载”“mysql 5.7.44 官方为什么之后 5.7.43” 的搜索版本号的页面错觉很容易让人迷惑。我的选型原则很简单老项目还在 5.7 上的暂时能跑别动但心里要有升级到 8.0 的路线图新项目一律 MySQL 8.0这是当前支持最广泛、资料最多、组件兼容最好的版本如果有特定平台要求用 LTS 基线直接选 8.4但一定要提前验证客户端的认证插件兼容性。8.4 和 8.0 最大的管理差异就是默认安全策略更严mysql_native_password默认禁用。如果你在 8.4 上还想用老 Navicat 连接大概率会碰壁。部署前用最新客户端连一次比上线后救火省心得多。6.2 面试中关于 MySQL 管理的高频题怎么答热词里有“mysql面试题”我挑几个最常遇到的说一下回答思路事务隔离级别有哪些MySQL 默认 RR怎么解决幻读回答时讲 MVCC 快照读 当前读的 Next-key Lock 就够。为什么 InnoDB 用 BTree 而不是 Hash因为要支持范围查询和顺序 IOHash 只能等值匹配。redo log 和 binlog 有什么区别redo log 是 InnoDB 崩溃恢复binlog 是逻辑复制和时间点恢复两者记录内容和用途不同。主从延迟怎么排查先看Seconds_Behind_Master再分析大事务、慢 SQL、DDL 操作从库硬件是否拖后腿也要看。锁等待和死锁有什么区别锁等待是排队拿锁死锁是互相等待对方手里的锁数据库会自动回滚其中一个事务。面试时最好带上真实案例比如“我处理过一次锁等待从 processlist 看到Waiting for table metadata lock查 metadata_locks 找到是 DDL 一直没提交kill 后用 pt-online-schema-change 重跑”比背概念有说服力。6.3 常用命令与工具清单最后把每天都会用到的管理命令整理成一张表场景命令/工具看当前线程SHOW PROCESSLIST看表结构DESC tb_name / SHOW CREATE TABLE tb_name看索引SHOW INDEX FROM tb_nameSQL 执行计划EXPLAIN FORMATJSON SELECT ...备份mysqldump / xtrabackup慢查询分析mysqldumpslow / pt-query-digest主从状态SHOW SLAVE STATUS\G锁等待sys.innodb_lock_waits可视化连接Navicat、DBeaver、Jumpserver 内置 MySQL 工具这些命令不是用来背的而是在故障时快速定位的关键入口。用熟了之后很多看起来吓人的报错也就是日志里一行真实原因的事。真要说管理 MySQL 最大的心得我只有八个字先看日志别瞎猜。无论是启动失败、连不上、锁等待还是主从中断error log、processlist、slow log 都会把线索摆在你面前你只需要按顺序查通常十分钟内能定位。另一个小技巧是给每个新实例都建立一个带日期和业务名的备份目录恢复时不用猜哪个备份对应哪一天。希望这篇能让你少走我当年走过的弯路。
返回列表