sqlite> DELETE FROM mails WHERE (`id` = 71);
SQL error: database is locked
これが機能するようにデータベースのロックを解除するにはどうすればよいですか?
sqlite> DELETE FROM mails WHERE (`id` = 71);
SQL error: database is locked
これが機能するようにデータベースのロックを解除するにはどうすればよいですか?
Windows では、このプログラムhttp://www.nirsoft.net/utils/opened_files_view.htmlを試して、プロセスが db ファイルを処理していることを確認できます。データベースのロックを解除するためにそのプログラムを閉じてみてください
Linux と macOS では、たとえばロックされたファイルが development.db の場合、同様のことができます。
$定着開発.db
このコマンドは、ファイルをロックしているプロセスを表示します。
> 開発.db: 5430
プロセスを強制終了するだけです...
殺す -9 5430
...そして、データベースのロックが解除されます。
書き込み中にアプリをクラッシュさせて、sqlite db をロックしてしまいました。これが私がそれを修正した方法です:
echo ".dump" | sqlite old.db | sqlite new.db
から取得: http://random.kakaopor.hu/how-to-repair-an-sqlite-database
SQLite wiki のDatabaseIsLockedページには、このエラー メッセージの説明が記載されています。部分的には、競合の原因は内部 (エラーを発生させたプロセス) にあると述べています。このページで説明していないのは、SQLite がプロセス内の何かがロックを保持していると判断する方法と、どのような条件が誤検知につながる可能性があるかです。
このエラー コードは、同じデータベース接続からデータベースに対して同時に 2 つの互換性のない処理を実行しようとした場合に発生します。
v3 で導入されたファイル ロックに関連する変更は、将来の読者に役立つ可能性があり、ここで見つけることができます: SQLite バージョン 3 のファイル ロックと同時実行
-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 ファイルを常に所定の位置に残し、コンテンツを変更して、ロールバックする部分的なトランザクションがあるかどうかを示します。
「データベースがロックされています」エラーを削除するには、次の手順に従います。
プロセスが SQLite DB をロックしてクラッシュした場合、DB は永久にロックされたままになります。それが問題です。他のプロセスがロックしているわけではありません。
SQLiteデータベースファイルは単なるファイルであるため、最初のステップは、読み取り専用ではないことを確認することです。もう1つ行うことは、DBを開いた状態で何らかのGUISQLiteDBビューアがないことを確認することです。別のシェルでDBを開くことも、コードでDBを開くこともできます。通常、これは、別のスレッド、またはSQLiteデータベースブラウザなどのアプリケーションでDBを書き込み用に開いている場合に表示されます。
私のロックは、ハングしたプロセスではなく、システムのクラッシュが原因でした。これを解決するために、ファイルの名前を変更し、元の名前と場所にコピーしました。
Linuxシェルを使用すると...
mv mydata.db temp.db
cp temp.db mydata.db
NFSマウントに保存されたリモートサーバー上のSQLiteデータベースを使用して、この問題が発生しました。データベースが開いている間に使用したリモート シェル セッションがクラッシュした後、SQLite はロックを取得できませんでした。
上記で提案された回復のレシピは、私にはうまくいきませんでした (最初にデータベースを移動してからコピーして戻すというアイデアを含みます)。しかし、NFS 以外のシステムにコピーした後、データベースは使用可能になり、データは失われていないようです。
接続文字列に" " を追加Pooling=true
したところ、うまくいきました。
このエラーは、ファイルが共有フォルダーなどのリモート フォルダーにある場合に発生する可能性があります。データベースをローカル ディレクトリに変更したところ、完全に機能しました。
SQLite でのロックのさまざまな状態に関するドキュメントが非常に役立つことがわかりました。マイケル、データベースへの読み取りは実行できるが、書き込みは実行できない場合は、プロセスがデータベースで RESERVED ロックを取得しているが、まだ書き込みを実行していないことを意味します。SQLite3 を使用している場合、PENDING と呼ばれる新しいロックがあり、これ以上のプロセスは接続できませんが、既存の接続は読み取りを実行できます。これが問題である場合は、代わりにそれを確認する必要があります。
私はアプリ内でこのような問題を抱えています.2つの接続からSQLiteにアクセスします.1つは読み取り専用で、もう1つは書き込みと読み取り用です。読み取り専用接続が 2 番目の接続からの書き込みをブロックしたようです。最後に、使用後すぐに準備済みステートメントをファイナライズするか、少なくともリセットする必要があることが判明しました。準備済みステートメントが開かれるまで、データベースへの書き込みがブロックされていました。
電話を忘れないでください:
sqlite_reset(xxx);
また
sqlite_finalize(xxx);
データベースの内部の問題であるはずです...
私にとっては、「SQLiteマネージャー」でデータベースを参照しようとした後に明らかになりました...
したがって、データベースに接続する別のプロセスが見つからず、それを修正できない場合は、この根本的な解決策を試してください:
rake db:migrate
「 」で実行私の Linux 環境でlsofコマンドを使用すると、ファイルを開いたままプロセスがハングしていることを突き止めることができました。
プロセスを強制終了し、問題は解決しました。
同様のことが私にも起こりました。私の Web アプリケーションはデータベースから読み取ることができましたが、挿入や更新を実行できませんでした。Apache を再起動すると、少なくとも一時的に問題が解決しました。
ただし、根本的な原因を突き止められるとよいでしょう。
私も同じ問題を抱えていました。どうやら、ロールバック機能は、dbファイルと同じであるが最新の変更がないジャーナルでdbファイルを上書きしているようです。私はこれを以下のコードに実装しましたが、それ以来正常に機能していますが、データベースがロックされたままになる前は、コードがループに陥ってしまいました。
お役に立てれば
##############
#### 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 )
この例外が発生する一般的な理由の 1 つは、読み取り操作用のリソースを保持している間に書き込み操作を実行しようとした場合です。たとえば、テーブルから SELECT を実行し、最初に ResultSet を閉じずに、選択したものを UPDATE しようとするとします。
ここで説明したものとは少し異なるシナリオでこのエラーが発生しました。
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
スペースの状況が処理された後、すべてが正常に戻りました。
多くの回答がある古い質問ですが、上記の回答を読んで最近従った手順は次のとおりですが、私の場合、問題は cifs リソース共有が原因でした。このケースは以前に報告されていないので、誰かに役立つことを願っています.
接続の開始時にロックモードを強制してみてください
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
SQLITE_BUSY結果コードのように見えるマルチスレッドアプリケーションでも「データベースがロックされています」というエラーが発生していましたが、sqlite3_busy_timeoutを30000などの適切な長さに設定して解決しました。
(ちなみに、7 年前の質問で誰もこれを発見できなかったのはなんと奇妙なことでしょう! SQLite は本当に独特で驚くべきプロジェクトです...)
再起動オプションに進む前に、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 プログラムがあることを示しました。
同じエラーが発生しました。5 minets google-ing の後、データベースを使用していた 1 つのシェル ウィッチを閉じていないことがわかりました。閉じて、もう一度やり直してください;)
端末セッションから Python スクリプトを実行している Mac OS X 10.5.7 でも、これと同じ問題に遭遇しました。スクリプトを停止し、ターミナル ウィンドウがコマンド プロンプトに表示されていたにもかかわらず、次に実行したときにこのエラーが発生しました。解決策は、ターミナル ウィンドウを閉じてから、もう一度開くことでした。私には意味がありませんが、うまくいきました。
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
私の経験では、このエラーの原因は次のとおりです。複数の接続を開いた。
例えば:
複数のスレッド/リクエストを処理する方法についてSQLITE3の詳細についてはよくわかりませんが、sqlitebrowserとelectronスレッドを閉じると、レールは正常に動作し、ブロックされなくなります。
以前のコメントから、-journalファイルが存在すると述べました。
これは、トランザクションを開いて(排他的?)、まだデータをコミットしていないことを意味している可能性があります。あなたのプログラムまたは他のプロセスは、ジャーナルを残しましたか?
sqliteプロセスを再起動すると、ジャーナルファイルが確認され、コミットされていないアクションがクリーンアップされ、-journalファイルが削除されます。
私の場合、このエラーも発生しました。
(SQLite Manager、データベースに接続する他のプログラム) など、ロックされたデータベースの原因となる可能性のある他のプロセスを既に確認しました。しかし、それに接続する他のプログラムはありません。接続されたままになるのは、同じアプリケーション内の別のアクティブなSQLConnectionだけです。
新しい SQLConnectionと新しいコマンドを確立する前に、まだ接続されている可能性がある以前のアクティブな SQLConnectionを確認してください(最初に切断します) 。
これは、そのデータベースで他のクエリが実行されているためです。SQLite は、クエリが同期的に実行されるデータベースです。したがって、他の誰かがそのデータベースを使用している場合、クエリまたはトランザクションを実行すると、このエラーが発生します。
そのため、特定のデータベースを使用しているプロセスを停止してから、クエリを実行してください。
これを試すことができます:.timeout 100
timeout を設定します。コマンドラインで何が起こるかわかりませんが、これを行うとC#.Netで:"UPDATE table-name SET column-name = value;"
データベースがロックされていますが、これ"UPDATE table-name SET column-name = value"
はうまくいきます。
; を追加すると、sqlite はさらにコマンドを探します。
Seun Osewa が言ったように、ロックを取得した状態でゾンビ プロセスが端末に常駐することがあります。スクリプトが実行されてクラッシュし、プロンプトに戻りますが、ライブラリ呼び出しによってどこかにゾンビ プロセスが生成され、そのプロセスがロックされています。
(OSX上で)使用していた端末を閉じるとうまくいくかもしれません。再起動すると動作します。何もしていない "python" プロセス (たとえば) を探して、それらを強制終了することができます。
何らかの理由でデータベースがロックされました。これが私がそれを修正した方法です。
今はうまくいきます。