Może istnieć inny proces uzyskujący dostęp do pliku bazy danych - czy sprawdziłeś lsof?
nieistniejący
Miałem ten sam problem, problem był w programie antywirusowym, kiedy go dezaktywowałem, moja aplikacja działa dobrze, ale kiedy go aktywuję, znajduję błąd „baza danych jest zablokowana”, mam nadzieję, że to pomoże.
user8510915
Odpowiedzi:
267
W systemie Windows możesz wypróbować ten program http://www.nirsoft.net/utils/opened_files_view.html, aby dowiedzieć się, że proces obsługuje plik db. Spróbuj zamknąć ten program w celu odblokowania bazy danych
W systemie Linux i macOS możesz zrobić coś podobnego, na przykład, jeśli zablokowany plik to programowanie.db:
... z oczywistym zastrzeżeniem, że musisz wiedzieć, co robisz. Jeśli jest to nieistotny proces, to killpowinno być w porządku, ale musisz uważać, aby go odpowiednio zabić i kill -9prawdopodobnie jest to błąd i / lub przesada. Jeśli proces zostanie zawieszony i inaczej nie umrze, czasem potrzebujesz kill -9. Ale nie chcesz iść i zabijać głównego zadania produkcyjnego, abyś mógł zgłosić, że baza danych nie jest już zablokowana!
tripleee
Prostszym rozwiązaniem byłoby po prostu zrestartowanie komputera.
chacham15,
7
@ chacham15: zakładasz, że baza danych znajduje się na „moim” komputerze i ignorujesz możliwość wielu ważnych procesów uruchomionych na tym samym komputerze, co ten z zablokowaną bazą danych. „Prostsze” rozwiązanie nigdy nie jest takie proste;)
tzot 30.01.2013
1
@KyleCarlson - sqlite i mysql zasadniczo różnią się pod tym względem. Nie ma nic szczególnie złego w przeglądarce SQLite-db-browser.
Berry Tsakala,
6
To rozwiązanie zakłada, że istnieje proces blokujący plik. Możliwe, że proces się zawiesił, pozostawiając plik SQLite w stanie niezdatnym do użytku. W takim przypadku zobacz moją odpowiedź.
Robert
90
Powodowałem, że moja db sqlite została zablokowana przez awarię aplikacji podczas zapisu. Oto jak to naprawiłem:
sqlite3:sqlite> .dump PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; /**** ERROR: (5) database is locked *****/ ROLLBACK; -- due to errors
woky
Nie działa dlaFOREIGN KEY constraint failed (RELEASE RESTOREPOINT)
gies0r
52
Wymieniona poniżej strona DatabaseIsLocked nie jest już dostępna. Strona Blokowanie plików i współbieżność opisuje zmiany związane z blokowaniem plików wprowadzone w v3 i mogą być przydatne dla przyszłych czytelników. https://www.sqlite.org/lockingv3.html
Strona SQLite Wiki DatabaseIsLocked oferuje dobre wyjaśnienie tego komunikatu o błędzie. Po części stwierdza, że źródło niezgody ma charakter wewnętrzny (dla procesu powodującego błąd).
Ta strona nie wyjaśnia, w jaki sposób SQLite decyduje, że coś w twoim procesie ma blokadę i jakie warunki mogą prowadzić do fałszywie pozytywnego wyniku.
Problem polega na tym, że strona jest niepoprawna lub nieaktualna: mam proces, który dosłownie nic nie robi, ale tylko jeden WSTAW, który otrzymuje ten zablokowany komunikat: nie jest możliwe, aby ten proces spowodował blokadę. Problem polegał na innym procesie rozmowy z tym samym DB.
Dan Jameson
4
@ converter42 Link uszkodzony.
Ole Tange
32
Usunięcie pliku -journal brzmi jak okropny pomysł. Ma to umożliwić sqlite przywrócenie bazy danych do spójnego stanu po awarii. Jeśli usuniesz go, gdy baza danych jest niespójna, pozostanie uszkodzona baza danych. Powołując się na stronę z witryny sqlite :
Jeśli nastąpi awaria lub utrata zasilania, a na dysku pozostanie gorący dziennik, ważne jest, aby oryginalny plik bazy danych i gorący dziennik pozostały na dysku z ich oryginalnymi nazwami, dopóki plik bazy danych nie zostanie otwarty przez inny proces SQLite i wycofany . [...]
Podejrzewamy, że typowy tryb awarii odzyskiwania SQLite wygląda następująco: występuje awaria zasilania. Po przywróceniu zasilania zdrowy użytkownik lub administrator systemu zaczyna rozglądać się na dysku w poszukiwaniu uszkodzeń. Widzą swój plik bazy danych o nazwie „ważny.data”. Ten plik jest może im znany. Ale po awarii jest też gorący dziennik o nazwie „ważny.data-dziennik”. Następnie użytkownik usuwa gorący dziennik, myśląc, że pomaga oczyścić system. Nie wiemy, jak temu zapobiec, poza edukacją użytkowników.
Wycofanie powinno nastąpić automatycznie przy następnym otwarciu bazy danych, ale zakończy się niepowodzeniem, jeśli proces nie będzie mógł zablokować bazy danych. Jak powiedzieli inni, jednym z możliwych powodów jest to, że inny proces ma go obecnie otwarty. Inną możliwością jest przestarzała blokada NFS, jeśli baza danych znajduje się na wolumenie NFS. W takim przypadku obejściem problemu jest zastąpienie pliku bazy danych świeżą kopią, która nie jest zablokowana na serwerze NFS (mv database.db original.db; cp original.db database.db). Zauważ, że FAQ sqlite zaleca ostrożność w zakresie równoczesnego dostępu do baz danych na woluminach NFS, ze względu na błędne implementacje blokowania plików NFS.
Nie potrafię wyjaśnić, dlaczego usunięcie pliku -journal pozwoliłoby zablokować bazę danych, której wcześniej nie mogłeś. Czy to jest powtarzalne?
Nawiasem mówiąc, obecność pliku -journal niekoniecznie oznacza, że nastąpiła awaria lub że istnieją zmiany, które należy wycofać. Sqlite ma kilka różnych trybów dziennika, aw trybach PERSIST lub TRUNCATE zawsze pozostawia plik -journal na swoim miejscu i zmienia zawartość, aby wskazać, czy istnieją częściowe transakcje do wycofania.
Próbowałem „fuser <DB>” jak opisano powyżej, ale nie działało. Te proste kroki działają dla mnie.
Jackie Yeh,
W moim przypadku musiałem również ponownie uruchomić Notatnik Jupyter.
Victor
15
Jeśli proces ma blokadę na SQLite DB i ulega awarii, DB pozostaje zablokowane na stałe. To jest problem. To nie jest tak, że jakiś inny proces ma blokadę.
To po prostu nieprawda. Blokady są utrzymywane przez system operacyjny. Przeczytaj odpowiedź poniżej.
JJ
13
pliki db SQLite są tylko plikami, więc pierwszym krokiem byłoby upewnienie się, że nie są one tylko do odczytu. Inną rzeczą jest upewnienie się, że nie masz przeglądarki GUI SQLite DB z otwartą bazą danych. Możesz mieć otwartą bazę danych w innej powłoce lub twój kod może mieć otwartą bazę danych. Zazwyczaj jest to widoczne, jeśli inny wątek lub aplikacja, taka jak SQLite Database Browser, ma otwartą bazę danych do zapisu.
Z mojego doświadczenia wynika, że SQLite Database Browser (SDB) odtwarzalnie blokuje bazę danych, jeśli edytujesz za jej pomocą dane, ale nie zapisujesz ich w SDB. Jeśli go zapiszesz, zwolni blokadę.
Chelonian
Mogę wstawić, ale nie mogę usunąć.
Wennie
10
Właśnie miałem ten problem, używając bazy danych SQLite na zdalnym serwerze, przechowywanej na wierzchowcu NFS. SQLite nie był w stanie uzyskać blokady po awarii sesji zdalnej powłoki, której użyłem, gdy baza danych była otwarta.
Przepisy dotyczące odzyskiwania sugerowane powyżej nie działały dla mnie (w tym pomysł, aby najpierw przenieść, a następnie skopiować bazę danych z powrotem). Ale po skopiowaniu go do systemu innego niż NFS baza danych stała się użyteczna i nie wydaje się, że dane zostały utracone.
Moja blokada została spowodowana awarią systemu, a nie zawieszeniem się. Aby rozwiązać ten problem, po prostu zmieniłem nazwę pliku, a następnie skopiowałem go z powrotem do oryginalnej nazwy i lokalizacji.
Uważam, że dokumentacja różnych stanów blokowania w SQLite jest bardzo pomocna. Michael, jeśli możesz wykonywać odczyty, ale nie możesz zapisywać do bazy danych, oznacza to, że proces uzyskał ZAREZERWOWANĄ blokadę w bazie danych, ale jeszcze nie wykonał zapisu. Jeśli używasz SQLite3, istnieje nowa blokada o nazwie PENDING, w której nie można już łączyć żadnych procesów, ale istniejące połączenia mogą wykonywać odczyty, więc jeśli to jest problem, powinieneś na to spojrzeć.
Ten błąd może zostać zgłoszony, jeśli plik znajduje się w folderze zdalnym, takim jak folder współdzielony. Zmieniłem bazę danych na katalog lokalny i działała idealnie.
Mam taki problem w aplikacji, który ma dostęp do SQLite z 2 połączeń - jedno było tylko do odczytu, a drugie do pisania i czytania. Wygląda na to, że to połączenie tylko do odczytu zablokowało zapis z drugiego połączenia. Wreszcie okazuje się, że po użyciu konieczne jest sfinalizowanie lub przynajmniej zresetowanie przygotowanych instrukcji. Do momentu otwarcia przygotowanej instrukcji spowodowało to, że baza danych została zablokowana do zapisu.
Niektóre funkcje, takie jak INDEX'ing, mogą zająć bardzo dużo czasu - i podczas działania blokuje całą bazę danych. W takich przypadkach może nawet nie używać pliku dziennika!
Tak więc najlepszym / jedynym sposobem sprawdzenia, czy baza danych jest zablokowana, ponieważ proces AKTYWNIE zapisuje do niej (i dlatego powinieneś zostawić ją w spokoju, dopóki jej operacja nie zostanie zakończona) to dwukrotne skopiowanie pliku md5 (lub md5sum w niektórych systemach) . Jeśli otrzymasz inną sumę kontrolną, baza danych jest zapisywana i naprawdę NAPRAWDĘ nie chcesz zabić -9 tego procesu, ponieważ możesz łatwo skończyć z uszkodzoną tabelą / bazą danych.
Powtórzę, ponieważ jest to ważne - rozwiązaniem NIE jest znalezienie programu blokującego i zabicie go - to sprawdzenie, czy baza danych ma blokadę zapisu z dobrego powodu, i idź stamtąd. Czasami właściwym rozwiązaniem jest przerwa na kawę.
Jedynym sposobem na utworzenie takiej sytuacji zablokowania, ale nie zapisania, jest uruchomienie programu BEGIN EXCLUSIVE, ponieważ chciał on dokonać pewnych zmian w tabeli lub czegoś podobnego, a następnie z jakiegokolwiek powodu nigdy nie wysyła ENDpóźniej, a proces nigdy się nie kończy . Wszystkie trzy warunki, które są spełnione, są mało prawdopodobne w poprawnie napisanym kodzie, i jako takie 99 razy na 100, gdy ktoś chce zabić -9 ich procesu blokowania, proces blokowania faktycznie blokuje bazę danych z dobrego powodu. Programiści zazwyczaj nie dodająBEGIN EXCLUSIVE warunku, chyba że naprawdę tego potrzebują, ponieważ zapobiega to współbieżności i zwiększa liczbę skarg użytkowników. Sam SQLite dodaje go tylko wtedy, gdy jest naprawdę potrzebny (na przykład podczas indeksowania).
Wreszcie status „zablokowany” nie istnieje WEWNĄTRZ pliku, jak podano kilka odpowiedzi - znajduje się on w jądrze systemu operacyjnego. Uruchomiony proces BEGIN EXCLUSIVEzażądał od systemu operacyjnego blokady pliku. Nawet jeśli Twój wyłączny proces się zawiesił, Twój system operacyjny będzie w stanie dowiedzieć się, czy powinien utrzymać blokadę pliku, czy nie !! Nie jest możliwe, aby baza danych była zablokowana, ale żaden proces nie blokuje jej aktywnie !! Jeśli chodzi o sprawdzenie, który proces blokuje plik, zwykle lepiej jest użyć lsof zamiast fuser (jest to dobry przykład, dlaczego: /unix/94316/fuser-vs-lsof- sprawdzić pliki w użyciu ). Alternatywnie, jeśli masz DTrace (OSX), możesz użyć iosnoop na pliku.
Właśnie przydarzyło mi się coś podobnego - moja aplikacja internetowa mogła czytać z bazy danych, ale nie mogła wykonywać żadnych wstawień ani aktualizacji. Ponowne uruchomienie Apache rozwiązało problem przynajmniej tymczasowo.
Polecenie lsof w moim środowisku Linux pomogło mi zorientować się, że proces zawiesza się, utrzymując otwarty plik.
Zabił proces i problem został rozwiązany.
Powinien to być wewnętrzny problem bazy danych ...
Dla mnie objawił się po próbie przeglądania bazy danych za pomocą „SQLite manager” ...
Jeśli więc nie możesz znaleźć innego procesu, połącz się z bazą danych i po prostu nie możesz go naprawić, po prostu wypróbuj to radykalne rozwiązanie:
Zapewnij, aby wyeksportować swoje tabele (możesz użyć „SQLite manager” w Firefox)
Jeśli migracja zmieni schemat bazy danych, usuń ostatnią nieudaną migrację
Zmień nazwę pliku „database.sqlite”
Uruchom „rake db: migrate”, aby utworzyć nową działającą bazę danych
Podaj, aby dać odpowiednie uprawnienia do bazy danych do importowania tabeli
Ten sam problem napotkałem w systemie Mac OS X 10.5.7, uruchamiając skrypty Python z sesji terminalowej. Mimo że zatrzymałem skrypty, a okno terminala znajdowało się w wierszu polecenia, przy następnym uruchomieniu dałoby ten błąd. Rozwiązaniem było zamknięcie okna terminala, a następnie otwarcie go ponownie. Dla mnie to nie ma sensu, ale zadziałało.
Właśnie miałem ten sam błąd. Po 5 minutach wyszukiwania w Google stwierdziłem, że nie zamknąłem żadnej powłoki, która używała bazy danych. Po prostu zamknij i spróbuj ponownie;)
Miałem ten sam problem. Najwyraźniej funkcja wycofywania wydaje się zastępować plik db dziennikiem, który jest taki sam jak plik db, ale bez ostatniej zmiany. Zaimplementowałem to w moim kodzie poniżej i od tego czasu działa dobrze, podczas gdy zanim mój kod utknął w pętli, gdy baza danych pozostała zablokowana.
Mam nadzieję że to pomoże
mój kod python
################## 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 )
Jednym z powszechnych powodów występowania tego wyjątku jest próba wykonania operacji zapisu, przy jednoczesnym utrzymaniu zasobów dla operacji odczytu. Na przykład, jeśli wybierzesz z tabeli, a następnie spróbujesz zaktualizować coś, co wybrałeś, bez uprzedniego zamknięcia zestawu wyników.
Miałem również błędy „baza danych jest zablokowana” w aplikacji wielowątkowej, która wydaje się być kodem wynikowym SQLITE_BUSY , i rozwiązałem go, ustawiając sqlite3_busy_timeout na coś odpowiednio długiego jak 30000.
(Na marginesie, jak dziwne, że na 7-letnie pytanie nikt tego jeszcze nie odkrył! SQLite jest naprawdę osobliwym i niesamowitym projektem ...)
Stare pytanie, z dużą ilością odpowiedzi, oto kroki, które ostatnio wykonałem, czytając powyższe odpowiedzi, ale w moim przypadku problem był spowodowany udostępnianiem zasobów cifs. Ta sprawa nie została wcześniej zgłoszona, więc mam nadzieję, że komuś pomoże.
Sprawdź, czy w kodzie Java nie ma otwartych połączeń.
Sprawdź, czy żadne inne procesy nie używają pliku db SQLite z lsof.
Sprawdź, czy właściciel użytkownika działającego procesu jvm ma uprawnienia do r / w nad plikiem.
Spróbuj wymusić tryb blokady przy otwieraniu połączenia za pomocą
final SQLiteConfig config = new SQLiteConfig();
config.setReadOnly(false);
config.setLockingMode(LockingMode.NORMAL);
connection = DriverManager.getConnection(url, config.toProperties());
Jeśli używasz pliku db SQLite w folderze współdzielonym NFS, sprawdź ten punkt FAQ SQLite i przejrzyj opcje konfiguracji montowania, aby upewnić się, że unikasz blokad, jak opisano tutaj :
Wystąpił ten błąd w scenariuszu nieco innym niż te opisane tutaj.
Baza danych SQLite opierała się na systemie plików NFS współdzielonym przez 3 serwery. Na 2 serwerach udało mi się pomyślnie uruchomić zapytania w bazie danych, na trzecim myślałem, że otrzymuję komunikat „Baza danych jest zablokowana”.
Problem z tą trzecią maszyną polegał na tym, że nie miała już wolnego miejsca /var. Za każdym razem, gdy próbowałem uruchomić zapytanie w DOWOLNEJ bazie danych SQLite znajdującej się w tym systemie plików, pojawia się komunikat „Baza danych jest zablokowana”, a także ten błąd dotyczący dzienników:
8 sierpnia 10:33:38 jądro server01: lockd: nie można monitorować 172.22.84.87
A ten także:
8 sierpnia 10:33:38 server01 rpc.statd [7430]: Nie można wstawić: pisanie /var/lib/nfs/statd/sm/other.server.name.com: Brak miejsca na urządzeniu 8 sierpnia 10:33: 38 server01 rpc.statd [7430]: STAT_FAIL do server01 dla SM_MON z 172.22.84.87
Po załatwieniu sytuacji kosmicznej wszystko wróciło do normy.
%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
Prochowiec
~/Library/Application Support/Google/Chrome/Default/Web Data
Z poprzednich komentarzy powiedziałeś, że plik -journal był obecny.
Może to oznaczać, że otworzyłeś (WYŁĄCZNIE?) Transakcję i jeszcze nie zatwierdziłeś danych. Czy twój program lub jakiś inny proces pozostawił „dziennik” za sobą?
Ponowne uruchomienie procesu sqlite sprawdzi plik dziennika i wyczyści wszelkie nieprzyjęte działania i usunie plik -journal.
Jak powiedział Seun Osewa, czasami proces zombie będzie siedział w terminalu z zamkiem, nawet jeśli nie wydaje ci się to możliwe. Twój skrypt uruchamia się, ulega awarii i wracasz do monitu, ale gdzieś wywołanie biblioteki zombie wywołało gdzieś proces i ten proces ma blokadę.
Zamykanie terminalu, w którym byłeś (w OSX) może działać. Ponowne uruchomienie będzie działać. Możesz poszukać procesów „python” (na przykład), które nic nie robią, i zabić je.
możesz spróbować: .timeout 100ustawić limit czasu. Nie wiem, co się dzieje w wierszu polecenia, ale w C # .Net, gdy to robię: "UPDATE table-name SET column-name = value;"dostaję Baza danych jest zablokowana, ale "UPDATE table-name SET column-name = value"to idzie dobrze.
Wygląda na to, że po dodaniu; sqlite będzie szukał dalszych poleceń.
Odpowiedzi:
W systemie Windows możesz wypróbować ten program http://www.nirsoft.net/utils/opened_files_view.html, aby dowiedzieć się, że proces obsługuje plik db. Spróbuj zamknąć ten program w celu odblokowania bazy danych
W systemie Linux i macOS możesz zrobić coś podobnego, na przykład, jeśli zablokowany plik to programowanie.db:
To polecenie pokaże, jaki proces blokuje plik:
Po prostu zabij ten proces ...
... A twoja baza danych zostanie odblokowana.
źródło
kill
powinno być w porządku, ale musisz uważać, aby go odpowiednio zabić ikill -9
prawdopodobnie jest to błąd i / lub przesada. Jeśli proces zostanie zawieszony i inaczej nie umrze, czasem potrzebujeszkill -9
. Ale nie chcesz iść i zabijać głównego zadania produkcyjnego, abyś mógł zgłosić, że baza danych nie jest już zablokowana!Powodowałem, że moja db sqlite została zablokowana przez awarię aplikacji podczas zapisu. Oto jak to naprawiłem:
Zaczerpnięte z: http://random.kakaopor.hu/how-to-repair-an-sqlite-database
źródło
sqlite> .dump PRAGMA foreign_keys=OFF; BEGIN TRANSACTION; /**** ERROR: (5) database is locked *****/ ROLLBACK; -- due to errors
FOREIGN KEY constraint failed (RELEASE RESTOREPOINT)
Wymieniona poniżej strona DatabaseIsLocked nie jest już dostępna. Strona Blokowanie plików i współbieżność opisuje zmiany związane z blokowaniem plików wprowadzone w v3 i mogą być przydatne dla przyszłych czytelników. https://www.sqlite.org/lockingv3.html
Strona SQLite Wiki DatabaseIsLocked oferuje dobre wyjaśnienie tego komunikatu o błędzie. Po części stwierdza, że źródło niezgody ma charakter wewnętrzny (dla procesu powodującego błąd).
Ta strona nie wyjaśnia, w jaki sposób SQLite decyduje, że coś w twoim procesie ma blokadę i jakie warunki mogą prowadzić do fałszywie pozytywnego wyniku.
źródło
Usunięcie pliku -journal brzmi jak okropny pomysł. Ma to umożliwić sqlite przywrócenie bazy danych do spójnego stanu po awarii. Jeśli usuniesz go, gdy baza danych jest niespójna, pozostanie uszkodzona baza danych. Powołując się na stronę z witryny sqlite :
Wycofanie powinno nastąpić automatycznie przy następnym otwarciu bazy danych, ale zakończy się niepowodzeniem, jeśli proces nie będzie mógł zablokować bazy danych. Jak powiedzieli inni, jednym z możliwych powodów jest to, że inny proces ma go obecnie otwarty. Inną możliwością jest przestarzała blokada NFS, jeśli baza danych znajduje się na wolumenie NFS. W takim przypadku obejściem problemu jest zastąpienie pliku bazy danych świeżą kopią, która nie jest zablokowana na serwerze NFS (mv database.db original.db; cp original.db database.db). Zauważ, że FAQ sqlite zaleca ostrożność w zakresie równoczesnego dostępu do baz danych na woluminach NFS, ze względu na błędne implementacje blokowania plików NFS.
Nie potrafię wyjaśnić, dlaczego usunięcie pliku -journal pozwoliłoby zablokować bazę danych, której wcześniej nie mogłeś. Czy to jest powtarzalne?
Nawiasem mówiąc, obecność pliku -journal niekoniecznie oznacza, że nastąpiła awaria lub że istnieją zmiany, które należy wycofać. Sqlite ma kilka różnych trybów dziennika, aw trybach PERSIST lub TRUNCATE zawsze pozostawia plik -journal na swoim miejscu i zmienia zawartość, aby wskazać, czy istnieją częściowe transakcje do wycofania.
źródło
Jeśli chcesz usunąć błąd „baza danych jest zablokowana”, wykonaj następujące kroki:
źródło
Jeśli proces ma blokadę na SQLite DB i ulega awarii, DB pozostaje zablokowane na stałe. To jest problem. To nie jest tak, że jakiś inny proces ma blokadę.
źródło
pliki db SQLite są tylko plikami, więc pierwszym krokiem byłoby upewnienie się, że nie są one tylko do odczytu. Inną rzeczą jest upewnienie się, że nie masz przeglądarki GUI SQLite DB z otwartą bazą danych. Możesz mieć otwartą bazę danych w innej powłoce lub twój kod może mieć otwartą bazę danych. Zazwyczaj jest to widoczne, jeśli inny wątek lub aplikacja, taka jak SQLite Database Browser, ma otwartą bazę danych do zapisu.
źródło
Właśnie miałem ten problem, używając bazy danych SQLite na zdalnym serwerze, przechowywanej na wierzchowcu NFS. SQLite nie był w stanie uzyskać blokady po awarii sesji zdalnej powłoki, której użyłem, gdy baza danych była otwarta.
Przepisy dotyczące odzyskiwania sugerowane powyżej nie działały dla mnie (w tym pomysł, aby najpierw przenieść, a następnie skopiować bazę danych z powrotem). Ale po skopiowaniu go do systemu innego niż NFS baza danych stała się użyteczna i nie wydaje się, że dane zostały utracone.
źródło
Moja blokada została spowodowana awarią systemu, a nie zawieszeniem się. Aby rozwiązać ten problem, po prostu zmieniłem nazwę pliku, a następnie skopiowałem go z powrotem do oryginalnej nazwy i lokalizacji.
Korzystanie z powłoki linux, która byłaby ...
źródło
Dodałem „
Pooling=true
” do ciągu połączenia i zadziałało.źródło
Uważam, że dokumentacja różnych stanów blokowania w SQLite jest bardzo pomocna. Michael, jeśli możesz wykonywać odczyty, ale nie możesz zapisywać do bazy danych, oznacza to, że proces uzyskał ZAREZERWOWANĄ blokadę w bazie danych, ale jeszcze nie wykonał zapisu. Jeśli używasz SQLite3, istnieje nowa blokada o nazwie PENDING, w której nie można już łączyć żadnych procesów, ale istniejące połączenia mogą wykonywać odczyty, więc jeśli to jest problem, powinieneś na to spojrzeć.
źródło
Ten błąd może zostać zgłoszony, jeśli plik znajduje się w folderze zdalnym, takim jak folder współdzielony. Zmieniłem bazę danych na katalog lokalny i działała idealnie.
źródło
Mam taki problem w aplikacji, który ma dostęp do SQLite z 2 połączeń - jedno było tylko do odczytu, a drugie do pisania i czytania. Wygląda na to, że to połączenie tylko do odczytu zablokowało zapis z drugiego połączenia. Wreszcie okazuje się, że po użyciu konieczne jest sfinalizowanie lub przynajmniej zresetowanie przygotowanych instrukcji. Do momentu otwarcia przygotowanej instrukcji spowodowało to, że baza danych została zablokowana do zapisu.
NIE ZAPOMNIJ:
lub
źródło
Niektóre funkcje, takie jak INDEX'ing, mogą zająć bardzo dużo czasu - i podczas działania blokuje całą bazę danych. W takich przypadkach może nawet nie używać pliku dziennika!
Tak więc najlepszym / jedynym sposobem sprawdzenia, czy baza danych jest zablokowana, ponieważ proces AKTYWNIE zapisuje do niej (i dlatego powinieneś zostawić ją w spokoju, dopóki jej operacja nie zostanie zakończona) to dwukrotne skopiowanie pliku md5 (lub md5sum w niektórych systemach) . Jeśli otrzymasz inną sumę kontrolną, baza danych jest zapisywana i naprawdę NAPRAWDĘ nie chcesz zabić -9 tego procesu, ponieważ możesz łatwo skończyć z uszkodzoną tabelą / bazą danych.
Powtórzę, ponieważ jest to ważne - rozwiązaniem NIE jest znalezienie programu blokującego i zabicie go - to sprawdzenie, czy baza danych ma blokadę zapisu z dobrego powodu, i idź stamtąd. Czasami właściwym rozwiązaniem jest przerwa na kawę.
Jedynym sposobem na utworzenie takiej sytuacji zablokowania, ale nie zapisania, jest uruchomienie programu
BEGIN EXCLUSIVE
, ponieważ chciał on dokonać pewnych zmian w tabeli lub czegoś podobnego, a następnie z jakiegokolwiek powodu nigdy nie wysyłaEND
później, a proces nigdy się nie kończy . Wszystkie trzy warunki, które są spełnione, są mało prawdopodobne w poprawnie napisanym kodzie, i jako takie 99 razy na 100, gdy ktoś chce zabić -9 ich procesu blokowania, proces blokowania faktycznie blokuje bazę danych z dobrego powodu. Programiści zazwyczaj nie dodająBEGIN EXCLUSIVE
warunku, chyba że naprawdę tego potrzebują, ponieważ zapobiega to współbieżności i zwiększa liczbę skarg użytkowników. Sam SQLite dodaje go tylko wtedy, gdy jest naprawdę potrzebny (na przykład podczas indeksowania).Wreszcie status „zablokowany” nie istnieje WEWNĄTRZ pliku, jak podano kilka odpowiedzi - znajduje się on w jądrze systemu operacyjnego. Uruchomiony proces
BEGIN EXCLUSIVE
zażądał od systemu operacyjnego blokady pliku. Nawet jeśli Twój wyłączny proces się zawiesił, Twój system operacyjny będzie w stanie dowiedzieć się, czy powinien utrzymać blokadę pliku, czy nie !! Nie jest możliwe, aby baza danych była zablokowana, ale żaden proces nie blokuje jej aktywnie !! Jeśli chodzi o sprawdzenie, który proces blokuje plik, zwykle lepiej jest użyć lsof zamiast fuser (jest to dobry przykład, dlaczego: /unix/94316/fuser-vs-lsof- sprawdzić pliki w użyciu ). Alternatywnie, jeśli masz DTrace (OSX), możesz użyć iosnoop na pliku.źródło
Właśnie przydarzyło mi się coś podobnego - moja aplikacja internetowa mogła czytać z bazy danych, ale nie mogła wykonywać żadnych wstawień ani aktualizacji. Ponowne uruchomienie Apache rozwiązało problem przynajmniej tymczasowo.
Byłoby jednak miło, aby móc znaleźć przyczynę.
źródło
Polecenie lsof w moim środowisku Linux pomogło mi zorientować się, że proces zawiesza się, utrzymując otwarty plik.
Zabił proces i problem został rozwiązany.
źródło
Ten link rozwiązuje problem. : Gdy Sqlite podaje: Błąd blokady bazy danych To rozwiązało problem, który może być dla Ciebie przydatny.
Możesz także użyć opcji rozpoczęcia transakcji i zakończenia transakcji, aby nie blokować bazy danych w przyszłości.
źródło
Powinien to być wewnętrzny problem bazy danych ...
Dla mnie objawił się po próbie przeglądania bazy danych za pomocą „SQLite manager” ...
Jeśli więc nie możesz znaleźć innego procesu, połącz się z bazą danych i po prostu nie możesz go naprawić, po prostu wypróbuj to radykalne rozwiązanie:
rake db:migrate
”źródło
Ten sam problem napotkałem w systemie Mac OS X 10.5.7, uruchamiając skrypty Python z sesji terminalowej. Mimo że zatrzymałem skrypty, a okno terminala znajdowało się w wierszu polecenia, przy następnym uruchomieniu dałoby ten błąd. Rozwiązaniem było zamknięcie okna terminala, a następnie otwarcie go ponownie. Dla mnie to nie ma sensu, ale zadziałało.
źródło
Właśnie miałem ten sam błąd. Po 5 minutach wyszukiwania w Google stwierdziłem, że nie zamknąłem żadnej powłoki, która używała bazy danych. Po prostu zamknij i spróbuj ponownie;)
źródło
Miałem ten sam problem. Najwyraźniej funkcja wycofywania wydaje się zastępować plik db dziennikiem, który jest taki sam jak plik db, ale bez ostatniej zmiany. Zaimplementowałem to w moim kodzie poniżej i od tego czasu działa dobrze, podczas gdy zanim mój kod utknął w pętli, gdy baza danych pozostała zablokowana.
Mam nadzieję że to pomoże
mój kod python
źródło
Jednym z powszechnych powodów występowania tego wyjątku jest próba wykonania operacji zapisu, przy jednoczesnym utrzymaniu zasobów dla operacji odczytu. Na przykład, jeśli wybierzesz z tabeli, a następnie spróbujesz zaktualizować coś, co wybrałeś, bez uprzedniego zamknięcia zestawu wyników.
źródło
Miałem również błędy „baza danych jest zablokowana” w aplikacji wielowątkowej, która wydaje się być kodem wynikowym SQLITE_BUSY , i rozwiązałem go, ustawiając sqlite3_busy_timeout na coś odpowiednio długiego jak 30000.
(Na marginesie, jak dziwne, że na 7-letnie pytanie nikt tego jeszcze nie odkrył! SQLite jest naprawdę osobliwym i niesamowitym projektem ...)
źródło
Przed przejściem do opcji ponownego uruchomienia warto sprawdzić, czy możesz znaleźć użytkownika bazy danych sqlite.
W systemie Linux można
fuser
w tym celu zastosować:W moim przypadku otrzymałem następującą odpowiedź:
Co pokazało, że mam inny program Python z pid 3556 (manage.py) korzystający z bazy danych.
źródło
Stare pytanie, z dużą ilością odpowiedzi, oto kroki, które ostatnio wykonałem, czytając powyższe odpowiedzi, ale w moim przypadku problem był spowodowany udostępnianiem zasobów cifs. Ta sprawa nie została wcześniej zgłoszona, więc mam nadzieję, że komuś pomoże.
Spróbuj wymusić tryb blokady przy otwieraniu połączenia za pomocą
Jeśli używasz pliku db SQLite w folderze współdzielonym NFS, sprawdź ten punkt FAQ SQLite i przejrzyj opcje konfiguracji montowania, aby upewnić się, że unikasz blokad, jak opisano tutaj :
źródło
Wystąpił ten błąd w scenariuszu nieco innym niż te opisane tutaj.
Baza danych SQLite opierała się na systemie plików NFS współdzielonym przez 3 serwery. Na 2 serwerach udało mi się pomyślnie uruchomić zapytania w bazie danych, na trzecim myślałem, że otrzymuję komunikat „Baza danych jest zablokowana”.
Problem z tą trzecią maszyną polegał na tym, że nie miała już wolnego miejsca
/var
. Za każdym razem, gdy próbowałem uruchomić zapytanie w DOWOLNEJ bazie danych SQLite znajdującej się w tym systemie plików, pojawia się komunikat „Baza danych jest zablokowana”, a także ten błąd dotyczący dzienników:A ten także:
Po załatwieniu sytuacji kosmicznej wszystko wróciło do normy.
źródło
Jeśli próbujesz odblokować bazę danych Chrome, aby wyświetlić ją za pomocą SQLite , zamknij Chrome.
Windows
Prochowiec
źródło
Z poprzednich komentarzy powiedziałeś, że plik -journal był obecny.
Może to oznaczać, że otworzyłeś (WYŁĄCZNIE?) Transakcję i jeszcze nie zatwierdziłeś danych. Czy twój program lub jakiś inny proces pozostawił „dziennik” za sobą?
Ponowne uruchomienie procesu sqlite sprawdzi plik dziennika i wyczyści wszelkie nieprzyjęte działania i usunie plik -journal.
źródło
Jak powiedział Seun Osewa, czasami proces zombie będzie siedział w terminalu z zamkiem, nawet jeśli nie wydaje ci się to możliwe. Twój skrypt uruchamia się, ulega awarii i wracasz do monitu, ale gdzieś wywołanie biblioteki zombie wywołało gdzieś proces i ten proces ma blokadę.
Zamykanie terminalu, w którym byłeś (w OSX) może działać. Ponowne uruchomienie będzie działać. Możesz poszukać procesów „python” (na przykład), które nic nie robią, i zabić je.
źródło
możesz spróbować:
.timeout 100
ustawić limit czasu. Nie wiem, co się dzieje w wierszu polecenia, ale w C # .Net, gdy to robię:"UPDATE table-name SET column-name = value;"
dostaję Baza danych jest zablokowana, ale"UPDATE table-name SET column-name = value"
to idzie dobrze.Wygląda na to, że po dodaniu; sqlite będzie szukał dalszych poleceń.
źródło