MySQL 死锁:产生原因、分析与解决

MySQL 死锁:产生原因、分析与解决 在高并发系统中,数据库死锁是比较常见的问题。 很多开发者第一次遇到死锁时,会认为: 数据库是不是出问题了? 实际上,死锁本身并不意味着 MySQL 出现了故障。对于 InnoDB 来说,死锁是并发事务之间形成循环等待后,由存储引擎主动检测并处理的一种正常机制。 真正需要解决的问题不是简单地“关闭死锁”,而是: 为什么会产生死锁? 哪些 SQL 导致了循环等待? 为什么某个事务被回滚? 如何从根本上减少死锁? 应用程序收到死锁异常后应该怎么处理? 理解这些问题,才能正确处理生产环境中的死锁。 1. 什么是死锁 死锁(Deadlock)是指两个或多个事务互相持有对方需要的锁,同时等待对方释放锁,最终形成循环等待。 例如有两个账户: 账户 1 账户 2 事务 A: 锁住账户 1 ↓ 等待账户 2 事务 B: 锁住账户 2 ↓ 等待账户 1 最终形成: 事务 A → 等待事务 B 持有的锁 事务 B → 等待事务 A 持有的锁 这就是典型的死锁。 需要注意,死锁和锁等待不是一回事。 普通锁等待可能是: 事务 A 持有锁 ↓ 事务 B 等待事务 A 只要事务 A 最终提交或回滚,事务 B 就可以继续执行。...

2023年11月13日 · 5 min · Leanku

Linux 常用命令速查手册

Linux 服务器出现问题时,最重要的不是记住多少命令,而是能否快速找到问题所在。 例如: 服务器突然变慢,应该先检查 CPU 还是内存? 内存占用很高,如何判断是真正的内存不足,还是 Linux 正常使用缓存? 磁盘空间显示已满,但找不到占用空间的大文件,应该怎么办? 服务启动成功,却无法通过外部网络访问,如何定位问题? 某个端口被占用,如何找到对应的进程? 这些都是日常服务器运维中经常遇到的问题。 本文整理了一份 Linux 常用命令速查手册,按照实际排查场景划分,涵盖系统信息、CPU、内存、磁盘、网络、端口、进程和日志等内容。每个部分不仅介绍常用命令,还会说明关键参数和典型排查思路,方便日常查阅。 一、系统基础信息 排查服务器问题时,首先应该了解当前系统的基本情况,包括操作系统版本、内核版本、运行时间和系统负载。 1.1 查看操作系统版本 # 查看发行版信息 cat /etc/os-release # 查看系统内核版本 uname -r # 查看完整内核信息 uname -a # 查看系统架构 uname -m /etc/os-release 可以查看当前 Linux 发行版及版本,例如 Ubuntu、Debian、Rocky Linux 等。 uname -r 主要用于确认当前运行的 Linux 内核版本。 1.2 查看系统运行时间 # 查看系统运行时间和负载 uptime # 查看当前登录用户 who # 查看当前用户及系统负载 w uptime 输出示例: 14:30:01 up 30 days, 2:15, 2 users, load average: 1....

2023年11月03日 · 8 min · Leanku

WebSocket 详解:实时双向通信是如何实现的?

WebSocket 详解:实时双向通信是如何实现的? 前面几篇分别介绍了 TCP/IP、Socket、HTTP 和 HTTPS。 到这里,一个问题自然出现了: HTTP 已经可以完成客户端和服务器之间的通信,为什么还需要 WebSocket? 因为传统 HTTP 的基本模型是: Client │ │ Request ▼ Server │ │ Response ▼ Client 如果服务器想主动通知客户端,就比较麻烦。 例如: 用户收到新消息 订单状态发生变化 股票价格发生变化 游戏状态发生变化 服务器有数据更新,但客户端没有主动发请求。 传统方案只能不断: Client → Server:有新消息吗? Server → Client:没有 Client → Server:有新消息吗? Server → Client:没有 Client → Server:有新消息吗? Server → Client:有 这就是轮询。 WebSocket 的目标就是解决这类问题: Client ⇄ Server 建立连接之后,双方都可以主动发送数据。 RFC 6455 将 WebSocket 定义为一种基于 TCP 的双向通信协议,协议由连接建立握手和数据帧传输两部分组成。 1. WebSocket 到底是什么? WebSocket 是一个应用层通信协议。 它建立在 TCP 之上:...

2023年09月16日 · 7 min · Leanku

HTTPS 详解:TLS 如何保护 HTTP 通信?

HTTPS 详解:TLS 如何保护 HTTP 通信? HTTP 解决的是: 客户端和服务器如何表达请求与响应。 但如果直接使用 HTTP: Client ─────── HTTP ───────> Server 网络上的中间节点理论上可以看到通信内容,甚至可能篡改数据。 例如登录请求: POST /login HTTP/1.1 Content-Type: application/json { "username": "tom", "password": "123456" } 如果通信没有加密,用户名、密码以及响应内容都可能暴露。 因此 Web 中通常使用: HTTPS = HTTP + TLS TLS 位于 HTTP 与底层传输之间,为上层应用提供安全通信能力。 TLS 的目标主要包括: 机密性 完整性 身份认证 TLS 1.3 规范明确将建立安全信道、认证通信对端以及保护应用数据作为核心目标。需要注意的是,TLS 1.3 的 RFC 8446 已被 RFC 9846 更新,因此实际学习和实现时应同时关注最新规范。 1. 为什么需要 HTTPS? 先看一个最简单的 HTTP 请求: Client │ │ HTTP │ username=tom │ password=123456 ▼ Server 假设客户端与服务器之间经过:...

2023年09月10日 · 6 min · Leanku

MySQL 常用优化方法

MySQL 常用优化方法 MySQL 性能优化不能简单理解为“加索引”。SQL、索引、数据量、执行计划、表结构以及业务访问方式都会影响最终性能。 下面整理一些实际开发中比较常用的 MySQL 优化方法。 1. 使用 EXPLAIN 分析 SQL 分析慢 SQL 时,首先应该查看执行计划: EXPLAIN SELECT * FROM orders WHERE user_id = 10001 AND status = 1 ORDER BY created_at DESC LIMIT 20; 重点关注: 字段 说明 type 表的访问方式,如 const、ref、range、ALL possible_keys 可能使用的索引 key 实际使用的索引 key_len 实际使用的索引长度 rows 优化器估算需要扫描的行数 filtered 过滤后的数据比例 Extra 额外执行信息 重点关注: type = ALL rows 很大 key = NULL Using filesort Using temporary 但这些结果并不代表一定有问题,需要结合实际数据量和执行时间判断。 MySQL 8.x 还可以使用: EXPLAIN ANALYZE SELECT ....

2023年09月03日 · 4 min · Leanku

Redis的数据类型及使用场景

Redis的数据类型及使用场景 一、基本数据类型 1.字符串(String) string 是 redis 最基本的类型,你可以理解成与 Memcached 一模一样的类型,一个 key 对应一个 value。 string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如 jpg 图片或者序列化的对象。 string 类型是 Redis 最基本的数据类型,string 类型的值最大能存储 512MB。 常用命令: SET key value 设置指定 key 的值。 GET key 获取指定 key 的值。 应用场景: String 是最常用的一种数据类型,普通的 key/value 存储都可以归为此类,即可以完全实现目前 Memcached 的功能,并且效率更高。还可以享受 Redis 的定时持久化,操作日志及 Replication 等功能。除了提供与 Memcached 一样的 get、set、incr、decr 等操作外,Redis 还提供了下面一些操作: 获取字符串长度 往字符串 append 内容 设置和获取字符串的某一段内容 设置及获取字符串的某一位(bit) 批量设置一系列字符串的内容 使用场景: 常规 key-value 缓存应用。常规计数:微博数,粉丝数。 实现方式: String 在 redis 内部存储默认就是一个字符串,被 redisObject 所引用,当遇到 incr,decr 等操作时会转成数值型进行计算,此时 redisObject 的 encoding 字段为 int...

2023年09月01日 · 7 min · Leanku

SQL语法速成

SQL语法速成 SQL 语法结构 子句 - 是语句和查询的组成成分。(在某些情况下,这些都是可选的。) 表达式 - 可以产生任何标量值,或由列和行的数据库表 谓词 - 给需要评估的 SQL 三值逻辑(3VL)(true/false/unknown)或布尔真值指定条件,并限制语句和查询的效果,或改变程序流程。 查询 - 基于特定条件检索数据。这是 SQL 的一个重要组成部分。 语句 - 可以持久地影响纲要和数据,也可以控制数据库事务、程序流程、连接、会话或诊断。 SQL 语法要点 SQL 语句不区分大小写,但是数据库表名、列名和值是否区分,依赖于具体的 DBMS 以及配置。 例如:SELECT 与 select 、Select 是相同的。 多条 SQL 语句必须以分号 ; 分隔。 处理 SQL 语句时,所有空格都被忽略。SQL 语句可以写成一行,也可以分写为多行。 SQL 支持三种注释 ## 注释1 -- 注释2 /* 注释3 */ 增删改查,又称为 CRUD,数据库基本操作中的基本操作。 插入数据 INSERT INTO 语句用于向表中插入新记录。 插入完整的行 INSERT INTO user VALUES (10, 'root', 'root', '[email protected]'); 插入行的一部分 INSERT INTO user(username, password, email)VALUES ('admin', 'admin', 'xxxx@163....

2023年09月01日 · 2 min · Leanku

MySQL EXPLAIN 妙用:执行计划分析与优化技巧

MySQL EXPLAIN 妙用:执行计划分析与优化技巧 在 MySQL 开发中,遇到 SQL 执行缓慢时,最常用的分析工具之一就是 EXPLAIN。 它可以帮助我们回答几个关键问题: MySQL 使用了哪个索引? SQL 是全表扫描还是索引扫描? 预计扫描多少行? 多表 JOIN 的执行顺序是什么? 是否发生了额外排序或临时表? 优化器的估算是否准确? MySQL 8.x 还提供了 EXPLAIN ANALYZE,可以进一步查看实际执行情况。 官方文档:MySQL EXPLAIN 官方文档 一、EXPLAIN 基本用法 最简单的使用方式: EXPLAIN SELECT * FROM users WHERE id = 10001; 也可以分析复杂 SQL: EXPLAIN SELECT o.id, o.amount, u.name FROM orders o JOIN users u ON u.id = o.user_id WHERE o.status = 1 ORDER BY o.created_at DESC LIMIT 20; 常见输出: +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+ | 1 | SIMPLE | users | const| PRIMARY | PRIMARY | 8 | const | 1 | | +----+-------------+-------+------+---------------+---------+---------+-------+------+-------------+ 实际分析时,不需要一开始记住所有字段,重点关注以下列:...

2023年09月01日 · 4 min · Leanku

MySQL JOIN 原理与优化

MySQL JOIN 原理与优化 JOIN 是关系型数据库中最常见的操作之一。用户、订单、商品、文章、评论等业务数据通常分散在不同表中,查询时再通过关联关系组合起来。 例如: SELECT o.id, o.order_no, u.username FROM orders o JOIN users u ON u.id = o.user_id WHERE o.status = 1; 这条 SQL 看起来很简单,但 MySQL 实际需要解决几个问题: 使用哪张表作为驱动表? ↓ 如何找到另一张表对应的数据? ↓ 是否能够使用索引? ↓ 需要扫描多少行? ↓ 最终执行成本是多少? 因此,JOIN 优化并不是简单地“少 JOIN 几张表”,真正重要的是理解 JOIN 的执行方式、数据访问路径以及索引设计。 1. JOIN 的基本原理 假设有两张表: users +----+----------+ | id | username | +----+----------+ | 1 | Alice | | 2 | Bob | | 3 | Tom | +----+----------+ orders +----+---------+---------+ | id | user_id | amount | +----+---------+---------+ | 1 | 1 | 100....

2023年08月04日 · 6 min · Leanku

MySQL Schema 设计与管理

MySQL Schema 设计与管理 数据库 Schema 是应用系统数据模型的基础。一个设计合理的 Schema,可以让业务开发更加简单,也能降低查询性能问题、数据不一致以及后期数据库迁移的成本。 Schema 设计并不只是“建几张表、加几个字段”,而是需要综合考虑 业务模型、数据类型、约束、索引、数据增长、查询方式以及后续变更。 本文从实际项目出发,介绍 MySQL Schema 的设计方法、管理方法,并通过一个简单的业务案例说明如何从业务模型逐步设计数据库。 1. 什么是 MySQL Schema 在 MySQL 中,Schema 通常可以理解为数据库本身,例如: CREATE DATABASE user CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci; 然后在 Schema 中创建表: user ├── users ├── roles ├── permissions ├── user_roles └── audit_logs 在实际项目中,我们通常会同时讨论两个层面的设计: Schema 级设计:字符集、排序规则、数据库命名等 Table 级设计:表结构、字段、约束、索引、关联关系等 因此,Schema 设计本质上是在设计整个数据模型。 一个好的数据库设计通常需要解决几个问题: 业务数据如何存储? ↓ 表与表之间是什么关系? ↓ 字段应该使用什么类型? ↓ 哪些数据必须保证唯一? ↓ 哪些查询需要索引? ↓ 数据量增长后怎么办? ↓ 数据库结构如何持续演进? 2. Schema 设计的基本方法 数据库设计不要从“我要建哪些表”开始,而应该从业务模型开始。 例如一个简单的项目管理系统:...

2023年08月03日 · 5 min · Leanku