码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 【完整解决方案】生产实战,数据库发生了死锁


    文章目录

    • 1.什么时候数据库会有死锁
        • 1. 资源争用
        • 2. 长时间持有锁
        • 3. 并发事务
        • 4. 不一致的锁定顺序
        • 示例
          • Transaction 1
          • Transaction 2
        • 避免死锁的方法
    • 2.发生死锁时
        • 自动死锁检测与解决
        • 手动处理
        • 实例
    • 3.如何查看数据库是否存在了死锁
        • MySQL
        • PostgreSQL
        • SQL Server
        • Oracle
    • 4.MySQL错误日志文件在哪看
        • 1. 确定错误日志文件的位置
          • 通过MySQL配置文件(my.cnf 或 my.ini)
          • 通过MySQL命令行
        • 2. 查看错误日志文件
          • 在Linux/MacOS上使用命令行工具
          • 在Windows上使用文本编辑器
        • 3. 示例:检查死锁信息
    • 5.错误文件信息的导出
        • 导出`SHOW ENGINE INNODB STATUS`的信息
          • 使用命令行导出到文件
          • 使用MySQL工作台导出
        • 导出错误日志文件
          • 使用命令行导出错误日志文件
          • 使用文本编辑器打开并保存
        • 通过SFTP或FTP导出到远程服务器
        • 通过脚本自动化导出
    • 6.在生产环境中,如果出现死锁,需要立即采取措施来解除死锁并恢复正常的数据库操作
        • 1. 手动检测和终止死锁事务
          • 1.1 检查死锁信息
          • 1.2 查找并终止事务
        • 2. 监控和自动化处理
          • MySQL
        • 3. 优化数据库和应用程序
        • 4. 定期监控和分析

    1.什么时候数据库会有死锁

    数据库中的死锁通常发生在多个事务同时竞争相同的资源并且相互等待对方释放资源的情况下。这会导致每个事务都无法继续执行,进入一种无限等待的状态。下面是一些常见的导致数据库死锁的情况:

    1. 资源争用

    当两个或多个事务在不同顺序上锁定相同的资源时,可能会导致死锁。例如:

    • 事务A锁定资源1,然后请求资源2。
    • 事务B锁定资源2,然后请求资源1。
      这种情况下,事务A和事务B都会等待对方释放资源,从而形成死锁。

    2. 长时间持有锁

    如果某个事务长时间持有锁不释放,而其他事务需要访问被锁定的资源,也可能导致死锁。尤其是在长时间运行的事务中,锁资源的时间过长会增加死锁的风险。

    3. 并发事务

    在高并发环境下,多个事务同时访问和修改相同的数据表和记录,会增加死锁的可能性。例如,多个事务同时插入、更新或删除相同的数据行,可能导致锁竞争和死锁。

    4. 不一致的锁定顺序

    如果事务对资源的锁定顺序不一致,也可能导致死锁。例如:

    • 事务A先锁定表1,然后锁定表2。
    • 事务B先锁定表2,然后锁定表1。
      这种情况下,事务A和事务B都在等待对方释放锁,从而形成死锁。

    示例

    假设有两个事务Transaction 1和Transaction 2,它们分别执行以下SQL语句:

    Transaction 1
    BEGIN;
    UPDATE accounts SET balance = balance - 100 WHERE account_id = 1;
    UPDATE accounts SET balance = balance + 100 WHERE account_id = 2;
    COMMIT;
    
    Transaction 2
    BEGIN;
    UPDATE accounts SET balance = balance - 100 WHERE account_id = 2;
    UPDATE accounts SET balance = balance + 100 WHERE account_id = 1;
    COMMIT;
    

    在这种情况下:

    • Transaction 1首先锁定account_id为1的记录,并且尝试锁定account_id为2的记录。
    • Transaction 2首先锁定account_id为2的记录,并且尝试锁定account_id为1的记录。

    这就造成了Transaction 1等待Transaction 2释放account_id为2的锁,而Transaction 2等待Transaction 1释放account_id为1的锁,从而形成死锁。

    避免死锁的方法

    1. 一致的锁定顺序:确保所有事务以一致的顺序锁定资源。
    2. 最小化事务持有锁的时间:在事务中尽可能短的时间内持有锁,避免长时间运行的事务。
    3. 使用合适的隔离级别:在某些情况下,较低的隔离级别(如Read Committed)可能有助于减少死锁,但需要权衡数据一致性问题。
    4. 锁定策略:使用行级锁定而不是表级锁定,可以减少锁竞争的范围。
    5. 监控和调优:定期监控数据库的锁定和死锁情况,并对死锁频发的查询进行调优。

    通过合理的设计和调优,可以有效减少死锁的发生,提升数据库的并发处理能力。

    2.发生死锁时

    当数据库发生死锁时,常见的处理方法包括检测死锁并终止某些事务,以解除死锁状态。不同的数据库管理系统(DBMS)有不同的机制来处理死锁:

    自动死锁检测与解决

    许多现代数据库管理系统(如MySQL、PostgreSQL、SQL Server、Oracle)都有内置的死锁检测机制,能够自动检测到死锁并采取措施解除死锁。

    1. MySQL

    MySQL的InnoDB存储引擎有内置的死锁检测机制。当检测到死锁时,它会自动回滚其中一个事务,以解除死锁。通常,会回滚持有最少锁的事务。

    1. PostgreSQL

    PostgreSQL也有内置的死锁检测机制。检测到死锁时,它会回滚其中一个事务,并抛出一个错误信息(ERROR: deadlock detected),通知应用程序该事务被中止。

    1. SQL Server

    SQL Server使用一种称为死锁图(deadlock graph)的结构来检测死锁。当检测到死锁时,它会选择一个"牺牲者"事务来回滚,并解除死锁。选择牺牲者的标准通常是基于事务的成本。

    1. Oracle

    Oracle通过一种称为死锁检测和自动回滚(Deadlock Detection and Automatic Rollback)的机制来处理死锁。Oracle会自动检测到死锁并回滚一个事务来解除死锁。

    手动处理

    在某些情况下,您可能需要手动处理死锁问题。以下是一些建议:

    1. 捕获异常并重试

    在应用程序代码中捕获死锁异常,并重试被中止的事务。这种方法通常被称为乐观并发控制。

    try {
       
        // 执行事务
    } catch (SQLException e) {
       
        if (e.getErrorCode() == 1213) {
        // MySQL中的死锁错误代码是1213
            // 重试事务
        } else {
       
            throw e;
        }
    }
  • 相关阅读:
    【DevOps】搭建你的第一个 Docker 应用栈
    【C语言】循环结构程序设计 (详细讲解)
    小菜学前端笔记-06-03
    支付通道被黑客攻击
    小文一篇,说说:where、:has和:is的特殊性吧
    CAS号:1869922-24-6_PC Biotin-PEG3-alkyne_可光裂解生物素基团
    基于springboot+vue的电动车实名制挂牌管理系统 elementui
    15 Transformer 框架概述
    Ansible stat模块 stat模块 – 检索文件或文件系统状态
    led台灯哪个牌子质量好?2022最新的台灯牌子排名
  • 原文地址:https://blog.csdn.net/m0_57021623/article/details/139728538
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号