zoukankan      html  css  js  c++  java
  • mysql数据库大规模数据读写并行时导致的锁表问题

    问题介绍

    最近在给学校做的一个项目中,有一个功能涉及到考核分数问题。
    我当时一想,这个问题并不是很难,于是就直接采用了这样的方法:拿着一个表中的数据作为索引,去挨个遍历相关表中的数据,最后经过算分的过程,直接在算分函数中将算出的分数直接写入数据库,这就导致了标题说的问题。

    解决过程

    这个问题出现的现象是这样的:我从数据库中读取出来的作为索引的数据共有2000多条,使用增强for循环将数据传入算分的方法中。但是后来发现,算出分数的数据总计也就300多条,本以为是这条作为索引的数据在其他表中没有相关的数据造成的分数为0,后来发现,即使是在其他表中有数据的,算出的分数依旧是0。
    这个问题着实令人费解,本以为是增强for循环的线程安全问题,后来就将增强for循环改成了迭代器,但是这个问题依旧没有解决。
    紧接着,我想了想,开始测试一下这条分数为0的数据是否被读入了函数当中,于是我在算分的函数中设置了个判断条件,结果发现,这条数据真的是没有被读入函数。
    无奈之下,只能是一点点debug,我将传入的参数改成了数据表中没有分数的这条数据的,居然发现这条数据能够被成功计算出分数。
    这时候我整个人已经是懵逼的了,我不禁在想,为什么会出现这种情况?单独将值传入函数,可以计算出分数值,但所有数据一起读写,就会出现这个问题呢?
    此时我已经坐在电脑前debug了一个下午,晚饭也没有吃,本来中午就应该上线的功能,硬是到了晚上依然没有被解决,确实有点慌了。
    无奈之下只能是请教之前负责这个项目的学长,但是学长有课,只能等到八点半。在等待期间,我依旧是在疯狂的debug,真的是一点头绪都没有。
    学长来了之后,他在循环的过程中加入了一个计算次数的变量,每次输出一下,结果发现,程序并没有执行完成,总是执行到第420次就停了,期间没有任何错误信息,没有任何其他异常,诡异的很。
    不过这个时候我们已经意识到了是mysql数据库的问题。
    就这样,学长和我们一起一直盯到了两点,之前已经将分数采用一次读取几百条数据的方式成功将分数算出来交给学校科研院处理了。
    随着学长一个激动的叫声,问题总算是得到了解决!

    最终的解决方案

    原来,在我设计的方法中,是读写同时进行的。
    虽然第一次将数据读到一个集合中了,但是每次循环都会再次从数据库中读取大量的数据,数据的条数超过了几万条,这还不算,在每次读取后,计算出分数,会将分数直接写入数据库,就这样,在频繁的与数据库进行读写操作的时候,mysql不干了,直接将这个表锁住了。
    这也解释了为什么系统的其他的功能可以使用,偏偏和分数相关的功能都不能用的问题。
    于是最终将写入分数的步骤单独拿了出来,这样子,成功的将所有数据的分数都算了出来。
    持续了超过十个小时的过程中,终于将问题解决了。

    经验教训

    经过这次惨痛的教训,使我深刻明白了一个问题,下次再设计方法的时候,一定要将读写操作分开进行,否则就会出现十分严重的问题。
    虽然整个过程困难无比,但还是收获巨大的,这种感觉真的特别好。
    我想以后真的不可能会忘记读写分离这件事情了,哈哈!
    谢谢帮忙的学长还有同学!

    结语

    想了解更多的专业知识、前瞻信息、技术文章吗?那么请我的个人公众号:进击的程序狗,一起进步!

  • 相关阅读:
    如何将网格式报表打印成其它样式
    拥有与实力不相称的脾气是种灾难——北漂18年(23)
    8.8.1 Optimizing Queries with EXPLAIN
    mysql 没有rowid 怎么实现根据rowid回表呢?
    secondary index
    8.5.5 Bulk Data Loading for InnoDB Tables 批量数据加载
    mysql 中key 指的是索引
    8.5.4 Optimizing InnoDB Redo Logging 优化InnoDB Redo 日志
    8.5.3 Optimizing InnoDB Read-Only Transactions 优化InnoDB 只读事务
    8.5.1 Optimizing Storage Layout for InnoDB Tables InnoDB表的存储布局优化
  • 原文地址:https://www.cnblogs.com/roobtyan/p/9576710.html
Copyright © 2011-2022 走看看