Mungkin ada proses lain mengakses file database - apakah Anda memeriksa lsof?
ada
Saya memiliki masalah yang sama, masalahnya ada di antivirus ketika saya menonaktifkannya aplikasi saya berfungsi dengan baik, tetapi ketika saya mengaktifkannya saya menemukan beberapa kesalahan "database terkunci", saya harap itu akan membantu Anda.
... dengan peringatan jelas bahwa Anda perlu tahu apa yang Anda lakukan. Jika ini adalah proses yang tidak penting maka killharus baik-baik saja, tetapi Anda harus berhati-hati untuk membunuhnya dengan benar, dan kill -9mungkin salah dan / atau berlebihan. Jika prosesnya terhenti dan tidak akan mati, terkadang Anda memang membutuhkannya kill -9. Tetapi Anda tidak ingin pergi dan mematikan pekerjaan produksi utama hanya agar Anda dapat melaporkan bahwa basis data tidak lagi terkunci!
tripleee
Solusi yang lebih sederhana adalah dengan hanya me-restart komputer Anda.
chacham15
7
@ chacham15: Anda berasumsi bahwa basis data ada di komputer "saya", dan Anda mengabaikan kemungkinan banyak proses penting yang berjalan di komputer yang sama dengan yang ada di basis data yang terkunci. Solusi "sederhana" tidak pernah sesederhana itu;)
tzot
1
@KyleCarlson - sqlite dan mysql pada dasarnya berbeda dalam aspek itu. Tidak ada yang salah dengan SQLite-db-browser.
Berry Tsakala
6
Solusi ini mengasumsikan bahwa ada proses mengunci file. Ada kemungkinan bahwa proses macet meninggalkan file SQLite dalam keadaan tidak dapat digunakan. Dalam hal ini, lihat jawaban saya.
robert
90
Saya menyebabkan sqlite db menjadi terkunci dengan menabrak aplikasi saat menulis. Inilah cara saya memperbaikinya:
sqlite3:sqlite> .dump PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; /**** ERROR: (5) database is locked *****/ ROLLBACK; -- due to errors
woky
Tidak bekerja untukFOREIGN KEY constraint failed (RELEASE RESTOREPOINT)
gies0r
52
Halaman DatabaseIsLocked yang tercantum di bawah tidak lagi tersedia. Halaman Penguncian File dan Konkurensi menjelaskan perubahan terkait penguncian file yang diperkenalkan di v3 dan mungkin bermanfaat bagi pembaca di masa mendatang. https://www.sqlite.org/lockingv3.html
Halaman DatabaseIsLocked SQLiki wiki menawarkan penjelasan yang baik tentang pesan kesalahan ini. Ini menyatakan, sebagian, bahwa sumber pertengkaran adalah internal (untuk proses memancarkan kesalahan).
Apa yang tidak dijelaskan halaman ini adalah bagaimana SQLite memutuskan bahwa sesuatu dalam proses Anda memegang kunci dan kondisi apa yang dapat mengarah pada false positive.
Masalahnya adalah halaman tersebut salah atau kedaluwarsa: Saya memiliki proses yang tidak melakukan apa-apa selain satu INSERT yang mendapatkan pesan yang dikunci: tidak mungkin proses ini menyebabkan kunci. Masalahnya adalah dalam proses lain berbicara dengan DB yang sama.
Dan Jameson
4
@ converter42 Tautan rusak.
Ole Tange
32
Menghapus file -jurnal terdengar seperti ide yang buruk. Itu ada di sana untuk memungkinkan sqlite untuk memutar kembali database ke keadaan yang konsisten setelah crash. Jika Anda menghapusnya saat database dalam keadaan tidak konsisten, maka Anda pergi dengan database yang rusak. Mengutip halaman dari situs sqlite :
Jika crash atau kehilangan daya memang terjadi dan jurnal panas dibiarkan di disk, sangat penting bahwa file database asli dan jurnal panas tetap di disk dengan nama asli mereka sampai file database dibuka oleh proses SQLite lain dan digulung kembali . [...]
Kami menduga bahwa mode kegagalan umum untuk pemulihan SQLite terjadi seperti ini: Terjadi kegagalan daya. Setelah daya pulih, pengguna atau administrator sistem yang bermaksud baik mulai mencari-cari kerusakan pada disk. Mereka melihat file database mereka bernama "important.data". File ini mungkin tidak asing bagi mereka. Tetapi setelah crash, ada juga jurnal panas bernama "important.data-journal". Pengguna kemudian menghapus jurnal panas, berpikir bahwa mereka membantu membersihkan sistem. Kami tahu tidak ada cara untuk mencegah hal ini selain dari pendidikan pengguna.
Kembalikan seharusnya terjadi secara otomatis saat berikutnya database dibuka, tetapi itu akan gagal jika proses tidak dapat mengunci database. Seperti yang dikatakan orang lain, salah satu alasan yang memungkinkan untuk ini adalah bahwa proses lain saat ini terbuka. Kemungkinan lain adalah kunci NFS basi, jika database pada volume NFS. Dalam hal ini, solusinya adalah mengganti file database dengan salinan baru yang tidak terkunci pada server NFS (mv database.db original.db; cp original.db database.db). Perhatikan bahwa FAQ sqlite merekomendasikan kehati-hatian tentang akses bersamaan ke database pada volume NFS, karena implementasi penguncian file NFS yang bermasalah.
Saya tidak bisa menjelaskan mengapa menghapus file -jurnal akan membiarkan Anda mengunci basis data yang sebelumnya tidak bisa Anda lakukan. Apakah itu dapat direproduksi?
Ngomong-ngomong, keberadaan file -jurnal tidak selalu berarti bahwa ada crash atau ada perubahan yang harus dibatalkan. Sqlite memiliki beberapa mode jurnal yang berbeda, dan dalam mode PERSIST atau TRUNCATE ia meninggalkan file -jurnal pada tempatnya, dan mengubah konten untuk menunjukkan apakah ada transaksi parsial untuk memutar kembali.
Saya mencoba 'fuser <DB>' seperti dijelaskan di atas, tetapi tidak berhasil. Langkah sederhana ini berhasil untuk saya.
Jackie Yeh
Dalam kasus saya, saya juga harus me-restart Notebook Jupyter saya.
Victor
15
Jika suatu proses memiliki kunci pada DB SQLite dan crash, DB tetap terkunci secara permanen. Itulah masalahnya. Bukannya beberapa proses lain memiliki kunci.
Ini tidak benar. Kunci dikelola oleh OS. Baca jawabannya di bawah ini.
JJ
13
file db SQLite hanyalah file, jadi langkah pertama adalah memastikan itu bukan hanya-baca. Hal lain yang harus dilakukan adalah memastikan bahwa Anda tidak memiliki semacam penampil DB GUI SQLite dengan DB terbuka. Anda bisa membuka DB di shell lain, atau kode Anda mungkin memiliki DB terbuka. Biasanya Anda akan melihat ini jika utas yang berbeda, atau aplikasi seperti SQLite Database Browser memiliki DB terbuka untuk ditulis.
Dalam pengalaman saya, SQLite Database Browser (SDB) secara reproduktif mengunci basis data jika Anda mengedit data dengannya tetapi kemudian tidak menyimpannya di SDB. Jika Anda menyimpannya, itu melepaskan kunci.
Chelonian
Saya bisa menyisipkan tetapi saya tidak bisa menghapus.
Wennie
10
Saya punya masalah ini sekarang, menggunakan database SQLite pada server jauh, disimpan pada mount NFS. SQLite tidak dapat memperoleh kunci setelah sesi shell remote yang saya gunakan mengalami crash ketika database terbuka.
Resep untuk pemulihan yang disarankan di atas tidak bekerja untuk saya (termasuk ide untuk memindahkan terlebih dahulu dan kemudian menyalin database kembali). Tetapi setelah menyalinnya ke sistem non-NFS, database menjadi dapat digunakan dan bukan data yang tampaknya telah hilang.
Kunci saya disebabkan oleh sistem crash dan bukan oleh proses gantung. Untuk mengatasi ini saya cukup mengganti nama file kemudian menyalinnya kembali ke nama dan lokasi aslinya.
Saya menemukan dokumentasi berbagai negara mengunci SQLite sangat membantu. Michael, jika Anda dapat melakukan membaca tetapi tidak dapat melakukan menulis ke database, itu berarti bahwa suatu proses telah mendapatkan kunci RESERVED pada database Anda tetapi belum menjalankan penulisan. Jika Anda menggunakan SQLite3, ada kunci baru yang disebut PENDING di mana tidak ada lagi proses yang diizinkan untuk menyambungkan tetapi koneksi yang ada dapat tetap melakukan pembacaan, jadi jika ini masalahnya, Anda harus melihatnya.
Kesalahan ini dapat terjadi jika file ada di folder jarak jauh, seperti folder bersama. Saya mengubah database ke direktori lokal dan itu bekerja dengan sempurna.
Saya memiliki masalah seperti itu di dalam aplikasi, yang mengakses SQLite dari 2 koneksi - satu hanya-baca dan yang kedua untuk menulis dan membaca. Sepertinya koneksi read-only memblokir penulisan dari koneksi kedua. Akhirnya, ternyata diperlukan untuk menyelesaikan atau, setidaknya, mengatur ulang pernyataan yang disiapkan SEGERA setelah digunakan. Sampai pernyataan yang disiapkan dibuka, itu menyebabkan database diblokir untuk penulisan.
Beberapa fungsi, seperti INDEX'ing, dapat memakan waktu sangat lama - dan mengunci seluruh basis data saat dijalankan. Dalam hal seperti itu, bahkan mungkin tidak menggunakan file jurnal!
Jadi cara terbaik / satu-satunya untuk memeriksa apakah basis data Anda terkunci karena suatu proses AKTIF menulisnya (dan dengan demikian Anda harus membiarkannya sendiri sampai selesai operasinya) adalah dengan md5 (atau md5sum pada beberapa sistem) file dua kali . Jika Anda mendapatkan checksum yang berbeda, database sedang ditulis, dan Anda benar-benar BENAR-BENAR tidak ingin membunuh -9 proses itu karena Anda dapat dengan mudah berakhir dengan tabel / database yang korup jika Anda melakukannya.
Saya akan mengulangi, karena ini penting - solusinya adalah TIDAK menemukan program penguncian dan membunuhnya - itu untuk menemukan apakah database memiliki kunci tulis untuk alasan yang baik, dan pergi dari sana. Terkadang solusi yang tepat adalah hanya coffee break.
Satu-satunya cara untuk membuat situasi terkunci-tapi-tidak-sedang-ditulis-ke ini adalah jika program Anda berjalan BEGIN EXCLUSIVE, karena ingin melakukan beberapa perubahan tabel atau sesuatu, maka untuk alasan apa pun tidak pernah mengirim ENDsesudahnya, dan proses tidak pernah berakhir . Ketiga kondisi yang dipenuhi sangat tidak mungkin dalam kode yang ditulis dengan benar, dan dengan demikian 99 kali dari 100 ketika seseorang ingin membunuh -9 proses penguncian mereka, proses penguncian sebenarnya mengunci database Anda untuk alasan yang baik. Pemrogram biasanya tidak menambahkan BEGIN EXCLUSIVEkondisi kecuali mereka benar-benar perlu, karena mencegah konkurensi dan meningkatkan keluhan pengguna. SQLite sendiri hanya menambahkannya ketika benar-benar perlu (seperti saat pengindeksan).
Akhirnya, status 'terkunci' tidak ada DI DALAM file seperti yang telah dijawab beberapa jawaban - ia berada di kernel Sistem Operasi. Proses yang dijalankan BEGIN EXCLUSIVEtelah meminta dari OS kunci ditempatkan pada file. Bahkan jika proses eksklusif Anda macet, OS Anda akan dapat mengetahui apakah harus menjaga kunci file atau tidak !! Tidak mungkin berakhir dengan basis data yang terkunci tetapi tidak ada proses yang secara aktif menguncinya !! Ketika datang untuk melihat proses mana yang mengunci file, biasanya lebih baik menggunakan lsof daripada fuser (ini adalah demonstrasi yang bagus tentang mengapa: /unix/94316/fuser-vs-lsof- to-check-files-in-use ). Atau jika Anda memiliki DTrace (OSX), Anda dapat menggunakan iosnoop pada file.
Saya baru saja mengalami hal serupa pada saya - aplikasi web saya dapat membaca dari database, tetapi tidak dapat melakukan sisipan atau pembaruan. Reboot Apache memecahkan masalah setidaknya untuk sementara waktu.
Akan lebih baik, bagaimanapun, untuk dapat melacak penyebab dasarnya.
Perintah lsof di lingkungan Linux saya membantu saya mengetahui bahwa ada proses yang menggantung agar file tetap terbuka.
Membunuh proses dan masalah terpecahkan.
Seharusnya menjadi masalah internal basis data ...
Bagi saya itu telah dimanifestasikan setelah mencoba menelusuri basis data dengan "SQLite manager" ...
Jadi, jika Anda tidak dapat menemukan proses lain terhubung ke basis data dan Anda tidak dapat memperbaikinya, coba saja solusi radikal ini:
Berikan untuk mengekspor tabel Anda (Anda dapat menggunakan "SQLite manager" di Firefox)
Jika migrasi mengubah skema database Anda, hapus migrasi yang gagal terakhir
Ganti nama file "database.sqlite" Anda
Jalankan "rake db: migrate" untuk membuat database yang berfungsi
Berikan untuk memberikan izin yang tepat ke database untuk mengimpor tabel
Saya mengalami masalah yang sama pada Mac OS X 10.5.7 menjalankan skrip Python dari sesi terminal. Meskipun saya telah menghentikan skrip dan jendela terminal duduk di command prompt, itu akan memberikan kesalahan ini saat dijalankan berikutnya. Solusinya adalah dengan menutup jendela terminal dan kemudian membukanya lagi. Tidak masuk akal bagi saya, tetapi itu berhasil.
Saya baru saja mengalami kesalahan yang sama. Setelah 5 menit google-ing saya menemukan bahwa saya tidak menutup satu penyihir shell menggunakan db. Tutup saja dan coba lagi;)
Saya memiliki masalah yang sama. Rupanya fungsi rollback tampaknya menimpa file db dengan jurnal yang sama dengan file db tetapi tanpa perubahan terbaru. Saya sudah menerapkan ini dalam kode saya di bawah ini dan sudah berfungsi dengan baik sejak saat itu, sedangkan sebelum kode saya hanya akan terjebak dalam loop karena database tetap terkunci.
Semoga ini membantu
kode python saya
################## Defs ##################
def conn_exec( connection ,cursor, cmd_str ):
done = False
try_count =0.0whilenot done:
try:cursor.execute( cmd_str )
done = True
except sqlite.IntegrityError:# Ignore this error because it means the item already existsin 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 for2 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.0whilenot done:
try:
connection.commit()
done = True
except sqlite.IntegrityError:# Ignore this error because it means the item already existsin 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 for2 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 ifdatabase 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 )
Salah satu alasan umum untuk mendapatkan pengecualian ini adalah ketika Anda mencoba melakukan operasi tulis sambil tetap memegang sumber daya untuk operasi baca. Misalnya, jika Anda MEMILIH dari tabel, dan kemudian mencoba untuk MEMPERBARUI sesuatu yang telah Anda pilih tanpa menutup ResultSet Anda terlebih dahulu.
Saya mengalami "database terkunci" kesalahan dalam aplikasi multi-threaded juga, yang tampaknya menjadi kode hasil SQLITE_BUSY , dan saya menyelesaikannya dengan menetapkan sqlite3_busy_timeout ke sesuatu yang sesuai dengan panjang seperti 30000.
(Di samping catatan, betapa aneh bahwa pada pertanyaan berusia 7 tahun tidak ada yang tahu ini! SQLite benar-benar adalah proyek yang aneh dan menakjubkan ...)
Sebuah pertanyaan lama, dengan banyak jawaban, inilah langkah-langkah yang saya ikuti baru-baru ini membaca jawaban di atas, tetapi dalam kasus saya masalahnya adalah karena berbagi sumber daya cifs. Kasus ini tidak dilaporkan sebelumnya, jadi semoga membantu seseorang.
Periksa tidak ada koneksi yang dibiarkan terbuka di kode java Anda.
Periksa tidak ada proses lain yang menggunakan file db SQLite Anda dengan lsof.
Periksa pemilik pengguna yang menjalankan proses jvm Anda memiliki r / w izin atas file tersebut.
Cobalah untuk memaksa mode kunci pada pembukaan koneksi dengan
final SQLiteConfig config = new SQLiteConfig();
config.setReadOnly(false);
config.setLockingMode(LockingMode.NORMAL);
connection = DriverManager.getConnection(url, config.toProperties());
Jika Anda menggunakan file db SQLite Anda di folder bersama NFS, periksa titik faq SQLite ini, dan tinjau opsi konfigurasi pemasangan Anda untuk memastikan Anda menghindari kunci, seperti dijelaskan di sini :
Saya mendapatkan kesalahan ini dalam skenario yang sedikit berbeda dari yang dijelaskan di sini.
Basis data SQLite bersandar pada sistem file NFS yang dibagikan oleh 3 server. Pada 2 server saya berhasil menjalankan query pada database, pada pemikiran ketiga saya mendapatkan pesan "database is locked".
Masalahnya dengan mesin ke-3 ini adalah tidak ada ruang tersisa /var. Setiap kali saya mencoba menjalankan kueri di database SQL APAPUN yang terletak di sistem file ini, saya menerima pesan "database is locked" dan juga kesalahan ini di atas log:
8 Agustus 10:33:38 server01 kernel: lockd: tidak dapat memantau 172.22.84.87
Dan yang ini juga:
8 Agustus 10:33:38 server01 rpc.statd [7430]: Gagal menyisipkan: menulis /var/lib/nfs/statd/sm/other.server.name.com: Tidak ada ruang tersisa di perangkat 8 Agustus 10:33: 38 server01 rpc.statd [7430]: STAT_FAIL ke server01 untuk SM_MON dari 172.22.84.87
Setelah situasi ruang ditangani semuanya kembali normal.
Jika Anda mencoba membuka kunci basis data Chrome untuk melihatnya dengan SQLite , maka matikan saja Chrome.
Windows
%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
Mac
~/Library/Application Support/Google/Chrome/Default/Web Data
Dari komentar Anda sebelumnya, Anda mengatakan file jurnal ada.
Ini bisa berarti bahwa Anda telah membuka dan (EKSKLUSIF?) Transaksi dan belum melakukan data. Apakah program Anda atau proses lain meninggalkan -jurnal?
Restart proses sqlite akan melihat file jurnal dan membersihkan setiap tindakan yang tidak berkomitmen dan menghapus file -journal
Seperti dikatakan Seun Osewa, kadang-kadang proses zombie akan duduk di terminal dengan kunci yang diperoleh, bahkan jika Anda tidak berpikir itu mungkin. Script Anda berjalan, macet, dan Anda kembali ke prompt, tetapi ada proses zombie yang muncul di suatu tempat oleh panggilan perpustakaan, dan proses itu memiliki kunci.
Menutup terminal tempat Anda berada (pada OSX) mungkin berhasil. Mulai ulang akan berhasil. Anda bisa mencari proses "python" (misalnya) yang tidak melakukan apa-apa, dan membunuh mereka.
Anda dapat mencoba ini: .timeout 100untuk mengatur batas waktu. Saya tidak tahu apa yang terjadi di baris perintah tetapi di C # .Net ketika saya melakukan ini: "UPDATE table-name SET column-name = value;"Saya mendapatkan Basis Data terkunci tetapi ini "UPDATE table-name SET column-name = value"berjalan dengan baik.
Sepertinya ketika Anda menambahkan;, sqlite akan mencari perintah lebih lanjut.
Jawaban:
Di windows Anda dapat mencoba program ini http://www.nirsoft.net/utils/opened_files_view.html untuk mengetahui proses penanganan file db. Coba tutup program itu untuk membuka kunci basis data
Di Linux dan macOS Anda dapat melakukan sesuatu yang serupa, misalnya, jika file Anda terkunci pengembangan.db:
Perintah ini akan menunjukkan proses apa yang mengunci file:
Bunuh saja prosesnya ...
... Dan basis data Anda akan dibuka.
sumber
kill
harus baik-baik saja, tetapi Anda harus berhati-hati untuk membunuhnya dengan benar, dankill -9
mungkin salah dan / atau berlebihan. Jika prosesnya terhenti dan tidak akan mati, terkadang Anda memang membutuhkannyakill -9
. Tetapi Anda tidak ingin pergi dan mematikan pekerjaan produksi utama hanya agar Anda dapat melaporkan bahwa basis data tidak lagi terkunci!Saya menyebabkan sqlite db menjadi terkunci dengan menabrak aplikasi saat menulis. Inilah cara saya memperbaikinya:
Diambil dari: http://random.kakaopor.hu/how-to-repair-an-sqlite-database
sumber
sqlite> .dump PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; /**** ERROR: (5) database is locked *****/ ROLLBACK; -- due to errors
FOREIGN KEY constraint failed (RELEASE RESTOREPOINT)
Halaman DatabaseIsLocked yang tercantum di bawah tidak lagi tersedia. Halaman Penguncian File dan Konkurensi menjelaskan perubahan terkait penguncian file yang diperkenalkan di v3 dan mungkin bermanfaat bagi pembaca di masa mendatang. https://www.sqlite.org/lockingv3.html
Halaman DatabaseIsLocked SQLiki wiki menawarkan penjelasan yang baik tentang pesan kesalahan ini. Ini menyatakan, sebagian, bahwa sumber pertengkaran adalah internal (untuk proses memancarkan kesalahan).
Apa yang tidak dijelaskan halaman ini adalah bagaimana SQLite memutuskan bahwa sesuatu dalam proses Anda memegang kunci dan kondisi apa yang dapat mengarah pada false positive.
sumber
Menghapus file -jurnal terdengar seperti ide yang buruk. Itu ada di sana untuk memungkinkan sqlite untuk memutar kembali database ke keadaan yang konsisten setelah crash. Jika Anda menghapusnya saat database dalam keadaan tidak konsisten, maka Anda pergi dengan database yang rusak. Mengutip halaman dari situs sqlite :
Kembalikan seharusnya terjadi secara otomatis saat berikutnya database dibuka, tetapi itu akan gagal jika proses tidak dapat mengunci database. Seperti yang dikatakan orang lain, salah satu alasan yang memungkinkan untuk ini adalah bahwa proses lain saat ini terbuka. Kemungkinan lain adalah kunci NFS basi, jika database pada volume NFS. Dalam hal ini, solusinya adalah mengganti file database dengan salinan baru yang tidak terkunci pada server NFS (mv database.db original.db; cp original.db database.db). Perhatikan bahwa FAQ sqlite merekomendasikan kehati-hatian tentang akses bersamaan ke database pada volume NFS, karena implementasi penguncian file NFS yang bermasalah.
Saya tidak bisa menjelaskan mengapa menghapus file -jurnal akan membiarkan Anda mengunci basis data yang sebelumnya tidak bisa Anda lakukan. Apakah itu dapat direproduksi?
Ngomong-ngomong, keberadaan file -jurnal tidak selalu berarti bahwa ada crash atau ada perubahan yang harus dibatalkan. Sqlite memiliki beberapa mode jurnal yang berbeda, dan dalam mode PERSIST atau TRUNCATE ia meninggalkan file -jurnal pada tempatnya, dan mengubah konten untuk menunjukkan apakah ada transaksi parsial untuk memutar kembali.
sumber
Jika Anda ingin menghapus kesalahan "basis data dikunci" maka ikuti langkah-langkah ini:
sumber
Jika suatu proses memiliki kunci pada DB SQLite dan crash, DB tetap terkunci secara permanen. Itulah masalahnya. Bukannya beberapa proses lain memiliki kunci.
sumber
file db SQLite hanyalah file, jadi langkah pertama adalah memastikan itu bukan hanya-baca. Hal lain yang harus dilakukan adalah memastikan bahwa Anda tidak memiliki semacam penampil DB GUI SQLite dengan DB terbuka. Anda bisa membuka DB di shell lain, atau kode Anda mungkin memiliki DB terbuka. Biasanya Anda akan melihat ini jika utas yang berbeda, atau aplikasi seperti SQLite Database Browser memiliki DB terbuka untuk ditulis.
sumber
Saya punya masalah ini sekarang, menggunakan database SQLite pada server jauh, disimpan pada mount NFS. SQLite tidak dapat memperoleh kunci setelah sesi shell remote yang saya gunakan mengalami crash ketika database terbuka.
Resep untuk pemulihan yang disarankan di atas tidak bekerja untuk saya (termasuk ide untuk memindahkan terlebih dahulu dan kemudian menyalin database kembali). Tetapi setelah menyalinnya ke sistem non-NFS, database menjadi dapat digunakan dan bukan data yang tampaknya telah hilang.
sumber
Kunci saya disebabkan oleh sistem crash dan bukan oleh proses gantung. Untuk mengatasi ini saya cukup mengganti nama file kemudian menyalinnya kembali ke nama dan lokasi aslinya.
Menggunakan shell linux yang akan ...
sumber
Saya menambahkan "
Pooling=true
" ke string koneksi dan itu berhasil.sumber
Saya menemukan dokumentasi berbagai negara mengunci SQLite sangat membantu. Michael, jika Anda dapat melakukan membaca tetapi tidak dapat melakukan menulis ke database, itu berarti bahwa suatu proses telah mendapatkan kunci RESERVED pada database Anda tetapi belum menjalankan penulisan. Jika Anda menggunakan SQLite3, ada kunci baru yang disebut PENDING di mana tidak ada lagi proses yang diizinkan untuk menyambungkan tetapi koneksi yang ada dapat tetap melakukan pembacaan, jadi jika ini masalahnya, Anda harus melihatnya.
sumber
Kesalahan ini dapat terjadi jika file ada di folder jarak jauh, seperti folder bersama. Saya mengubah database ke direktori lokal dan itu bekerja dengan sempurna.
sumber
Saya memiliki masalah seperti itu di dalam aplikasi, yang mengakses SQLite dari 2 koneksi - satu hanya-baca dan yang kedua untuk menulis dan membaca. Sepertinya koneksi read-only memblokir penulisan dari koneksi kedua. Akhirnya, ternyata diperlukan untuk menyelesaikan atau, setidaknya, mengatur ulang pernyataan yang disiapkan SEGERA setelah digunakan. Sampai pernyataan yang disiapkan dibuka, itu menyebabkan database diblokir untuk penulisan.
JANGAN LUPA PANGGILAN:
atau
sumber
Beberapa fungsi, seperti INDEX'ing, dapat memakan waktu sangat lama - dan mengunci seluruh basis data saat dijalankan. Dalam hal seperti itu, bahkan mungkin tidak menggunakan file jurnal!
Jadi cara terbaik / satu-satunya untuk memeriksa apakah basis data Anda terkunci karena suatu proses AKTIF menulisnya (dan dengan demikian Anda harus membiarkannya sendiri sampai selesai operasinya) adalah dengan md5 (atau md5sum pada beberapa sistem) file dua kali . Jika Anda mendapatkan checksum yang berbeda, database sedang ditulis, dan Anda benar-benar BENAR-BENAR tidak ingin membunuh -9 proses itu karena Anda dapat dengan mudah berakhir dengan tabel / database yang korup jika Anda melakukannya.
Saya akan mengulangi, karena ini penting - solusinya adalah TIDAK menemukan program penguncian dan membunuhnya - itu untuk menemukan apakah database memiliki kunci tulis untuk alasan yang baik, dan pergi dari sana. Terkadang solusi yang tepat adalah hanya coffee break.
Satu-satunya cara untuk membuat situasi terkunci-tapi-tidak-sedang-ditulis-ke ini adalah jika program Anda berjalan
BEGIN EXCLUSIVE
, karena ingin melakukan beberapa perubahan tabel atau sesuatu, maka untuk alasan apa pun tidak pernah mengirimEND
sesudahnya, dan proses tidak pernah berakhir . Ketiga kondisi yang dipenuhi sangat tidak mungkin dalam kode yang ditulis dengan benar, dan dengan demikian 99 kali dari 100 ketika seseorang ingin membunuh -9 proses penguncian mereka, proses penguncian sebenarnya mengunci database Anda untuk alasan yang baik. Pemrogram biasanya tidak menambahkanBEGIN EXCLUSIVE
kondisi kecuali mereka benar-benar perlu, karena mencegah konkurensi dan meningkatkan keluhan pengguna. SQLite sendiri hanya menambahkannya ketika benar-benar perlu (seperti saat pengindeksan).Akhirnya, status 'terkunci' tidak ada DI DALAM file seperti yang telah dijawab beberapa jawaban - ia berada di kernel Sistem Operasi. Proses yang dijalankan
BEGIN EXCLUSIVE
telah meminta dari OS kunci ditempatkan pada file. Bahkan jika proses eksklusif Anda macet, OS Anda akan dapat mengetahui apakah harus menjaga kunci file atau tidak !! Tidak mungkin berakhir dengan basis data yang terkunci tetapi tidak ada proses yang secara aktif menguncinya !! Ketika datang untuk melihat proses mana yang mengunci file, biasanya lebih baik menggunakan lsof daripada fuser (ini adalah demonstrasi yang bagus tentang mengapa: /unix/94316/fuser-vs-lsof- to-check-files-in-use ). Atau jika Anda memiliki DTrace (OSX), Anda dapat menggunakan iosnoop pada file.sumber
Saya baru saja mengalami hal serupa pada saya - aplikasi web saya dapat membaca dari database, tetapi tidak dapat melakukan sisipan atau pembaruan. Reboot Apache memecahkan masalah setidaknya untuk sementara waktu.
Akan lebih baik, bagaimanapun, untuk dapat melacak penyebab dasarnya.
sumber
Perintah lsof di lingkungan Linux saya membantu saya mengetahui bahwa ada proses yang menggantung agar file tetap terbuka.
Membunuh proses dan masalah terpecahkan.
sumber
Tautan ini memecahkan masalah. : Ketika Sqlite memberikan: Kesalahan terkunci di basis data Memecahkan masalah saya mungkin bermanfaat bagi Anda.
Dan Anda dapat menggunakan mulai transaksi dan akhiri transaksi untuk tidak membuat basis data dikunci di masa mendatang.
sumber
Seharusnya menjadi masalah internal basis data ...
Bagi saya itu telah dimanifestasikan setelah mencoba menelusuri basis data dengan "SQLite manager" ...
Jadi, jika Anda tidak dapat menemukan proses lain terhubung ke basis data dan Anda tidak dapat memperbaikinya, coba saja solusi radikal ini:
rake db:migrate
"sumber
Saya mengalami masalah yang sama pada Mac OS X 10.5.7 menjalankan skrip Python dari sesi terminal. Meskipun saya telah menghentikan skrip dan jendela terminal duduk di command prompt, itu akan memberikan kesalahan ini saat dijalankan berikutnya. Solusinya adalah dengan menutup jendela terminal dan kemudian membukanya lagi. Tidak masuk akal bagi saya, tetapi itu berhasil.
sumber
Saya baru saja mengalami kesalahan yang sama. Setelah 5 menit google-ing saya menemukan bahwa saya tidak menutup satu penyihir shell menggunakan db. Tutup saja dan coba lagi;)
sumber
Saya memiliki masalah yang sama. Rupanya fungsi rollback tampaknya menimpa file db dengan jurnal yang sama dengan file db tetapi tanpa perubahan terbaru. Saya sudah menerapkan ini dalam kode saya di bawah ini dan sudah berfungsi dengan baik sejak saat itu, sedangkan sebelum kode saya hanya akan terjebak dalam loop karena database tetap terkunci.
Semoga ini membantu
kode python saya
sumber
Salah satu alasan umum untuk mendapatkan pengecualian ini adalah ketika Anda mencoba melakukan operasi tulis sambil tetap memegang sumber daya untuk operasi baca. Misalnya, jika Anda MEMILIH dari tabel, dan kemudian mencoba untuk MEMPERBARUI sesuatu yang telah Anda pilih tanpa menutup ResultSet Anda terlebih dahulu.
sumber
Saya mengalami "database terkunci" kesalahan dalam aplikasi multi-threaded juga, yang tampaknya menjadi kode hasil SQLITE_BUSY , dan saya menyelesaikannya dengan menetapkan sqlite3_busy_timeout ke sesuatu yang sesuai dengan panjang seperti 30000.
(Di samping catatan, betapa aneh bahwa pada pertanyaan berusia 7 tahun tidak ada yang tahu ini! SQLite benar-benar adalah proyek yang aneh dan menakjubkan ...)
sumber
Sebelum turun opsi reboot, ada baiknya untuk melihat apakah Anda dapat menemukan pengguna dari database sqlite.
Di Linux, seseorang dapat menggunakan
fuser
untuk tujuan ini:Dalam kasus saya, saya mendapat respons berikut:
Yang menunjukkan bahwa saya punya program Python lain dengan pid 3556 (manage.py) menggunakan database.
sumber
Sebuah pertanyaan lama, dengan banyak jawaban, inilah langkah-langkah yang saya ikuti baru-baru ini membaca jawaban di atas, tetapi dalam kasus saya masalahnya adalah karena berbagi sumber daya cifs. Kasus ini tidak dilaporkan sebelumnya, jadi semoga membantu seseorang.
Cobalah untuk memaksa mode kunci pada pembukaan koneksi dengan
Jika Anda menggunakan file db SQLite Anda di folder bersama NFS, periksa titik faq SQLite ini, dan tinjau opsi konfigurasi pemasangan Anda untuk memastikan Anda menghindari kunci, seperti dijelaskan di sini :
sumber
Saya mendapatkan kesalahan ini dalam skenario yang sedikit berbeda dari yang dijelaskan di sini.
Basis data SQLite bersandar pada sistem file NFS yang dibagikan oleh 3 server. Pada 2 server saya berhasil menjalankan query pada database, pada pemikiran ketiga saya mendapatkan pesan "database is locked".
Masalahnya dengan mesin ke-3 ini adalah tidak ada ruang tersisa
/var
. Setiap kali saya mencoba menjalankan kueri di database SQL APAPUN yang terletak di sistem file ini, saya menerima pesan "database is locked" dan juga kesalahan ini di atas log:Dan yang ini juga:
Setelah situasi ruang ditangani semuanya kembali normal.
sumber
Jika Anda mencoba membuka kunci basis data Chrome untuk melihatnya dengan SQLite , maka matikan saja Chrome.
Windows
Mac
sumber
Dari komentar Anda sebelumnya, Anda mengatakan file jurnal ada.
Ini bisa berarti bahwa Anda telah membuka dan (EKSKLUSIF?) Transaksi dan belum melakukan data. Apakah program Anda atau proses lain meninggalkan -jurnal?
Restart proses sqlite akan melihat file jurnal dan membersihkan setiap tindakan yang tidak berkomitmen dan menghapus file -journal
sumber
Seperti dikatakan Seun Osewa, kadang-kadang proses zombie akan duduk di terminal dengan kunci yang diperoleh, bahkan jika Anda tidak berpikir itu mungkin. Script Anda berjalan, macet, dan Anda kembali ke prompt, tetapi ada proses zombie yang muncul di suatu tempat oleh panggilan perpustakaan, dan proses itu memiliki kunci.
Menutup terminal tempat Anda berada (pada OSX) mungkin berhasil. Mulai ulang akan berhasil. Anda bisa mencari proses "python" (misalnya) yang tidak melakukan apa-apa, dan membunuh mereka.
sumber
Anda dapat mencoba ini:
.timeout 100
untuk mengatur batas waktu. Saya tidak tahu apa yang terjadi di baris perintah tetapi di C # .Net ketika saya melakukan ini:"UPDATE table-name SET column-name = value;"
Saya mendapatkan Basis Data terkunci tetapi ini"UPDATE table-name SET column-name = value"
berjalan dengan baik.Sepertinya ketika Anda menambahkan;, sqlite akan mencari perintah lebih lanjut.
sumber