我有一个系统,它使用Perl脚本将数据从xml文件加载到MySQL数据库中以生成一些报告。 以前它使用的是MySQL 5.1,我现在需要升级到MySQL 5.7。
在这两种情况下,我都有mysql auto-commit = 1(仅作为默认配置)和perl auto-commit = 0(在运行sql之前的脚本中 - 仅用于具有显式提交语句的插入)
升级后,将使用InnoDB作为默认引擎创建新表,并且因为我不想要事务管理并将我的表从MyISAM更改为InnoDB,所以我使用以下标志来抑制使用.my .CNF
默认存储引擎= MyISAM的
的残疾存储引擎= InnoDB的
在进行了上述更改之后,我能够实现MyISAM引擎的表创建,但仍然看起来事务管理是如何启用的(这是我的猜测)并且我面临以下问题
mysql> show full processlist;
+----+------+-----------+---------+---------+------+---------------------------------+----------------------------+
| Id | User | Host | db | Command | Time | State | Info |
+----+------+-----------+---------+---------+------+---------------------------------+----------------------------+
| 14 | test | localhost | REGRESS | Sleep | 17 | | NULL |
| 15 | test | localhost | REGRESS | Query | 16 | Waiting for table metadata lock | OPTIMIZE TABLE TEST.SOURCE |
| 16 | test | localhost | NULL | Query | 0 | starting | show full processlist |
+----+------+-----------+---------+---------+------+---------------------------------+----------------------------+
我确定这不是因为表锁定的唯一方法,因为我没有遇到MySQL 5.1的问题,我使用过" skip-innodb"选项和默认存储引擎是MyISAM。
我无法获得任何官方文档,其中默认情况下在MySQL 5.7中启用了事务。如果有人可以证实这一点,那就太好了。即使在使用MyISAM引擎获得表格(如我的情况下)之后,看起来它仍然需要将每个查询作为事务处理,这是我怀疑的问题。
如果需要更多信息,请告诉我。
有什么办法可以通过设置一些env变量来禁用MySQL 5.7中的事务管理吗?
我们可以通过任何方式禁用InnoDB引擎,除了上面的标志设置吗?
提前致谢。
答案 0 :(得分:0)
Metadata locking(这就是为什么它不能干扰5.1中的脚本),在不同的事务处于活动状态时阻止ddl更改:
服务器通过获取事务中使用的表的元数据锁并延迟释放这些锁直到事务结束来实现此目的。表上的元数据锁可防止更改表的结构。这种锁定方法的含义是,一个会话中的事务正在使用的表在其他会话中不能在DDL语句中使用,直到事务结束。
对于您的情况,请务必注意,这也包括MyISAM表,即使它们不是事务性的:
这个原则不仅适用于交易表,也适用于非交易表。
因此,即使您在事务中使用“只”一个MyISAM表,也不能在事务结束之前更改该表。交易由start transaction
启动,或者如果您禁用autocommit
。自动提交是enabled by default,效果是
在自动提交模式下,每个语句实际上都是一个完整的事务,因此为语句获取的元数据锁只保留在语句的末尾。
因此,虽然MySQL 5.7中默认不启用事务,但如果禁用autocommit
(这是您在脚本中执行的操作),则会隐式启动事务。虽然此事务对MyISAM表的查询没有影响,但从MySQL 5.5开始,它仍然会添加元数据锁,从而对ddl语句产生影响(在其他会话中)。如果您不想这样做,请不要禁用自动提交。
你做不到的事情(如果这就是你所追求的)是通过禁用InnoDB来完全禁用“交易功能”。 InnoDB是一个存储引擎。与MyISAM相比,它支持事务,但它不是事务功能本身 - 尽管肯定存在非常大的共同依赖性,因为没有支持事务的主存储引擎,该功能将没有那么多价值。 transactional concept是mysql不可分割的一部分,不能被禁用 - 这是非常基础的,文档(据我所知)甚至没有明确说明。
答案 1 :(得分:0)
使用MyISAM,您可以同时在同一个表上执行多个读取。但做其他任何事情都会锁定桌面。坚持使用MyISAM是错误的;你应该努力转移到InnoDB。在5.7之后的版本中,MyISAM被弃用。
MyISAM没有"交易"。例如,如果服务器在多行UPDATE
的中间崩溃,则某些行将被提交到表中;有些人不会。这违反了"交易的主要原则"。