首页 > 数据库 >修复sqlite3数据库 database disk image is malformed

修复sqlite3数据库 database disk image is malformed

时间:2024-02-27 18:33:19浏览次数:31  
标签:.__ database self malformed sql sqlite3 path os

database disk image is malformed 错误

sqlite是一个文本型数据库,其内部虽然做了异常处理,且官网上也说一般的异常不会引起数据库文件损坏,但是官方还是给出了有可能导致数据库文件损坏的情况

以下内容来自官网:

SQLite 经过非常仔细的测试,以帮助确保它尽可能没有错误。对每个 SQLite 版本执行的众多测试包括模拟电源故障、I/O 错误和内存不足 (OOM) 错误的测试,并验证在任何这些事件期间不会发生数据库损坏。SQLite 还经过现场验证,约有 20 亿次活动部署,没有出现严重问题。

然而,没有一个软件是 100% 完美的。SQLite 中存在一些历史错误(现已修复),这些错误可能会导致数据库损坏。可能还有一些尚未被发现。由于 SQLite 的广泛测试和广泛使用,导致数据库损坏的错误往往非常隐蔽。应用程序遇到 SQLite bug 的可能性很小。为了说明这一点,下面列出了从 2009 年 4 月 1 日到 2013 年 4 月 15 日这四年期间在 SQLite 中发现的所有数据库损坏错误。这个帐户应该让读者直观地了解 SQLite 中的各种错误,这些错误设法通过测试过程并进入发布版本。

来源: How To Corrupt An SQLite Database File

修复方案一( 命令行手动修复)

  • 以下是在linux环境下执行的,如果是windows需要把sqlite3修改为sqlite3.exe。

  • 确保sqlite3在环境变量中,可以直接调用到,否则需要指明路径。

1.命令行打开sqlite3.exe并读取损坏的文件

sqlite3 CorruptDB

此时进入了sqlite命令行环境

2.导出sql语句到临时文件

sqlite>.output tmp.sql
sqlite>.dump
sqlite>.quit

3.修改tmp.sql文件

由于数据库文件损坏,所以sqlite自动将tmp.sql最后一行加上了一句Rollback,因此我们需要手动修改tmp.sql文件,将最后一行的Rollback改为Commit;

这一步是最重要的!!!

4.读取tmp.sql并写入到新库中

sqlite3 NewDB

sqlite>.read tmp.sql
sqlite>.quit

大功告成!

修复方案二(python脚本自动修复)

  • 一共有三个文件,一个python文件外加两个sql文件,原理是将方案一的所有操作集成为一个脚本执行。

三个文件内容如下

repair_tool.py

# -*- coding: utf-8 -*-
import os


class Repair(object):

    def __init__(self):

        # 前提是sqlite3已经添加到环境变量
        self.__sqlite3_path = "sqlite3"

        self.__path = os.path.dirname(os.path.abspath(__file__))
        self.__dbDir = os.path.join(os.path.dirname(os.path.dirname(self.__path)), "data")

        self.__tmpFilePath = os.path.join(self.__dbDir, "tmp.sql")

        self.__dbPath = os.path.join(self.__dbDir, "data.db")
        self.__newDbPath = os.path.join(self.__dbDir, "new_data.db")

        self.__dumpSqlPath = os.path.join(self.__path, "dump.sql")
        self.__readSqlPath = os.path.join(self.__path, "read.sql")

    def doRepair(self):
        # print("INFO: Starting repairing, please wait for a while.")
        self.__dumpSql()
        # print("INFO: DumpSql is successful.")
        self.__modLastLine()
        # print("INFO: Modify last line is successful.")
        self.__readSql()
        # print("INFO: ReadSql is successful.")
        self.__delTmp()
        # print("INFO: Delete TempFile is successful.")
        self.__copyDB()
        # print("INFO: Repairing is successful!")

    def __dumpSql(self):
        cmd = "cd " + self.__dbDir + "&&" + f'''{self.__sqlite3_path} {self.__dbPath}<{self.__dumpSqlPath}'''
        os.system(cmd)

    def __readSql(self):

        with open(self.__newDbPath, "a"):
            ...
        cmd = "cd " + self.__dbDir + "&&" + f'''{self.__sqlite3_path} {self.__newDbPath}<{self.__readSqlPath}'''
        os.system(cmd)

    def __delTmp(self):
        os.remove(self.__tmpFilePath)

    def __copyDB(self):

        os.remove(self.__dbPath)
        os.rename(self.__newDbPath, self.__dbPath)

    def __modLastLine(self):
        with open(self.__tmpFilePath, "rb+") as f:
            file_size = os.path.getsize(self.__tmpFilePath)
            offset = -8

            while -1 * offset < file_size:
                f.seek(offset, os.SEEK_END)
                lines = f.readlines()
                if len(lines) >= 2:
                    last_line_len = len(lines[-1])
                    f.seek(-last_line_len, os.SEEK_END)
                    f.truncate()
                    f.write(b"Commit;")
                    return
                else:
                    offset *= 2


if __name__ == "__main__":
    repair = Repair()
    repair.doRepair()

dump.sql

.output tmp.sql
.dump
.quit

read.sql

.read tmp.sql
.quit

标签:.__,database,self,malformed,sql,sqlite3,path,os
From: https://www.cnblogs.com/liuyangQAQ/p/18037546

相关文章

  • Oracle设置日志参数-ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
    要实现两个数据库之间的实时同步,需要给Oracle设置参数ALTERDATABASEADDSUPPLEMENTALLOGDATA;--执行了12小时,等待数据库中的其它事务都提交以后才执行完成ALTERDATABASEADDSUPPLEMENTALLOGDATA(PRIMARYKEY)COLUMNS;ALTERDATABASEADDSUPPLEMENTALLOGDATA(......
  • SQL Server Accelerated Database Recovery调研
    背景  作为RDS for SQL Server团队,我们给用户提供核心的商业数据库服务,而数据库服务的SLA至关重要,而RTO又是数据库SLA的重要部分,但最近对于一些使用大规格实例的GC6以上客户,出现过一些由于重启/HA导致花费较长时间在数据库恢复过程,从而导致长时间服务不可用,严重影响了我们......
  • ERROR 1044 (42000): Access denied for user 'root'@'%' to database 'mysql&
    转自https://www.cnblogs.com/jiangfeilong/p/10560754.html 关键要授予 WITHGRANTOPTION;#原因:修改数据库账号时删除了默认的localhostroot, 新建了%root 但没有赋予全部权限;解决方法:1.关闭数据库#mysqldstop2.在my.cnf里加入skip-grant-tables3.停止服务器......
  • SpringBoot3 整合 SQLite3 + MybatisPuls
    !!前置要求!!假设你已经掌握SpringBoot3、Maven、Mybaits、MybatisPuls。假设你已经新建好SQLite3测试库。如果没有可以按此结构新建,保存到任意位置。1.项目结构2.依赖注意SpringBoot3版本这边用最新的打包失败,所以改用3.1.2pom.xml<?xmlversion="1.0"encoding="......
  • 详解'unicodeescape' codec can't decode bytes in position 16-17: malformed \N ch
    详解'unicodeescape'codeccan'tdecodebytesinposition16-17:malformed\Ncharacterescape在Python的字符串处理中,有时候可能会遇到如下错误信息:'unicodeescape'codeccan'tdecodebytesinposition16-17:malformed\Ncharacterescape。本篇文章将详细解释这个错......
  • [perl]: perl to database ( MariaDB )
    [perl]:  perl to database(MariaDB)     一、说明 1、暂无  二、源码1#!/usr/bin/perl-w234#file_name:db.pl567usestrict;8useDBI;910subdatabase11{12my$host="192.168.11.30";......
  • FastAPI学习-28 alembic数据迁移报错:Target database is not up to date 报错解决办法
    前言当表结构有变更,数据迁移时,出现报错:Targetdatabaseisnotuptodate遇到的问题执行迁移命令alembicrevision--autogenerate-m"testv4"出现如下报错>alembicrevision--autogenerate-m"testv4"INFO[alembic.runtime.migration]ContextimplMySQLImpl.INFO[alem......
  • FastAPI学习-28 alembic数据迁移报错:Target database is not up to date 报错解决办法
    前言当表结构有变更,数据迁移时,出现报错:Targetdatabaseisnotuptodate遇到的问题执行迁移命令alembicrevision--autogenerate-m"testv4"出现如下报错>alembicrevision--autogenerate-m"testv4"INFO[alembic.runtime.migration]ContextimplMySQLImpl.INF......
  • ORA-01102: cannot mount database in EXCLUSIVE mode的错误解决
    数据库运行环境oracle19c,安装后,启动数据库时报错,如下,经排查解决方法记录如下SQL>startupmountORACLEinstancestarted.TotalSystemGlobalArea2415917880bytesFixedSize   8899384bytesVariableSize  520093696bytesDatabaseBuffers 1879048192bytes......
  • 如何对Azure Database for MySQL进行数据恢复
    如何对AzureDatabaseforMySQL进行数据恢复一般情况下,我们使用Azure中的PaaS数据库产品是时,我们不仅不用关心数据库底层的基础设施部署,同样也不用担心数据库的备份。在AzurePaaS数据库产品中,都内置了数据库备份的功能,作为用户而言,我们不需要为数据库备份这个功能付费,只需要对备......