84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
我在爬虫里面用的是MySQLdb这个包进行insert操作,我一开始是所有子线程公用一个mysql连接,结果发现数据写不进去,然后我又试过所有子线程公用一个cursor游标,出现了只有部分数据写进去了,而且自增id居然还自增了。(也就是数据没有写入进去,但是自增id的自增数增加了),最后我干脆每个子线程在每一次写入的时候创建一个连接句柄,然后就出现了如图症状,请问这该怎么办啊?有什么优化方法吗?
认证高级PHP讲师
谢邀。Metadata Lock(MDL)是在5.5才引入到mysql的元数据保护机制。5.5对于metadata的保护是事务级别的,只有在事务结束后才释放MDL。当一个会话在主库执行 DML 操作还没提交时,另一个会话对同一个对象执行了 DDL 操作如 drop table,而由于 MySQL 的 binlog 是基于事务提交的先后顺序进行记录的,因此在从库上应用时,就出现了先 drop table,然后再向 table 中 insert 的情况,导致从库应用出错。 因此,MySQL 在 5.5.3 版本后引入了 Metadata lock,只有在事务结束后才会释放 Metadata lock,因此在事务提交或回滚前,是无法进行 DDL 操作的。造成Waiting for table metadata lock的原因,一般是以下几个简单的场景:场景一:长事物运行,阻塞DDL,继而阻塞所有同表的后续操作场景二:未提交事物,阻塞DDL,继而阻塞所有同表的后续操作
那么如何解决呢?查看所有的处于等待阻塞状态的事务锁lock
USE INFORMATION_SCHEMA
SELECT * FROM INNODB_LOCKS WHERE LOCK_TRX_ID IN (SELECT BLOCKING_TRX_ID FROM INNODB_LOCK_WAITS);
或者你可以直接定位到特定表
SELECT * FROM INNODB_LOCKS WHERE LOCK_TABLE = db_name.table_name;
直接删除相关记录应该是可以解除锁。
建议:采用连接池而不是所有线程公用一个连接,每个事务都记得提交或回滚等。建议参考:https://dev.mysql.com/doc/ref...http://www.cnblogs.com/cchust...https://gold.xitu.io/entry/57...http://www.cnblogs.com/digdee...
表是 Innodb 的吧,然后没开自动提交也没有手动提交。
首先,多线程共用一个连接,相当于并发,很多线程需要等待。每个线程一个连接利用率不高,所以一般都是连接池。不用了回收,并且连接一直保持,避免了频繁连接断开。
配图,题主是否开启事务
谢邀。Metadata Lock(MDL)是在5.5才引入到mysql的元数据保护机制。5.5对于metadata的保护是事务级别的,只有在事务结束后才释放MDL。
当一个会话在主库执行 DML 操作还没提交时,另一个会话对同一个对象执行了 DDL 操作如 drop table,而由于 MySQL 的 binlog 是基于事务提交的先后顺序进行记录的,因此在从库上应用时,就出现了先 drop table,然后再向 table 中 insert 的情况,导致从库应用出错。 因此,MySQL 在 5.5.3 版本后引入了 Metadata lock,只有在事务结束后才会释放 Metadata lock,因此在事务提交或回滚前,是无法进行 DDL 操作的。
造成Waiting for table metadata lock的原因,一般是以下几个简单的场景:
场景一:长事物运行,阻塞DDL,继而阻塞所有同表的后续操作
场景二:未提交事物,阻塞DDL,继而阻塞所有同表的后续操作
那么如何解决呢?
查看所有的处于等待阻塞状态的事务锁lock
或者你可以直接定位到特定表
直接删除相关记录应该是可以解除锁。
建议:采用连接池而不是所有线程公用一个连接,每个事务都记得提交或回滚等。
建议参考:
https://dev.mysql.com/doc/ref...
http://www.cnblogs.com/cchust...
https://gold.xitu.io/entry/57...
http://www.cnblogs.com/digdee...
表是 Innodb 的吧,然后没开自动提交也没有手动提交。
首先,多线程共用一个连接,相当于并发,很多线程需要等待。
每个线程一个连接利用率不高,所以一般都是连接池。不用了回收,并且连接一直保持,避免了频繁连接断开。
配图,题主是否开启事务