简体   繁体   English

Django默认隔离级别和db二进制日志格式错误

[英]Django default isolation level and db binary log format error

I'm running a set of tests on my django webserver using pytest-django . 我正在使用pytest-djangodjango网络服务器上运行一组测试。 I'm trying to switch from a MySQL database server to MariaDB in my testing/CI on travis, and for that I also switched from the mysqldb python package to pymysql . 我正在尝试在travis上的测试/ CI中从MySQL数据库服务器切换至MariaDB,为此我也从mysqldb python软件包切换至pymysql

When using MariaDB, I suddenly get a strange exception for all my database related tests: 使用MariaDB时,我所有与数据库相关的测试突然出现一个奇怪的异常:

pymysql.err.InternalError: (1665, 'Cannot execute statement: impossible to write to binary log since BINLOG_FORMAT = STATEMENT and at least one table uses a storage engine limited to row-based logging. InnoDB is limited to row-logging when transaction isolation level is READ COMMITTED or READ UNCOMMITTED.') pymysql.err.InternalError:(1665,'无法执行语句:由于BINLOG_FORMAT = STATEMENT并且至少一个表使用了仅限于基于行的日志记录的存储引擎,因此无法写入二进制日志。当事务隔离时,InnoDB限于行日志记录级别为READ COMMITTED或READ UNCOMMITTED。”)

This exception is below in a stack of several exceptions in all tests for that job, but I've identified it as the root cause for the issue. 在该工作的所有测试中,以下是该异常的堆栈,其中包含一些异常,但是我已将其确定为问题的根本原因。

It's important to note that out of the two jobs that run the test-suite directly on travis, and another that runs it on docker (inside travis), only one fails, the one running on python 3.6. 重要的是要注意,在直接在travis上运行测试套件的两个作业中,以及在docker上(在travis内)运行它的另一个作业中,只有一个失败,一个在python 3.6上运行。

Although I roughly understand the cause of the problem I could not find a lot of information about the specifics or any reason for it to trigger/manifest all of a sudden. 尽管我大致了解了问题的原因,但我找不到大量有关具体信息或突然触发/表明其原因的信息。 Except this Django documentation issue . 除了此Django文档问题

Given it's only triggered for the python3 test job and Django2 dropping support for python2 I assume the issues are related but still I can't seem to figure a reasonable/decent solution. 鉴于它只是为python3测试工作触发的,而Django2放弃了对python2的支持,我认为这些问题是相关的,但我似乎仍然找不到一个合理/合理的解决方案。 I feel I'm missing at least some of the cause/reasoning behind what's going on in here. 我觉得我至少缺少这里所发生情况的某些原因/原因。

I didn't make any changes to database configuration and all services are running with builtin installations. 我没有对数据库配置进行任何更改,所有服务都通过内置安装运行。

For reference, this is a travis job for the PR, in case I missed something important out. 作为参考,如果我错过了重要的事情, 是PR的travis工作。

TL;DR: installing a more up-to-date version of MariaDB solved the issue. TL; DR:安装更新的MariaDB版本可以解决此问题。

Reading some more on the issue, I was able to determine the root cause was indeed due to a collision between two default configurations in my environment: 阅读有关该问题的更多信息,我能够确定根本原因确实是由于环境中两个默认配置之间的冲突造成的:

  1. BINLOG_FORMAT = STATEMENT . BINLOG_FORMAT = STATEMENT

    This was the default in MariaDB until version 10.2.4, according to MariaDB's documentation . 根据MariaDB的文档 ,这是MariaDB的默认版本,直到版本10.2.4。 Since I was using Travis-CI and because of how using MariaDB on travisCI was documented version 10.0 was hardcoded , thus defaulting to above value. 由于我使用的是Travis-CI,并且由于记录在travisCI上如何使用MariaDB的缘故,版本10.0已进行硬编码 ,因此默认为上述值。

  2. transaction isolation level is set to READ COMMITTED 事务隔离级别设置为READ COMMITTED

    On Python3, Django>=2.0 was installed, in which transaction isolation level is set to READ COMMITTED according to Django's documentation . 在Python3上,安装了Django> = 2.0,根据Django的文档 ,其中事务隔离级别设置为READ COMMITTED This configuration seems to be a safer default value. 此配置似乎是一个更安全的默认值。

Replacing the major/minor version string in the example travis mariadb snippet: 在示例travis mariadb代码段中替换主要/次要版本字符串:

addons:
  - mariadb: '10.0'

With a major only version string of '10.3' made travis install a more up-to-date version or MariaDB, which defaulted to the more flexible BINLOG_FORMAT = MIXED configuration. travis使用仅主要版本字符串“ '10.3'进行安装,安装了最新版本或MariaDB,默认为更灵活的BINLOG_FORMAT = MIXED配置。

# config as this way, add options
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'xxx',
        'USER': 'xx',
        'PASSWORD': 'xx',
        'HOST': 'xxx',
        'POST': 'xxx',
        'OPTIONS': {
            'isolation_level': "repeatable read"
        },
    },
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM