문제

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 : 예를 들어 비슷한 작업을 수행 할 수 있습니다.

$ fuser development.db

이 명령은 파일을 잠그는 프로세스를 보여줍니다.

> Development.db : 5430

그냥 프로세스를 죽여 ...

-9 5430을 처치하십시오

... 그리고 데이터베이스가 잠금 해제됩니다.

다른 팁

쓰기 중 앱을 충돌시켜 SQLITE DB가 잠겨졌습니다. 다음은 다음과 같습니다.

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

가져온 : http://random.kakaopor.hu/how-to-repair-an-sqlite-database

아래에 나열된 데이터베이스시 슬록드 페이지는 더 이상 사용할 수 없습니다. 파일 잠금 및 동시성 페이지는 V3에 소개 된 파일 잠금과 관련된 변경 사항을 설명하며 향후 독자에게 유용 할 수 있습니다. https://www.sqlite.org/lockingv3.html

Sqlite Wiki DatabaseIslocked 페이지는이 오류 메시지에 대한 좋은 설명을 제공합니다. 그것은 부분적으로 경합의 원천이 내부적이라고 말한다 (오류를 방출하는 프로세스).

이 페이지를 설명하지 않는 것은 SQLITE가 프로세스의 무언가가 잠금을 고정하고 어떤 조건이 잘못된 긍정적으로 이어질 수 있는지 결정하는 방법입니다.

-journal 파일을 삭제하는 것은 끔찍한 아이디어처럼 들립니다. 충돌 후 SQLITE가 데이터베이스를 일관된 상태로 롤백 할 수 있도록합니다. 데이터베이스가 일관되지 않은 상태 인 동안 삭제하면 손상된 데이터베이스가 남아 있습니다. 에서 페이지를 인용합니다 sqlite 사이트:

충돌 또는 전력 손실이 발생하고 핫 저널이 디스크에 남아 있으면 원래 데이터베이스 파일과 핫 저널은 다른 SQLITE 프로세스에 의해 데이터베이스 파일을 열 때까지 원래 이름으로 디스크에 남아 있어야합니다. . [...

우리는 SQLITE 복구를위한 공통 실패 모드가 다음과 같이 발생한다고 생각합니다. 정전이 발생합니다. 전원이 복원 된 후, 선의의 사용자 또는 시스템 관리자가 디스크를 둘러보기 시작합니다. 그들은 "imgure.data"라는 데이터베이스 파일을 볼 수 있습니다. 이 파일은 아마도 그들에게 친숙 할 것입니다. 그러나 충돌 후 "중요 .Data-Journal"이라는 핫 저널도 있습니다. 그런 다음 사용자는 Hot Journal을 삭제하여 시스템을 정리하는 데 도움이된다고 생각합니다. 우리는 사용자 교육 이외의 다른 방법을 예방할 방법이 없습니다.

다음에 데이터베이스가 열릴 때 롤백이 자동으로 발생하지만 프로세스가 데이터베이스를 잠글 수 없으면 실패합니다. 다른 사람들이 말했듯이, 그 이유 중 하나는 다른 프로세스가 현재 개방되어 있기 때문입니다. 데이터베이스가 NFS 볼륨에있는 경우 또 다른 가능성은 오래된 NFS 잠금입니다. 이 경우 해결 방법은 데이터베이스 파일을 NFS 서버 (MV Database.db Original.db; CP Original.db Database.db)에 고정되지 않은 새로운 사본으로 바꾸는 것입니다. SQLITE FAQ는 NFS 파일 잠금의 버기 구현으로 인해 NFS 볼륨의 데이터베이스에 대한 동시 액세스에 대한주의를 권장합니다.

-journal 파일을 삭제하면 이전에 할 수 없었던 데이터베이스를 잠글 수있는 이유를 설명 할 수 없습니다. 그게 재현 가능합니까?

그건 그렇고, -journal 파일의 존재가 반드시 충돌이 있거나 롤백해야 할 변경이 있음을 의미하지는 않습니다. SQLITE는 몇 가지 다른 저널 모드를 가지고 있으며, 지속 또는 자르기 모드에서는 -journal 파일을 항상 제자리에두고 내용을 변경하여 롤백 할 부분 트랜잭션이 있는지 여부를 나타냅니다.

"데이터베이스가 잠겨 있습니다"오류를 제거하려면 다음 단계를 따르십시오.

  1. 데이터베이스 파일을 다른 위치에 복사하십시오.
  2. 데이터베이스를 복사 된 데이터베이스로 바꾸십시오. 이렇게하면 데이터베이스 파일에 액세스 한 모든 프로세스를 피할 수 있습니다.

프로세스에 SQLITE DB에 잠금이 있고 충돌이 발생하면 DB는 영구적으로 잠겨 있습니다. 그게 바로 문제 야. 다른 프로세스에 자물쇠가있는 것은 아닙니다.

sqlite db 파일은 단지 파일이므로 첫 번째 단계는 읽기 전용이 아닌지 확인하는 것입니다. 또 다른 일은 DB Open을 사용하여 일종의 GUI SQLITE DB 뷰어가 없는지 확인하는 것입니다. 다른 쉘에서 DB를 열 수 있거나 코드가 DB를 열 수 있습니다. 일반적으로 다른 스레드 또는 SQLITE 데이터베이스 브라우저와 같은 응용 프로그램에 DB가 서면으로 열려있는 경우이를 볼 수 있습니다.

NFS 마운트에 저장된 원격 서버의 SQLITE 데이터베이스를 사용하여 지금이 문제가 발생했습니다. 데이터베이스가 열려있는 동안 사용한 원격 쉘 세션이 충돌 한 후 SQLITE는 잠금을 얻을 수 없었습니다.

위에서 제안한 복구 레시피는 나에게 효과가 없었습니다 (먼저 이동 한 다음 데이터베이스를 복사하려는 아이디어 포함). 그러나 NONFS 시스템에 복사 한 후 데이터베이스를 사용할 수 있었고 데이터가 손실되지 않은 것으로 보입니다.

내 자물쇠는 시스템 충돌로 인해 발생했으며 교수형 프로세스가 아닙니다. 이것을 해결하기 위해 나는 단순히 파일의 이름을 바꾸고 원래 이름과 위치로 다시 복사했습니다.

Linux 쉘 사용 ...

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

나는 "추가"Pooling=true"연결 문자열에 작동했습니다.

나는 찾았다 선적 서류 비치 SQLITE의 다양한 잠금 상태 중에서 매우 도움이됩니다. Michael, 읽기를 수행 할 수는 있지만 데이터베이스에 쓰기를 수행 할 수없는 경우 프로세스가 데이터베이스에 예약 된 잠금을 얻었지만 아직 쓰기를 실행하지 않았 음을 의미합니다. SQLITE3을 사용하는 경우 더 이상 프로세스가 연결되지 않지만 기존 연결이 읽기를 수행 할 수있는 경우 보류중인 새 잠금 장치가 있습니다. 따라서 문제가 발생하면 대신 살펴 봐야합니다.

파일이 공유 폴더와 같이 원격 폴더에 있으면이 오류를 던질 수 있습니다. 데이터베이스를 로컬 디렉토리로 변경하여 완벽하게 작동했습니다.

앱 내에 그러한 문제가 있는데, 이는 2 개의 연결에서 SQLITE에 액세스 할 수 있습니다. 하나는 읽기 전용이고 두 번째는 쓰기 및 읽기를위한 두 번째입니다. 읽기 전용 연결이 두 번째 연결에서 쓰기를 차단 한 것처럼 보입니다. 마지막으로, 사용 직후에 준비된 진술을 마무리하거나 최소한 재설정해야한다는 것이 밝혀졌습니다. 준비된 진술이 열릴 때까지 데이터베이스가 서면으로 차단되었습니다.

전화를 잊지 마세요 :

sqlite_reset(xxx);

또는

sqlite_finalize(xxx);

인덱스와 같은 일부 기능은 매우 오랜 시간이 걸릴 수 있으며 실행 중에 전체 데이터베이스를 잠글 수 있습니다. 그런 경우에는 저널 파일조차 사용하지 않을 수도 있습니다!

따라서 프로세스가 적극적으로 글을 쓰고 있기 때문에 데이터베이스가 잠겨 있는지 확인하는 가장 좋은 방법 (따라서 작동이 완료 될 때까지 혼자 두어야 함)이 MD5 (또는 일부 시스템의 MD5SUM)에 두 번 이루어집니다. . 다른 체크섬을 얻으면 데이터베이스가 작성되고 있으며, 실제로 손상된 테이블/데이터베이스로 쉽게 끝날 수 있기 때문에 실제로 -9를 죽이고 싶지 않습니다.

솔루션은 잠금 프로그램을 찾아서 죽이는 것이 중요하기 때문에 반복 할 것입니다. 데이터베이스에 정당한 이유가있는 쓰기 잠금 장치가 있는지 확인하고 거기에서 이동하는 것입니다. 때때로 올바른 솔루션은 커피 브레이크 일뿐입니다.

이 잠긴이 잠긴 상태로 작성된 상황을 만들 수있는 유일한 방법은 프로그램이 실행되는 경우입니다. BEGIN EXCLUSIVE, 그것은 약간의 테이블 변경이나 무언가를하고 싶었 기 때문에 어떤 이유로 든 END 나중에, 그리고 과정은 결코 종료되지 않습니다. 충족되는 세 가지 조건 모두 적절하게 작성된 코드에서는 거의 가능하지 않으며, 누군가가 잠금 프로세스 -9를 죽이고 싶을 때 100 개 중 99 배나 잠금 프로세스는 실제로 정당한 이유로 데이터베이스를 잠그고 있습니다. 프로그래머는 일반적으로 추가하지 않습니다 BEGIN EXCLUSIVE 동시성을 방지하고 사용자 불만을 증가시키기 때문에 실제로 필요하지 않는 한 상태. sqlite 자체는 실제로 필요할 때 (색인화시 등) 만 추가합니다.

마지막으로, 여러 답변이 언급 한대로 파일 내부에 '잠긴'상태가 존재하지 않습니다. 운영 체제의 커널에 있습니다. 실행 된 과정 BEGIN EXCLUSIVE OS에서 파일에 잠금 장치를 요청했습니다. 독점 프로세스가 충돌하더라도 OS는 파일 잠금을 유지 해야하는지 여부를 알아낼 수 있습니다 !! 잠긴 데이터베이스로 끝나는 것은 불가능하지만 프로세스가 적극적으로 잠그는 것은 없습니다 !! 파일을 잠그는 프로세스를 보는 경우 일반적으로 퓨저 대신 LSOF를 사용하는 것이 좋습니다 (이것은 이유를 잘 보여줍니다. https://unix.stackexchange.com/questions/94316/fuser-vs-lsof-toeck-files-in-use). 또는 DTRACE (OSX)가있는 경우 파일에서 iOSNOOP를 사용할 수 있습니다.

방금 나와 비슷한 일이 발생했습니다. 웹 응용 프로그램은 데이터베이스에서 읽을 수 있었지만 인서트 나 업데이트를 수행 할 수 없었습니다. Apache의 재부팅은 적어도 일시적으로 문제를 해결했습니다.

그러나 근본 원인을 추적 할 수있는 것이 좋을 것입니다.

LSOF Linux 환경의 명령은 프로세스가 파일을 열어두고 있음을 알아내는 데 도움이되었습니다.
과정을 죽였고 문제가 해결되었습니다.

이 링크는 문제를 해결합니다. : SQLITE가 제공하는 경우 : 데이터베이스 잠금 오류그것은 내 문제가 당신에게 유용 할 수 있다고 해결했다.

또한 트랜잭션 시작 및 엔드 트랜잭션을 사용하여 미래에 데이터베이스를 잠그지 않도록 할 수 있습니다.

데이터베이스의 내부 문제 여야합니다 ...
저에게는 "SQLITE Manager"로 데이터베이스를 탐색하려고 시도한 후에 나타났습니다.
따라서 다른 프로세스를 찾을 수 없으면 데이터베이스에 연결할 수 없으면 문제를 해결할 수 없습니다.이 급진적 인 솔루션을 사용해보십시오.

  1. 테이블 내보내기 (Firefox에서 "SQLITE Manager"를 사용할 수 있음).
  2. 마이그레이션이 변경되면 데이터베이스 체계가 마지막으로 실패한 마이그레이션을 삭제합니다.
  3. "database.sqlite"파일의 이름을 바꿉니다
  4. "Rake DB : Migrate"를 실행하여 새로운 작업 데이터베이스를 만들기 위해
  5. 테이블 가져 오기에 대한 데이터베이스에 올바른 권한을 부여하기 위해 제공
  6. 백업 테이블을 가져 오십시오
  7. 새로운 마이그레이션을 작성하십시오
  8. "로 실행"rake db:migrate"

Mac OS X 10.5.7에서 터미널 세션에서 Python 스크립트를 실행하는 것과 같은 문제를 해결했습니다. 스크립트를 중지했지만 터미널 창이 명령 프롬프트에 앉아 있었지만 다음에 실행될 때이 오류가 발생합니다. 해결책은 터미널 창을 닫은 다음 다시 열어주는 것이 었습니다. 나에게 의미가 없지만 효과가있었습니다.

방금 같은 오류가있었습니다. 5 장의 미네트 후 Google-ing 나는 하나의 쉘 마녀가 DB를 사용하고 있다는 것을 알았습니다. 그냥 닫고 다시 시도하십시오;)

나는 같은 문제가 있었다. 분명히 롤백 함수는 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 )

이 예외를 얻는 일반적인 이유 중 하나는 읽기 작업을 위해 리소스를 유지하면서 쓰기 작업을 수행하려고 할 때입니다. 예를 들어, 테이블에서 선택한 다음 결과 세트를 먼저 닫지 않고 선택한 것을 업데이트하려고합니다.

재부팅 옵션을 내려 가기 전에 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 프로그램이 있음을 보여주었습니다.

많은 답변이있는 오래된 질문은 최근에 위의 답변을 읽은 단계는 다음과 같습니다. 그러나 제 경우에는 문제가 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

시나리오 에서이 오류가 여기에 설명 된 것과 약간 다릅니다.

SQLITE 데이터베이스는 3 개의 서버에서 공유하는 NFS 파일 시스템에 놓여있었습니다. 서버의 2 개에서 나는 데이터베이스에서 쿼리를 성공적으로 실행할 수 있었고, 세 번째는 "데이터베이스가 잠겨있다"는 메시지를 받고 있다고 생각했습니다.

이 세 번째 기계의 것은 공간이 남아 있지 않다는 것입니다. /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] : SM_MON 172.22.84.87 용 STAT_FAIL to Server01

우주 상황이 처리 된 후 모든 것이 정상으로 돌아 왔습니다.

이전 의견에서 -저널 파일이 존재한다고 말했습니다.

이것은 당신이 당신이 열고 (배타적?) 거래를 시작했으며 아직 데이터를 커밋하지 않았 음을 의미 할 수 있습니다. 귀하의 프로그램이나 다른 프로세스가 -journal을 뒤로 남겨 두었습니까 ??

sqlite 프로세스를 다시 시작하면 저널 파일을보고 커밋되지 않은 작업을 정리하고 -journal 파일을 제거합니다.

Seun Osewa가 말했듯이, 때로는 좀비 프로세스가 가능하다고 생각하지 않더라도 잠금 장치와 함께 터미널에 앉아있을 것입니다. 스크립트가 실행되고 충돌하며 프롬프트로 돌아가지만 라이브러리 통화로 어딘가에 좀비 프로세스가 발생하며 해당 프로세스에는 잠금이 있습니다.

(OSX에서)에 있던 터미널을 닫으면 효과가있을 수 있습니다. 재부팅이 작동합니다. 당신은 아무것도하지 않는 "Python"프로세스 (예 : 아무것도하지 않는)를 찾아서 죽일 수 있습니다.

당신은 이것을 시도 할 수 있습니다 : .timeout 100 시간 초과를 설정합니다. 나는 이것을 할 때 c# .net에서 무슨 일이 일어나는지 모르겠지만 다음과 같습니다. "UPDATE table-name SET column-name = value;" 데이터베이스가 잠겨 있습니다 "UPDATE table-name SET column-name = value" 괜찮아요.

추가 할 때; SQLITE '는 추가 명령을 찾을 것 같습니다.

Litedac 구성 요소와 함께 Delphi를 사용할 때이 오류가 발생했습니다. 연결된 속성이 SQLite 연결 구성 요소 (이 경우 TliteConnection)에 맞게 설정된 경우 Delphi IDE에서 내 앱을 실행하는 동안 만 발생했습니다.

다중 스레드 애플리케이션에서 "데이터베이스가 잠겨 있습니다"오류가있었습니다. sqlite_busy 결과 코드와 설정으로 해결했습니다 sqlite3_busy_timeout 30000과 같은 적절한 일입니다.

(부수적으로, 7 살짜리 질문에서 아무도 이미 이것을 찾지 못했습니다! sqlite는 실제로 독특하고 놀라운 프로젝트입니다 ...)

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top