背景:实际django项目中遇到这样一个问题,两个进程A,B去读写MySQL数据库,A 在insert m 完成后通过redis 通知B去读MySQL。如下图所示,在进程B允许过程中,往数据库多插入几十条数据后,进程B依然查询不到。如下图所示:实际数据表中有6250,但是在进程中查询只有6218条,他对进程启动动新增的数据都查询不到。
问题:A insert完成后,这时B并不能查询到新增的记录m。但是通过其他客户端工具可以看到新增的m记录,特别的是B进程在重启后也能看到记录m。
当然更有意思的是这种现象在开发环境中并不会出现,只在测试环境中会有该问题。
分析1:由于项目使用的django技术,对MySQL查询和插入操作也是django封装进行,加上数据库确实存在该记录。所以怀疑是django没有去真实查询数据库。
排查过程1:到底有没有真实去查数据库?由于该问题是可以复现的,所有使用python manage.py shell 进来一步步去查。
第一,tcpdump 抓包可以搞定,第二,如果是测试开发环境,可以把MySQL 查询日志 的打开,通过日志去看是否进行查询动作。
这里使用方法1,在进程B的机器上执行 tcpdump port 3306, 如果想通过wireshrk 查看详细信息可以使用:tcpdump -w mysql.pcap port 3306 and host xxx ,打开
mysql.pcap就能看确实进行了查询,如图一:
分析2:看来B是去查询MySQL了。但是MySQL确实没有返回m,看来是django 使用MySQL有些配置上有问题(不要轻易怀疑是MySQL的问题,毕竟它很成熟,一般都是使用上的不当)。这次为了证明这个猜想,需要打开MySQL的日志了。
排查过程2:找到my.cnf 在[mysqld] 下增加 log=/var/log/mysql/mysql.log 的配置。重启msyql(注:该操作仅限于在开发测试环境排查问题用,在生产环境慎用影响性能)
然后我们用tail -f /var/log/mysql/mysql.log 来观察 A 和 B 到底在干嘛。如图二:
通过查询日志可以知道的是,数据确实保存到了数据库中,其他客户端也可以查出。但是进程B查不出,并且B在开始时设置了set autocommit=0表示要手动提交事务。由于数据库的事务隔离
级别的不同会导致两个事务查询出不同的结果。关于事务隔离级别的话在另一篇文章中有详细的介绍。
可以通过下边的语句来看数据库的隔离级别是什么。当然操作具体表时还需要看表的引擎,比如MyISAM 是不支持事务的,而InnoDB是支持事务的。也就是说不管你的事务隔离机制如何, MyISAM 类型的表都可以立即查询到已经真实存储在数据库中的记录。
select @@TX_ISOLATION;
解决方法:
找到了原因解决方法就方便多了。
(1)如果觉得没有必要用事务,也就是每条语句执行后就可以直接持久化到数据,那就把django 中的 ‘django.middleware.transaction.TransactionMiddleware’去掉
(2)光是查询的话可以使用下边的代码:
from django.db import transaction with transaction.autocommit(): #业务代码
(3)第三个就是修改数据库的事务隔离级别(一般不建议)
(4)修改表的数据引擎,刚开始背景中介绍的开发环境不存在,测试环境存在,原因就是表引擎不同。
总结:
遇到问题后,首先要冷静分析现象出现的场景。什么情况下会复现该问题。尽量能使用差异点来定位问题可能的原因。
就像上边这个现象,B在重启后可以查询到m。利用其它客户端也能查询到m,唯独在B运行过程中查询不到,就可以根据B运行中和B重启的差异来分析。
当然如果对数据库事务熟悉的同学应该会敏感的想到可能的原因。也就不用去看msyql log 了。
相关推荐
在本实例中,我们将探讨如何使用Django框架从MySQL数据库中读取数据并将其呈现到前端页面上。Django是一个强大的Python Web开发框架,而MySQL则是一种广泛使用的关系型数据库管理系统。结合两者,我们可以构建动态的...
结合MySQL数据库,我们可以创建稳健的数据存储系统。本教程将详细介绍如何使用Django与MySQL协同工作,实现数据的插入操作。 首先,确保你已经安装了Python、Django和MySQL的相关库。Python的安装是基础,Django...
本主题将深入探讨如何在Django2版本中结合MySQL8数据库进行数据的插入和查询操作。MySQL8作为广泛使用的开源关系型数据库管理系统,为开发者提供了强大的数据存储和管理功能。 首先,我们需要确保安装了Django以及...
本篇文章将深入探讨如何在Django项目中结合ZTree插件,从MySQL数据库中读取数据表,并将这些数据以树状目录的形式展示出来。我们将讨论以下关键知识点: 1. Django框架: Django是一个开源的Web框架,遵循MTV...
这个项目中,我们学习了如何使用Django框架创建一个与MySQL数据库集成的Web应用,并通过RESTful API对外提供服务。涵盖了Django的基本命令、项目搭建、数据库配置、模型定义、视图创建、URL路由以及RESTful API设计...
使用Navicat-for-MySQL,开发者可以方便地查看数据库的状态,进行数据表的创建、修改和查询,以及查看、修改数据库用户的权限等。但是,值得强调的是,Navicat-for-MySQL并非数据库本身,而是对数据库进行操作的工具...
使用Python编程语言 Django MySQL数据库开发的web版学生管理系统,里面附带环境搭建的详细过程和开发过程中遇到的一些bug的讲解 使用Python编程语言 Django MySQL数据库开发的web版学生管理系统,里面附带环境搭建...
在本教程中,我们将深入探讨如何使用Django框架创建第一个项目,并将其与MySQL数据库集成以实现用户注册和登录功能。Django是一个强大的Python Web开发框架,而MySQL则是一种广泛使用的开源关系型数据库管理系统。让...
django中配置MySql数据库.html
使用Python PyMysql库将数据分别存入MySQL数据库对应的数据表中 使用Python Pandas库对数据进行数据清洗和数据处理分析 使用Python web开发框架Django开发设计API数据接口 使用web开发框架Vue3搭建每个功能模块组件 ...
django view接口实现excel表导入到数据库,主要运用xlrd包读取到excel表单的内容,然后再数据库里创建excel表的数据类型。我在里面增加了一层判断,就是如果库里面有excel表里面人或数据的话就会更新改变的数据,...
在Django中,通过定义模型类来描述数据库表结构,然后使用Django的管理器方法或ORM进行数据的增删改查操作。例如,可以创建一个新的记录,读取特定记录,更新现有记录的字段,或者彻底删除一条记录。 在实际开发中...
在使用Django进行Web应用开发的过程中,我们可能会遇到需要对数据库结构进行修改的情况,例如,添加新的字段、删除旧的表或者更改字段的数据类型等。这时,需要借助Django的迁移系统来同步数据库结构的变化。但是,...
Python开发 MySQL 数据库数据结构设计03. Django配置使用 MySQL.mp4
项目包含一个可以直接导入到MySQL的数据库文件,这意味着项目已经预设好了数据表结构,可能包括用户表、商品表、订单表等。 5. **Django ORM**: Django的ORM(对象关系映射)允许开发者使用Python对象来操作数据库...
4. **数据模型(Model)**: 在Django中,数据模型定义了应用程序的数据结构,它是Python类的实例,对应于数据库中的表。在员工管理系统中,可能有Employee、Department等模型,包含字段如姓名、工号、职位、部门等。...
在IT行业中,数据库是存储和管理数据的核心工具,而Django是一个流行的Python Web框架,它提供了与多种数据库交互的能力,包括MySQL。本教程将详细探讨如何在Django项目中从默认的SQLite数据库切换到MySQL数据库。 ...
在Django中,模型是数据库表的面向对象表示。每个模型定义了数据库表的列,字段则定义了列的数据类型和行为。默认情况下,Django将模型字段的值作为明文存储在数据库中。为了加密这些字段,我们需要自定义字段类,...
Django + python + mysql的在线考试系统源码 Django + python + mysql的在线考试系统源码 Django + python + mysql的在线考试系统源码 Django + python + mysql的在线考试系统源码 Django + python + mysql的...