ARTICLE DETAIL

资讯详情

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

MySQL常用命令大全:2026最新版实践指南

MySQL常用命令大全:2026最新版实践指南 干开发和运维这些年MySQL的命令来来回回就那么几句话但真到了线上出问题的时候很多人连下一步查什么都不知道。拿着这份“MySQL常用命令大全2026最新版”你完全可以当字典用从安装启动、库表操作、增删改查到用户权限、备份恢复、性能排查每一段都是按真实工作流排的命令后面还写了为什么要这么用、踩过哪些坑。内容以 MySQL 8.0/8.4 为主老版本的关键差异我会顺手标出来。适合三类人刚接触 MySQL 的新手照着敲就行被慢查询、死锁、连接数问题折腾过几次的运维还有需要给团队写操作规范、做培训的同学。命令不难难的是知道在什么场景用哪一条以及用的时候别踩到哪些隐藏坑。以下都是我实际验证过、删掉演示数据后的精简版。1. 环境准备与连接装完先做这几件事1.1 安装与启动不同系统的服务管理命令先说安装。现在 MySQL 8.0 以后的安装已经比 5.7 时代省心多了但不同平台还是有点差异。Debian/Ubuntu 系一般是一条 apt 命令搞定RHEL/CentOS 系用 dnf 或 yum包名注意区分 mysql-server 和 mysqld。# Debian / Ubuntu apt install mysql-server systemctl enable --now mysql # RHEL / CentOS 9 / Rocky dnf install mysql-server systemctl enable --now mysqld # Docker 方式开发环境最省事 docker run -d --name mysql8 \ -e MYSQL_ROOT_PASSWORD你的密码 \ -p 3306:3306 mysql:8.0 docker exec -it mysql8 mysql -uroot -p启动后第一件事不是急着登录而是先确认服务状态。用systemctl status mysqld看进程用journalctl -u mysqld -n 50看最近日志。刚安装完的 root 密码是随机生成的临时密码默认在错误日志里很多新手卡在这一步grep temporary password /var/log/mysqld.log拿到临时密码后登录再执行ALTER USER rootlocalhost IDENTIFIED BY 新密码;改成自己的密码。装完建议顺手跑一遍mysql_secure_installation把匿名用户、默认 test 库、root 远程登录这些问题一次性清理掉尤其在生产环境别跳过。1.2 登录连接与基础信息查看登录命令看着简单但实际踩坑极多。最标准的姿势mysql -h 127.0.0.1 -P 3306 -u root -p这里强调两点第一-h不要写 localhost因为 localhost 在 MySQL 语义里走的是 socket会跳过 TCP 权限校验某些场景下和-h 127.0.0.1的权限匹配结果完全不同。第二命令行里直接带密码mysql -uroot -p123456虽然方便却会被 shell 历史记录和监控工具留下明文不建议在生产这样干。我平时更推荐用mysql_config_editor把登录信息加密存起来mysql_config_editor set --login-pathroot --host127.0.0.1 --userroot --password mysql --login-pathroot -e SELECT VERSION();这样密码保存在~/.mylogin.cnf里别人看不到明文命令行也不带密码。登录进去以后最常用的几条查看命令SELECT VERSION(); SELECT CURRENT_USER(), DATABASE(); SHOW VARIABLES LIKE version_comment;再提一个很多人被坑过的 SSL 问题。MySQL 8.0 默认开启 SSL一些老版本驱动或特殊网络环境下会报 SSL 连接错误。临时排查可以这样mysql --ssl-modeDISABLED -uroot -p服务端如果想彻底关掉 SSL在 my.cnf 的[mysqld]段加一行skip_ssl重启后生效。不建议生产长期关闭这里只说是排查手段。2. 库与表管理建库、建表、改表结构的高频命令2.1 数据库级操作字符集选择是关键数据库级的命令就那几条但字符集选错会引发一堆后患。建库时一定要把utf8mb4写进去因为 8.0 之前默认的utf8不是真正的四字节 UTF-8emoji 和生僻字存进去直接报错。SHOW DATABASES; USE shop; CREATE DATABASE IF NOT EXISTS shop DEFAULT CHARACTER SET utf8mb4 DEFAULT COLLATE utf8mb4_0900_ai_ci; ALTER DATABASE shop CHARACTER SET utf8mb4;utf8mb4_0900_ai_ci是 8.0 的默认排序规则比老版的utf8mb4_general_ci排序更准确也更接近语言习惯。如果是 5.7 老库迁移上来字符集规则会不一样但整理库的排序规则属于另一个话题这里只需要记住新库一律 utf8mb4。需要整库删除的场景极少但一旦执行就是不可逆操作DROP DATABASE shop;生产环境执行前我习惯先把库名打印一遍确认或者干脆用mysqldump备份完再删别图快。2.2 建表与字段修改DEFAULT 0 和日期转换的实际用法建表是一个高频且细节极多的场景。看这个比较完整的例子CREATE TABLE orders ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, order_no VARCHAR(32) NOT NULL, customer_id INT UNSIGNED NOT NULL DEFAULT 0, status TINYINT NOT NULL DEFAULT 0, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_order_no (order_no) ) ENGINEInnoDB;注意几个细节customer_id和status都设了DEFAULT 0这是很常见的默认值需求。很多从 Excel 转过来的同学会问“MySQL 怎么设置默认值为 0”答案就是在字段定义后加DEFAULT 0。表创建之后想补上默认值用ALTER TABLE orders ALTER COLUMN status SET DEFAULT 0;再说“把字符串转为日期”。日常业务里前端传过来或从 Excel 导入的经常是2026-09-01 10:30:00这种字符串直接丢进 DATETIME 列会引发隐式转换的坑。标准做法是SELECT STR_TO_DATE(2026-09-01 10:30:00, %Y-%m-%d %H:%i:%s); -- 实际查询里配合使用 SELECT * FROM orders WHERE created_at STR_TO_DATE(2026-09-01, %Y-%m-%d);反向格式化用DATE_FORMAT(created_at, %Y-%m-%d)很多报表场景就是靠这两个函数在字符串和日期之间来回倒。表结构查看和修改也是高频操作DESC orders; SHOW CREATE TABLE orders\G ALTER TABLE orders ADD COLUMN remark VARCHAR(255) NULL COMMENT 备注; ALTER TABLE orders MODIFY COLUMN remark VARCHAR(500); ALTER TABLE orders DROP COLUMN remark; ALTER TABLE orders RENAME TO trade_orders;MODIFY COLUMN有个大坑它会覆盖整列定义。比如原来status TINYINT NOT NULL DEFAULT 0你只想改注释写成MODIFY COLUMN status TINYINT结果 NOT NULL 和 DEFAULT 全没了。修改一定要把原属性完整带上。另外MySQL 8.0 支持ALGORITHMINSTANT加列可以秒级完成大表加列时建议写成ALTER TABLE orders ADD COLUMN biz_id INT DEFAULT 0, ALGORITHMINSTANT;这个语法能避免大表 DDL 长时间锁表2026 年的运维手册里已经属于基本操作了。3. 数据增删改查DML 高频命令与实战坑3.1 SELECT 查询条件、排序、分页的正确写法查询命令的占比在日常工作中是最高的但写错的地方也最多。基础样板SELECT order_no, customer_id, status, created_at FROM orders WHERE customer_id 2001 AND status IN (0, 1) ORDER BY created_at DESC, id DESC LIMIT 20 OFFSET 0;这里ORDER BY created_at DESC, id DESC是很多人忽视的稳定排序细节。如果同一秒内有多条记录只按created_at排序MySQL 返回的顺序不保证稳定分页就会出现重复和漏数据。加上主键或唯一字段作为第二排序条件是分页场景的保底写法。分页超过一定深度要避免直接LIMIT 1000000, 20。MySQL 会扫描前面一百万行再丢弃代价极高。办法是用“延迟关联”SELECT o.* FROM orders o JOIN ( SELECT id FROM orders ORDER BY id DESC LIMIT 1000000, 20 ) tmp ON o.id tmp.id;子查询只查主键走索引极快再回表取出全行数据。关于LIKE前缀不带通配符可以用索引WHERE order_no LIKE A1000%。但LIKE %1000和LIKE %1000%都会让索引失效数据量大时是全表扫描的开始。3.2 INSERT、UPDATE、DELETE 和事务边界插入数据最常用的三种写法INSERT INTO orders (order_no, customer_id) VALUES (A10001, 2001); INSERT INTO orders SET order_no A10002, customer_id 2002; INSERT INTO orders (order_no, customer_id) VALUES (A10003, 2003), (A10004, 2004) ON DUPLICATE KEY UPDATE customer_id customer_id 1;需要注意 MySQL 8.0.20 之后ON DUPLICATE KEY UPDATE里不再推荐使用VALUES()函数而是改成行别名语法INSERT INTO orders (order_no, customer_id) VALUES (A10005, 2005) AS new ON DUPLICATE KEY UPDATE customer_id new.customer_id;这个变化不算大但如果你在网上搜到很多老文章仍写VALUES()别直接抄8.0.20 以上会给出 deprecation 警告。更新和删除核心原则就一句话WHERE条件必须明确没有条件的大范围操作在生产里就是事故来源。UPDATE orders SET status 1 WHERE order_no A10001; DELETE FROM orders WHERE order_no A10002; TRUNCATE TABLE orders; -- 清空全表速度快但不可恢复TRUNCATE和DELETE不一样DELETE走事务可以回滚TRUNCATE直接重建表速度极快但没有后悔药。平时清测试数据可以生产慎用。多行操作要保证原子性就得用事务START TRANSACTION; UPDATE account SET balance balance - 100 WHERE id 1; UPDATE account SET balance balance 100 WHERE id 2; COMMIT; -- 出错时执行 ROLLBACK;事务里最容易忽略的是 DDL 会隐式提交。执行START TRANSACTION后再跑ALTER TABLE前面做的 DML 直接就被提交了。这也是为什么线上变更总强调“先备份、后操作、分批执行”。4. 排序、分组与窗口函数8.0 时代的高效写法4.1 排序与分组ONLY_FULL_GROUP_BY 的坑分组统计的常见写法SELECT status, COUNT(*) AS cnt FROM orders GROUP BY status HAVING cnt 0 ORDER BY cnt DESC;HAVING用在分组后过滤WHERE用在分组前过滤两者执行顺序完全不同这是面试常问、实际也常错的地方。另一个高频报错是 ONLY_FULL_GROUP_BY在 MySQL 5.7 和 8.0 默认开启的sql_mode下下面这种查询会直接报错SELECT name, department_id, COUNT(*) FROM employees GROUP BY department_id;报错信息大概会提示 “which isnt in GROUP BY”。这不是 MySQL 出 bug而是 SQL 标准要求SELECT 里出现的非聚合列必须出现在 GROUP BY 里。解决办法有三类-- 方案一把字段加进 GROUP BY SELECT name, department_id, COUNT(*) FROM employees GROUP BY name, department_id; -- 方案二聚合非分组字段 SELECT department_id, GROUP_CONCAT(name) FROM employees GROUP BY department_id; -- 方案三用查询解决先分组再关联原表 SELECT e.name, t.department_id, t.cnt FROM employees e JOIN ( SELECT department_id, COUNT(*) cnt FROM employees GROUP BY department_id ) t ON e.department_id t.department_id;直接改sql_mode去掉 ONLY_FULL_GROUP_BY 是最后手段不是首选。你要知道这个模式存在的意义就是防止写出歧义 SQL把语义搞明白比关掉保护机制强得多。4.2 窗口函数与 CTE替代复杂子查询的利器MySQL 8.0 开始支持窗口函数这让很多“取每组前三条”“算累计值”的 SQL 写法完全变样。最典型的 TopN 需求SELECT * FROM ( SELECT e.*, ROW_NUMBER() OVER(PARTITION BY department_id ORDER BY salary DESC) AS rn FROM employees e ) t WHERE rn 3;ROW_NUMBER()按部门分组、按工资排序编号外层过滤前 3 名。这种写法比老版本用自连接或临时表要直观得多。需要同排名并列时用RANK()或DENSE_RANK()区别在于并列之后是否跳号。CTE公用表表达式也是 8.0 的常用能力WITH dept_avg AS ( SELECT department_id, AVG(salary) AS avg_sal FROM employees GROUP BY department_id ) SELECT e.name, e.salary, d.avg_sal FROM employees e JOIN dept_avg d ON e.department_id d.department_id;把子查询独立命名后主查询保留可读性多层嵌套的时候尤其好用。哪怕是最基础的场景用 CTE 都比层层嵌套的子查询好维护写 2026 年代码这个习惯值得养成。5. 用户与权限MySQL 8.0 的授权逻辑变了5.1 创建用户、授权、回收权限MySQL 8.0 和 5.7 在用户管理上有个关键区别8.0 里GRANT不再隐式创建用户必须先用CREATE USER建号。也就是说以前那种一条GRANT ALL ON db.* TO user%就完事的时代结束了。CREATE USER app192.168.10.% IDENTIFIED BY StrongPass123; GRANT SELECT, INSERT, UPDATE, DELETE ON shop.* TO app192.168.10.%; GRANT ALL PRIVILEGES ON shop.* TO dba% WITH GRANT OPTION; SHOW GRANTS FOR app192.168.10.%; REVOKE DELETE ON shop.* FROM app192.168.10.%; DROP USER old_user%;host 部分要特别留意。app%和applocalhost是两个完全独立的账号。只创建了app%在 MySQL 本机用mysql -uapp -p登录时走了 localhost socket反而可能匹配不到账号报 Access denied。权限匹配的顺序是先看更具体的 host再看通配。所以删号或改密前先确认当前连接来源用的到底是哪个 host。工作里我习惯把账号分成几类应用账号只授业务库的 DML 权限运维账号按需授 DDL备份账号只授 SELECT、LOCK TABLES、SHOW VIEW、TRIGGER 等备份必需权限。权限最小化这跟开发里的“最小权限原则”是一回事。5.2 修改密码、认证插件与忘记 root 密码改密码用ALTER USER可以设置过期策略ALTER USER app192.168.10.% IDENTIFIED BY NewPass456; ALTER USER app192.168.10.% PASSWORD EXPIRE INTERVAL 90 DAY;8.0 默认认证插件是caching_sha2_password好处是安全性更高坏处是太老的客户端和驱动不认。如果你接的是老版本 JDBC、PHP 扩展或其他旧工具连接会报认证失败或 SSL 相关错误。短期兼容办法是把账号切回老插件ALTER USER app192.168.10.% IDENTIFIED WITH mysql_native_password BY NewPass456;但注意MySQL 8.4 开始默认禁用了mysql_native_password如果确实是老驱动场景需要先在配置里显式开启。长期解决方案还是升级驱动。忘记 root 密码是每个人都会遇到的场景步骤记住就好systemctl stop mysqld mysqld_safe --skip-grant-tables --skip-networking mysql -uroot进入后执行FLUSH PRIVILEGES; ALTER USER rootlocalhost IDENTIFIED BY NewStrongPass;然后退出重启服务。关键点在启动参数里的--skip-networking它保证只有本机可以连避免空密码状态下被外部访问。改完密码立刻重启别让 MySQL 一直裸奔在跳过权限校验的状态。6. 备份、恢复与数据迁移这几条命令是救命稻草6.1 mysqldump 逻辑备份与恢复逻辑备份最常用的工具还是mysqldump。先说最稳的日常单库备份命令mysqldump -uroot -p --single-transaction \ --routines --triggers --events \ --default-character-setutf8mb4 \ shop /backup/shop_$(date %F).sql--single-transaction是在 InnoDB 下用一致性快照做备份不加它备份过程会锁表线上业务直接受影响。--routines备份存储过程和函数--triggers备份触发器--events备份定时任务这三样经常被漏掉导致恢复后只有表结构没有存储过程。全库备份和恢复# 全库备份 mysqldump -uroot -p --all-databases --set-gtid-purgedOFF /backup/all.sql # 恢复单库先建库再导入 mysql -uroot -p -e CREATE DATABASE shop DEFAULT CHARACTER SET utf8mb4; mysql -uroot -p shop /backup/shop_2026-09-01.sql # 进入 MySQL 后也可以 source mysql -uroot -p SOURCE /backup/shop_2026-09-01.sql;--set-gtid-purgedOFF在启用 GTID 的环境里导入备份时经常用到否则会因为事务 ID 冲突被拒绝。但如果你的目标环境就是用于从库重建那要保留 GTID 信息一条命令两种场景理解含义再决定。生产大库不建议直接mysqldump一波流可以加gzip压缩mysqldump -uroot -p --single-transaction shop | gzip /backup/shop_$(date %F).sql.gz gunzip -c /backup/shop_2026-09-01.sql.gz | mysql -uroot -p shop6.2 文件导入导出与 secure_file_priv 限制除了逻辑导出还有常见的 CSV 文件导入导出SELECT order_no, customer_id, status INTO OUTFILE /tmp/orders_export.csv FIELDS TERMINATED BY , OPTIONALLY ENCLOSED BY FROM orders; LOAD DATA INFILE /tmp/orders_export.csv INTO TABLE orders FIELDS TERMINATED BY , OPTIONALLY ENCLOSED BY ;LOAD DATA INFILE导入速度远快于逐条 INSERT数据量大的时候你会感谢它。但先要检查一个系统变量SHOW VARIABLES LIKE secure_file_priv;secure_file_priv为 NULL 时导入导出功能直接禁用为具体目录时只能操作该目录下的文件为空字符串表示不限制。很多同学执行INTO OUTFILE一直报错八成是没看这个参数。导出到指定目录后注意文件属主和权限避免写入不了或别人可读。7. 索引与查询优化EXPLAIN 和慢查询是核心工具7.1 索引的创建、查看与删除索引是查询性能的分水岭。常用命令SHOW INDEX FROM orders; CREATE INDEX idx_order_no ON orders(order_no); CREATE INDEX idx_customer_created ON orders(customer_id, created_at); ALTER TABLE orders ADD KEY idx_status(status); DROP INDEX idx_order_no ON orders;复合索引要理解“最左前缀”原则。idx_customer_created(customer_id, created_at)能同时支持WHERE customer_id ?和WHERE customer_id ? ORDER BY created_at但如果条件是WHERE created_at ?这个索引就帮不上忙了。建索引之前用 EXPLAIN 验证是最靠谱的方式别凭感觉建。还有个常见问题是冗余索引。有了(customer_id, created_at)之后再单独建(customer_id)前者已经覆盖后者后者就是浪费写入成本。清理冗余索引靠sys.schema_unused_indexes这类视图可以发现但先小表验证再删别在慢查询刚解决完的索引上动刀。7.2 EXPLAIN 与慢查询定位EXPLAIN 是分析 SQL 执行计划的第一工具。写法EXPLAIN SELECT * FROM orders WHERE customer_id 2001 ORDER BY created_at DESC LIMIT 20\G输出里的type字段从好到差大致是system/const→eq_ref→ref→range→index→ALL。看到ALL就是全表扫描量级一大就要警惕。Extra里出现Using filesort或Using temporary说明 SQL 触发了外部排序或临时表优化空间很大。MySQL 8.0.18 以后可以直接用EXPLAIN ANALYZE拿到真实执行耗时和返回行数EXPLAIN ANALYZE SELECT * FROM orders WHERE customer_id 2001 LIMIT 20\G它不只做预估而是真的去执行这条 SQL。对大表谨慎使用别在生产高峰期直接对超大查询跑 ANALYZE。慢查询日志定位具体 SQLSET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 1; SET GLOBAL log_output TABLE; SELECT * FROM mysql.slow_log ORDER BY start_time DESC LIMIT 5;把long_query_time设成 1表示超过 1 秒的 SQL 都会被记录。我把log_output设为TABLE方便直接 SQL 查询不用去翻文件。生产环境建议长期开启代价很低收益很高。真实环境里慢日志是最直接的优化入口先找 rows_examined 大的再看执行计划最后改索引或改 SQL按这个顺序来基本不会错。8. 事务、锁与并发问题线上卡顿怎么查8.1 隔离级别查看与事务控制并发越高锁的问题越突出。先确认当前隔离级别SELECT transaction_isolation; SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;MySQL 8.0 默认是REPEATABLE READ这也是 InnoDB 默认。事务控制命令在前面已经写过这里补充一下 SAVEPOINT 的用法适合大批量操作需要部分回滚的场景START TRANSACTION; UPDATE account SET balance balance - 100 WHERE id 1; SAVEPOINT sp1; UPDATE account SET balance balance 100 WHERE id 2; -- 发现第二句有问题 ROLLBACK TO sp1; COMMIT;注意ROLLBACK TO sp1只回滚到保存点不会结束事务最终还要手动COMMIT或ROLLBACK。这个命令日常用得不多但处理复杂批量任务时很救急。8.2 查看连接、杀掉长事务、定位锁等待线上突然卡顿第一反应是看当前连接SHOW FULL PROCESSLIST; SELECT id, user, host, db, command, time, state, info FROM information_schema.processlist WHERE command Sleep AND time 60;time字段是连接已持续秒数。看到大量Sleep可能只是连接池空闲不用紧张看到长时间Query或Waiting for table metadata lock就要关注了。杀线程用KILL 12345;一次杀掉所有超过 300 秒的非 Sleep 连接可以拼出来执行SELECT CONCAT(KILL , id, ;) FROM information_schema.processlist WHERE command Sleep AND time 300;锁等待定位最常用的三张表SELECT * FROM information_schema.innodb_trx WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) 60\G SELECT * FROM performance_schema.data_lock_waits\G SELECT * FROM performance_schema.data_locks\Ginnodb_trx能看到没提交的长事务data_lock_waits能看谁在等谁。经典处理流程先查长事务确认业务是否能释放再查锁等待链定位阻塞源最后 kill 掉阻塞方或让业务方提交事务。死锁信息另有专门入口SHOW ENGINE INNODB STATUS\G重点看LATEST DETECTED DEADLOCK段里面有死锁 SQL 和持有/等待的锁信息。预防死锁的常规手段多个表更新顺序保持一致、事务尽量短小、隔离级别能接受就降到READ COMMITTED、为高频更新行设计更合理的索引。9. 日常监控与状态巡检每天花两分钟看这几个数9.1 状态变量与性能参数不要等到出故障才去看 MysQL日常巡检其实就几条命令。连接数和负载是最先要看的SHOW GLOBAL STATUS LIKE Threads_connected; SHOW GLOBAL STATUS LIKE Max_used_connections; SHOW VARIABLES LIKE max_connections;Threads_connected是当前连接数max_connections是上限。如果当前连接数经常顶到上限业务侧大概率存在连接泄漏。Max_used_connections是历史最高连接数观察它和上限的差距能预计什么时候会出问题。其他几个常用状态SHOW GLOBAL STATUS LIKE Uptime; SHOW GLOBAL STATUS LIKE Slow_queries; SHOW GLOBAL STATUS LIKE Innodb_row_lock_waits; SHOW VARIABLES LIKE %timeout%;Slow_queries累计慢查询数Innodb_row_lock_waits累计行锁等待次数这两个数字增长过快说明 SQL 或事务设计有问题。超时参数比较多wait_timeout、interactive_timeout、lock_wait_timeout各自管一种场景改之前先确认你要解决的是客户端空闲、连接等待还是锁等待。9.2 实时 SQL 分析与性能视图MySQL 自带的 sys 库是性能分析利器几行 SQL 就能看到真实开销最大的语句和表SELECT * FROM sys.statement_analysis ORDER BY rows_examined_avg DESC LIMIT 10; SELECT * FROM sys.schema_table_statistics WHERE table_schema shop ORDER BY total_latency DESC LIMIT 10;sys.statement_analysis能看到平均扫描行数最多、执行次数最多的语句这是优化最直接的入口。schema_table_statistics能发现哪些表访问延迟最高。日常巡检建议固定跑这几条比开一堆监控面板还实用。一条非常有用的组合命令每天上班先跑一遍SHOW GLOBAL STATUS LIKE Threads_connected; SHOW GLOBAL STATUS LIKE Max_used_connections; SHOW GLOBAL STATUS LIKE Slow_queries; SHOW FULL PROCESSLIST;四行输出占不了几秒钟但能让你对 MySQL 当前健康度心里有底。10. 常见问题排查实录2026 年遇到的坑都在这了我把这些年被问得最多、自己也踩过的问题整理成速查表遇到现象直接对照处理问题现象常见原因排查思路与处理命令连不上 MySQL服务未启动、端口被防火墙拦、bind-address 限制systemctl status mysqldss -lntp | grep 3306SHOW VARIABLES LIKE bind_addressAccess deniedhost 匹配错误或密码错误确认连接来源走的是 localhost 还是 TCP检查账号 host 用的是%还是具体 IPToo many connections连接数打满或连接泄漏SHOW VARIABLES LIKE max_connections临时调大SET GLOBAL max_connections500排查连接池SSL 连接错误客户端要求 SSL 但驱动或网络环境不兼容客户端加--ssl-modeDISABLED验证服务端排查skip_ssl优先升级驱动GROUP BY 查询报错ONLY_FULL_GROUP_BY 模式限制把非聚合列加入 GROUP BY或用窗口函数、子查询改写日期字符串比较结果异常字段类型是字符串比较时隐式转换用STR_TO_DATE()显式转换字段类型改为 DATE/DATETIMEmysqldump 卡住或锁表大表备份默认加锁加--single-transaction大实例考虑分库、物理备份方案误删数据UPDATE/DELETE 没带 WHERE 或忘在事务中开启 binlog 后可用SHOW BINARY LOGS;、SHOW BINLOG EVENTS IN ...找原始事件日常备份 binlog 保命这里展开说两个最常见的。第一是“误删数据”怎么办。如果 binlog 开着理论上可以把误操作之前的 binlog 事件重放回来但过程比较繁琐而且依赖binlog_formatROW、binlog_row_imageFULL这些参数。所以我强调日常备份必须做binlog 必须开操作大表数据前先SELECT一遍确认影响行数。第二是“杀不掉线程”。如果KILL之后线程还是存在通常是长事务没有回滚完成要看innodb_trx和锁等待信息直接KILL可能触发大回滚短时间内负担更重需要评估。生产操作还有一个铁律大表 DDL 不要在业务高峰期直接执行。MySQL 8.0 的ALGORITHMINSTANT降低了很多风险但老版本或不能 INSTANT 的变更仍然会锁表。我习惯是把这类操作放在低峰期配合工具或分批次处理。最后再分享一个压箱底的小习惯把登录提示符改成带库名和主机名避免在测试库执行生产 SQL 的惨剧。在~/.my.cnf里写[mysql] prompt\\u\\h [\\d] 改完后每次登录会自动看到当前用户、主机和所在库一眼就知道自己在哪里。命令这东西不需要背全理解每条命令解决什么场景的问题出问题时能想起来“该用哪一把工具”这才是命令大全的意义。
返回列表