ホームページ  >  に質問  >  本文

python多线程爬虫往mysql里面写数据导致死锁

我在爬虫里面用的是MySQLdb这个包进行insert操作,我一开始是所有子线程公用一个mysql连接,结果发现数据写不进去,然后我又试过所有子线程公用一个cursor游标,出现了只有部分数据写进去了,而且自增id居然还自增了。(也就是数据没有写入进去,但是自增id的自增数增加了),最后我干脆每个子线程在每一次写入的时候创建一个连接句柄,然后就出现了如图症状,请问这该怎么办啊?有什么优化方法吗?

PHP中文网PHP中文网2741日前399

全員に返信(3)返信します

  • 怪我咯

    怪我咯2017-04-18 10:12:53

    お誘いありがとうございます。メタデータ ロック (MDL) は、5.5 で mysql のメタデータ保護メカニズムに導入されました。 5.5 メタデータの保護はトランザクション レベルで行われ、MDL はトランザクションの終了後にのみ解放されます。
    セッションがメイン データベースで DML 操作を実行し、まだ送信されていない場合、別のセッションが同じオブジェクトに対してテーブルの削除などの DDL 操作を実行します。MySQL のバイナリログはトランザクションの送信順序に基づいて記録されるため、ライブラリから適用すると、テーブルが最初に削除されてからテーブルに挿入される状況が発生し、ライブラリからのアプリケーションでエラーが発生します。したがって、MySQL はバージョン 5.5.3 以降、メタデータ ロックを導入しました。メタデータ ロックはトランザクションの終了後にのみ解放されます。したがって、トランザクションがコミットまたはロールバックされるまでは DDL 操作を実行できません。
    テーブル メタデータ ロックの待機の原因は、通常、次の単純なシナリオです。
    シナリオ 1: 長時間のトランザクションの実行、DDL のブロック、および同じテーブルでの後続のすべての操作のブロック
    シナリオ 2 : トランザクションは送信されず、DDL がブロックされ、同じテーブルに対する後続の操作がすべてブロックされます。

    それではどうやって解決すればいいのでしょうか?
    ブロック状態を待機しているすべてのトランザクション ロックを表示する

    リーリー リーリー

    または、特定のテーブルを直接ターゲットにすることもできます

    リーリー

    関連するレコードを直接削除すると、ロックが解除されます。

    推奨事項: すべてのスレッドの接続を共有する代わりに接続プールを使用し、各トランザクションをコミットまたはロールバックすることを忘れないでください。
    推奨されるリファレンス:
    https://dev.mysql.com/doc/ref...
    http://www.cnblogs.com/cchust...
    https://gold .xitu.io/entry/57...
    http://www.cnblogs.com/digdee...

    返事
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:12:53

    テーブルは Innodb からのものですが、自動送信は有効になっておらず、手動送信はありません。

    返事
    0
  • 黄舟

    黄舟2017-04-18 10:12:53

    まず第一に、複数のスレッドが接続を共有します。これは、多くのスレッドが待機する必要があることと同じです。
    スレッドごとに 1 つの接続の使用率は高くないため、通常は接続プールになります。リサイクルの必要がなく、常に接続が維持されるため、頻繁に接続が切断されることはありません。

    写真付き、対象者が取引を開始したかどうか

    返事
    0
  • キャンセル返事