ฉันจะปลดล็อกฐานข้อมูล SQLite ได้อย่างไร


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

ฉันจะปลดล็อกฐานข้อมูลเพื่อให้ทำงานได้อย่างไร


อาจมีกระบวนการอื่นเข้าถึงไฟล์ฐานข้อมูล - คุณตรวจสอบ lsof หรือไม่
ร่วม

ฉันมีปัญหาเดียวกันปัญหาคือในโปรแกรมป้องกันไวรัสเมื่อฉันปิดการใช้งานแอพของฉันทำงานได้ดี แต่เมื่อฉันเปิดใช้งานฉันพบข้อผิดพลาดบางอย่าง "ฐานข้อมูลถูกล็อค" ฉันหวังว่าจะช่วยคุณ
user8510915

คำตอบ:


267

ใน windows คุณสามารถลองใช้โปรแกรมนี้http://www.nirsoft.net/utils/opened_files_view.htmlเพื่อค้นหากระบวนการกำลังจัดการไฟล์ db ลองปิดโปรแกรมนั้นเพื่อปลดล็อกฐานข้อมูล

ใน Linux และ macOS คุณสามารถทำสิ่งที่คล้ายกันได้เช่นหากไฟล์ที่ถูกล็อคของคุณคือ development.db:

$ fuser development.db

คำสั่งนี้จะแสดงกระบวนการที่ล็อกไฟล์:

> development.db: 5430

เพิ่งฆ่ากระบวนการ ...

ฆ่า -9 5430

... และฐานข้อมูลของคุณจะถูกปลดล็อค


19
... ด้วยข้อแม้ที่ชัดเจนที่คุณต้องรู้ว่าคุณกำลังทำอะไรอยู่ หากเป็นกระบวนการที่ไม่สำคัญก็killควรจะดี แต่คุณต้องระมัดระวังในการฆ่าอย่างถูกต้องและkill -9อาจผิดและ / หรือมากเกินไป kill -9หากกระบวนการแขวนและจะไม่เป็นอย่างอื่นตายบางครั้งคุณไม่จำเป็นที่จะต้อง แต่คุณไม่ต้องการไปและฆ่างานผลิตหลักเพียงเพื่อให้คุณสามารถรายงานว่าฐานข้อมูลไม่ถูกล็อคอีกต่อไป!
tripleee

วิธีที่ง่ายกว่าคือเพียงรีสตาร์ทคอมพิวเตอร์
chacham15

7
@ chacham15: คุณคิดว่าฐานข้อมูลอยู่ในคอมพิวเตอร์ "ของฉัน" และคุณไม่สนใจความเป็นไปได้ของกระบวนการที่สำคัญมากมายที่ทำงานบนคอมพิวเตอร์เครื่องเดียวกับที่มีฐานข้อมูลที่ถูกล็อค “ความเรียบง่าย” การแก้ปัญหาคือไม่เคยว่าง่าย;)
tzot

1
@ KyleCarlson - sqlite และ mysql นั้นมีความแตกต่างกันในด้านนั้น ไม่มีอะไรผิดปกติกับ SQLite-db-browser
Berry Tsakala

6
วิธีแก้ปัญหานี้อนุมานว่ามีกระบวนการในการล็อคไฟล์ อาจเป็นไปได้ว่ากระบวนการขัดข้องปล่อยให้ไฟล์ SQLite อยู่ในสถานะที่ใช้ไม่ได้ ในกรณีนี้ดูคำตอบของฉัน
เบิ

90

ฉันทำให้ sqlite db ของฉันถูกล็อคโดยหยุดทำงานแอพระหว่างการเขียน นี่คือวิธีที่ฉันแก้ไขมัน:

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

นำมาจาก: http://random.kakaopor.hu/how-to-repair-an-sqlite-database


4
sqlite3:sqlite> .dump PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; /**** ERROR: (5) database is locked *****/ ROLLBACK; -- due to errors
woky

ไม่ทำงานFOREIGN KEY constraint failed (RELEASE RESTOREPOINT)
gies0r

52

หน้า DatabaseIsLocked ที่แสดงด้านล่างไม่สามารถใช้ได้อีกต่อไป หน้าการล็อกไฟล์และการทำงานพร้อมกันอธิบายการเปลี่ยนแปลงที่เกี่ยวข้องกับการล็อกไฟล์ที่แนะนำใน v3 และอาจเป็นประโยชน์สำหรับผู้อ่านในอนาคตhttps://www.sqlite.org/lockingv3.html

DatabaseIsLocked ของ SQLite wikiหน้าเสนอคำอธิบายที่ดีของข้อความแสดงข้อผิดพลาดนี้ บางส่วนระบุว่าแหล่งที่มาของการช่วงชิงเป็นภายใน (ไปยังกระบวนการที่ทำให้เกิดข้อผิดพลาด)

สิ่งที่หน้านี้ไม่ได้อธิบายคือวิธีที่ SQLite ตัดสินใจว่าบางสิ่งในกระบวนการของคุณมีการล็อคและเงื่อนไขใดที่อาจนำไปสู่การบวกผิด ๆ


2
ปัญหาคือหน้านั้นไม่ถูกต้องหรือล้าสมัย: ฉันมีกระบวนการที่ไม่ทำอะไรเลยนอกจาก INSERT เดียวที่ได้รับข้อความที่ถูกล็อคนั่นเป็นไปไม่ได้ที่กระบวนการนี้จะทำให้เกิดการล็อค ปัญหาเกิดขึ้นในกระบวนการอื่นที่กำลังพูดคุยกับฐานข้อมูลเดียวกัน
Dan Jameson

4
@ converter42 ลิงก์เสีย
Ole Tange

32

การลบไฟล์ -journal ดูเหมือนเป็นความคิดที่แย่มาก มีเพื่อให้ sqlite ย้อนกลับฐานข้อมูลไปสู่สถานะที่สอดคล้องหลังจากความผิดพลาด หากคุณลบในขณะที่ฐานข้อมูลอยู่ในสถานะที่ไม่สอดคล้องกันคุณจะเหลือฐานข้อมูลที่เสียหาย อ้างถึงหน้าจากเว็บไซต์ sqlite :

หากเกิดข้อผิดพลาดหรือการสูญเสียพลังงานและมีการบันทึกรายวันร้อนบนดิสก์จำเป็นต้องมีไฟล์ฐานข้อมูลดั้งเดิมและบันทึกประจำวันที่ร้อนอยู่บนดิสก์ด้วยชื่อเดิมจนกว่าจะเปิดไฟล์ฐานข้อมูลโดยกระบวนการ SQLite อื่นและย้อนกลับ . [ ... ]

เราสงสัยว่าโหมดความล้มเหลวทั่วไปสำหรับการกู้คืน SQLite เกิดขึ้นเช่นนี้: เกิดไฟฟ้าขัดข้อง หลังจากไฟฟ้าถูกกู้คืนผู้ใช้หรือผู้ดูแลระบบที่มีความหมายเริ่มมองไปรอบ ๆ บนดิสก์เพื่อดูความเสียหาย พวกเขาเห็นไฟล์ฐานข้อมูลชื่อ "important.data" ไฟล์นี้อาจคุ้นเคยกับพวกเขา แต่หลังจากความผิดพลาดนอกจากนี้ยังมีวารสารยอดนิยมชื่อ "important.data-journal" จากนั้นผู้ใช้ลบสมุดรายวันร้อนโดยคิดว่าพวกเขากำลังช่วยล้างข้อมูลระบบ เรารู้ว่าไม่มีวิธีใดที่จะป้องกันสิ่งนี้นอกจากการให้ความรู้แก่ผู้ใช้

การย้อนกลับควรเกิดขึ้นโดยอัตโนมัติในครั้งถัดไปที่ฐานข้อมูลถูกเปิด แต่จะล้มเหลวหากกระบวนการไม่สามารถล็อคฐานข้อมูล ดังที่คนอื่นได้กล่าวไว้เหตุผลหนึ่งที่เป็นไปได้สำหรับเรื่องนี้ก็คือกระบวนการอื่นเปิดอยู่ ความเป็นไปได้อีกอย่างหนึ่งคือล็อก NFS เก่าถ้าฐานข้อมูลอยู่บนวอลุ่ม NFS ในกรณีนั้นวิธีแก้ปัญหาคือการแทนที่ไฟล์ฐานข้อมูลด้วยสำเนาใหม่ที่ไม่ได้ล็อกบนเซิร์ฟเวอร์ NFS (mv database.db original.db; cp original.db database.db) โปรดทราบว่า sqlite FAQ แนะนำข้อควรระวังเกี่ยวกับการเข้าถึงฐานข้อมูลพร้อมกันบนวอลุ่ม NFS เนื่องจากการปรับใช้ buggy ของการล็อกไฟล์ NFS

ฉันไม่สามารถอธิบายได้ว่าทำไมการลบไฟล์ -journal จะช่วยให้คุณล็อคฐานข้อมูลที่คุณไม่เคยทำมาก่อน ทำซ้ำได้หรือไม่

การปรากฏตัวของไฟล์ -journal นั้นไม่ได้แปลว่ามีความผิดพลาดหรือมีการเปลี่ยนแปลงที่จะย้อนกลับ Sqlite มีโหมดวารสารที่แตกต่างกันสองสามรูปแบบและในโหมด PERSIST หรือ TRUNCATE มันจะทำให้ไฟล์ -journal เข้าที่เสมอและเปลี่ยนเนื้อหาเพื่อระบุว่ามีธุรกรรมบางส่วนที่จะย้อนกลับหรือไม่


23

หากคุณต้องการลบข้อผิดพลาด "ฐานข้อมูลถูกล็อค" ให้ทำตามขั้นตอนเหล่านี้:

  1. คัดลอกไฟล์ฐานข้อมูลของคุณไปยังตำแหน่งอื่น
  2. แทนที่ฐานข้อมูลด้วยฐานข้อมูลที่คัดลอก นี่จะเป็นการยกเลิกการประมวลผลทั้งหมดที่เข้าถึงไฟล์ฐานข้อมูลของคุณ

2
ฉันลอง 'fuser <DB>' ตามที่อธิบายไว้ข้างต้น แต่ไม่ได้ผล ขั้นตอนง่าย ๆ นี้ใช้ได้สำหรับฉัน
Jackie Yeh

ในกรณีของฉันฉันต้องรีสตาร์ท Jupyter Notebook ของฉันด้วย
วิคเตอร์

15

หากกระบวนการมีการล็อค SQLite DB และล้มเหลวฐานข้อมูลจะถูกล็อคอย่างถาวร นั่นคือปัญหา. ไม่ใช่ว่ากระบวนการอื่นมีการล็อค


48
ดังนั้นวิธีการปลดล็อคฐานข้อมูลหรือไม่
Erik Kaplun

4
สิ่งนี้ไม่เป็นความจริง ล็อคได้รับการดูแลโดยระบบปฏิบัติการ อ่านคำตอบด้านล่าง
JJ

13

ไฟล์ SQLite db เป็นเพียงไฟล์ดังนั้นขั้นตอนแรกคือการทำให้แน่ใจว่าไม่ใช่แบบอ่านอย่างเดียว สิ่งอื่น ๆ ที่ต้องทำคือให้แน่ใจว่าคุณไม่มีตัวแสดง GUI SQLite DB ที่เปิด DB อยู่ คุณสามารถเปิดฐานข้อมูลในเชลล์อื่นหรือรหัสของคุณอาจเปิดฐานข้อมูล โดยทั่วไปแล้วคุณจะเห็นสิ่งนี้หากเธรดอื่นหรือแอปพลิเคชันเช่นเบราว์เซอร์ฐานข้อมูล SQLite มีฐานข้อมูลเปิดสำหรับการเขียน


4
จากประสบการณ์ของฉันเบราว์เซอร์ฐานข้อมูล SQLite (SDB) จะล็อกฐานข้อมูลซ้ำถ้าคุณแก้ไขข้อมูลด้วย แต่ไม่ต้องบันทึกใน SDB หากคุณบันทึกไว้จะเป็นการปลดล็อค
Chelonian

ฉันสามารถแทรกได้ แต่ไม่สามารถลบได้
Wennie

10

ฉันมีปัญหานี้ในตอนนี้โดยใช้ฐานข้อมูล SQLite บนเซิร์ฟเวอร์ระยะไกลที่เก็บไว้ใน NFS mount SQLite ไม่สามารถรับการล็อคหลังจากเซสชันเชลล์ระยะไกลที่ฉันใช้เกิดปัญหาขณะที่ฐานข้อมูลเปิดอยู่

สูตรการกู้คืนที่แนะนำข้างต้นไม่ได้ผลสำหรับฉัน (รวมถึงแนวคิดในการย้ายครั้งแรกแล้วคัดลอกฐานข้อมูลกลับ) แต่หลังจากการคัดลอกไปยังระบบที่ไม่ใช่ NFS ฐานข้อมูลก็สามารถใช้งานได้และดูเหมือนว่าข้อมูลจะไม่สูญหาย


9

ล็อคของฉันเกิดจากระบบล้มเหลวและไม่ได้เกิดจากกระบวนการแขวน ในการแก้ไขปัญหานี้ฉันเพียงแค่เปลี่ยนชื่อไฟล์จากนั้นคัดลอกกลับเป็นชื่อเดิมและที่ตั้ง

ใช้เปลือก linux ที่จะ ...

mv mydata.db temp.db
cp temp.db mydata.db

วิธีแก้ปัญหาที่ง่ายมากแก้ปัญหาฐานข้อมูลที่ล็อคในไดรฟ์เครือข่าย
Maverick2805


4

ฉันพบเอกสารของสถานะต่างๆของการล็อคใน SQLite จะมีประโยชน์มาก Michael ถ้าคุณสามารถอ่านได้ แต่ไม่สามารถทำการเขียนไปยังฐานข้อมูลได้นั่นหมายความว่ากระบวนการได้ล็อคการจองไว้ในฐานข้อมูลของคุณ แต่ยังไม่ได้ดำเนินการเขียน หากคุณกำลังใช้ SQLite3 จะมีการล็อกใหม่ที่เรียกว่า PENDING โดยที่ไม่อนุญาตให้กระบวนการเชื่อมต่อ แต่การเชื่อมต่อที่มีอยู่สามารถอ่านได้ดังนั้นถ้านี่เป็นปัญหาที่คุณควรพิจารณาดูแทน


4

ข้อผิดพลาดนี้สามารถโยนได้หากไฟล์อยู่ในโฟลเดอร์ระยะไกลเช่นโฟลเดอร์ที่แชร์ ฉันเปลี่ยนฐานข้อมูลเป็นไดเรกทอรีท้องถิ่นและทำงานได้อย่างสมบูรณ์


3

ฉันมีปัญหาดังกล่าวภายในแอปที่เข้าถึง SQLite จากการเชื่อมต่อ 2 อันอันหนึ่งเป็นแบบอ่านอย่างเดียวและสองสำหรับการเขียนและอ่าน ดูเหมือนว่าการเชื่อมต่อแบบอ่านอย่างเดียวบล็อกการเขียนจากการเชื่อมต่อที่สอง ในที่สุดมันจะกลายเป็นว่ามันจะต้องจบหรืออย่างน้อยรีเซ็ตงบเตรียมทันทีหลังจากใช้ จนกว่าจะมีการเปิดคำสั่งที่เตรียมไว้มันทำให้ฐานข้อมูลถูกบล็อกเพื่อการเขียน

อย่าลืมโทร:

sqlite_reset(xxx);

หรือ

sqlite_finalize(xxx);

3

บางฟังก์ชั่นเช่น INDEX'ing อาจใช้เวลานานมากและจะล็อคฐานข้อมูลทั้งหมดในขณะที่ทำงาน ในกรณีเช่นนั้นอาจใช้ไฟล์เจอร์นัลไม่ได้!

ดังนั้นวิธีที่ดีที่สุด / เพื่อตรวจสอบว่าฐานข้อมูลของคุณถูกล็อกหรือไม่เพราะกระบวนการนั้นเขียนลงไปอย่างจริงจัง (และคุณควรปล่อยให้มันอยู่คนเดียวจนกว่าการดำเนินการจะเสร็จสิ้น) คือ md5 (หรือ md5sum ในบางระบบ) . หากคุณได้รับ checksum ที่แตกต่างกันฐานข้อมูลจะถูกเขียนและคุณจริง ๆ ไม่ต้องการฆ่า -9 กระบวนการนั้นเนื่องจากคุณสามารถท้ายด้วยตาราง / ฐานข้อมูลเสียหายถ้าคุณทำ

ฉันจะย้ำเพราะมันเป็นสิ่งสำคัญ - การแก้ปัญหาคือไม่พบโปรแกรมล็อคและฆ่ามัน - เพื่อค้นหาว่าฐานข้อมูลมีล็อกการเขียนด้วยเหตุผลที่ดีและไปจากที่นั่น บางครั้งทางออกที่ถูกต้องเป็นเพียงแค่ช่วงพักดื่มกาแฟ

วิธีเดียวที่จะสร้างนี้ล็อค แต่ไม่เป็นที่เขียนต่อสถานการณ์คือถ้าวิ่งโปรแกรมของคุณBEGIN EXCLUSIVEเพราะมันอยากจะทำการปรับเปลี่ยนตารางบางส่วนหรือบางสิ่งบางอย่างแล้วด้วยเหตุผลใดไม่เคยส่งENDหลังจากนั้นและกระบวนการที่ไม่เคยสิ้นสุด เงื่อนไขทั้งสามที่พบนั้นไม่น่าเป็นไปได้อย่างมากในรหัสที่เขียนอย่างถูกต้องและเช่น 99 ครั้งจาก 100 เมื่อมีคนต้องการฆ่า -9 กระบวนการล็อคของพวกเขากระบวนการล็อคจริง ๆ แล้วล็อคฐานข้อมูลของคุณด้วยเหตุผลที่ดี โดยทั่วไปโปรแกรมเมอร์ไม่ได้เพิ่มBEGIN EXCLUSIVEเงื่อนไขจนกว่าพวกเขาจะต้องการเพราะมันช่วยป้องกันการเกิดพร้อมกันและเพิ่มการร้องเรียนของผู้ใช้ SQLite จะเพิ่มตัวเองเมื่อจำเป็นเท่านั้น (เช่นเมื่อจัดทำดัชนี)

ในที่สุดสถานะ 'ล็อค' ไม่ได้อยู่ภายในไฟล์ดังที่ได้ระบุไว้หลายคำตอบ - มันอยู่ในเคอร์เนลของระบบปฏิบัติการ กระบวนการที่รันBEGIN EXCLUSIVEได้ร้องขอจากระบบปฏิบัติการจะถูกล็อคไว้ในไฟล์ แม้ว่ากระบวนการพิเศษของคุณจะขัดข้องระบบปฏิบัติการของคุณจะสามารถทราบได้ว่าควรจะรักษาล็อกไฟล์หรือไม่ !! มันเป็นไปไม่ได้ที่จะจบลงด้วยฐานข้อมูลที่ถูกล็อค แต่ไม่มีกระบวนการใดกำลังล็อคอยู่ !! เมื่อมาถึงการดูว่ากระบวนการใดทำการล็อกไฟล์โดยปกติแล้วจะใช้ lsof แทนที่จะเป็น fuser (นี่เป็นการสาธิตที่ดีว่าทำไม: /unix/94316/fuser-vs-lsof- เพื่อตรวจสอบไฟล์ที่ใช้งาน ) หรือหากคุณมี DTrace (OSX) คุณสามารถใช้ iosnoop กับไฟล์


2

ฉันเพิ่งมีสิ่งที่คล้ายกันเกิดขึ้นกับฉัน - เว็บแอปพลิเคชันของฉันสามารถอ่านได้จากฐานข้อมูล แต่ไม่สามารถแทรกหรืออัปเดตใด ๆ ได้ การรีบูต Apache แก้ปัญหาอย่างน้อยก็ชั่วคราว

อย่างไรก็ตามมันก็ดีนะที่จะสามารถติดตามสาเหตุที่แท้จริง


2

คำสั่งlsofบนสภาพแวดล้อม Linux ของฉันช่วยให้ฉันเข้าใจว่ากระบวนการกำลังหยุดทำงานทำให้ไฟล์เปิดอยู่
ฆ่ากระบวนการและปัญหาได้รับการแก้ไข


2

ลิงก์นี้แก้ปัญหาได้ : เมื่อ Sqlite ให้: ข้อผิดพลาดการล็อคฐานข้อมูล มันแก้ไขปัญหาของฉันได้อาจเป็นประโยชน์กับคุณ

และคุณสามารถใช้เริ่มต้นธุรกรรมและสิ้นสุดธุรกรรมเพื่อไม่ให้ล็อกฐานข้อมูลในอนาคต


2

ควรเป็นปัญหาภายในของฐานข้อมูล ...
สำหรับฉันมันถูกแสดงออกมาหลังจากพยายามเรียกดูฐานข้อมูลด้วย "ผู้จัดการ SQLite" ...
ดังนั้นถ้าคุณไม่พบกระบวนการอื่นที่เชื่อมต่อกับฐานข้อมูลและคุณไม่สามารถแก้ไขได้ ลองใช้วิธีการแก้ปัญหาที่รุนแรงนี้:

  1. จัดทำเพื่อส่งออกตารางของคุณ (คุณสามารถใช้ "ผู้จัดการ SQLite" บน Firefox)
  2. หากการโยกย้ายเปลี่ยนแบบแผนฐานข้อมูลของคุณให้ลบการโยกย้ายครั้งสุดท้ายที่ล้มเหลว
  3. เปลี่ยนชื่อไฟล์ "database.sqlite" ของคุณ
  4. ดำเนินการ "rake db: migrate" เพื่อสร้างฐานข้อมูลการทำงานใหม่
  5. จัดเตรียมเพื่อให้สิทธิ์ที่ถูกต้องกับฐานข้อมูลสำหรับการนำเข้าของตาราง
  6. นำเข้าตารางที่สำรองไว้
  7. เขียนการโยกย้ายใหม่
  8. ดำเนินการด้วย " rake db:migrate"

1

ฉันพบปัญหาเดียวกันนี้ใน Mac OS X 10.5.7 ที่รันสคริปต์ Python จากเทอร์มินัลเซสชัน แม้ว่าฉันจะหยุดสคริปต์และหน้าต่างเทอร์มินัลนั่งอยู่ที่พรอมต์คำสั่งมันจะให้ข้อผิดพลาดนี้ในครั้งต่อไปที่มันทำงาน วิธีแก้ไขคือปิดหน้าต่างเทอร์มินัลแล้วเปิดขึ้นอีกครั้ง ไม่สมเหตุสมผลสำหรับฉัน แต่มันได้ผล


1

ฉันเพิ่งมีข้อผิดพลาดเดียวกัน หลังจาก 5 นาที google-ing ฉันพบว่าฉันไม่ได้ปิดแม่มดเปลือกหอยหนึ่งตัวกำลังใช้ db เพียงปิดแล้วลองอีกครั้ง;)


1

ผมมีปัญหาเหมือนกัน. เห็นได้ชัดว่าฟังก์ชั่นย้อนกลับดูเหมือนจะเขียนทับไฟล์ 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

เหตุผลหนึ่งที่พบบ่อยสำหรับการรับข้อยกเว้นนี้คือเมื่อคุณพยายามทำการเขียนในขณะที่ยังคงเก็บทรัพยากรสำหรับการดำเนินการอ่าน ตัวอย่างเช่นหากคุณเลือกจากตารางจากนั้นลองอัปเดตสิ่งที่คุณเลือกโดยไม่ต้องปิดชุดผลลัพธ์ของคุณก่อน


1

ฉันมีข้อผิดพลาด "ฐานข้อมูลถูกล็อค" ในแอปพลิเคชันแบบมัลติเธรดซึ่งดูเหมือนจะเป็นรหัสผลลัพธ์SQLITE_BUSYและฉันแก้ไขด้วยการตั้งค่าsqlite3_busy_timeoutให้เหมาะกับบางสิ่งที่เหมาะสมเช่น 30000

(ในบันทึกย่อด้านข้าง, แปลกที่คำถาม 7 ปีไม่มีใครพบสิ่งนี้ออกมาแล้ว! SQLite เป็นโครงการที่แปลกประหลาดและน่าทึ่งจริงๆ ... )


1

ก่อนที่จะลงไปในตัวเลือกการรีบูทมันคุ้มค่าที่จะดูว่าคุณสามารถหาผู้ใช้ฐานข้อมูล sqlite ได้หรือไม่

บนลีนุกซ์เราสามารถใช้วิธี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

ซึ่งแสดงให้เห็นว่าฉันมีโปรแกรม Python อื่นที่มี pid 3556 (Manage.py) โดยใช้ฐานข้อมูล


1

คำถามเก่าที่มีคำตอบมากมายนี่คือขั้นตอนที่ฉันเพิ่งติดตามอ่านคำตอบข้างต้น แต่ในกรณีของฉันปัญหาเกิดจากการแบ่งปันทรัพยากร cifs กรณีนี้ไม่ได้รายงานไปก่อนหน้านี้ดังนั้นหวังว่าจะช่วยคนได้

  • ตรวจสอบว่าไม่มีการเชื่อมต่อใดถูกเปิดทิ้งไว้ในรหัส java ของคุณ
  • ตรวจสอบว่าไม่มีกระบวนการอื่นกำลังใช้ไฟล์ SQLite db กับ lsof
  • ตรวจสอบเจ้าของผู้ใช้ของกระบวนการ jvm ที่ทำงานของคุณมีสิทธิ์ r / w มากกว่าไฟล์
  • ลองบังคับโหมดล็อคในการเปิดการเชื่อมต่อด้วย

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

หากคุณใช้ไฟล์ฐานข้อมูล SQLite ของคุณมากกว่าโฟลเดอร์ที่ใช้ร่วม NFS ตรวจสอบจุดนี้ของคำถามที่พบบ่อย SQLite และตรวจสอบตัวเลือกการกำหนดค่าการติดตั้งเพื่อให้แน่ใจว่าการหลีกเลี่ยงการล็อคของคุณตามที่อธิบายไว้ที่นี่ :

//myserver /mymount cifs username=*****,password=*****,iocharset=utf8,sec=ntlm,file,nolock,file_mode=0700,dir_mode=0700,uid=0500,gid=0500 0 0

1

ฉันได้รับข้อผิดพลาดนี้ในสถานการณ์ที่แตกต่างจากที่อธิบายไว้เล็กน้อย

ฐานข้อมูล SQLite วางอยู่บนระบบไฟล์ NFS ที่แบ่งใช้โดย 3 เซิร์ฟเวอร์ ในวันที่ 2 ของเซิร์ฟเวอร์ฉันสามารถรันคิวรีบนฐานข้อมูลได้สำเร็จในวันที่สามฉันคิดว่าฉันได้รับข้อความ "ฐานข้อมูลถูกล็อค"

สิ่งที่มาพร้อมกับเครื่องที่ 3 /varนี้คือการที่มันได้ไม่มีช่องว่างด้านซ้ายบน ทุกครั้งที่ฉันพยายามเรียกใช้แบบสอบถามในฐานข้อมูล SQLite ใด ๆ ที่อยู่ในระบบไฟล์นี้ฉันได้รับข้อความ "ฐานข้อมูลถูกล็อค" และข้อผิดพลาดนี้ในบันทึก:

8 สิงหาคม 10:33:38 server01 เคอร์เนล: lockd: ไม่สามารถมอนิเตอร์ 172.22.84.87

และอันนี้ก็:

8 สิงหาคม 10:33:38 server01 rpc.statd [7430]: ล้มเหลวในการแทรก: เขียน /var/lib/nfs/statd/sm/other.server.name.com: ไม่มีพื้นที่เหลือบนอุปกรณ์ 8 สิงหาคม 10:33: 38 server01 rpc.statd [7430]: STAT_FAIL ถึง server01 สำหรับ SM_MON จาก 172.22.84.87

หลังจากสถานการณ์พื้นที่ถูกจัดการทุกอย่างกลับสู่ปกติ


1

หากคุณพยายามปลดล็อกฐานข้อมูล Chromeเพื่อดูด้วย SQLiteให้ปิด 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

0

จากความคิดเห็นก่อนหน้าของคุณคุณบอกว่ามีไฟล์ -journal อยู่

นี่อาจหมายความว่าคุณได้เปิดและทำธุรกรรม (EXCLUSIVE?) และยังไม่ได้ส่งมอบข้อมูล โปรแกรมของคุณหรือกระบวนการอื่น ๆ ทิ้ง -journal ไว้เบื้องหลัง ??

การรีสตาร์ทกระบวนการ sqlite จะดูที่ไฟล์เจอร์นัลและล้างการดำเนินการที่ไม่มีข้อผูกมัดและลบไฟล์ -journal


0

อย่างที่ Seun Osewa ได้กล่าวไว้บางครั้งกระบวนการของซอมบี้จะเข้ามาในเทอร์มินัลพร้อมกับล็อคแม้ว่าคุณจะไม่คิดว่ามันเป็นไปได้ก็ตาม สคริปต์ของคุณทำงานหยุดทำงานและคุณกลับไปที่พรอมต์ แต่มีกระบวนการซอมบี้เกิดขึ้นที่ใดที่หนึ่งโดยการเรียกใช้ไลบรารีและกระบวนการนั้นมีการล็อค

การปิดเทอร์มินัลที่คุณอยู่ (ใน OSX) อาจใช้งานได้ การรีบูตเครื่องจะทำงาน คุณสามารถค้นหากระบวนการ "หลาม" (ตัวอย่าง) ที่ไม่ได้ทำอะไรและฆ่าพวกเขา


0

คุณสามารถลอง: .timeout 100ตั้งค่าการหมดเวลา ฉันไม่ทราบว่าเกิดอะไรขึ้นในบรรทัดคำสั่ง แต่ใน C # .Net เมื่อฉันทำสิ่งนี้: "UPDATE table-name SET column-name = value;"ฉันได้รับฐานข้อมูลถูกล็อค แต่"UPDATE table-name SET column-name = value"มันก็ไปได้

ดูเหมือนว่าเมื่อคุณเพิ่ม; sqlite จะค้นหาคำสั่งเพิ่มเติม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.