297
sqlite> DELETE FROM mails WHERE (`id` = 71);
SQL error: database is locked

これが機能するようにデータベースのロックを解除するにはどうすればよいですか?

4

38 に答える 38

300

Windows では、このプログラムhttp://www.nirsoft.net/utils/opened_files_view.htmlを試して、プロセスが db ファイルを処理していることを確認できます。データベースのロックを解除するためにそのプログラムを閉じてみてください

Linux と macOS では、たとえばロックされたファイルが development.db の場合、同様のことができます。

$定着開発.db

このコマンドは、ファイルをロックしているプロセスを表示します。

> 開発.db: 5430

プロセスを強制終了するだけです...

殺す -9 5430

...そして、データベースのロックが解除されます。

于 2010-08-13T22:37:16.860 に答える
95

書き込み中にアプリをクラッシュさせて、sqlite db をロックしてしまいました。これが私がそれを修正した方法です:

echo ".dump" | sqlite old.db | sqlite new.db

から取得: http://random.kakaopor.hu/how-to-repair-an-sqlite-database

于 2011-10-12T13:12:52.397 に答える
55

SQLite wiki のDatabaseIsLockedページには、このエラー メッセージの説明が記載されています。部分的には、競合の原因は内部 (エラーを発生させたプロセス) にあると述べています。このページで説明していないのは、SQLite がプロセス内の何かがロックを保持していると判断する方法と、どのような条件が誤検知につながる可能性があるかです。

このエラー コードは、同じデータベース接続からデータベースに対して同時に 2 つの互換性のない処理を実行しようとした場合に発生します。


v3 で導入されたファイル ロックに関連する変更は、将来の読者に役立つ可能性があり、ここで見つけることができます: SQLite バージョン 3 のファイル ロックと同時実行

于 2008-10-20T14:24:02.277 に答える
33

-journal ファイルを削除するのはひどい考えのように思えます。クラッシュ後にsqliteがデータベースを一貫した状態にロールバックできるようにするためにあります。データベースが一貫性のない状態で削除すると、破損したデータベースが残ります。sqlite サイトからのページの引用:

クラッシュまたは停電が発生し、ホット ジャーナルがディスクに残っている場合は、データベース ファイルが別の SQLite プロセスによって開かれ、ロールバックされるまで、元のデータベース ファイルとホット ジャーナルを元の名前でディスクに残すことが不可欠です。 . [...]

SQLite リカバリの一般的な障害モードは、次のように発生すると考えられます。電源障害が発生します。電源が回復した後、善意のユーザーまたはシステム管理者がディスクの損傷を探し始めます。「important.data」という名前のデータベース ファイルが表示されます。このファイルは、おそらくおなじみのものです。しかし、クラッシュの後、「important.data-journal」という名前のホット ジャーナルもあります。ユーザーは、システムのクリーンアップに役立っていると考えて、ホット ジャーナルを削除します。ユーザー教育以外にこれを防ぐ方法はありません。

ロールバックは、次回データベースを開いたときに自動的に行われるはずですが、プロセスがデータベースをロックできない場合は失敗します。他の人が言ったように、これの考えられる理由の1つは、別のプロセスが現在開いていることです。もう 1 つの可能性は、データベースが NFS ボリューム上にある場合の古い NFS ロックです。その場合の回避策は、データベース ファイルを、NFS サーバーでロックされていない新しいコピーに置き換えることです (mv database.db original.db; cp original.db database.db)。sqlite FAQ では、NFS ファイル ロックの実装にバグがあるため、NFS ボリューム上のデータベースへの同時アクセスに関して注意するよう推奨しています。

-journal ファイルを削除すると、以前はできなかったデータベースをロックできるようになる理由を説明できません。それは再現可能ですか?

ところで、-journal ファイルの存在は、必ずしもクラッシュがあったことや、ロールバックされる変更があることを意味するわけではありません。Sqlite にはいくつかの異なるジャーナル モードがあり、PERSIST または TRUNCATE モードでは -journal ファイルを常に所定の位置に残し、コンテンツを変更して、ロールバックする部分的なトランザクションがあるかどうかを示します。

于 2009-06-22T14:25:15.060 に答える
30

「データベースがロックされています」エラーを削除するには、次の手順に従います。

  1. データベース ファイルを別の場所にコピーします。
  2. データベースをコピーしたデータベースに置き換えます。これにより、データベース ファイルにアクセスしていたすべてのプロセスが逆参照されます。
于 2013-03-07T12:28:33.807 に答える
15

プロセスが SQLite DB をロックしてクラッシュした場合、DB は永久にロックされたままになります。それが問題です。他のプロセスがロックしているわけではありません。

于 2009-01-29T22:58:06.557 に答える
13

SQLiteデータベースファイルは単なるファイルであるため、最初のステップは、読み取り専用ではないことを確認することです。もう1つ行うことは、DBを開いた状態で何らかのGUISQLiteDBビューアがないことを確認することです。別のシェルでDBを開くことも、コードでDBを開くこともできます。通常、これは、別のスレッド、またはSQLiteデータベースブラウザなどのアプリケーションでDBを書き込み用に開いている場合に表示されます。

于 2008-09-29T22:39:14.273 に答える
12

私のロックは、ハングしたプロセスではなく、システムのクラッシュが原因でした。これを解決するために、ファイルの名前を変更し、元の名前と場所にコピーしました。

Linuxシェルを使用すると...

mv mydata.db temp.db
cp temp.db mydata.db
于 2009-08-04T11:02:36.647 に答える
11

NFSマウントに保存されたリモートサーバー上のSQLiteデータベースを使用して、この問題が発生しました。データベースが開いている間に使用したリモート シェル セッションがクラッシュした後、SQLite はロックを取得できませんでした。

上記で提案された回復のレシピは、私にはうまくいきませんでした (最初にデータベースを移動してからコピーして戻すというアイデアを含みます)。しかし、NFS 以外のシステムにコピーした後、データベースは使用可能になり、データは失われていないようです。

于 2011-06-16T03:19:32.503 に答える
7

接続文字列に" " を追加Pooling=trueしたところ、うまくいきました。

于 2016-03-08T09:49:00.987 に答える
4

このエラーは、ファイルが共有フォルダーなどのリモート フォルダーにある場合に発生する可能性があります。データベースをローカル ディレクトリに変更したところ、完全に機能しました。

于 2012-09-12T20:29:35.770 に答える
4

SQLite でのロックのさまざまな状態に関するドキュメントが非常に役立つことがわかりました。マイケル、データベースへの読み取りは実行できるが、書き込みは実行できない場合は、プロセスがデータベースで RESERVED ロックを取得しているが、まだ書き込みを実行していないことを意味します。SQLite3 を使用している場合、PENDING と呼ばれる新しいロックがあり、これ以上のプロセスは接続できませんが、既存の接続は読み取りを実行できます。これが問題である場合は、代わりにそれを確認する必要があります。

于 2008-11-14T18:44:35.950 に答える
3

私はアプリ内でこのような問題を抱えています.2つの接続からSQLiteにアクセスします.1つは読み取り専用で、もう1つは書き込みと読み取り用です。読み取り専用接続が 2 番目の接続からの書き込みをブロックしたようです。最後に、使用後すぐに準備済みステートメントをファイナライズするか、少なくともリセットする必要があることが判明しました。準備済みステートメントが開かれるまで、データベースへの書き込みがブロックされていました。

電話を忘れないでください:

sqlite_reset(xxx);

また

sqlite_finalize(xxx);
于 2012-02-17T18:39:06.070 に答える
2

データベースの内部の問題であるはずです...
私にとっては、「SQLiteマネージャー」でデータベースを参照しようとした後に明らかになりました...
したがって、データベースに接続する別のプロセスが見つからず、それを修正できない場合は、この根本的な解決策を試してください:

  1. テーブルのエクスポートを提供します (Firefox では「SQLite マネージャー」を使用できます)。
  2. 移行によってデータベース スキームが変更された場合は、最後に失敗した移行を削除します
  3. 「database.sqlite」ファイルの名前を変更します
  4. 「rake db:migrate」を実行して、新しい作業用データベースを作成します
  5. テーブルのインポートのためにデータベースに適切な権限を与えるために提供する
  6. バックアップしたテーブルをインポートする
  7. 新しい移行を書く
  8. rake db:migrate「 」で実行
于 2011-04-03T11:49:40.157 に答える
2

私の Linux 環境でlsofコマンドを使用すると、ファイルを開いたままプロセスがハングしていることを突き止めることができました。
プロセスを強制終了し、問題は解決しました。

于 2011-09-16T20:29:25.050 に答える
2

同様のことが私にも起こりました。私の Web アプリケーションはデータベースから読み取ることができましたが、挿入や更新を実行できませんでした。Apache を再起動すると、少なくとも一時的に問題が解決しました。

ただし、根本的な原因を突き止められるとよいでしょう。

于 2008-11-14T18:37:13.000 に答える
1

私も同じ問題を抱えていました。どうやら、ロールバック機能は、dbファイルと同じであるが最新の変更がないジャーナルでdbファイルを上書きしているようです。私はこれを以下のコードに実装しましたが、それ以来正常に機能していますが、データベースがロックされたままになる前は、コードがループに陥ってしまいました。

お役に立てれば

私のPythonコード

##############
#### Defs ####
##############
def conn_exec( connection , cursor , cmd_str ):
    done        = False
    try_count   = 0.0
    while not done:
        try:
            cursor.execute( cmd_str )
            done = True
        except sqlite.IntegrityError:
            # Ignore this error because it means the item already exists in the database
            done = True
        except Exception, error:
            if try_count%60.0 == 0.0:       # print error every minute
                print "\t" , "Error executing command" , cmd_str
                print "Message:" , error

            if try_count%120.0 == 0.0:      # if waited for 2 miutes, roll back
                print "Forcing Unlock"
                connection.rollback()

            time.sleep(0.05)    
            try_count += 0.05


def conn_comit( connection ):
    done        = False
    try_count   = 0.0
    while not done:
        try:
            connection.commit()
            done = True
        except sqlite.IntegrityError:
            # Ignore this error because it means the item already exists in the database
            done = True
        except Exception, error:
            if try_count%60.0 == 0.0:       # print error every minute
                print "\t" , "Error executing command" , cmd_str
                print "Message:" , error

            if try_count%120.0 == 0.0:      # if waited for 2 miutes, roll back
                print "Forcing Unlock"
                connection.rollback()

            time.sleep(0.05)    
            try_count += 0.05       




##################
#### Run Code ####
##################
connection = sqlite.connect( db_path )
cursor = connection.cursor()
# Create tables if database does not exist
conn_exec( connection , cursor , '''CREATE TABLE IF NOT EXISTS fix (path TEXT PRIMARY KEY);''')
conn_exec( connection , cursor , '''CREATE TABLE IF NOT EXISTS tx (path TEXT PRIMARY KEY);''')
conn_exec( connection , cursor , '''CREATE TABLE IF NOT EXISTS completed (fix DATE, tx DATE);''')
conn_comit( connection )
于 2012-02-17T11:56:43.823 に答える
1

この例外が発生する一般的な理由の 1 つは、読み取り操作用のリソースを保持している間に書き込み操作を実行しようとした場合です。たとえば、テーブルから SELECT を実行し、最初に ResultSet を閉じずに、選択したものを UPDATE しようとするとします。

于 2012-10-24T17:33:42.863 に答える
1

ここで説明したものとは少し異なるシナリオでこのエラーが発生しました。

SQLite データベースは、3 台のサーバーで共有される NFS ファイルシステムに置かれました。2 台のサーバーでは、データベースに対してクエリを正常に実行できましたが、3 台目のサーバーでは、「データベースがロックされています」というメッセージが表示されると思いました。

この 3 台目のマシンの問題点は、スペースが残っていないことでした/var。このファイルシステムにあるSQLiteデータベースでクエリを実行しようとするたびに、「データベースがロックされています」というメッセージと、ログに次のエラーが表示されました。

8 月 8 日 10:33:38 server01 カーネル: lockd: 172.22.84.87 を監視できません

そして、これも:

8 月 8 日 10:33:38 server01 rpc.statd[7430]: 挿入に失敗しました: /var/lib/nfs/statd/sm/other.server.name.com の書き込み: デバイスにスペースが残っていません 8 月 8 日 10:33: 38 server01 rpc.statd[7430]: 172.22.84.87 の SM_MON に対する server01 への STAT_FAIL

スペースの状況が処理された後、すべてが正常に戻りました。

于 2016-08-09T03:21:29.980 に答える
1

多くの回答がある古い質問ですが、上記の回答を読んで最近従った手順は次のとおりですが、私の場合、問題は cifs リソース共有が原因でした。このケースは以前に報告されていないので、誰かに役立つことを願っています.

  • Java コードで接続が開いたままになっていないことを確認します。
  • 他のプロセスが lsof で SQLite db ファイルを使用していないことを確認してください。
  • 実行中の jvm プロセスのユーザー所有者が、ファイルに対する r/w 権限を持っていることを確認してください。
  • 接続の開始時にロックモードを強制してみてください

    final SQLiteConfig config = new SQLiteConfig();
    
    config.setReadOnly(false);
    
    config.setLockingMode(LockingMode.NORMAL);
    
    connection = DriverManager.getConnection(url, config.toProperties());
    

NFS共有フォルダーでSQLite dbファイルを使用している場合は、SQLite faqのこのポイントを確認し、マウント構成オプションを確認して、ここで説明されているようにロックを回避していることを確認してください。

//myserver /mymount cifs username=*****,password=*****,iocharset=utf8,sec=ntlm,file,nolock,file_mode=0700,dir_mode=0700,uid=0500,gid=0500 0 0
于 2016-04-20T10:31:15.213 に答える
1

SQLITE_BUSY結果コードのように見えるマルチスレッドアプリケーションでも「データベースがロックされています」というエラーが発生していましたが、sqlite3_busy_timeoutを30000などの適切な長さに設定して解決しました。

(ちなみに、7 年前の質問で誰もこれを発見できなかったのはなんと奇妙なことでしょう! SQLite は本当に独特で驚くべきプロジェクトです...)

于 2016-03-02T22:38:09.657 に答える
1

再起動オプションに進む前に、sqlite データベースのユーザーを見つけることができるかどうかを確認する価値があります。

Linux では、fuserこの目的のために以下を使用できます。

$ fuser database.db

$ fuser database.db-journal

私の場合、次の応答がありました。

philip    3556  4700  0 10:24 pts/3    00:00:01 /usr/bin/python manage.py shell

これは、データベースを使用して pid 3556 (manage.py) を持つ別の Python プログラムがあることを示しました。

于 2010-06-21T10:45:32.213 に答える
1

同じエラーが発生しました。5 minets google-ing の後、データベースを使用していた 1 つのシェル ウィッチを閉じていないことがわかりました。閉じて、もう一度やり直してください;)

于 2011-12-15T09:11:05.793 に答える
1

端末セッションから Python スクリプトを実行している Mac OS X 10.5.7 でも、これと同じ問題に遭遇しました。スクリプトを停止し、ターミナル ウィンドウがコマンド プロンプトに表示されていたにもかかわらず、次に実行したときにこのエラーが発生しました。解決策は、ターミナル ウィンドウを閉じてから、もう一度開くことでした。私には意味がありませんが、うまくいきました。

于 2009-06-12T20:20:21.627 に答える
1

Chrome データベースのロックを解除して SQLite で表示しようとしている場合は、 Chrome をシャットダウンしてください。

ウィンドウズ

%userprofile%\Local Settings\Application Data\Google\Chrome\User Data\Default\Web Data

or

%userprofile%\Local Settings\Application Data\Google\Chrome\User Data\Default\Chrome Web Data

マック

~/Library/Application Support/Google/Chrome/Default/Web Data
于 2018-02-25T20:51:54.863 に答える
1

私の経験では、このエラーの原因は次のとおりです。複数の接続を開いた。

例えば:

  1. 1 つ以上の sqlitebrowser (GUI)
  2. 1 つ以上の電子スレッド
  3. レールスレッド

複数のスレッド/リクエストを処理する方法についてSQLITE3の詳細についてはよくわかりませんが、sqlitebrowserとelectronスレッドを閉じると、レールは正常に動作し、ブロックされなくなります。

于 2021-04-18T09:19:24.507 に答える
0

以前のコメントから、-journalファイルが存在すると述べました。

これは、トランザクションを開いて(排他的?)、まだデータをコミットしていないことを意味している可能性があります。あなたのプログラムまたは他のプロセスは、ジャーナルを残しましたか?

sqliteプロセスを再起動すると、ジャーナルファイルが確認され、コミットされていないアクションがクリーンアップされ、-journalファイルが削除されます。

于 2008-12-29T01:44:57.637 に答える
0

私の場合、このエラーも発生しました。

(SQLite Manager、データベースに接続する他のプログラム) など、ロックされたデータベースの原因となる可能性のある他のプロセスを既に確認しました。しかし、それに接続する他のプログラムはありません。接続されたままになるのは、同じアプリケーション内の別のアクティブなSQLConnectionだけです。

新しい SQLConnection新しいコマンドを確立する前に、まだ接続されている可能性がある以前のアクティブな SQLConnectionを確認してください(最初に切断します) 。

于 2016-04-22T17:54:05.780 に答える
0

これは、そのデータベースで他のクエリが実行されているためです。SQLite は、クエリが同期的に実行されるデータベースです。したがって、他の誰かがそのデータベースを使用している場合、クエリまたはトランザクションを実行すると、このエラーが発生します。

そのため、特定のデータベースを使用しているプロセスを停止してから、クエリを実行してください。

于 2016-05-30T08:30:30.810 に答える
0

これを試すことができます:.timeout 100timeout を設定します。コマンドラインで何が起こるかわかりませんが、これを行うとC#.Netで:"UPDATE table-name SET column-name = value;"データベースがロックされていますが、これ"UPDATE table-name SET column-name = value"はうまくいきます。

; を追加すると、sqlite はさらにコマンドを探します。

于 2010-06-27T11:28:28.007 に答える
0

Seun Osewa が言ったように、ロックを取得した状態でゾンビ プロセスが端末に常駐することがあります。スクリプトが実行されてクラッシュし、プロンプトに戻りますが、ライブラリ呼び出しによってどこかにゾンビ プロセスが生成され、そのプロセスがロックされています。

(OSX上で)使用していた端末を閉じるとうまくいくかもしれません。再起動すると動作します。何もしていない "python" プロセス (たとえば) を探して、それらを強制終了することができます。

于 2010-01-07T05:51:56.330 に答える
0

何らかの理由でデータベースがロックされました。これが私がそれを修正した方法です。

  1. sqlite ファイルを自分のシステム (FTP) にダウンロードしました
  2. オンラインの sqlite ファイルを削除しました
  3. ファイルをホスティングプロバイダーにアップロードしました

今はうまくいきます。

于 2014-05-24T14:12:47.283 に答える
0

ツール「DB Browser for SQLite」を実行していて、そこでも作業していました。明らかに、そのツールは物事をロックします。「Write Changes」または「Revert Changes」をクリックすると、ロックが解除され、他のプロセス (React-Native スクリプト) でそのエラーが発生しなくなりました。

DB Browser for SQLite - 変更の書き込み

于 2020-11-06T14:34:51.400 に答える