如何解锁SQLite数据库?

sqlite> DELETE FROM mails WHERE (`id` = 71);

SQL error: database is locked

如何解锁数据库以便这样做?

ryantm asked 2019-03-04T16:16:22Z

30个解决方案

226 votes

在Windows中你可以尝试这个程序[http://www.nirsoft.net/utils/opened_files_view.html]来找出处理db文件的过程。 尝试关闭该程序以解锁数据库

在Linux和macOS中,您可以执行类似的操作,例如,如果您的锁定文件是development.db:

$ fuser development.db

此命令将显示锁定文件的进程:

> development.db:5430

只是杀了这个过程......

杀了-9 5430

...并且您的数据库将被解锁。

noneno answered 2019-03-04T16:17:24Z

82 votes

我在写入过程中使应用程序崩溃导致我的sqlite数据库被锁定。 这是我如何修复它:

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

摘自:[http://random.kakaopor.hu/how-to-repair-an-sqlite-database]

robert answered 2019-03-04T16:17:56Z

51 votes

SQLite wiki DatabaseIsLocked页面提供了对此错误消息的良好解释。 它部分地说明争用的来源是内部的(对于发出错误的过程)。

这个页面没有解释的是SQLite如何决定你的进程中的某些东西是否存在锁定以及哪些条件可能导致误报。

converter42 answered 2019-03-04T16:18:29Z

27 votes

删除-journal文件听起来像一个糟糕的主意。 它允许sqlite在崩溃后将数据库回滚到一致状态。 如果在数据库处于不一致状态时将其删除,则会留下损坏的数据库。 引用sqlite站点的页面:

如果确实发生了崩溃或断电并且磁盘上留有热日志,则原始数据库文件和热日志必须保留在磁盘上并保留其原始名称,直到另一个SQLite进程打开数据库文件并回滚。[...]

我们怀疑SQLite恢复的常见故障模式是这样的:发生电源故障。 电源恢复后,善意的用户或系统管理员开始在磁盘上查看损坏情况。 他们看到他们的数据库文件名为“important.data”。 这个文件对他们来说可能很熟悉。 但在崩溃之后,还有一个名为“important.data-journal”的热门期刊。 然后用户删除热门日志,认为他们正在帮助清理系统。 除了用户教育之外,我们知道无法阻止这种情况。

回滚应该在下次打开数据库时自动发生,但如果进程无法锁定数据库,则会失败。 正如其他人所说,其中一个可能的原因是另一个流程目前正在开放。 如果数据库位于NFS卷上,则另一种可能性是过时的NFS锁定。 在这种情况下,解决方法是使用未在NFS服务器上锁定的新副本替换数据库文件(mv database.db original.db; cp original.db database.db)。 请注意,由于NFS文件锁定的错误实现,sqlite FAQ建议谨慎对NFS卷上的数据库进行并发访问。

我无法解释为什么删除-journal文件会让你锁定以前无法访问的数据库。 这是可重复的吗?

顺便说一下,-journal文件的存在并不一定意味着发生了崩溃或者有回滚的变化。 Sqlite有一些不同的日志模式,在PERSIST或TRUNCATE模式下,它始终保留-journal文件,并更改内容以指示是否存在要回滚的部分事务。

Aaron answered 2019-03-04T16:19:36Z

12 votes

如果进程锁定SQLite DB并崩溃,则数据库将永久锁定。 那就是问题所在。 并不是某些其他进程有锁定。

answered 2019-03-04T16:20:02Z

12 votes

如果要删除“数据库已锁定”错误,请按照下列步骤操作:

将数据库文件复制到其他位置。

用复制的数据库替换数据库。 这将取消引用正在访问数据库文件的所有进程。

vinayak jadi answered 2019-03-04T16:20:44Z

10 votes

SQLite db文件只是文件,因此第一步是确保它不是只读的。 另一件事是确保在数据库打开的情况下没有某种GUI SQLite DB查看器。 您可以在另一个shell中打开数据库,或者您的代码可能打开了数据库。 通常,如果不同的线程或SQLite数据库浏览器等应用程序打开DB进行编写,您会看到这一点。

Heat Miser answered 2019-03-04T16:21:12Z

9 votes

我刚才遇到了这个问题,使用存储在NFS挂载上的远程服务器上的SQLite数据库。 在我使用的远程shell会话在数据库打开时崩溃后,SQLite无法获得锁定。

上面提到的恢复配方对我来说不起作用(包括首先移动然后再复制数据库的想法)。 但是在将其复制到非NFS系统之后,数据库变得可用,并且数据似乎没有丢失。

jogojapan answered 2019-03-04T16:21:45Z

4 votes

我发现SQLite中各种锁定状态的文档非常有用。 迈克尔,如果你可以执行读操作但不能对数据库执行写操作,这意味着进程已经对数据库进行了RESERVED锁定但尚未执行写入。 如果您正在使用SQLite3,那么有一个名为PENDING的新锁,其中不允许更多进程连接,但现有连接可以执行读取,因此如果这是问题,您应该查看它。

Kyle Cronin answered 2019-03-04T16:22:10Z

4 votes

如果文件位于远程文件夹(如共享文件夹)中,则可能引发此错误。 我将数据库更改为本地目录,它运行良好。

Zequez answered 2019-03-04T16:22:35Z

4 votes

我在连接字符串中添加了“Pooling=true”,但它确实有效。

user1900210 answered 2019-03-04T16:23:00Z

3 votes

我的锁是由系统崩溃引起的,而不是由挂起的进程引起的。 要解决此问题,我只需重命名该文件,然后将其复制回原始名称和位置。

使用一个可以...的linux shell

mv mydata.db temp.db

cp temp.db mydata.db

Ben L answered 2019-03-04T16:23:33Z

3 votes

我在app中有这样的问题,从2个连接访问SQLite - 一个是只读的,第二个是写和读。 看起来这个只读连接阻止了从第二个连接写入。 最后,结果是需要在使用后立即完成或至少重置准备好的语句。 在准备好的语句打开之前,它导致数据库被阻止写入。

不要忘记打电话:

sqlite_reset(xxx);

要么

sqlite_finalize(xxx);

Mike Keskinov answered 2019-03-04T16:24:09Z

3 votes

一些函数,如INDEX'ing,可能需要很长时间 - 它会在运行时锁定整个数据库。 在这样的情况下,它甚至可能不使用日志文件!

所以最好/唯一的方法是检查你的数据库是否被锁定,因为一个进程是非常活跃地写入它(因此你应该单独留下地狱直到它完成它的操作)是md5(或某些系统上的md5sum)文件两次。如果你得到一个不同的校验和,那么正在编写数据库,而你真的真的不想杀死-9那个进程,因为如果你这样做,你很容易就会得到一个损坏的表/数据库。

我将重申,因为它很重要 - 解决方案不是找到锁定程序并将其删除 - 这是为了找出数据库是否有充分理由的写锁定,并从那里开始。 有时,正确的解决方案只是喝咖啡休息时间。

创建这个锁定但未被写入的情况的唯一方法是,如果你的程序运行BEGIN EXCLUSIVE,因为它想要做一些表格更改或其他什么,然后无论出于何种原因从未发送过END,并且该过程永远不会终止。 任何正确编写的代码都不太可能满足所有这三个条件,并且当有人想杀死他们的锁定过程时,这样的99次中有100次,锁定过程实际上是锁定数据库的原因。 程序员通常不会添加BEGIN EXCLUSIVE条件,除非他们真的需要,因为它会阻止并发并增加用户投诉。 SQLite本身只在真正需要时添加它(比如索引时)。

最后,文件中存在“锁定”状态,因为有几个答案已经声明 - 它位于操作系统的内核中。 运行BEGIN EXCLUSIVE的进程已从OS请求锁定文件。 即使您的独家进程已崩溃,您的操作系统也能够确定它是否应该保持文件锁定! 不可能最终得到一个被锁定但没有进程主动锁定它的数据库!!当看到哪个进程锁定文件时,通常最好使用lsof而不是fuser(这是一个很好的演示原因:[https://unix.stackexchange.com/questions/94316/fuser-vs-lsof -to-check-files-in-use)。]或者,如果你有DTrace(OSX),你可以在文件上使用iosnoop。

J.J answered 2019-03-04T16:25:09Z

2 votes

我刚刚遇到类似的事情 - 我的Web应用程序能够从数据库中读取,但无法执行任何插入或更新。 重新启动Apache至少暂时解决了这个问题。

然而,能够追查根本原因是很好的。

Michael Cox answered 2019-03-04T16:25:44Z

2 votes

我的Linux环境中的lsof命令帮助我弄清楚一个进程正在挂起保持文件打开。

杀死了这个过程,问题解决了。

PinkSheep answered 2019-03-04T16:26:18Z

2 votes

这个链接解决了这个问题。 :当Sqlite给出:数据库锁定错误它解决了我的问题可能对你有用。

并且您可以使用begin transaction和end transaction来防止将来锁定数据库。

shreeji answered 2019-03-04T16:26:51Z

2 votes

应该是数据库的内部问题......

对我来说,在尝试使用“SQLite manager”浏览数据库之后就已经表现出来......

所以,如果你找不到另一个进程连接到数据库,你就是无法修复它,试试这个激进的解决方案:

提供导出表格(可以在Firefox上使用“SQLite manager”)

如果迁移更改了数据库模式,请删除上次失败的迁移

重命名“database.sqlite”文件

执行“rake db:migrate”以创建新的工作数据库

提供为数据库提供表的导入权限

导入备份表

编写新的迁移

用“rake db:migrate”执行

Davide Ganz answered 2019-03-04T16:28:28Z

1 votes

我在Mac OS X 10.5.7上遇到了同样的问题,从终端会话运行Python脚本。 即使我已经停止了脚本并且终端窗口位于命令提示符下,它也会在下次运行时出现此错误。 解决方案是关闭终端窗口,然后再次打开它。 对我没有意义,但它奏效了。

Shawn Swaner answered 2019-03-04T16:28:57Z

1 votes

我刚才有同样的错误。在5个谷歌谷歌之后我发现我没有关闭一个使用数据库的shell。关闭它然后再试一次;)

Flow answered 2019-03-04T16:29:23Z

1 votes

我有同样的问题。 显然,回滚功能似乎使用与db文件相同但没有最新更改的日志覆盖db文件。 我已经在下面的代码中实现了这一点,从那时起它一直运行良好,而在我的代码之前因数据库保持锁定而陷入困境。

希望这可以帮助

我的python代码

##############

#### 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 )

Jared answered 2019-03-04T16:29:59Z

1 votes

获得此异常的一个常见原因是,当您尝试执行写入操作同时仍保留用于读取操作的资源时。 例如,如果从表中选择SELECT,然后尝试更新已选择的内容而不先关闭ResultSet。

Martin Carney answered 2019-03-04T16:30:27Z

1 votes

在关闭重新启动选项之前,有必要查看是否可以找到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程序。

Philip Clarke answered 2019-03-04T16:31:15Z

1 votes

一个老问题,有很多答案,这是我最近在阅读上面的答案后的步骤,但在我的情况下,问题是由于CIF资源共享。 这个案子以前没有报道,所以希望它可以帮到某人。

检查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常见问题解答的这一点,并检查安装配置选项以确保避免锁定,如下所述:

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

kothvandir answered 2019-03-04T16:32:24Z

1 votes

我在一个与这里描述的情况略有不同的场景中得到了这个错误。

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]:STAT_FAIL到server01,SM_MON为172.22.84.87

处理完空间情况后,一切都恢复正常。

ederribeiro answered 2019-03-04T16:33:33Z

0 votes

根据您之前的评论,您说-journal文件存在。

这可能意味着您已打开并且(EXCLUSIVE?)事务并且尚未提交数据。 你的程序或其他进程是否留下了-journal?

重新启动sqlite进程将查看日志文件并清除所有未提交的操作并删除-journal文件。

answered 2019-03-04T16:34:15Z

0 votes

正如Seun Osewa所说,即使你认为不可能,有时一个僵尸进程会坐在终端上,锁定获取。 你的脚本运行,崩溃,然后你回到提示符,但是有一个僵尸进程通过库调用在某处产生,并且该进程具有锁定。

关闭您所在的终端(在OSX上)可能会有效。 重新启动将起作用。 您可以查找没有做任何事情的“python”进程(例如)并杀死它们。

wisty answered 2019-03-04T16:34:49Z

0 votes

你可以试试这个:.timeout 100来设置超时。我不知道在命令行中发生了什么,但在C#.Net中我这样做:"UPDATE table-name SET column-name = value;"我得到数据库已锁定,但这"UPDATE table-name SET column-name = value"它没关系。

它看起来像你添加;,sqlite会寻找进一步的命令。

nXqd answered 2019-03-04T16:35:23Z

0 votes

将Delphi与LiteDAC组件一起使用时出现此错误。事实证明,只有当连接属性为SQLite连接组件(在本例中为TLiteConnection)设置为True时,才会从Delphi IDE运行我的应用程序。

TheSteven answered 2019-03-04T16:35:52Z

0 votes

Adminer是一个小的(但功能强大的)phpmyadmin替代我用来监视sqlite数据库。 由于某种原因,数据库被锁定。 这是我修复它的方法。

我将sqlite文件下载到我的系统(FTP)

删除了在线sqlite文件

将文件上传回托管服务提供商

它现在工作正常。

Mohsin answered 2019-03-04T16:36:49Z

sqlite数据库加锁提交_如何解锁SQLite数据库?相关推荐

  1. sqlite数据库加锁提交_怎样给sqlite数据库设定密码

    Sqlite数据库的加密1.创建空的sqlite数据库.//数据库名的后缀你可以直接指定,甚至没有后缀都可以//方法一:创建一个空sqlite数据库,用IO的方式FileStream fs = Fil ...

  2. 两个server 两个数据库 微服务_微服务的数据库设计

    单独的数据库: 微服务设计的一个关键是数据库设计,基本原则是每个服务都有自己单独的数据库,而且只有微服务本身可以访问这个数据库.它是基于下面三个原因. 优化服务接口:微服务之间的接口越小越好,最好只有 ...

  3. mysql操作数据库语句大全_常用的Mysql数据库操作语句大全整理

    一.用户管理: 1.新建用户: >create user name identified by 'ssapdrow'; 2.更改密码: >set password for name=pas ...

  4. 数据库类型少_全栈之数据库系列 - 数据库的设计、架构和使用规范

    当我们要存储的数据比较少的时候,数据库设计的优势并不能发挥出来,但是当我们对数据的需求量越来越大时,对数据库的设计就很有必要性了!如果数据库的设计不当会造成数据冗余.修改复杂.操作数据异常等问题,而好 ...

  5. mysql数据库前端缓存_什么是MySQL数据库的缓存池原理?看完或许就懂了

    前言 面试官:同学,你能说说Mysql 缓存池吗? 是CPP啊:啊,这么难吗,容我组织一下语言.(内心OS:这TM还不简单?我能给你扯半小时!) 面试官:可以,给你一分钟时间想一想吧. ....一分钟 ...

  6. 华为的mysql数据库如何登陆_怎么登陆mysql数据库

    {"moduleinfo":{"card_count":[{"count_phone":1,"count":1}],&q ...

  7. e4a数据库mysql中间件_[e4a同步内陆数据库至mysql]?确立一个中间件毗邻数据库

    首先是准备工作,同时这部门可以温习前面内容: 1.确立一个mysql数据库,写几个字段. 2.确立一个中心件毗邻数据库. 3.编写E4A程序毗邻该数据库. 然后就是几个操作历程: 4.用E4A实现数据 ...

  8. access2013数据库实验笔记_实验一 ACCESS数据库及表的操作

    1 .掌握数据库的创建及其它简单操作 2 .熟练掌握数据表建立.数据表维护.数据表的操作 二.实验容与要求 1 .数据库的创建.打开.关闭 2 .数据表的创建:建立表结构.设置字段属性.建立表之间关系 ...

  9. 得到mysql服务器所有数据库的列表_查看MySQL所有数据库列表

    1. 前言 本文主要讲解如何在Linux系统上查看MySQL所有数据库列表. 在管理MySQL数据库服务器时,最常见的任务之一就是熟悉环境.这包括查看驻留在服务器上的数据库.查看特定数据库的表或查看关 ...

最新文章

  1. xdoj 1114(线段树离线处理)
  2. lsa五类_OSPF外部路由4类5类LSA
  3. arcgis的python脚本-ArcGIS Python脚本使用
  4. Microsoft Hyper-V Server 2008 R2和SCVMM2012部署XenDesktop 5.6桌面虚拟化系列之二准备虚拟桌面模板...
  5. WildFly 8.2.0.Final版本–更改的快速概述
  6. 软件工程 案例分析作业
  7. 五分钟快速过完Verilog HDL基本概念(1)
  8. NYOJ 85:有趣的数(打表,规律)
  9. Dynamics CRM 2015中的SSRS Report集成配置
  10. 服务器系统2008网络发现,Windows Server 2008中解决局域网共享发现问题
  11. AI健身房真的存在?比炒概念更可怕的是VENTO已经做出来了
  12. 获取UI控件位置信息
  13. kafka数据丢包原因及解决方案
  14. poi解析excel(处理单元格公式)
  15. ros::Rate loop_rate(10); loop_rate.sleep(); 在程序中是休眠到一定时间,并不占用CPU时间
  16. 返回结果集Result类
  17. 4核处理器_AMD新款4核处理器899元,配一套电脑是不是可以更便宜了?
  18. OpenWrt TL-WR841N WAN口down问题
  19. PDF文件怎么转换成PPT
  20. 蚂蚁研究员玉伯:做一个简单自由有爱的技术人

热门文章

  1. esp8266~lwip突破MTU最大1500限制
  2. 点击BootStrap下拉框无反应
  3. 快应用:足以超越原生APP
  4. python tableau工作流_提取数据
  5. FPGA | Xilinx ISE14.7 LVDS应用
  6. 什么是二值图像、什么是灰度图像、什么是彩色图像?区别?
  7. Your configuration specifies to merge with the ref ‘refs/heads/develop‘from the remote, but no such
  8. 加密相册、保险箱App打开就闪退、点击提示App Store不提供应用、需要更新才能使用的解决方案
  9. 教你用Python感知女朋友的情绪变化?
  10. java 捕获 nullpointerexception,Android上无法捕获java.lang.NullPointerException